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-2012 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_libcsetjmp.h"   // to keep _threadstate.h happy
37#include "pub_core_threadstate.h"
38#include "pub_core_aspacemgr.h"
39#include "pub_core_debuginfo.h"    // VG_(di_notify_*)
40#include "pub_core_transtab.h"     // VG_(discard_translations)
41#include "pub_core_xarray.h"
42#include "pub_core_clientstate.h"
43#include "pub_core_debuglog.h"
44#include "pub_core_libcbase.h"
45#include "pub_core_libcassert.h"
46#include "pub_core_libcfile.h"
47#include "pub_core_libcprint.h"
48#include "pub_core_libcproc.h"
49#include "pub_core_libcsignal.h"
50#include "pub_core_machine.h"      // VG_(get_SP)
51#include "pub_core_mallocfree.h"
52#include "pub_core_tooliface.h"
53#include "pub_core_options.h"
54#include "pub_core_scheduler.h"
55#include "pub_core_signals.h"
56#include "pub_core_syscall.h"
57#include "pub_core_syswrap.h"
58#include "pub_tool_inner.h"
59#if defined(ENABLE_INNER_CLIENT_REQUEST)
60#include "valgrind.h"
61#endif
62
63#include "priv_types_n_macros.h"
64#include "priv_syswrap-generic.h"
65#include "priv_syswrap-linux.h"
66
67
68// Run a thread from beginning to end and return the thread's
69// scheduler-return-code.
70static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
71{
72   VgSchedReturnCode ret;
73   ThreadId     tid = (ThreadId)tidW;
74   ThreadState* tst = VG_(get_ThreadState)(tid);
75
76   VG_(debugLog)(1, "syswrap-linux",
77                    "thread_wrapper(tid=%lld): entry\n",
78                    (ULong)tidW);
79
80   vg_assert(tst->status == VgTs_Init);
81
82   /* make sure we get the CPU lock before doing anything significant */
83   VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
84
85   if (0)
86      VG_(printf)("thread tid %d started: stack = %p\n",
87		  tid, &tid);
88
89   /* Make sure error reporting is enabled in the new thread. */
90   tst->err_disablement_level = 0;
91
92   VG_TRACK(pre_thread_first_insn, tid);
93
94   tst->os_state.lwpid = VG_(gettid)();
95   /* Set the threadgroup for real.  This overwrites the provisional
96      value set in do_clone() syswrap-*-linux.c.  See comments in
97      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=%lld): exit\n",
112                    (ULong)tidW);
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=%lld): pre-thread_wrapper\n",
137                    (ULong)tidW);
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=%lld): post-thread_wrapper\n",
160                    (ULong)tidW);
161
162   c = VG_(count_living_threads)();
163   vg_assert(c >= 1); /* stay sane */
164
165   // Tell the tool this thread is exiting
166   VG_TRACK( pre_thread_ll_exit, tid );
167
168   /* If the thread is exiting with errors disabled, complain loudly;
169      doing so is bad (does the user know this has happened?)  Also,
170      in all cases, be paranoid and clear the flag anyway so that the
171      thread slot is safe in this respect if later reallocated.  This
172      should be unnecessary since the flag should be cleared when the
173      slot is reallocated, in thread_wrapper(). */
174   if (tst->err_disablement_level > 0) {
175      VG_(umsg)(
176         "WARNING: exiting thread has error reporting disabled.\n"
177         "WARNING: possibly as a result of some mistake in the use\n"
178         "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
179      );
180      VG_(debugLog)(
181         1, "syswrap-linux",
182            "run_a_thread_NORETURN(tid=%lld): "
183            "WARNING: exiting thread has err_disablement_level = %u\n",
184            (ULong)tidW, tst->err_disablement_level
185      );
186   }
187   tst->err_disablement_level = 0;
188
189   if (c == 1) {
190
191      VG_(debugLog)(1, "syswrap-linux",
192                       "run_a_thread_NORETURN(tid=%lld): "
193                          "last one standing\n",
194                          (ULong)tidW);
195
196      /* We are the last one standing.  Keep hold of the lock and
197         carry on to show final tool results, then exit the entire system.
198         Use the continuation pointer set at startup in m_main. */
199      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
200
201   } else {
202
203      VG_(debugLog)(1, "syswrap-linux",
204                       "run_a_thread_NORETURN(tid=%lld): "
205                          "not last one standing\n",
206                          (ULong)tidW);
207
208      /* OK, thread is dead, but others still exist.  Just exit. */
209
210      /* This releases the run lock */
211      VG_(exit_thread)(tid);
212      vg_assert(tst->status == VgTs_Zombie);
213
214      INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
215
216      /* We have to use this sequence to terminate the thread to
217         prevent a subtle race.  If VG_(exit_thread)() had left the
218         ThreadState as Empty, then it could have been reallocated,
219         reusing the stack while we're doing these last cleanups.
220         Instead, VG_(exit_thread) leaves it as Zombie to prevent
221         reallocation.  We need to make sure we don't touch the stack
222         between marking it Empty and exiting.  Hence the
223         assembler. */
224#if defined(VGP_x86_linux)
225      asm volatile (
226         "pushl %%ebx\n"
227         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
228         "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
229         "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
230         "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
231	 "popl %%ebx\n"
232         : "=m" (tst->status)
233         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
234         : "eax"
235      );
236#elif defined(VGP_amd64_linux)
237      asm volatile (
238         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
239         "movq	%2, %%rax\n"    /* set %rax = __NR_exit */
240         "movq	%3, %%rdi\n"    /* set %rdi = tst->os_state.exitcode */
241         "syscall\n"		/* exit(tst->os_state.exitcode) */
242         : "=m" (tst->status)
243         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
244         : "rax", "rdi"
245      );
246#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
247      { UInt vgts_empty = (UInt)VgTs_Empty;
248        asm volatile (
249          "stw %1,%0\n\t"          /* set tst->status = VgTs_Empty */
250          "li  0,%2\n\t"           /* set r0 = __NR_exit */
251          "lwz 3,%3\n\t"           /* set r3 = tst->os_state.exitcode */
252          "sc\n\t"                 /* exit(tst->os_state.exitcode) */
253          : "=m" (tst->status)
254          : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
255          : "r0", "r3"
256        );
257      }
258#elif defined(VGP_arm_linux)
259      asm volatile (
260         "str  %1, %0\n"      /* set tst->status = VgTs_Empty */
261         "mov  r7, %2\n"      /* set %r7 = __NR_exit */
262         "ldr  r0, %3\n"      /* set %r0 = tst->os_state.exitcode */
263         "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
264         : "=m" (tst->status)
265         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
266         : "r0", "r7"
267      );
268#elif defined(VGP_s390x_linux)
269      asm volatile (
270         "st   %1, %0\n"        /* set tst->status = VgTs_Empty */
271         "lg   2, %3\n"         /* set r2 = tst->os_state.exitcode */
272         "svc %2\n"             /* exit(tst->os_state.exitcode) */
273         : "=m" (tst->status)
274         : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
275         : "2"
276      );
277#elif defined(VGP_mips32_linux)
278      asm volatile (
279         "sw   %1, %0\n\t"     /* set tst->status = VgTs_Empty */
280         "li  	$2, %2\n\t"     /* set v0 = __NR_exit */
281         "lw   $4, %3\n\t"     /* set a0 = tst->os_state.exitcode */
282         "syscall\n\t"         /* exit(tst->os_state.exitcode) */
283         "nop"
284         : "=m" (tst->status)
285         : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
286         : "cc", "memory" , "v0", "a0"
287      );
288#else
289# error Unknown platform
290#endif
291
292      VG_(core_panic)("Thread exit failed?\n");
293   }
294
295   /*NOTREACHED*/
296   vg_assert(0);
297}
298
299Word ML_(start_thread_NORETURN) ( void* arg )
300{
301   ThreadState* tst = (ThreadState*)arg;
302   ThreadId     tid = tst->tid;
303
304   run_a_thread_NORETURN ( (Word)tid );
305   /*NOTREACHED*/
306   vg_assert(0);
307}
308
309/* Allocate a stack for this thread, if it doesn't already have one.
310   They're allocated lazily, and never freed.  Returns the initial stack
311   pointer value to use, or 0 if allocation failed. */
312Addr ML_(allocstack)(ThreadId tid)
313{
314   ThreadState* tst = VG_(get_ThreadState)(tid);
315   VgStack*     stack;
316   Addr         initial_SP;
317
318   /* Either the stack_base and stack_init_SP are both zero (in which
319      case a stack hasn't been allocated) or they are both non-zero,
320      in which case it has. */
321
322   if (tst->os_state.valgrind_stack_base == 0)
323      vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
324
325   if (tst->os_state.valgrind_stack_base != 0)
326      vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
327
328   /* If no stack is present, allocate one. */
329
330   if (tst->os_state.valgrind_stack_base == 0) {
331      stack = VG_(am_alloc_VgStack)( &initial_SP );
332      if (stack) {
333         tst->os_state.valgrind_stack_base    = (Addr)stack;
334         tst->os_state.valgrind_stack_init_SP = initial_SP;
335      }
336   }
337
338   if (0)
339      VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
340                   tid,
341                   (void*)tst->os_state.valgrind_stack_base,
342                   (void*)tst->os_state.valgrind_stack_init_SP );
343
344   return tst->os_state.valgrind_stack_init_SP;
345}
346
347/* Allocate a stack for the main thread, and run it all the way to the
348   end.  Although we already have a working VgStack
349   (VG_(interim_stack)) it's better to allocate a new one, so that
350   overflow detection works uniformly for all threads.
351*/
352void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
353{
354   Addr sp;
355   VG_(debugLog)(1, "syswrap-linux",
356                    "entering VG_(main_thread_wrapper_NORETURN)\n");
357
358   sp = ML_(allocstack)(tid);
359#if defined(ENABLE_INNER_CLIENT_REQUEST)
360   {
361      // we must register the main thread stack before the call
362      // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
363      // reports 'write error' on the non registered stack.
364      ThreadState* tst = VG_(get_ThreadState)(tid);
365      INNER_REQUEST
366         ((void)
367          VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
368                                   tst->os_state.valgrind_stack_init_SP));
369   }
370#endif
371
372#if defined(VGP_ppc32_linux)
373   /* make a stack frame */
374   sp -= 16;
375   sp &= ~0xF;
376   *(UWord *)sp = 0;
377#elif defined(VGP_ppc64_linux)
378   /* make a stack frame */
379   sp -= 112;
380   sp &= ~((Addr)0xF);
381   *(UWord *)sp = 0;
382#elif defined(VGP_s390x_linux)
383   /* make a stack frame */
384   sp -= 160;
385   sp &= ~((Addr)0xF);
386   *(UWord *)sp = 0;
387#endif
388
389   /* If we can't even allocate the first thread's stack, we're hosed.
390      Give up. */
391   vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
392
393   /* shouldn't be any other threads around yet */
394   vg_assert( VG_(count_living_threads)() == 1 );
395
396   ML_(call_on_new_stack_0_1)(
397      (Addr)sp,               /* stack */
398      0,                      /* bogus return address */
399      run_a_thread_NORETURN,  /* fn to call */
400      (Word)tid               /* arg to give it */
401   );
402
403   /*NOTREACHED*/
404   vg_assert(0);
405}
406
407
408/* Do a clone which is really a fork() */
409SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
410                            Int* parent_tidptr, Int* child_tidptr )
411{
412   vki_sigset_t fork_saved_mask;
413   vki_sigset_t mask;
414   SysRes       res;
415
416   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
417                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
418      return VG_(mk_SysRes_Error)( VKI_EINVAL );
419
420   /* Block all signals during fork, so that we can fix things up in
421      the child without being interrupted. */
422   VG_(sigfillset)(&mask);
423   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
424
425   VG_(do_atfork_pre)(tid);
426
427   /* Since this is the fork() form of clone, we don't need all that
428      VG_(clone) stuff */
429#if defined(VGP_x86_linux) \
430    || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
431    || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
432   res = VG_(do_syscall5)( __NR_clone, flags,
433                           (UWord)NULL, (UWord)parent_tidptr,
434                           (UWord)NULL, (UWord)child_tidptr );
435#elif defined(VGP_amd64_linux)
436   /* note that the last two arguments are the opposite way round to x86 and
437      ppc32 as the amd64 kernel expects the arguments in a different order */
438   res = VG_(do_syscall5)( __NR_clone, flags,
439                           (UWord)NULL, (UWord)parent_tidptr,
440                           (UWord)child_tidptr, (UWord)NULL );
441#elif defined(VGP_s390x_linux)
442   /* Note that s390 has the stack first and then the flags */
443   res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
444                          (UWord)parent_tidptr, (UWord)child_tidptr);
445#else
446# error Unknown platform
447#endif
448
449   if (!sr_isError(res) && sr_Res(res) == 0) {
450      /* child */
451      VG_(do_atfork_child)(tid);
452
453      /* restore signal mask */
454      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
455
456      /* If --child-silent-after-fork=yes was specified, set the
457         output file descriptors to 'impossible' values.  This is
458         noticed by send_bytes_to_logging_sink in m_libcprint.c, which
459         duly stops writing any further output. */
460      if (VG_(clo_child_silent_after_fork)) {
461         if (!VG_(log_output_sink).is_socket)
462            VG_(log_output_sink).fd = -1;
463         if (!VG_(xml_output_sink).is_socket)
464            VG_(xml_output_sink).fd = -1;
465      }
466   }
467   else
468   if (!sr_isError(res) && sr_Res(res) > 0) {
469      /* parent */
470      VG_(do_atfork_parent)(tid);
471
472      if (VG_(clo_trace_syscalls))
473	  VG_(printf)("   clone(fork): process %d created child %ld\n",
474                      VG_(getpid)(), sr_Res(res));
475
476      /* restore signal mask */
477      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
478   }
479
480   return res;
481}
482
483
484/* ---------------------------------------------------------------------
485   PRE/POST wrappers for arch-generic, Linux-specific syscalls
486   ------------------------------------------------------------------ */
487
488// Nb: See the comment above the generic PRE/POST wrappers in
489// m_syswrap/syswrap-generic.c for notes about how they work.
490
491#define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
492#define POST(name)      DEFN_POST_TEMPLATE(linux, name)
493
494// Macros to support 64-bit syscall args split into two 32 bit values
495#define LOHI64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
496#if defined(VG_LITTLEENDIAN)
497#define MERGE64(lo,hi)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
498#define MERGE64_FIRST(name) name##_low
499#define MERGE64_SECOND(name) name##_high
500#elif defined(VG_BIGENDIAN)
501#define MERGE64(hi,lo)   ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
502#define MERGE64_FIRST(name) name##_high
503#define MERGE64_SECOND(name) name##_low
504#else
505#error Unknown endianness
506#endif
507
508/* ---------------------------------------------------------------------
509   *mount wrappers
510   ------------------------------------------------------------------ */
511
512PRE(sys_mount)
513{
514   // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
515   // We are conservative and check everything, except the memory pointed to
516   // by 'data'.
517   *flags |= SfMayBlock;
518   PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx(%s), %#lx, %#lx )",
519         ARG1,(Char*)ARG1, ARG2,(Char*)ARG2, ARG3,(Char*)ARG3, ARG4, ARG5);
520   PRE_REG_READ5(long, "mount",
521                 char *, source, char *, target, char *, type,
522                 unsigned long, flags, void *, data);
523   if (ARG1)
524      PRE_MEM_RASCIIZ( "mount(source)", ARG1);
525   PRE_MEM_RASCIIZ( "mount(target)", ARG2);
526   PRE_MEM_RASCIIZ( "mount(type)", ARG3);
527}
528
529PRE(sys_oldumount)
530{
531   PRINT("sys_oldumount( %#lx )", ARG1);
532   PRE_REG_READ1(long, "umount", char *, path);
533   PRE_MEM_RASCIIZ( "umount(path)", ARG1);
534}
535
536PRE(sys_umount)
537{
538   PRINT("sys_umount( %#lx, %ld )", ARG1, ARG2);
539   PRE_REG_READ2(long, "umount2", char *, path, int, flags);
540   PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
541}
542
543/* ---------------------------------------------------------------------
544   16- and 32-bit uid/gid wrappers
545   ------------------------------------------------------------------ */
546
547PRE(sys_setfsuid16)
548{
549   PRINT("sys_setfsuid16 ( %ld )", ARG1);
550   PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
551}
552
553PRE(sys_setfsuid)
554{
555   PRINT("sys_setfsuid ( %ld )", ARG1);
556   PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
557}
558
559PRE(sys_setfsgid16)
560{
561   PRINT("sys_setfsgid16 ( %ld )", ARG1);
562   PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
563}
564
565PRE(sys_setfsgid)
566{
567   PRINT("sys_setfsgid ( %ld )", ARG1);
568   PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
569}
570
571PRE(sys_setresuid16)
572{
573   PRINT("sys_setresuid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
574   PRE_REG_READ3(long, "setresuid16",
575                 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
576}
577
578PRE(sys_setresuid)
579{
580   PRINT("sys_setresuid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
581   PRE_REG_READ3(long, "setresuid",
582                 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
583}
584
585PRE(sys_getresuid16)
586{
587   PRINT("sys_getresuid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
588   PRE_REG_READ3(long, "getresuid16",
589                 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
590                 vki_old_uid_t *, suid);
591   PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
592   PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
593   PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
594}
595POST(sys_getresuid16)
596{
597   vg_assert(SUCCESS);
598   if (RES == 0) {
599      POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
600      POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
601      POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
602   }
603}
604
605PRE(sys_getresuid)
606{
607   PRINT("sys_getresuid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
608   PRE_REG_READ3(long, "getresuid",
609                 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
610   PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
611   PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
612   PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
613}
614POST(sys_getresuid)
615{
616   vg_assert(SUCCESS);
617   if (RES == 0) {
618      POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
619      POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
620      POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
621   }
622}
623
624PRE(sys_setresgid16)
625{
626   PRINT("sys_setresgid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
627   PRE_REG_READ3(long, "setresgid16",
628                 vki_old_gid_t, rgid,
629                 vki_old_gid_t, egid, vki_old_gid_t, sgid);
630}
631
632PRE(sys_setresgid)
633{
634   PRINT("sys_setresgid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
635   PRE_REG_READ3(long, "setresgid",
636                 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
637}
638
639PRE(sys_getresgid16)
640{
641   PRINT("sys_getresgid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
642   PRE_REG_READ3(long, "getresgid16",
643                 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
644                 vki_old_gid_t *, sgid);
645   PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
646   PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
647   PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
648}
649POST(sys_getresgid16)
650{
651   vg_assert(SUCCESS);
652   if (RES == 0) {
653      POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
654      POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
655      POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
656   }
657}
658
659PRE(sys_getresgid)
660{
661   PRINT("sys_getresgid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
662   PRE_REG_READ3(long, "getresgid",
663                 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
664   PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
665   PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
666   PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
667}
668POST(sys_getresgid)
669{
670   vg_assert(SUCCESS);
671   if (RES == 0) {
672      POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
673      POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
674      POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
675   }
676}
677
678/* ---------------------------------------------------------------------
679   miscellaneous wrappers
680   ------------------------------------------------------------------ */
681
682PRE(sys_exit_group)
683{
684   ThreadId     t;
685   ThreadState* tst;
686
687   PRINT("exit_group( %ld )", ARG1);
688   PRE_REG_READ1(void, "exit_group", int, status);
689
690   tst = VG_(get_ThreadState)(tid);
691
692   /* A little complex; find all the threads with the same threadgroup
693      as this one (including this one), and mark them to exit */
694   for (t = 1; t < VG_N_THREADS; t++) {
695      if ( /* not alive */
696           VG_(threads)[t].status == VgTs_Empty
697           ||
698	   /* not our group */
699           VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
700         )
701         continue;
702
703      VG_(threads)[t].exitreason = VgSrc_ExitThread;
704      VG_(threads)[t].os_state.exitcode = ARG1;
705
706      if (t != tid)
707	 VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */
708   }
709
710   /* We have to claim the syscall already succeeded. */
711   SET_STATUS_Success(0);
712}
713
714PRE(sys_llseek)
715{
716   PRINT("sys_llseek ( %ld, 0x%lx, 0x%lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5);
717   PRE_REG_READ5(long, "llseek",
718                 unsigned int, fd, unsigned long, offset_high,
719                 unsigned long, offset_low, vki_loff_t *, result,
720                 unsigned int, whence);
721   if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
722      SET_STATUS_Failure( VKI_EBADF );
723   else
724      PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
725}
726POST(sys_llseek)
727{
728   vg_assert(SUCCESS);
729   if (RES == 0)
730      POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
731}
732
733PRE(sys_adjtimex)
734{
735   struct vki_timex *tx = (struct vki_timex *)ARG1;
736   PRINT("sys_adjtimex ( %#lx )", ARG1);
737   PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
738   PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
739
740#define ADJX(bits,field) 				\
741   if (tx->modes & (bits))                              \
742      PRE_MEM_READ( "adjtimex(timex->"#field")",	\
743		    (Addr)&tx->field, sizeof(tx->field))
744
745   if (tx->modes & VKI_ADJ_ADJTIME) {
746      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
747         PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
748   } else {
749      ADJX(VKI_ADJ_OFFSET, offset);
750      ADJX(VKI_ADJ_FREQUENCY, freq);
751      ADJX(VKI_ADJ_MAXERROR, maxerror);
752      ADJX(VKI_ADJ_ESTERROR, esterror);
753      ADJX(VKI_ADJ_STATUS, status);
754      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
755      ADJX(VKI_ADJ_TICK, tick);
756   }
757#undef ADJX
758
759   PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
760}
761
762POST(sys_adjtimex)
763{
764   POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
765}
766
767PRE(sys_ioperm)
768{
769   PRINT("sys_ioperm ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
770   PRE_REG_READ3(long, "ioperm",
771                 unsigned long, from, unsigned long, num, int, turn_on);
772}
773
774PRE(sys_syslog)
775{
776   *flags |= SfMayBlock;
777   PRINT("sys_syslog (%ld, %#lx, %ld)", ARG1,ARG2,ARG3);
778   PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
779   switch (ARG1) {
780   // The kernel uses magic numbers here, rather than named constants,
781   // therefore so do we.
782   case 2: case 3: case 4:
783      PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
784      break;
785   default:
786      break;
787   }
788}
789POST(sys_syslog)
790{
791   switch (ARG1) {
792   case 2: case 3: case 4:
793      POST_MEM_WRITE( ARG2, ARG3 );
794      break;
795   default:
796      break;
797   }
798}
799
800PRE(sys_vhangup)
801{
802   PRINT("sys_vhangup ( )");
803   PRE_REG_READ0(long, "vhangup");
804}
805
806PRE(sys_sysinfo)
807{
808   PRINT("sys_sysinfo ( %#lx )",ARG1);
809   PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
810   PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
811}
812POST(sys_sysinfo)
813{
814   POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
815}
816
817PRE(sys_personality)
818{
819   PRINT("sys_personality ( %llu )", (ULong)ARG1);
820   PRE_REG_READ1(long, "personality", vki_u_long, persona);
821}
822
823PRE(sys_sysctl)
824{
825   struct __vki_sysctl_args *args;
826   PRINT("sys_sysctl ( %#lx )", ARG1 );
827   args = (struct __vki_sysctl_args *)ARG1;
828   PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
829   PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
830   if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
831                                          VKI_PROT_READ)) {
832      SET_STATUS_Failure( VKI_EFAULT );
833      return;
834   }
835
836   PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
837   if (args->newval != NULL)
838      PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
839   if (args->oldlenp != NULL) {
840      PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
841      PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
842   }
843}
844POST(sys_sysctl)
845{
846   struct __vki_sysctl_args *args;
847   args = (struct __vki_sysctl_args *)ARG1;
848   if (args->oldlenp != NULL) {
849      POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
850      POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
851   }
852}
853
854PRE(sys_prctl)
855{
856   *flags |= SfMayBlock;
857   PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4, ARG5 );
858   switch (ARG1) {
859   case VKI_PR_SET_PDEATHSIG:
860      PRE_REG_READ2(int, "prctl", int, option, int, signal);
861      break;
862   case VKI_PR_GET_PDEATHSIG:
863      PRE_REG_READ2(int, "prctl", int, option, int *, signal);
864      PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
865      break;
866   case VKI_PR_GET_DUMPABLE:
867      PRE_REG_READ1(int, "prctl", int, option);
868      break;
869   case VKI_PR_SET_DUMPABLE:
870      PRE_REG_READ2(int, "prctl", int, option, int, dump);
871      break;
872   case VKI_PR_GET_UNALIGN:
873      PRE_REG_READ2(int, "prctl", int, option, int *, value);
874      PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
875      break;
876   case VKI_PR_SET_UNALIGN:
877      PRE_REG_READ2(int, "prctl", int, option, int, value);
878      break;
879   case VKI_PR_GET_KEEPCAPS:
880      PRE_REG_READ1(int, "prctl", int, option);
881      break;
882   case VKI_PR_SET_KEEPCAPS:
883      PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
884      break;
885   case VKI_PR_GET_FPEMU:
886      PRE_REG_READ2(int, "prctl", int, option, int *, value);
887      PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
888      break;
889   case VKI_PR_SET_FPEMU:
890      PRE_REG_READ2(int, "prctl", int, option, int, value);
891      break;
892   case VKI_PR_GET_FPEXC:
893      PRE_REG_READ2(int, "prctl", int, option, int *, value);
894      PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
895      break;
896   case VKI_PR_SET_FPEXC:
897      PRE_REG_READ2(int, "prctl", int, option, int, value);
898      break;
899   case VKI_PR_GET_TIMING:
900      PRE_REG_READ1(int, "prctl", int, option);
901      break;
902   case VKI_PR_SET_TIMING:
903      PRE_REG_READ2(int, "prctl", int, option, int, timing);
904      break;
905   case VKI_PR_SET_NAME:
906      PRE_REG_READ2(int, "prctl", int, option, char *, name);
907      PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
908      break;
909   case VKI_PR_GET_NAME:
910      PRE_REG_READ2(int, "prctl", int, option, char *, name);
911      PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
912      break;
913   case VKI_PR_GET_ENDIAN:
914      PRE_REG_READ2(int, "prctl", int, option, int *, value);
915      PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
916      break;
917   case VKI_PR_SET_ENDIAN:
918      PRE_REG_READ2(int, "prctl", int, option, int, value);
919      break;
920   default:
921      PRE_REG_READ5(long, "prctl",
922                    int, option, unsigned long, arg2, unsigned long, arg3,
923                    unsigned long, arg4, unsigned long, arg5);
924      break;
925   }
926}
927POST(sys_prctl)
928{
929   switch (ARG1) {
930   case VKI_PR_GET_PDEATHSIG:
931      POST_MEM_WRITE(ARG2, sizeof(Int));
932      break;
933   case VKI_PR_GET_UNALIGN:
934      POST_MEM_WRITE(ARG2, sizeof(Int));
935      break;
936   case VKI_PR_GET_FPEMU:
937      POST_MEM_WRITE(ARG2, sizeof(Int));
938      break;
939   case VKI_PR_GET_FPEXC:
940      POST_MEM_WRITE(ARG2, sizeof(Int));
941      break;
942   case VKI_PR_GET_NAME:
943      POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
944      break;
945   case VKI_PR_GET_ENDIAN:
946      POST_MEM_WRITE(ARG2, sizeof(Int));
947      break;
948   }
949}
950
951PRE(sys_sendfile)
952{
953   *flags |= SfMayBlock;
954   PRINT("sys_sendfile ( %ld, %ld, %#lx, %lu )", ARG1,ARG2,ARG3,ARG4);
955   PRE_REG_READ4(ssize_t, "sendfile",
956                 int, out_fd, int, in_fd, vki_off_t *, offset,
957                 vki_size_t, count);
958   if (ARG3 != 0)
959      PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
960}
961POST(sys_sendfile)
962{
963   if (ARG3 != 0 ) {
964      POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
965   }
966}
967
968PRE(sys_sendfile64)
969{
970   *flags |= SfMayBlock;
971   PRINT("sendfile64 ( %ld, %ld, %#lx, %lu )",ARG1,ARG2,ARG3,ARG4);
972   PRE_REG_READ4(ssize_t, "sendfile64",
973                 int, out_fd, int, in_fd, vki_loff_t *, offset,
974                 vki_size_t, count);
975   if (ARG3 != 0)
976      PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
977}
978POST(sys_sendfile64)
979{
980   if (ARG3 != 0 ) {
981      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
982   }
983}
984
985PRE(sys_futex)
986{
987   /*
988      arg    param                              used by ops
989
990      ARG1 - u32 *futex				all
991      ARG2 - int op
992      ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
993      ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
994      ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
995      ARG6 - int val3				CMP_REQUEUE
996    */
997   PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
998   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
999   case VKI_FUTEX_CMP_REQUEUE:
1000   case VKI_FUTEX_WAKE_OP:
1001   case VKI_FUTEX_CMP_REQUEUE_PI:
1002      PRE_REG_READ6(long, "futex",
1003                    vki_u32 *, futex, int, op, int, val,
1004                    struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1005      break;
1006   case VKI_FUTEX_REQUEUE:
1007   case VKI_FUTEX_WAIT_REQUEUE_PI:
1008      PRE_REG_READ5(long, "futex",
1009                    vki_u32 *, futex, int, op, int, val,
1010                    struct timespec *, utime, vki_u32 *, uaddr2);
1011      break;
1012   case VKI_FUTEX_WAIT_BITSET:
1013      /* Check that the address at least begins in client-accessible area. */
1014      if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1015            SET_STATUS_Failure( VKI_EFAULT );
1016            return;
1017      }
1018      if (*(vki_u32 *)ARG1 != ARG3) {
1019         PRE_REG_READ5(long, "futex",
1020                       vki_u32 *, futex, int, op, int, val,
1021                       struct timespec *, utime, int, dummy);
1022      } else {
1023         PRE_REG_READ6(long, "futex",
1024                       vki_u32 *, futex, int, op, int, val,
1025                       struct timespec *, utime, int, dummy, int, val3);
1026      }
1027      break;
1028   case VKI_FUTEX_WAKE_BITSET:
1029      PRE_REG_READ6(long, "futex",
1030                    vki_u32 *, futex, int, op, int, val,
1031                    int, dummy, int, dummy2, int, val3);
1032      break;
1033   case VKI_FUTEX_WAIT:
1034   case VKI_FUTEX_LOCK_PI:
1035      PRE_REG_READ4(long, "futex",
1036                    vki_u32 *, futex, int, op, int, val,
1037                    struct timespec *, utime);
1038      break;
1039   case VKI_FUTEX_WAKE:
1040   case VKI_FUTEX_FD:
1041   case VKI_FUTEX_TRYLOCK_PI:
1042      PRE_REG_READ3(long, "futex",
1043                    vki_u32 *, futex, int, op, int, val);
1044      break;
1045   case VKI_FUTEX_UNLOCK_PI:
1046   default:
1047      PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1048      break;
1049   }
1050
1051   *flags |= SfMayBlock;
1052
1053   switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1054   case VKI_FUTEX_WAIT:
1055   case VKI_FUTEX_LOCK_PI:
1056   case VKI_FUTEX_WAIT_BITSET:
1057   case VKI_FUTEX_WAIT_REQUEUE_PI:
1058      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1059      if (ARG4 != 0)
1060	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1061      break;
1062
1063   case VKI_FUTEX_REQUEUE:
1064   case VKI_FUTEX_CMP_REQUEUE:
1065   case VKI_FUTEX_CMP_REQUEUE_PI:
1066   case VKI_FUTEX_WAKE_OP:
1067      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1068      PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1069      break;
1070
1071   case VKI_FUTEX_FD:
1072   case VKI_FUTEX_TRYLOCK_PI:
1073   case VKI_FUTEX_UNLOCK_PI:
1074      PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1075     break;
1076
1077   case VKI_FUTEX_WAKE:
1078   case VKI_FUTEX_WAKE_BITSET:
1079      /* no additional pointers */
1080      break;
1081
1082   default:
1083      SET_STATUS_Failure( VKI_ENOSYS );   // some futex function we don't understand
1084      break;
1085   }
1086}
1087POST(sys_futex)
1088{
1089   vg_assert(SUCCESS);
1090   POST_MEM_WRITE( ARG1, sizeof(int) );
1091   if (ARG2 == VKI_FUTEX_FD) {
1092      if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1093         VG_(close)(RES);
1094         SET_STATUS_Failure( VKI_EMFILE );
1095      } else {
1096         if (VG_(clo_track_fds))
1097            ML_(record_fd_open_nameless)(tid, RES);
1098      }
1099   }
1100}
1101
1102PRE(sys_set_robust_list)
1103{
1104   PRINT("sys_set_robust_list ( %#lx, %ld )", ARG1,ARG2);
1105   PRE_REG_READ2(long, "set_robust_list",
1106                 struct vki_robust_list_head *, head, vki_size_t, len);
1107
1108   /* Just check the robust_list_head structure is readable - don't
1109      try and chase the list as the kernel will only read it when
1110      the thread exits so the current contents is irrelevant. */
1111   if (ARG1 != 0)
1112      PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1113}
1114
1115PRE(sys_get_robust_list)
1116{
1117   PRINT("sys_get_robust_list ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
1118   PRE_REG_READ3(long, "get_robust_list",
1119                 int, pid,
1120                 struct vki_robust_list_head **, head_ptr,
1121                 vki_size_t *, len_ptr);
1122   PRE_MEM_WRITE("get_robust_list(head_ptr)",
1123                 ARG2, sizeof(struct vki_robust_list_head *));
1124   PRE_MEM_WRITE("get_robust_list(len_ptr)",
1125                 ARG3, sizeof(struct vki_size_t *));
1126}
1127POST(sys_get_robust_list)
1128{
1129   POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1130   POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1131}
1132
1133PRE(sys_pselect6)
1134{
1135   *flags |= SfMayBlock;
1136   PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1137   PRE_REG_READ6(long, "pselect6",
1138                 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1139                 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1140                 void *, sig);
1141   // XXX: this possibly understates how much memory is read.
1142   if (ARG2 != 0)
1143      PRE_MEM_READ( "pselect6(readfds)",
1144		     ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1145   if (ARG3 != 0)
1146      PRE_MEM_READ( "pselect6(writefds)",
1147		     ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1148   if (ARG4 != 0)
1149      PRE_MEM_READ( "pselect6(exceptfds)",
1150		     ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1151   if (ARG5 != 0)
1152      PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1153   if (ARG6 != 0)
1154      PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(void *)+sizeof(vki_size_t) );
1155}
1156
1157PRE(sys_ppoll)
1158{
1159   UInt i;
1160   struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1161   *flags |= SfMayBlock;
1162   PRINT("sys_ppoll ( %#lx, %ld, %#lx, %#lx, %llu )\n", ARG1,ARG2,ARG3,ARG4,(ULong)ARG5);
1163   PRE_REG_READ5(long, "ppoll",
1164                 struct vki_pollfd *, ufds, unsigned int, nfds,
1165                 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1166                 vki_size_t, sigsetsize);
1167
1168   for (i = 0; i < ARG2; i++) {
1169      PRE_MEM_READ( "ppoll(ufds.fd)",
1170                    (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1171      PRE_MEM_READ( "ppoll(ufds.events)",
1172                    (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1173      PRE_MEM_WRITE( "ppoll(ufd.reventss)",
1174                     (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1175   }
1176
1177   if (ARG3)
1178      PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1179   if (ARG4)
1180      PRE_MEM_READ( "ppoll(sigmask)", ARG4, sizeof(vki_sigset_t) );
1181}
1182
1183POST(sys_ppoll)
1184{
1185   if (RES > 0) {
1186      UInt i;
1187      struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1188      for (i = 0; i < ARG2; i++)
1189	 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1190   }
1191}
1192
1193
1194/* ---------------------------------------------------------------------
1195   epoll_* wrappers
1196   ------------------------------------------------------------------ */
1197
1198PRE(sys_epoll_create)
1199{
1200   PRINT("sys_epoll_create ( %ld )", ARG1);
1201   PRE_REG_READ1(long, "epoll_create", int, size);
1202}
1203POST(sys_epoll_create)
1204{
1205   vg_assert(SUCCESS);
1206   if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1207      VG_(close)(RES);
1208      SET_STATUS_Failure( VKI_EMFILE );
1209   } else {
1210      if (VG_(clo_track_fds))
1211         ML_(record_fd_open_nameless) (tid, RES);
1212   }
1213}
1214
1215PRE(sys_epoll_create1)
1216{
1217   PRINT("sys_epoll_create1 ( %ld )", ARG1);
1218   PRE_REG_READ1(long, "epoll_create1", int, flags);
1219}
1220POST(sys_epoll_create1)
1221{
1222   vg_assert(SUCCESS);
1223   if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1224      VG_(close)(RES);
1225      SET_STATUS_Failure( VKI_EMFILE );
1226   } else {
1227      if (VG_(clo_track_fds))
1228         ML_(record_fd_open_nameless) (tid, RES);
1229   }
1230}
1231
1232PRE(sys_epoll_ctl)
1233{
1234   static const HChar* epoll_ctl_s[3] = {
1235      "EPOLL_CTL_ADD",
1236      "EPOLL_CTL_DEL",
1237      "EPOLL_CTL_MOD"
1238   };
1239   PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#lx )",
1240         ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
1241   PRE_REG_READ4(long, "epoll_ctl",
1242                 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1243   if (ARG2 != VKI_EPOLL_CTL_DEL)
1244      PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1245}
1246
1247PRE(sys_epoll_wait)
1248{
1249   *flags |= SfMayBlock;
1250   PRINT("sys_epoll_wait ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
1251   PRE_REG_READ4(long, "epoll_wait",
1252                 int, epfd, struct vki_epoll_event *, events,
1253                 int, maxevents, int, timeout);
1254   PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1255}
1256POST(sys_epoll_wait)
1257{
1258   vg_assert(SUCCESS);
1259   if (RES > 0)
1260      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1261}
1262
1263PRE(sys_epoll_pwait)
1264{
1265   *flags |= SfMayBlock;
1266   PRINT("sys_epoll_pwait ( %ld, %#lx, %ld, %ld, %#lx, %llu )", ARG1,ARG2,ARG3,ARG4,ARG5,(ULong)ARG6);
1267   PRE_REG_READ6(long, "epoll_pwait",
1268                 int, epfd, struct vki_epoll_event *, events,
1269                 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1270                 vki_size_t, sigsetsize);
1271   PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1272   if (ARG4)
1273      PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1274}
1275POST(sys_epoll_pwait)
1276{
1277   vg_assert(SUCCESS);
1278   if (RES > 0)
1279      POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1280}
1281
1282PRE(sys_eventfd)
1283{
1284   PRINT("sys_eventfd ( %lu )", ARG1);
1285   PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1286}
1287POST(sys_eventfd)
1288{
1289   if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1290      VG_(close)(RES);
1291      SET_STATUS_Failure( VKI_EMFILE );
1292   } else {
1293      if (VG_(clo_track_fds))
1294         ML_(record_fd_open_nameless) (tid, RES);
1295   }
1296}
1297
1298PRE(sys_eventfd2)
1299{
1300   PRINT("sys_eventfd2 ( %lu, %ld )", ARG1,ARG2);
1301   PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1302}
1303POST(sys_eventfd2)
1304{
1305   if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1306      VG_(close)(RES);
1307      SET_STATUS_Failure( VKI_EMFILE );
1308   } else {
1309      if (VG_(clo_track_fds))
1310         ML_(record_fd_open_nameless) (tid, RES);
1311   }
1312}
1313
1314PRE(sys_fallocate)
1315{
1316   *flags |= SfMayBlock;
1317#if VG_WORDSIZE == 4
1318   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1319         ARG1, ARG2, MERGE64(ARG3,ARG4), MERGE64(ARG5,ARG6));
1320   PRE_REG_READ6(long, "fallocate",
1321                 int, fd, int, mode,
1322                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1323                 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1324#elif VG_WORDSIZE == 8
1325   PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1326         ARG1, ARG2, (Long)ARG3, (Long)ARG4);
1327   PRE_REG_READ4(long, "fallocate",
1328                 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1329#else
1330#  error Unexpected word size
1331#endif
1332   if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1333      SET_STATUS_Failure( VKI_EBADF );
1334}
1335
1336PRE(sys_prlimit64)
1337{
1338   PRINT("sys_prlimit64 ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
1339   PRE_REG_READ4(long, "prlimit64",
1340                 vki_pid_t, pid, unsigned int, resource,
1341                 const struct rlimit64 *, new_rlim,
1342                 struct rlimit64 *, old_rlim);
1343   if (ARG3)
1344      PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
1345   if (ARG4)
1346      PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
1347
1348   if (ARG3 &&
1349       ((struct vki_rlimit64 *)ARG3)->rlim_cur > ((struct vki_rlimit64 *)ARG3)->rlim_max) {
1350      SET_STATUS_Failure( VKI_EINVAL );
1351   }
1352   else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
1353      switch (ARG2) {
1354      case VKI_RLIMIT_NOFILE:
1355         SET_STATUS_Success( 0 );
1356         if (ARG4) {
1357            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(fd_soft_limit);
1358            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(fd_hard_limit);
1359         }
1360         if (ARG3) {
1361            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(fd_hard_limit) ||
1362                ((struct vki_rlimit64 *)ARG3)->rlim_max != VG_(fd_hard_limit)) {
1363               SET_STATUS_Failure( VKI_EPERM );
1364            }
1365            else {
1366               VG_(fd_soft_limit) = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1367            }
1368         }
1369         break;
1370
1371      case VKI_RLIMIT_DATA:
1372         SET_STATUS_Success( 0 );
1373         if (ARG4) {
1374            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_data).rlim_cur;
1375            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_data).rlim_max;
1376         }
1377         if (ARG3) {
1378            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
1379                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_data).rlim_max) {
1380               SET_STATUS_Failure( VKI_EPERM );
1381            }
1382            else {
1383               VG_(client_rlimit_data).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1384               VG_(client_rlimit_data).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1385            }
1386         }
1387         break;
1388
1389      case VKI_RLIMIT_STACK:
1390         SET_STATUS_Success( 0 );
1391         if (ARG4) {
1392            ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_stack).rlim_cur;
1393            ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_stack).rlim_max;
1394         }
1395         if (ARG3) {
1396            if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
1397                ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
1398               SET_STATUS_Failure( VKI_EPERM );
1399            }
1400            else {
1401               VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1402               VG_(client_rlimit_stack).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1403               VG_(client_rlimit_stack).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1404           }
1405         }
1406         break;
1407      }
1408   }
1409}
1410
1411POST(sys_prlimit64)
1412{
1413   if (ARG4)
1414      POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
1415}
1416
1417/* ---------------------------------------------------------------------
1418   tid-related wrappers
1419   ------------------------------------------------------------------ */
1420
1421PRE(sys_gettid)
1422{
1423   PRINT("sys_gettid ()");
1424   PRE_REG_READ0(long, "gettid");
1425}
1426
1427PRE(sys_set_tid_address)
1428{
1429   PRINT("sys_set_tid_address ( %#lx )", ARG1);
1430   PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
1431}
1432
1433PRE(sys_tkill)
1434{
1435   PRINT("sys_tgkill ( %ld, %ld )", ARG1,ARG2);
1436   PRE_REG_READ2(long, "tkill", int, tid, int, sig);
1437   if (!ML_(client_signal_OK)(ARG2)) {
1438      SET_STATUS_Failure( VKI_EINVAL );
1439      return;
1440   }
1441
1442   /* Check to see if this kill gave us a pending signal */
1443   *flags |= SfPollAfter;
1444
1445   if (VG_(clo_trace_signals))
1446      VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
1447		   ARG2, ARG1);
1448
1449   /* If we're sending SIGKILL, check to see if the target is one of
1450      our threads and handle it specially. */
1451   if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
1452      SET_STATUS_Success(0);
1453      return;
1454   }
1455
1456   /* Ask to handle this syscall via the slow route, since that's the
1457      only one that sets tst->status to VgTs_WaitSys.  If the result
1458      of doing the syscall is an immediate run of
1459      async_signalhandler() in m_signals, then we need the thread to
1460      be properly tidied away.  I have the impression the previous
1461      version of this wrapper worked on x86/amd64 only because the
1462      kernel did not immediately deliver the async signal to this
1463      thread (on ppc it did, which broke the assertion re tst->status
1464      at the top of async_signalhandler()). */
1465   *flags |= SfMayBlock;
1466}
1467POST(sys_tkill)
1468{
1469   if (VG_(clo_trace_signals))
1470      VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
1471                   ARG2, ARG1);
1472}
1473
1474PRE(sys_tgkill)
1475{
1476   PRINT("sys_tgkill ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1477   PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
1478   if (!ML_(client_signal_OK)(ARG3)) {
1479      SET_STATUS_Failure( VKI_EINVAL );
1480      return;
1481   }
1482
1483   /* Check to see if this kill gave us a pending signal */
1484   *flags |= SfPollAfter;
1485
1486   if (VG_(clo_trace_signals))
1487      VG_(message)(Vg_DebugMsg,
1488                   "tgkill: sending signal %ld to pid %ld/%ld\n",
1489		   ARG3, ARG1, ARG2);
1490
1491   /* If we're sending SIGKILL, check to see if the target is one of
1492      our threads and handle it specially. */
1493   if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
1494      SET_STATUS_Success(0);
1495      return;
1496   }
1497
1498   /* Ask to handle this syscall via the slow route, since that's the
1499      only one that sets tst->status to VgTs_WaitSys.  If the result
1500      of doing the syscall is an immediate run of
1501      async_signalhandler() in m_signals, then we need the thread to
1502      be properly tidied away.  I have the impression the previous
1503      version of this wrapper worked on x86/amd64 only because the
1504      kernel did not immediately deliver the async signal to this
1505      thread (on ppc it did, which broke the assertion re tst->status
1506      at the top of async_signalhandler()). */
1507   *flags |= SfMayBlock;
1508}
1509POST(sys_tgkill)
1510{
1511   if (VG_(clo_trace_signals))
1512      VG_(message)(Vg_DebugMsg,
1513                   "tgkill: sent signal %ld to pid %ld/%ld\n",
1514                   ARG3, ARG1, ARG2);
1515}
1516
1517/* ---------------------------------------------------------------------
1518   fadvise64* wrappers
1519   ------------------------------------------------------------------ */
1520
1521PRE(sys_fadvise64)
1522{
1523   PRINT("sys_fadvise64 ( %ld, %lld, %lu, %ld )",
1524         ARG1, MERGE64(ARG2,ARG3), ARG4, ARG5);
1525   PRE_REG_READ5(long, "fadvise64",
1526                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
1527                 vki_size_t, len, int, advice);
1528}
1529
1530PRE(sys_fadvise64_64)
1531{
1532   PRINT("sys_fadvise64_64 ( %ld, %lld, %lld, %ld )",
1533         ARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), ARG6);
1534   PRE_REG_READ6(long, "fadvise64_64",
1535                 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
1536                 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
1537}
1538
1539/* ---------------------------------------------------------------------
1540   io_* wrappers
1541   ------------------------------------------------------------------ */
1542
1543// Nb: this wrapper has to pad/unpad memory around the syscall itself,
1544// and this allows us to control exactly the code that gets run while
1545// the padding is in place.
1546
1547PRE(sys_io_setup)
1548{
1549   PRINT("sys_io_setup ( %lu, %#lx )", ARG1,ARG2);
1550   PRE_REG_READ2(long, "io_setup",
1551                 unsigned, nr_events, vki_aio_context_t *, ctxp);
1552   PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
1553}
1554
1555POST(sys_io_setup)
1556{
1557   SizeT size;
1558   struct vki_aio_ring *r;
1559
1560   size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1561                       ARG1*sizeof(struct vki_io_event));
1562   r = *(struct vki_aio_ring **)ARG2;
1563   vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
1564
1565   ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
1566                                      VKI_PROT_READ | VKI_PROT_WRITE,
1567                                      VKI_MAP_ANONYMOUS, -1, 0 );
1568
1569   POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
1570}
1571
1572// Nb: This wrapper is "Special" because we need 'size' to do the unmap
1573// after the syscall.  We must get 'size' from the aio_ring structure,
1574// before the syscall, while the aio_ring structure still exists.  (And we
1575// know that we must look at the aio_ring structure because Tom inspected the
1576// kernel and glibc sources to see what they do, yuk.)
1577//
1578// XXX This segment can be implicitly unmapped when aio
1579// file-descriptors are closed...
1580PRE(sys_io_destroy)
1581{
1582   SizeT size = 0;
1583
1584   PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
1585   PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
1586
1587   // If we are going to seg fault (due to a bogus ARG1) do it as late as
1588   // possible...
1589   if (ML_(safe_to_deref)( (void*)ARG1, sizeof(struct vki_aio_ring))) {
1590      struct vki_aio_ring *r = (struct vki_aio_ring *)ARG1;
1591      size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1592                          r->nr*sizeof(struct vki_io_event));
1593   }
1594
1595   SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
1596
1597   if (SUCCESS && RES == 0) {
1598      Bool d = VG_(am_notify_munmap)( ARG1, size );
1599      VG_TRACK( die_mem_munmap, ARG1, size );
1600      if (d)
1601         VG_(discard_translations)( (Addr64)ARG1, (ULong)size,
1602                                    "PRE(sys_io_destroy)" );
1603   }
1604}
1605
1606PRE(sys_io_getevents)
1607{
1608   *flags |= SfMayBlock;
1609   PRINT("sys_io_getevents ( %llu, %lld, %lld, %#lx, %#lx )",
1610         (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
1611   PRE_REG_READ5(long, "io_getevents",
1612                 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
1613                 struct io_event *, events,
1614                 struct timespec *, timeout);
1615   if (ARG3 > 0)
1616      PRE_MEM_WRITE( "io_getevents(events)",
1617                     ARG4, sizeof(struct vki_io_event)*ARG3 );
1618   if (ARG5 != 0)
1619      PRE_MEM_READ( "io_getevents(timeout)",
1620                    ARG5, sizeof(struct vki_timespec));
1621}
1622POST(sys_io_getevents)
1623{
1624   Int i;
1625   vg_assert(SUCCESS);
1626   if (RES > 0) {
1627      POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
1628      for (i = 0; i < RES; i++) {
1629         const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
1630         const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
1631
1632         switch (cb->aio_lio_opcode) {
1633         case VKI_IOCB_CMD_PREAD:
1634            if (vev->result > 0)
1635               POST_MEM_WRITE( cb->aio_buf, vev->result );
1636            break;
1637
1638         case VKI_IOCB_CMD_PWRITE:
1639            break;
1640
1641         case VKI_IOCB_CMD_FSYNC:
1642            break;
1643
1644         case VKI_IOCB_CMD_FDSYNC:
1645            break;
1646
1647         case VKI_IOCB_CMD_PREADV:
1648	     if (vev->result > 0) {
1649                  struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
1650                  Int remains = vev->result;
1651                  Int j;
1652
1653                  for (j = 0; j < cb->aio_nbytes; j++) {
1654                       Int nReadThisBuf = vec[j].iov_len;
1655                       if (nReadThisBuf > remains) nReadThisBuf = remains;
1656                       POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
1657                       remains -= nReadThisBuf;
1658                       if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
1659                  }
1660	     }
1661             break;
1662
1663         case VKI_IOCB_CMD_PWRITEV:
1664             break;
1665
1666         default:
1667            VG_(message)(Vg_DebugMsg,
1668                        "Warning: unhandled io_getevents opcode: %u\n",
1669                        cb->aio_lio_opcode);
1670            break;
1671         }
1672      }
1673   }
1674}
1675
1676PRE(sys_io_submit)
1677{
1678   Int i, j;
1679
1680   PRINT("sys_io_submit ( %llu, %ld, %#lx )", (ULong)ARG1,ARG2,ARG3);
1681   PRE_REG_READ3(long, "io_submit",
1682                 vki_aio_context_t, ctx_id, long, nr,
1683                 struct iocb **, iocbpp);
1684   PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
1685   if (ARG3 != 0) {
1686      for (i = 0; i < ARG2; i++) {
1687         struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
1688         struct vki_iovec *iov;
1689
1690         PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
1691         switch (cb->aio_lio_opcode) {
1692         case VKI_IOCB_CMD_PREAD:
1693            PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
1694            break;
1695
1696         case VKI_IOCB_CMD_PWRITE:
1697            PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
1698            break;
1699
1700         case VKI_IOCB_CMD_FSYNC:
1701            break;
1702
1703         case VKI_IOCB_CMD_FDSYNC:
1704            break;
1705
1706         case VKI_IOCB_CMD_PREADV:
1707            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1708            PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1709            for (j = 0; j < cb->aio_nbytes; j++)
1710                PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1711            break;
1712
1713         case VKI_IOCB_CMD_PWRITEV:
1714            iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1715            PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1716            for (j = 0; j < cb->aio_nbytes; j++)
1717                PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1718            break;
1719
1720         default:
1721            VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
1722                         cb->aio_lio_opcode);
1723            break;
1724         }
1725      }
1726   }
1727}
1728
1729PRE(sys_io_cancel)
1730{
1731   PRINT("sys_io_cancel ( %llu, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3);
1732   PRE_REG_READ3(long, "io_cancel",
1733                 vki_aio_context_t, ctx_id, struct iocb *, iocb,
1734                 struct io_event *, result);
1735   PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
1736   PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
1737}
1738POST(sys_io_cancel)
1739{
1740   POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
1741}
1742
1743/* ---------------------------------------------------------------------
1744   *_mempolicy wrappers
1745   ------------------------------------------------------------------ */
1746
1747PRE(sys_mbind)
1748{
1749   PRINT("sys_mbind ( %#lx, %lu, %ld, %#lx, %lu, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1750   PRE_REG_READ6(long, "mbind",
1751                 unsigned long, start, unsigned long, len,
1752                 unsigned long, policy, unsigned long *, nodemask,
1753                 unsigned long, maxnode, unsigned, flags);
1754   if (ARG1 != 0)
1755      PRE_MEM_READ( "mbind(nodemask)", ARG4,
1756                    VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
1757}
1758
1759PRE(sys_set_mempolicy)
1760{
1761   PRINT("sys_set_mempolicy ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
1762   PRE_REG_READ3(long, "set_mempolicy",
1763                 int, policy, unsigned long *, nodemask,
1764                 unsigned long, maxnode);
1765   PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
1766                 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1767}
1768
1769PRE(sys_get_mempolicy)
1770{
1771   PRINT("sys_get_mempolicy ( %#lx, %#lx, %ld, %#lx, %lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1772   PRE_REG_READ5(long, "get_mempolicy",
1773                 int *, policy, unsigned long *, nodemask,
1774                 unsigned long, maxnode, unsigned long, addr,
1775                 unsigned long, flags);
1776   if (ARG1 != 0)
1777      PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
1778   if (ARG2 != 0)
1779      PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
1780                     VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1781}
1782POST(sys_get_mempolicy)
1783{
1784   if (ARG1 != 0)
1785      POST_MEM_WRITE( ARG1, sizeof(Int) );
1786   if (ARG2 != 0)
1787      POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
1788}
1789
1790/* ---------------------------------------------------------------------
1791   inotify_* wrappers
1792   ------------------------------------------------------------------ */
1793
1794PRE(sys_inotify_init)
1795{
1796   PRINT("sys_inotify_init ( )");
1797   PRE_REG_READ0(long, "inotify_init");
1798}
1799POST(sys_inotify_init)
1800{
1801   vg_assert(SUCCESS);
1802   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
1803      VG_(close)(RES);
1804      SET_STATUS_Failure( VKI_EMFILE );
1805   } else {
1806      if (VG_(clo_track_fds))
1807         ML_(record_fd_open_nameless) (tid, RES);
1808   }
1809}
1810
1811PRE(sys_inotify_init1)
1812{
1813   PRINT("sys_inotify_init ( %ld )", ARG1);
1814   PRE_REG_READ1(long, "inotify_init", int, flag);
1815}
1816
1817POST(sys_inotify_init1)
1818{
1819   vg_assert(SUCCESS);
1820   if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
1821      VG_(close)(RES);
1822      SET_STATUS_Failure( VKI_EMFILE );
1823   } else {
1824      if (VG_(clo_track_fds))
1825         ML_(record_fd_open_nameless) (tid, RES);
1826   }
1827}
1828
1829PRE(sys_inotify_add_watch)
1830{
1831   PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", ARG1,ARG2,ARG3);
1832   PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
1833   PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
1834}
1835
1836PRE(sys_inotify_rm_watch)
1837{
1838   PRINT( "sys_inotify_rm_watch ( %ld, %lx )", ARG1,ARG2);
1839   PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
1840}
1841
1842/* ---------------------------------------------------------------------
1843   mq_* wrappers
1844   ------------------------------------------------------------------ */
1845
1846PRE(sys_mq_open)
1847{
1848   PRINT("sys_mq_open( %#lx(%s), %ld, %lld, %#lx )",
1849         ARG1,(char*)ARG1,ARG2,(ULong)ARG3,ARG4);
1850   PRE_REG_READ4(long, "mq_open",
1851                 const char *, name, int, oflag, vki_mode_t, mode,
1852                 struct mq_attr *, attr);
1853   PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
1854   if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
1855      const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
1856      PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
1857                     (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
1858      PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
1859                     (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
1860   }
1861}
1862POST(sys_mq_open)
1863{
1864   vg_assert(SUCCESS);
1865   if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
1866      VG_(close)(RES);
1867      SET_STATUS_Failure( VKI_EMFILE );
1868   } else {
1869      if (VG_(clo_track_fds))
1870         ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
1871   }
1872}
1873
1874PRE(sys_mq_unlink)
1875{
1876   PRINT("sys_mq_unlink ( %#lx(%s) )", ARG1,(char*)ARG1);
1877   PRE_REG_READ1(long, "mq_unlink", const char *, name);
1878   PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
1879}
1880
1881PRE(sys_mq_timedsend)
1882{
1883   *flags |= SfMayBlock;
1884   PRINT("sys_mq_timedsend ( %ld, %#lx, %llu, %ld, %#lx )",
1885         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
1886   PRE_REG_READ5(long, "mq_timedsend",
1887                 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
1888                 unsigned int, msg_prio, const struct timespec *, abs_timeout);
1889   if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
1890      SET_STATUS_Failure( VKI_EBADF );
1891   } else {
1892      PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
1893      if (ARG5 != 0)
1894         PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
1895                        sizeof(struct vki_timespec) );
1896   }
1897}
1898
1899PRE(sys_mq_timedreceive)
1900{
1901   *flags |= SfMayBlock;
1902   PRINT("sys_mq_timedreceive( %ld, %#lx, %llu, %#lx, %#lx )",
1903         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
1904   PRE_REG_READ5(ssize_t, "mq_timedreceive",
1905                 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
1906                 unsigned int *, msg_prio,
1907                 const struct timespec *, abs_timeout);
1908   if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
1909      SET_STATUS_Failure( VKI_EBADF );
1910   } else {
1911      PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
1912      if (ARG4 != 0)
1913         PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
1914                        ARG4, sizeof(unsigned int) );
1915      if (ARG5 != 0)
1916         PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
1917                        ARG5, sizeof(struct vki_timespec) );
1918   }
1919}
1920POST(sys_mq_timedreceive)
1921{
1922   POST_MEM_WRITE( ARG2, RES );
1923   if (ARG4 != 0)
1924      POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
1925}
1926
1927PRE(sys_mq_notify)
1928{
1929   PRINT("sys_mq_notify( %ld, %#lx )", ARG1,ARG2 );
1930   PRE_REG_READ2(long, "mq_notify",
1931                 vki_mqd_t, mqdes, const struct sigevent *, notification);
1932   if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
1933      SET_STATUS_Failure( VKI_EBADF );
1934   else if (ARG2 != 0)
1935      PRE_MEM_READ( "mq_notify(notification)",
1936                    ARG2, sizeof(struct vki_sigevent) );
1937}
1938
1939PRE(sys_mq_getsetattr)
1940{
1941   PRINT("sys_mq_getsetattr( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3 );
1942   PRE_REG_READ3(long, "mq_getsetattr",
1943                 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
1944                 struct mq_attr *, omqstat);
1945   if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
1946      SET_STATUS_Failure( VKI_EBADF );
1947   } else {
1948      if (ARG2 != 0) {
1949         const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
1950         PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
1951                        (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
1952      }
1953      if (ARG3 != 0)
1954         PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
1955                        sizeof(struct vki_mq_attr) );
1956   }
1957}
1958POST(sys_mq_getsetattr)
1959{
1960   if (ARG3 != 0)
1961      POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
1962}
1963
1964/* ---------------------------------------------------------------------
1965   clock_* wrappers
1966   ------------------------------------------------------------------ */
1967
1968PRE(sys_clock_settime)
1969{
1970   PRINT("sys_clock_settime( %ld, %#lx )", ARG1,ARG2);
1971   PRE_REG_READ2(long, "clock_settime",
1972                 vki_clockid_t, clk_id, const struct timespec *, tp);
1973   PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
1974}
1975
1976PRE(sys_clock_gettime)
1977{
1978   PRINT("sys_clock_gettime( %ld, %#lx )" , ARG1,ARG2);
1979   PRE_REG_READ2(long, "clock_gettime",
1980                 vki_clockid_t, clk_id, struct timespec *, tp);
1981   PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
1982}
1983POST(sys_clock_gettime)
1984{
1985   POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
1986}
1987
1988PRE(sys_clock_getres)
1989{
1990   PRINT("sys_clock_getres( %ld, %#lx )" , ARG1,ARG2);
1991   // Nb: we can't use "RES" as the param name because that's a macro
1992   // defined above!
1993   PRE_REG_READ2(long, "clock_getres",
1994                 vki_clockid_t, clk_id, struct timespec *, res);
1995   if (ARG2 != 0)
1996      PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
1997}
1998POST(sys_clock_getres)
1999{
2000   if (ARG2 != 0)
2001      POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2002}
2003
2004PRE(sys_clock_nanosleep)
2005{
2006   *flags |= SfMayBlock|SfPostOnFail;
2007   PRINT("sys_clock_nanosleep( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
2008   PRE_REG_READ4(int32_t, "clock_nanosleep",
2009                 vki_clockid_t, clkid, int, flags,
2010                 const struct timespec *, rqtp, struct timespec *, rmtp);
2011   PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2012   if (ARG4 != 0)
2013      PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2014}
2015POST(sys_clock_nanosleep)
2016{
2017   if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2018      POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2019}
2020
2021/* ---------------------------------------------------------------------
2022   timer_* wrappers
2023   ------------------------------------------------------------------ */
2024
2025PRE(sys_timer_create)
2026{
2027   PRINT("sys_timer_create( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
2028   PRE_REG_READ3(long, "timer_create",
2029                 vki_clockid_t, clockid, struct sigevent *, evp,
2030                 vki_timer_t *, timerid);
2031   if (ARG2 != 0)
2032      PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
2033   PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2034}
2035POST(sys_timer_create)
2036{
2037   POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2038}
2039
2040PRE(sys_timer_settime)
2041{
2042   PRINT("sys_timer_settime( %lld, %ld, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3,ARG4);
2043   PRE_REG_READ4(long, "timer_settime",
2044                 vki_timer_t, timerid, int, flags,
2045                 const struct itimerspec *, value,
2046                 struct itimerspec *, ovalue);
2047   PRE_MEM_READ( "timer_settime(value)", ARG3,
2048                  sizeof(struct vki_itimerspec) );
2049   if (ARG4 != 0)
2050       PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2051                      sizeof(struct vki_itimerspec) );
2052}
2053POST(sys_timer_settime)
2054{
2055   if (ARG4 != 0)
2056      POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2057}
2058
2059PRE(sys_timer_gettime)
2060{
2061   PRINT("sys_timer_gettime( %lld, %#lx )", (ULong)ARG1,ARG2);
2062   PRE_REG_READ2(long, "timer_gettime",
2063                 vki_timer_t, timerid, struct itimerspec *, value);
2064   PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2065                  sizeof(struct vki_itimerspec));
2066}
2067POST(sys_timer_gettime)
2068{
2069   POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2070}
2071
2072PRE(sys_timer_getoverrun)
2073{
2074   PRINT("sys_timer_getoverrun( %#lx )", ARG1);
2075   PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2076}
2077
2078PRE(sys_timer_delete)
2079{
2080   PRINT("sys_timer_delete( %#lx )", ARG1);
2081   PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2082}
2083
2084/* ---------------------------------------------------------------------
2085   timerfd* wrappers
2086   See also http://lwn.net/Articles/260172/ for an overview.
2087   See also /usr/src/linux/fs/timerfd.c for the implementation.
2088   ------------------------------------------------------------------ */
2089
2090/* Returns True if running on 2.6.22, else False (or False if
2091   cannot be determined). */
2092static Bool linux_kernel_2_6_22(void)
2093{
2094   static Int result = -1;
2095   Int fd, read;
2096   HChar release[64];
2097   SysRes res;
2098
2099   if (result == -1) {
2100      res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2101      if (sr_isError(res))
2102         return False;
2103      fd = sr_Res(res);
2104      read = VG_(read)(fd, release, sizeof(release) - 1);
2105      vg_assert(read >= 0);
2106      release[read] = 0;
2107      VG_(close)(fd);
2108      //VG_(printf)("kernel release = %s\n", release);
2109      result = (VG_(strncmp)(release, "2.6.22", 6) == 0
2110                && (release[6] < '0' || release[6] > '9'));
2111   }
2112   vg_assert(result == 0 || result == 1);
2113   return result == 1;
2114}
2115
2116PRE(sys_timerfd_create)
2117{
2118   if (linux_kernel_2_6_22()) {
2119      /* 2.6.22 kernel: timerfd system call. */
2120      PRINT("sys_timerfd ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2121      PRE_REG_READ3(long, "sys_timerfd",
2122                    int, fd, int, clockid, const struct itimerspec *, tmr);
2123      PRE_MEM_READ("timerfd(tmr)", ARG3,
2124                   sizeof(struct vki_itimerspec) );
2125      if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2126         SET_STATUS_Failure( VKI_EBADF );
2127   } else {
2128      /* 2.6.24 and later kernels: timerfd_create system call. */
2129      PRINT("sys_timerfd_create (%ld, %ld )", ARG1, ARG2);
2130      PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2131   }
2132}
2133POST(sys_timerfd_create)
2134{
2135   if (linux_kernel_2_6_22())
2136   {
2137      /* 2.6.22 kernel: timerfd system call. */
2138      if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2139         VG_(close)(RES);
2140         SET_STATUS_Failure( VKI_EMFILE );
2141      } else {
2142         if (VG_(clo_track_fds))
2143            ML_(record_fd_open_nameless) (tid, RES);
2144      }
2145   }
2146   else
2147   {
2148      /* 2.6.24 and later kernels: timerfd_create system call. */
2149      if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2150         VG_(close)(RES);
2151         SET_STATUS_Failure( VKI_EMFILE );
2152      } else {
2153         if (VG_(clo_track_fds))
2154            ML_(record_fd_open_nameless) (tid, RES);
2155      }
2156   }
2157}
2158
2159PRE(sys_timerfd_gettime)
2160{
2161   PRINT("sys_timerfd_gettime ( %ld, %#lx )", ARG1, ARG2);
2162   PRE_REG_READ2(long, "timerfd_gettime",
2163                 int, ufd,
2164                 struct vki_itimerspec*, otmr);
2165   if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2166      SET_STATUS_Failure(VKI_EBADF);
2167   else
2168      PRE_MEM_WRITE("timerfd_gettime(result)",
2169                    ARG2, sizeof(struct vki_itimerspec));
2170}
2171POST(sys_timerfd_gettime)
2172{
2173   if (RES == 0)
2174      POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2175}
2176
2177PRE(sys_timerfd_settime)
2178{
2179   PRINT("sys_timerfd_settime ( %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
2180   PRE_REG_READ4(long, "timerfd_settime",
2181                 int, ufd,
2182                 int, flags,
2183                 const struct vki_itimerspec*, utmr,
2184                 struct vki_itimerspec*, otmr);
2185   if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2186      SET_STATUS_Failure(VKI_EBADF);
2187   else
2188   {
2189      PRE_MEM_READ("timerfd_settime(result)",
2190                   ARG3, sizeof(struct vki_itimerspec));
2191      if (ARG4)
2192      {
2193         PRE_MEM_WRITE("timerfd_settime(result)",
2194                       ARG4, sizeof(struct vki_itimerspec));
2195      }
2196   }
2197}
2198POST(sys_timerfd_settime)
2199{
2200   if (RES == 0 && ARG4 != 0)
2201      POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2202}
2203
2204/* ---------------------------------------------------------------------
2205   capabilities wrappers
2206   ------------------------------------------------------------------ */
2207
2208PRE(sys_capget)
2209{
2210   PRINT("sys_capget ( %#lx, %#lx )", ARG1, ARG2 );
2211   PRE_REG_READ2(long, "capget",
2212                 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2213   PRE_MEM_READ( "capget(header)", ARG1,
2214                  sizeof(struct __vki_user_cap_header_struct) );
2215   PRE_MEM_WRITE( "capget(data)", ARG2,
2216                  sizeof(struct __vki_user_cap_data_struct) );
2217}
2218POST(sys_capget)
2219{
2220   if (ARG2 != (Addr)NULL)
2221      POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2222}
2223
2224PRE(sys_capset)
2225{
2226   PRINT("sys_capset ( %#lx, %#lx )", ARG1, ARG2 );
2227   PRE_REG_READ2(long, "capset",
2228                 vki_cap_user_header_t, header,
2229                 const vki_cap_user_data_t, data);
2230   PRE_MEM_READ( "capset(header)",
2231                  ARG1, sizeof(struct __vki_user_cap_header_struct) );
2232   PRE_MEM_READ( "capset(data)",
2233                  ARG2, sizeof(struct __vki_user_cap_data_struct) );
2234}
2235
2236/* ---------------------------------------------------------------------
2237   16-bit uid/gid/groups wrappers
2238   ------------------------------------------------------------------ */
2239
2240PRE(sys_getuid16)
2241{
2242   PRINT("sys_getuid16 ( )");
2243   PRE_REG_READ0(long, "getuid16");
2244}
2245
2246PRE(sys_setuid16)
2247{
2248   PRINT("sys_setuid16 ( %ld )", ARG1);
2249   PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
2250}
2251
2252PRE(sys_getgid16)
2253{
2254   PRINT("sys_getgid16 ( )");
2255   PRE_REG_READ0(long, "getgid16");
2256}
2257
2258PRE(sys_setgid16)
2259{
2260   PRINT("sys_setgid16 ( %ld )", ARG1);
2261   PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
2262}
2263
2264PRE(sys_geteuid16)
2265{
2266   PRINT("sys_geteuid16 ( )");
2267   PRE_REG_READ0(long, "geteuid16");
2268}
2269
2270PRE(sys_getegid16)
2271{
2272   PRINT("sys_getegid16 ( )");
2273   PRE_REG_READ0(long, "getegid16");
2274}
2275
2276PRE(sys_setreuid16)
2277{
2278   PRINT("setreuid16 ( 0x%lx, 0x%lx )", ARG1, ARG2);
2279   PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
2280}
2281
2282PRE(sys_setregid16)
2283{
2284   PRINT("sys_setregid16 ( %ld, %ld )", ARG1, ARG2);
2285   PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2286}
2287
2288PRE(sys_getgroups16)
2289{
2290   PRINT("sys_getgroups16 ( %ld, %#lx )", ARG1, ARG2);
2291   PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2292   if (ARG1 > 0)
2293      PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2294}
2295POST(sys_getgroups16)
2296{
2297   vg_assert(SUCCESS);
2298   if (ARG1 > 0 && RES > 0)
2299      POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2300}
2301
2302PRE(sys_setgroups16)
2303{
2304   PRINT("sys_setgroups16 ( %llu, %#lx )", (ULong)ARG1, ARG2);
2305   PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
2306   if (ARG1 > 0)
2307      PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2308}
2309
2310/* ---------------------------------------------------------------------
2311   *chown16 wrappers
2312   ------------------------------------------------------------------ */
2313
2314PRE(sys_chown16)
2315{
2316   PRINT("sys_chown16 ( %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3);
2317   PRE_REG_READ3(long, "chown16",
2318                 const char *, path,
2319                 vki_old_uid_t, owner, vki_old_gid_t, group);
2320   PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
2321}
2322
2323PRE(sys_fchown16)
2324{
2325   PRINT("sys_fchown16 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2326   PRE_REG_READ3(long, "fchown16",
2327                 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
2328}
2329
2330/* ---------------------------------------------------------------------
2331   *xattr wrappers
2332   ------------------------------------------------------------------ */
2333
2334PRE(sys_setxattr)
2335{
2336   *flags |= SfMayBlock;
2337   PRINT("sys_setxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
2338         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2339   PRE_REG_READ5(long, "setxattr",
2340                 char *, path, char *, name,
2341                 void *, value, vki_size_t, size, int, flags);
2342   PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
2343   PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
2344   PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
2345}
2346
2347PRE(sys_lsetxattr)
2348{
2349   *flags |= SfMayBlock;
2350   PRINT("sys_lsetxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
2351         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2352   PRE_REG_READ5(long, "lsetxattr",
2353                 char *, path, char *, name,
2354                 void *, value, vki_size_t, size, int, flags);
2355   PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
2356   PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
2357   PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
2358}
2359
2360PRE(sys_fsetxattr)
2361{
2362   *flags |= SfMayBlock;
2363   PRINT("sys_fsetxattr ( %ld, %#lx, %#lx, %llu, %ld )",
2364         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2365   PRE_REG_READ5(long, "fsetxattr",
2366                 int, fd, char *, name, void *, value,
2367                 vki_size_t, size, int, flags);
2368   PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
2369   PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
2370}
2371
2372PRE(sys_getxattr)
2373{
2374   *flags |= SfMayBlock;
2375   PRINT("sys_getxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
2376   PRE_REG_READ4(ssize_t, "getxattr",
2377                 char *, path, char *, name, void *, value, vki_size_t, size);
2378   PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
2379   PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
2380   PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
2381}
2382POST(sys_getxattr)
2383{
2384   vg_assert(SUCCESS);
2385   if (RES > 0 && ARG3 != (Addr)NULL) {
2386      POST_MEM_WRITE( ARG3, RES );
2387   }
2388}
2389
2390PRE(sys_lgetxattr)
2391{
2392   *flags |= SfMayBlock;
2393   PRINT("sys_lgetxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
2394   PRE_REG_READ4(ssize_t, "lgetxattr",
2395                 char *, path, char *, name, void *, value, vki_size_t, size);
2396   PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
2397   PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
2398   PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
2399}
2400POST(sys_lgetxattr)
2401{
2402   vg_assert(SUCCESS);
2403   if (RES > 0 && ARG3 != (Addr)NULL) {
2404      POST_MEM_WRITE( ARG3, RES );
2405   }
2406}
2407
2408PRE(sys_fgetxattr)
2409{
2410   *flags |= SfMayBlock;
2411   PRINT("sys_fgetxattr ( %ld, %#lx, %#lx, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
2412   PRE_REG_READ4(ssize_t, "fgetxattr",
2413                 int, fd, char *, name, void *, value, vki_size_t, size);
2414   PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
2415   PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
2416}
2417POST(sys_fgetxattr)
2418{
2419   if (RES > 0 && ARG3 != (Addr)NULL)
2420      POST_MEM_WRITE( ARG3, RES );
2421}
2422
2423PRE(sys_listxattr)
2424{
2425   *flags |= SfMayBlock;
2426   PRINT("sys_listxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2427   PRE_REG_READ3(ssize_t, "listxattr",
2428                 char *, path, char *, list, vki_size_t, size);
2429   PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
2430   PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
2431}
2432POST(sys_listxattr)
2433{
2434   if (RES > 0 && ARG2 != (Addr)NULL)
2435      POST_MEM_WRITE( ARG2, RES );
2436}
2437
2438PRE(sys_llistxattr)
2439{
2440   *flags |= SfMayBlock;
2441   PRINT("sys_llistxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2442   PRE_REG_READ3(ssize_t, "llistxattr",
2443                 char *, path, char *, list, vki_size_t, size);
2444   PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
2445   PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
2446}
2447POST(sys_llistxattr)
2448{
2449   if (RES > 0 && ARG2 != (Addr)NULL)
2450      POST_MEM_WRITE( ARG2, RES );
2451}
2452
2453PRE(sys_flistxattr)
2454{
2455   *flags |= SfMayBlock;
2456   PRINT("sys_flistxattr ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
2457   PRE_REG_READ3(ssize_t, "flistxattr",
2458                 int, fd, char *, list, vki_size_t, size);
2459   PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
2460}
2461POST(sys_flistxattr)
2462{
2463   if (RES > 0 && ARG2 != (Addr)NULL)
2464      POST_MEM_WRITE( ARG2, RES );
2465}
2466
2467PRE(sys_removexattr)
2468{
2469   *flags |= SfMayBlock;
2470   PRINT("sys_removexattr ( %#lx, %#lx )", ARG1, ARG2);
2471   PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
2472   PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
2473   PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
2474}
2475
2476PRE(sys_lremovexattr)
2477{
2478   *flags |= SfMayBlock;
2479   PRINT("sys_lremovexattr ( %#lx, %#lx )", ARG1, ARG2);
2480   PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
2481   PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
2482   PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
2483}
2484
2485PRE(sys_fremovexattr)
2486{
2487   *flags |= SfMayBlock;
2488   PRINT("sys_fremovexattr ( %ld, %#lx )", ARG1, ARG2);
2489   PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
2490   PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
2491}
2492
2493/* ---------------------------------------------------------------------
2494   sched_* wrappers
2495   ------------------------------------------------------------------ */
2496
2497PRE(sys_sched_setparam)
2498{
2499   PRINT("sched_setparam ( %ld, %#lx )", ARG1, ARG2 );
2500   PRE_REG_READ2(long, "sched_setparam",
2501                 vki_pid_t, pid, struct sched_param *, p);
2502   PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
2503}
2504POST(sys_sched_setparam)
2505{
2506   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2507}
2508
2509PRE(sys_sched_getparam)
2510{
2511   PRINT("sched_getparam ( %ld, %#lx )", ARG1, ARG2 );
2512   PRE_REG_READ2(long, "sched_getparam",
2513                 vki_pid_t, pid, struct sched_param *, p);
2514   PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
2515}
2516POST(sys_sched_getparam)
2517{
2518   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2519}
2520
2521PRE(sys_sched_getscheduler)
2522{
2523   PRINT("sys_sched_getscheduler ( %ld )", ARG1);
2524   PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
2525}
2526
2527PRE(sys_sched_setscheduler)
2528{
2529   PRINT("sys_sched_setscheduler ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
2530   PRE_REG_READ3(long, "sched_setscheduler",
2531                 vki_pid_t, pid, int, policy, struct sched_param *, p);
2532   if (ARG3 != 0)
2533      PRE_MEM_READ( "sched_setscheduler(p)",
2534		    ARG3, sizeof(struct vki_sched_param));
2535}
2536
2537PRE(sys_sched_yield)
2538{
2539   *flags |= SfMayBlock;
2540   PRINT("sched_yield()");
2541   PRE_REG_READ0(long, "sys_sched_yield");
2542}
2543
2544PRE(sys_sched_get_priority_max)
2545{
2546   PRINT("sched_get_priority_max ( %ld )", ARG1);
2547   PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
2548}
2549
2550PRE(sys_sched_get_priority_min)
2551{
2552   PRINT("sched_get_priority_min ( %ld )", ARG1);
2553   PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
2554}
2555
2556PRE(sys_sched_rr_get_interval)
2557{
2558   PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", ARG1, ARG2);
2559   PRE_REG_READ2(int, "sched_rr_get_interval",
2560                 vki_pid_t, pid,
2561                 struct vki_timespec *, tp);
2562   PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
2563                 ARG2, sizeof(struct vki_timespec));
2564}
2565
2566POST(sys_sched_rr_get_interval)
2567{
2568   POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
2569}
2570
2571PRE(sys_sched_setaffinity)
2572{
2573   PRINT("sched_setaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2574   PRE_REG_READ3(long, "sched_setaffinity",
2575                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2576   PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
2577}
2578
2579PRE(sys_sched_getaffinity)
2580{
2581   PRINT("sched_getaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
2582   PRE_REG_READ3(long, "sched_getaffinity",
2583                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2584   PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
2585}
2586POST(sys_sched_getaffinity)
2587{
2588   POST_MEM_WRITE(ARG3, ARG2);
2589}
2590
2591/* ---------------------------------------------------------------------
2592   miscellaneous wrappers
2593   ------------------------------------------------------------------ */
2594
2595PRE(sys_munlockall)
2596{
2597   *flags |= SfMayBlock;
2598   PRINT("sys_munlockall ( )");
2599   PRE_REG_READ0(long, "munlockall");
2600}
2601
2602// This has different signatures for different platforms.
2603//
2604//  x86:   int  sys_pipe(unsigned long __user *fildes);
2605//  AMD64: long sys_pipe(int *fildes);
2606//  ppc32: int  sys_pipe(int __user *fildes);
2607//  ppc64: int  sys_pipe(int __user *fildes);
2608//
2609// The type of the argument is most important, and it is an array of 32 bit
2610// values in all cases.  (The return type differs across platforms, but it
2611// is not used.)  So we use 'int' as its type.  This fixed bug #113230 which
2612// was caused by using an array of 'unsigned long's, which didn't work on
2613// AMD64.
2614PRE(sys_pipe)
2615{
2616   PRINT("sys_pipe ( %#lx )", ARG1);
2617   PRE_REG_READ1(int, "pipe", int *, filedes);
2618   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
2619}
2620POST(sys_pipe)
2621{
2622   Int *p = (Int *)ARG1;
2623   if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
2624       !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
2625      VG_(close)(p[0]);
2626      VG_(close)(p[1]);
2627      SET_STATUS_Failure( VKI_EMFILE );
2628   } else {
2629      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2630      if (VG_(clo_track_fds)) {
2631         ML_(record_fd_open_nameless)(tid, p[0]);
2632         ML_(record_fd_open_nameless)(tid, p[1]);
2633      }
2634   }
2635}
2636
2637/* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
2638   there's a second arg containing flags to be applied to the new file
2639   descriptors.  It hardly seems worth the effort to factor out the
2640   duplicated code, hence: */
2641PRE(sys_pipe2)
2642{
2643   PRINT("sys_pipe2 ( %#lx, %#lx )", ARG1, ARG2);
2644   PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
2645   PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
2646}
2647POST(sys_pipe2)
2648{
2649   Int *p = (Int *)ARG1;
2650   if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
2651       !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
2652      VG_(close)(p[0]);
2653      VG_(close)(p[1]);
2654      SET_STATUS_Failure( VKI_EMFILE );
2655   } else {
2656      POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2657      if (VG_(clo_track_fds)) {
2658         ML_(record_fd_open_nameless)(tid, p[0]);
2659         ML_(record_fd_open_nameless)(tid, p[1]);
2660      }
2661   }
2662}
2663
2664PRE(sys_dup3)
2665{
2666   PRINT("sys_dup3 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2667   PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
2668   if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
2669      SET_STATUS_Failure( VKI_EBADF );
2670}
2671
2672POST(sys_dup3)
2673{
2674   vg_assert(SUCCESS);
2675   if (VG_(clo_track_fds))
2676      ML_(record_fd_open_named)(tid, RES);
2677}
2678
2679PRE(sys_quotactl)
2680{
2681   PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
2682   PRE_REG_READ4(long, "quotactl",
2683                 unsigned int, cmd, const char *, special, vki_qid_t, id,
2684                 void *, addr);
2685   PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
2686}
2687
2688PRE(sys_waitid)
2689{
2690   *flags |= SfMayBlock;
2691   PRINT("sys_waitid( %ld, %ld, %#lx, %ld, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
2692   PRE_REG_READ5(int32_t, "sys_waitid",
2693                 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
2694                 int, options, struct vki_rusage *, ru);
2695   PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
2696   if (ARG5 != 0)
2697      PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
2698}
2699POST(sys_waitid)
2700{
2701   POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
2702   if (ARG5 != 0)
2703      POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
2704}
2705
2706PRE(sys_sync_file_range)
2707{
2708   *flags |= SfMayBlock;
2709#if VG_WORDSIZE == 4
2710   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2711         ARG1,MERGE64(ARG2,ARG3),MERGE64(ARG4,ARG5),ARG6);
2712   PRE_REG_READ6(long, "sync_file_range",
2713                 int, fd,
2714                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2715                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
2716                 unsigned int, flags);
2717#elif VG_WORDSIZE == 8
2718   PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2719         ARG1,(Long)ARG2,(Long)ARG3,ARG4);
2720   PRE_REG_READ4(long, "sync_file_range",
2721                 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
2722                 unsigned int, flags);
2723#else
2724#  error Unexpected word size
2725#endif
2726   if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
2727      SET_STATUS_Failure( VKI_EBADF );
2728}
2729
2730PRE(sys_sync_file_range2)
2731{
2732   *flags |= SfMayBlock;
2733#if VG_WORDSIZE == 4
2734   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2735         ARG1,ARG2,MERGE64(ARG3,ARG4),MERGE64(ARG5,ARG6));
2736   PRE_REG_READ6(long, "sync_file_range2",
2737                 int, fd, unsigned int, flags,
2738                 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2739                 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
2740#elif VG_WORDSIZE == 8
2741   PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2742         ARG1,ARG2,(Long)ARG3,(Long)ARG4);
2743   PRE_REG_READ4(long, "sync_file_range2",
2744                 int, fd, unsigned int, flags,
2745                 vki_loff_t, offset, vki_loff_t, nbytes);
2746#else
2747#  error Unexpected word size
2748#endif
2749   if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
2750      SET_STATUS_Failure( VKI_EBADF );
2751}
2752
2753PRE(sys_stime)
2754{
2755   PRINT("sys_stime ( %#lx )", ARG1);
2756   PRE_REG_READ1(int, "stime", vki_time_t*, t);
2757   PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
2758}
2759
2760PRE(sys_perf_event_open)
2761{
2762   struct vki_perf_event_attr *attr;
2763   PRINT("sys_perf_event_open ( %#lx, %ld, %ld, %ld, %ld )",
2764         ARG1,ARG2,ARG3,ARG4,ARG5);
2765   PRE_REG_READ5(long, "perf_event_open",
2766                 struct vki_perf_event_attr *, attr,
2767                 vki_pid_t, pid, int, cpu, int, group_fd,
2768                 unsigned long, flags);
2769   attr = (struct vki_perf_event_attr *)ARG1;
2770   PRE_MEM_READ( "perf_event_open(attr->size)",
2771                 (Addr)&attr->size, sizeof(attr->size) );
2772   PRE_MEM_READ( "perf_event_open(attr)",
2773                 (Addr)attr, attr->size );
2774}
2775
2776POST(sys_perf_event_open)
2777{
2778   vg_assert(SUCCESS);
2779   if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
2780      VG_(close)(RES);
2781      SET_STATUS_Failure( VKI_EMFILE );
2782   } else {
2783      if (VG_(clo_track_fds))
2784         ML_(record_fd_open_nameless)(tid, RES);
2785   }
2786}
2787
2788PRE(sys_getcpu)
2789{
2790   PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
2791   PRE_REG_READ3(int, "getcpu",
2792                 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
2793   if (ARG1 != 0)
2794      PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
2795   if (ARG2 != 0)
2796      PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
2797   if (ARG3 != 0)
2798      PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
2799}
2800
2801POST(sys_getcpu)
2802{
2803   if (ARG1 != 0)
2804      POST_MEM_WRITE( ARG1, sizeof(unsigned) );
2805   if (ARG2 != 0)
2806      POST_MEM_WRITE( ARG2, sizeof(unsigned) );
2807   if (ARG3 != 0)
2808      POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
2809}
2810
2811PRE(sys_move_pages)
2812{
2813   PRINT("sys_move_pages ( %ld, %ld, %#lx, %#lx, %#lx, %lx )",
2814         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
2815   PRE_REG_READ6(int, "move_pages",
2816                 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
2817                 const int *, nodes, int *, status, int, flags);
2818   PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
2819   if (ARG4)
2820      PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
2821   PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
2822}
2823
2824POST(sys_move_pages)
2825{
2826   POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
2827}
2828
2829/* ---------------------------------------------------------------------
2830   utime wrapper
2831   ------------------------------------------------------------------ */
2832
2833PRE(sys_utime)
2834{
2835   *flags |= SfMayBlock;
2836   PRINT("sys_utime ( %#lx, %#lx )", ARG1,ARG2);
2837   PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
2838   PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
2839   if (ARG2 != 0)
2840      PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
2841}
2842
2843/* ---------------------------------------------------------------------
2844   lseek wrapper
2845   ------------------------------------------------------------------ */
2846
2847PRE(sys_lseek)
2848{
2849   PRINT("sys_lseek ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2850   PRE_REG_READ3(vki_off_t, "lseek",
2851                 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
2852}
2853
2854/* ---------------------------------------------------------------------
2855   readahead wrapper
2856   ------------------------------------------------------------------ */
2857
2858PRE(sys_readahead)
2859{
2860   *flags |= SfMayBlock;
2861#if VG_WORDSIZE == 4
2862   PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, MERGE64(ARG2,ARG3), ARG4);
2863   PRE_REG_READ4(vki_off_t, "readahead",
2864                 int, fd, unsigned, MERGE64_FIRST(offset),
2865                 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
2866#elif VG_WORDSIZE == 8
2867   PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, (Long)ARG2, ARG3);
2868   PRE_REG_READ3(vki_off_t, "readahead",
2869                 int, fd, vki_loff_t, offset, vki_size_t, count);
2870#else
2871#  error Unexpected word size
2872#endif
2873   if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
2874      SET_STATUS_Failure( VKI_EBADF );
2875}
2876
2877/* ---------------------------------------------------------------------
2878   sig* wrappers
2879   ------------------------------------------------------------------ */
2880
2881PRE(sys_sigpending)
2882{
2883   PRINT( "sys_sigpending ( %#lx )", ARG1 );
2884   PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
2885   PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
2886}
2887POST(sys_sigpending)
2888{
2889   POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
2890}
2891
2892// This syscall is not used on amd64/Linux -- it only provides
2893// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
2894// This wrapper is only suitable for 32-bit architectures.
2895// (XXX: so how is it that PRE(sys_sigpending) above doesn't need
2896// conditional compilation like this?)
2897#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
2898    || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
2899PRE(sys_sigprocmask)
2900{
2901   vki_old_sigset_t* set;
2902   vki_old_sigset_t* oldset;
2903   vki_sigset_t bigger_set;
2904   vki_sigset_t bigger_oldset;
2905
2906   PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
2907   PRE_REG_READ3(long, "sigprocmask",
2908                 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
2909   if (ARG2 != 0)
2910      PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
2911   if (ARG3 != 0)
2912      PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
2913
2914   // Nb: We must convert the smaller vki_old_sigset_t params into bigger
2915   // vki_sigset_t params.
2916   set    = (vki_old_sigset_t*)ARG2;
2917   oldset = (vki_old_sigset_t*)ARG3;
2918
2919   VG_(memset)(&bigger_set,    0, sizeof(vki_sigset_t));
2920   VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
2921   if (set)
2922      bigger_set.sig[0] = *(vki_old_sigset_t*)set;
2923
2924   SET_STATUS_from_SysRes(
2925      VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
2926                                set ? &bigger_set    : NULL,
2927                             oldset ? &bigger_oldset : NULL)
2928   );
2929
2930   if (oldset)
2931      *oldset = bigger_oldset.sig[0];
2932
2933   if (SUCCESS)
2934      *flags |= SfPollAfter;
2935}
2936POST(sys_sigprocmask)
2937{
2938   vg_assert(SUCCESS);
2939   if (RES == 0 && ARG3 != 0)
2940      POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
2941}
2942
2943/* Convert from non-RT to RT sigset_t's */
2944static
2945void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
2946{
2947   VG_(sigemptyset)(set);
2948   set->sig[0] = *oldset;
2949}
2950PRE(sys_sigaction)
2951{
2952   vki_sigaction_toK_t   new, *newp;
2953   vki_sigaction_fromK_t old, *oldp;
2954
2955   PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
2956   PRE_REG_READ3(int, "sigaction",
2957                 int, signum, const struct old_sigaction *, act,
2958                 struct old_sigaction *, oldact);
2959
2960   newp = oldp = NULL;
2961
2962   if (ARG2 != 0) {
2963      struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
2964      PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
2965      PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
2966      PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
2967      if (ML_(safe_to_deref)(sa,sizeof(sa))
2968          && (sa->sa_flags & VKI_SA_RESTORER))
2969         PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
2970   }
2971
2972   if (ARG3 != 0) {
2973      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
2974      oldp = &old;
2975   }
2976
2977   if (ARG2 != 0) {
2978      struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
2979
2980      new.ksa_handler = oldnew->ksa_handler;
2981      new.sa_flags = oldnew->sa_flags;
2982      new.sa_restorer = oldnew->sa_restorer;
2983      convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
2984      newp = &new;
2985   }
2986
2987   SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
2988
2989   if (ARG3 != 0 && SUCCESS && RES == 0) {
2990      struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
2991
2992      oldold->ksa_handler = oldp->ksa_handler;
2993      oldold->sa_flags = oldp->sa_flags;
2994      oldold->sa_restorer = oldp->sa_restorer;
2995      oldold->sa_mask = oldp->sa_mask.sig[0];
2996   }
2997}
2998POST(sys_sigaction)
2999{
3000   vg_assert(SUCCESS);
3001   if (RES == 0 && ARG3 != 0)
3002      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3003}
3004#endif
3005
3006PRE(sys_signalfd)
3007{
3008   PRINT("sys_signalfd ( %d, %#lx, %llu )", (Int)ARG1,ARG2,(ULong)ARG3);
3009   PRE_REG_READ3(long, "sys_signalfd",
3010                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3011   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3012   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3013      SET_STATUS_Failure( VKI_EBADF );
3014}
3015POST(sys_signalfd)
3016{
3017   if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3018      VG_(close)(RES);
3019      SET_STATUS_Failure( VKI_EMFILE );
3020   } else {
3021      if (VG_(clo_track_fds))
3022         ML_(record_fd_open_nameless) (tid, RES);
3023   }
3024}
3025
3026PRE(sys_signalfd4)
3027{
3028   PRINT("sys_signalfd4 ( %d, %#lx, %llu, %ld )", (Int)ARG1,ARG2,(ULong)ARG3,ARG4);
3029   PRE_REG_READ4(long, "sys_signalfd4",
3030                 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3031   PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3032   if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3033      SET_STATUS_Failure( VKI_EBADF );
3034}
3035POST(sys_signalfd4)
3036{
3037   if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3038      VG_(close)(RES);
3039      SET_STATUS_Failure( VKI_EMFILE );
3040   } else {
3041      if (VG_(clo_track_fds))
3042         ML_(record_fd_open_nameless) (tid, RES);
3043   }
3044}
3045
3046
3047/* ---------------------------------------------------------------------
3048   rt_sig* wrappers
3049   ------------------------------------------------------------------ */
3050
3051PRE(sys_rt_sigaction)
3052{
3053   PRINT("sys_rt_sigaction ( %ld, %#lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4);
3054   PRE_REG_READ4(long, "rt_sigaction",
3055                 int, signum, const struct sigaction *, act,
3056                 struct sigaction *, oldact, vki_size_t, sigsetsize);
3057
3058   if (ARG2 != 0) {
3059      vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
3060      PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3061      PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3062      PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3063      if (sa->sa_flags & VKI_SA_RESTORER)
3064         PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3065   }
3066   if (ARG3 != 0)
3067      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3068
3069   // XXX: doesn't seem right to be calling do_sys_sigaction for
3070   // sys_rt_sigaction... perhaps this function should be renamed
3071   // VG_(do_sys_rt_sigaction)()  --njn
3072
3073   SET_STATUS_from_SysRes(
3074      VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
3075                            (vki_sigaction_fromK_t *)ARG3)
3076   );
3077}
3078POST(sys_rt_sigaction)
3079{
3080   vg_assert(SUCCESS);
3081   if (RES == 0 && ARG3 != 0)
3082      POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3083}
3084
3085PRE(sys_rt_sigprocmask)
3086{
3087   PRINT("sys_rt_sigprocmask ( %ld, %#lx, %#lx, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
3088   PRE_REG_READ4(long, "rt_sigprocmask",
3089                 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3090                 vki_size_t, sigsetsize);
3091   if (ARG2 != 0)
3092      PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3093   if (ARG3 != 0)
3094      PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3095
3096   // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3097   if (sizeof(vki_sigset_t) != ARG4)
3098      SET_STATUS_Failure( VKI_EMFILE );
3099   else {
3100      SET_STATUS_from_SysRes(
3101                  VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3102                                            (vki_sigset_t*) ARG2,
3103                                            (vki_sigset_t*) ARG3 )
3104      );
3105   }
3106
3107   if (SUCCESS)
3108      *flags |= SfPollAfter;
3109}
3110POST(sys_rt_sigprocmask)
3111{
3112   vg_assert(SUCCESS);
3113   if (RES == 0 && ARG3 != 0)
3114      POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3115}
3116
3117PRE(sys_rt_sigpending)
3118{
3119   PRINT( "sys_rt_sigpending ( %#lx )", ARG1 );
3120   PRE_REG_READ2(long, "rt_sigpending",
3121                 vki_sigset_t *, set, vki_size_t, sigsetsize);
3122   PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
3123}
3124POST(sys_rt_sigpending)
3125{
3126   POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3127}
3128
3129PRE(sys_rt_sigtimedwait)
3130{
3131   *flags |= SfMayBlock;
3132   PRINT("sys_rt_sigtimedwait ( %#lx, %#lx, %#lx, %lld )",
3133         ARG1,ARG2,ARG3,(ULong)ARG4);
3134   PRE_REG_READ4(long, "rt_sigtimedwait",
3135                 const vki_sigset_t *, set, vki_siginfo_t *, info,
3136                 const struct timespec *, timeout, vki_size_t, sigsetsize);
3137   if (ARG1 != 0)
3138      PRE_MEM_READ(  "rt_sigtimedwait(set)",  ARG1, sizeof(vki_sigset_t));
3139   if (ARG2 != 0)
3140      PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3141   if (ARG3 != 0)
3142      PRE_MEM_READ( "rt_sigtimedwait(timeout)",
3143                    ARG3, sizeof(struct vki_timespec) );
3144}
3145POST(sys_rt_sigtimedwait)
3146{
3147   if (ARG2 != 0)
3148      POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3149}
3150
3151PRE(sys_rt_sigqueueinfo)
3152{
3153   PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
3154   PRE_REG_READ3(long, "rt_sigqueueinfo",
3155                 int, pid, int, sig, vki_siginfo_t *, uinfo);
3156   if (ARG2 != 0)
3157      PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
3158}
3159POST(sys_rt_sigqueueinfo)
3160{
3161   if (!ML_(client_signal_OK)(ARG2))
3162      SET_STATUS_Failure( VKI_EINVAL );
3163}
3164
3165PRE(sys_rt_tgsigqueueinfo)
3166{
3167   PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)", ARG1, ARG2, ARG3, ARG4);
3168   PRE_REG_READ4(long, "rt_tgsigqueueinfo",
3169                 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
3170   if (ARG3 != 0)
3171      PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
3172}
3173
3174POST(sys_rt_tgsigqueueinfo)
3175{
3176   if (!ML_(client_signal_OK)(ARG3))
3177      SET_STATUS_Failure( VKI_EINVAL );
3178}
3179
3180// XXX: x86-specific?  The kernel prototypes for the different archs are
3181//      hard to decipher.
3182PRE(sys_rt_sigsuspend)
3183{
3184   /* The C library interface to sigsuspend just takes a pointer to
3185      a signal mask but this system call has two arguments - a pointer
3186      to the mask and the number of bytes used by it. The kernel insists
3187      on the size being equal to sizeof(sigset_t) however and will just
3188      return EINVAL if it isn't.
3189    */
3190   *flags |= SfMayBlock;
3191   PRINT("sys_rt_sigsuspend ( %#lx, %ld )", ARG1,ARG2 );
3192   PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
3193   if (ARG1 != (Addr)NULL) {
3194      PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
3195   }
3196}
3197
3198/* ---------------------------------------------------------------------
3199   linux msg* wrapper helpers
3200   ------------------------------------------------------------------ */
3201
3202void
3203ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
3204                            UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
3205{
3206   /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
3207   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3208   PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3209   PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3210}
3211
3212void
3213ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
3214                            UWord arg0, UWord arg1, UWord arg2,
3215                            UWord arg3, UWord arg4 )
3216{
3217   /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
3218                     long msgtyp, int msgflg); */
3219   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3220   PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3221   PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3222}
3223void
3224ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
3225                             UWord res,
3226                             UWord arg0, UWord arg1, UWord arg2,
3227                             UWord arg3, UWord arg4 )
3228{
3229   struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3230   POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3231   POST_MEM_WRITE( (Addr)&msgp->mtext, res );
3232}
3233
3234void
3235ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
3236                            UWord arg0, UWord arg1, UWord arg2 )
3237{
3238   /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
3239   switch (arg1 /* cmd */) {
3240   case VKI_IPC_INFO:
3241   case VKI_MSG_INFO:
3242   case VKI_IPC_INFO|VKI_IPC_64:
3243   case VKI_MSG_INFO|VKI_IPC_64:
3244      PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
3245                     arg2, sizeof(struct vki_msginfo) );
3246      break;
3247   case VKI_IPC_STAT:
3248   case VKI_MSG_STAT:
3249      PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
3250                     arg2, sizeof(struct vki_msqid_ds) );
3251      break;
3252   case VKI_IPC_STAT|VKI_IPC_64:
3253   case VKI_MSG_STAT|VKI_IPC_64:
3254      PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
3255                     arg2, sizeof(struct vki_msqid64_ds) );
3256      break;
3257   case VKI_IPC_SET:
3258      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3259                    arg2, sizeof(struct vki_msqid_ds) );
3260      break;
3261   case VKI_IPC_SET|VKI_IPC_64:
3262      PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3263                    arg2, sizeof(struct vki_msqid64_ds) );
3264      break;
3265   }
3266}
3267void
3268ML_(linux_POST_sys_msgctl) ( ThreadId tid,
3269                             UWord res,
3270                             UWord arg0, UWord arg1, UWord arg2 )
3271{
3272   switch (arg1 /* cmd */) {
3273   case VKI_IPC_INFO:
3274   case VKI_MSG_INFO:
3275   case VKI_IPC_INFO|VKI_IPC_64:
3276   case VKI_MSG_INFO|VKI_IPC_64:
3277      POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
3278      break;
3279   case VKI_IPC_STAT:
3280   case VKI_MSG_STAT:
3281      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
3282      break;
3283   case VKI_IPC_STAT|VKI_IPC_64:
3284   case VKI_MSG_STAT|VKI_IPC_64:
3285      POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
3286      break;
3287   }
3288}
3289
3290/* ---------------------------------------------------------------------
3291   *at wrappers
3292   ------------------------------------------------------------------ */
3293
3294PRE(sys_openat)
3295{
3296   HChar  name[30];
3297   SysRes sres;
3298
3299   if (ARG3 & VKI_O_CREAT) {
3300      // 4-arg version
3301      PRINT("sys_openat ( %ld, %#lx(%s), %ld, %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
3302      PRE_REG_READ4(long, "openat",
3303                    int, dfd, const char *, filename, int, flags, int, mode);
3304   } else {
3305      // 3-arg version
3306      PRINT("sys_openat ( %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3);
3307      PRE_REG_READ3(long, "openat",
3308                    int, dfd, const char *, filename, int, flags);
3309   }
3310
3311   if (ARG1 != VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat", tid, False))
3312      SET_STATUS_Failure( VKI_EBADF );
3313   else
3314      PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
3315
3316   /* Handle the case where the open is of /proc/self/cmdline or
3317      /proc/<pid>/cmdline, and just give it a copy of the fd for the
3318      fake file we cooked up at startup (in m_main).  Also, seek the
3319      cloned fd back to the start. */
3320
3321   VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
3322   if (ML_(safe_to_deref)( (void*)ARG2, 1 )
3323       && (VG_(strcmp)((Char *)ARG2, name) == 0
3324           || VG_(strcmp)((Char *)ARG2, "/proc/self/cmdline") == 0)) {
3325      sres = VG_(dup)( VG_(cl_cmdline_fd) );
3326      SET_STATUS_from_SysRes( sres );
3327      if (!sr_isError(sres)) {
3328         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
3329         if (off < 0)
3330            SET_STATUS_Failure( VKI_EMFILE );
3331      }
3332      return;
3333   }
3334
3335   /* Otherwise handle normally */
3336   *flags |= SfMayBlock;
3337}
3338
3339POST(sys_openat)
3340{
3341   vg_assert(SUCCESS);
3342   if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
3343      VG_(close)(RES);
3344      SET_STATUS_Failure( VKI_EMFILE );
3345   } else {
3346      if (VG_(clo_track_fds))
3347         ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG2);
3348   }
3349}
3350
3351PRE(sys_mkdirat)
3352{
3353   *flags |= SfMayBlock;
3354   PRINT("sys_mkdirat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
3355   PRE_REG_READ3(long, "mkdirat",
3356                 int, dfd, const char *, pathname, int, mode);
3357   PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
3358}
3359
3360PRE(sys_mknodat)
3361{
3362  PRINT("sys_mknodat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 );
3363   PRE_REG_READ4(long, "mknodat",
3364                 int, dfd, const char *, pathname, int, mode, unsigned, dev);
3365   PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
3366}
3367
3368PRE(sys_fchownat)
3369{
3370   PRINT("sys_fchownat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
3371   PRE_REG_READ4(long, "fchownat",
3372                 int, dfd, const char *, path,
3373                 vki_uid_t, owner, vki_gid_t, group);
3374   PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
3375}
3376
3377PRE(sys_futimesat)
3378{
3379   PRINT("sys_futimesat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
3380   PRE_REG_READ3(long, "futimesat",
3381                 int, dfd, char *, filename, struct timeval *, tvp);
3382   if (ARG2 != 0)
3383      PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
3384   if (ARG3 != 0)
3385      PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
3386}
3387
3388PRE(sys_utimensat)
3389{
3390   PRINT("sys_utimensat ( %ld, %#lx(%s), %#lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
3391   PRE_REG_READ4(long, "utimensat",
3392                 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
3393   if (ARG2 != 0)
3394      PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
3395   if (ARG3 != 0)
3396      PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
3397}
3398
3399PRE(sys_newfstatat)
3400{
3401   FUSE_COMPATIBLE_MAY_BLOCK();
3402   PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
3403   PRE_REG_READ3(long, "fstatat",
3404                 int, dfd, char *, file_name, struct stat *, buf);
3405   PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
3406   PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
3407}
3408
3409POST(sys_newfstatat)
3410{
3411   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
3412}
3413
3414PRE(sys_unlinkat)
3415{
3416   *flags |= SfMayBlock;
3417   PRINT("sys_unlinkat ( %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2);
3418   PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
3419   PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
3420}
3421
3422PRE(sys_renameat)
3423{
3424   PRINT("sys_renameat ( %ld, %#lx(%s), %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4);
3425   PRE_REG_READ4(long, "renameat",
3426                 int, olddfd, const char *, oldpath,
3427                 int, newdfd, const char *, newpath);
3428   PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
3429   PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
3430}
3431
3432PRE(sys_linkat)
3433{
3434   *flags |= SfMayBlock;
3435   PRINT("sys_linkat ( %ld, %#lx(%s), %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4,ARG5);
3436   PRE_REG_READ5(long, "linkat",
3437                 int, olddfd, const char *, oldpath,
3438                 int, newdfd, const char *, newpath,
3439                 int, flags);
3440   PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
3441   PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
3442}
3443
3444PRE(sys_symlinkat)
3445{
3446   *flags |= SfMayBlock;
3447   PRINT("sys_symlinkat ( %#lx(%s), %ld, %#lx(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3);
3448   PRE_REG_READ3(long, "symlinkat",
3449                 const char *, oldpath, int, newdfd, const char *, newpath);
3450   PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
3451   PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
3452}
3453
3454PRE(sys_readlinkat)
3455{
3456   HChar name[25];
3457   Word  saved = SYSNO;
3458
3459   PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
3460   PRE_REG_READ4(long, "readlinkat",
3461                 int, dfd, const char *, path, char *, buf, int, bufsiz);
3462   PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
3463   PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
3464
3465   /*
3466    * Handle the case where readlinkat is looking at /proc/self/exe or
3467    * /proc/<pid>/exe.
3468    */
3469   VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
3470   if (ML_(safe_to_deref)((void*)ARG2, 1)
3471       && (VG_(strcmp)((Char *)ARG2, name) == 0
3472           || VG_(strcmp)((Char *)ARG2, "/proc/self/exe") == 0)) {
3473      VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
3474      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
3475                                                      ARG3, ARG4));
3476   } else {
3477      /* Normal case */
3478      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
3479   }
3480
3481   if (SUCCESS && RES > 0)
3482      POST_MEM_WRITE( ARG3, RES );
3483}
3484
3485PRE(sys_fchmodat)
3486{
3487   PRINT("sys_fchmodat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
3488   PRE_REG_READ3(long, "fchmodat",
3489                 int, dfd, const char *, path, vki_mode_t, mode);
3490   PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
3491}
3492
3493PRE(sys_faccessat)
3494{
3495   PRINT("sys_faccessat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
3496   PRE_REG_READ3(long, "faccessat",
3497                 int, dfd, const char *, pathname, int, mode);
3498   PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
3499}
3500
3501/* ---------------------------------------------------------------------
3502   p{read,write}v wrappers
3503   ------------------------------------------------------------------ */
3504
3505PRE(sys_preadv)
3506{
3507   Int i;
3508   struct vki_iovec * vec;
3509   *flags |= SfMayBlock;
3510#if VG_WORDSIZE == 4
3511   /* Note that the offset argument here is in lo+hi order on both
3512      big and little endian platforms... */
3513   PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
3514   PRE_REG_READ5(ssize_t, "preadv",
3515                 unsigned long, fd, const struct iovec *, vector,
3516                 unsigned long, count, vki_u32, offset_low,
3517                 vki_u32, offset_high);
3518#elif VG_WORDSIZE == 8
3519   PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
3520   PRE_REG_READ4(ssize_t, "preadv",
3521                 unsigned long, fd, const struct iovec *, vector,
3522                 unsigned long, count, Word, offset);
3523#else
3524#  error Unexpected word size
3525#endif
3526   if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
3527      SET_STATUS_Failure( VKI_EBADF );
3528   } else {
3529      PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
3530
3531      if (ARG2 != 0) {
3532         /* ToDo: don't do any of the following if the vector is invalid */
3533         vec = (struct vki_iovec *)ARG2;
3534         for (i = 0; i < (Int)ARG3; i++)
3535            PRE_MEM_WRITE( "preadv(vector[...])",
3536                           (Addr)vec[i].iov_base, vec[i].iov_len );
3537      }
3538   }
3539}
3540
3541POST(sys_preadv)
3542{
3543   vg_assert(SUCCESS);
3544   if (RES > 0) {
3545      Int i;
3546      struct vki_iovec * vec = (struct vki_iovec *)ARG2;
3547      Int remains = RES;
3548
3549      /* RES holds the number of bytes read. */
3550      for (i = 0; i < (Int)ARG3; i++) {
3551	 Int nReadThisBuf = vec[i].iov_len;
3552	 if (nReadThisBuf > remains) nReadThisBuf = remains;
3553	 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
3554	 remains -= nReadThisBuf;
3555	 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
3556      }
3557   }
3558}
3559
3560PRE(sys_pwritev)
3561{
3562   Int i;
3563   struct vki_iovec * vec;
3564   *flags |= SfMayBlock;
3565#if VG_WORDSIZE == 4
3566   /* Note that the offset argument here is in lo+hi order on both
3567      big and little endian platforms... */
3568   PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
3569   PRE_REG_READ5(ssize_t, "pwritev",
3570                 unsigned long, fd, const struct iovec *, vector,
3571                 unsigned long, count, vki_u32, offset_low,
3572                 vki_u32, offset_high);
3573#elif VG_WORDSIZE == 8
3574   PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
3575   PRE_REG_READ4(ssize_t, "pwritev",
3576                 unsigned long, fd, const struct iovec *, vector,
3577                 unsigned long, count, Word, offset);
3578#else
3579#  error Unexpected word size
3580#endif
3581   if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
3582      SET_STATUS_Failure( VKI_EBADF );
3583   } else {
3584      PRE_MEM_READ( "pwritev(vector)",
3585		     ARG2, ARG3 * sizeof(struct vki_iovec) );
3586      if (ARG2 != 0) {
3587         /* ToDo: don't do any of the following if the vector is invalid */
3588         vec = (struct vki_iovec *)ARG2;
3589         for (i = 0; i < (Int)ARG3; i++)
3590            PRE_MEM_READ( "pwritev(vector[...])",
3591                           (Addr)vec[i].iov_base, vec[i].iov_len );
3592      }
3593   }
3594}
3595
3596/* ---------------------------------------------------------------------
3597   process_vm_{read,write}v wrappers
3598   ------------------------------------------------------------------ */
3599
3600PRE(sys_process_vm_readv)
3601{
3602   PRINT("sys_process_vm_readv ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
3603         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3604   PRE_REG_READ6(ssize_t, "process_vm_readv",
3605                 vki_pid_t, pid,
3606                 const struct iovec *, lvec,
3607                 unsigned long, liovcnt,
3608                 const struct iovec *, rvec,
3609                 unsigned long, riovcnt,
3610                 unsigned long, flags);
3611   PRE_MEM_READ( "process_vm_readv(lvec)",
3612                 ARG2, ARG3 * sizeof(struct vki_iovec) );
3613   PRE_MEM_READ( "process_vm_readv(rvec)",
3614                 ARG4, ARG5 * sizeof(struct vki_iovec) );
3615   if (ARG2 != 0) {
3616      /* TODO: Don't do any of the following if lvec is invalid */
3617      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
3618      UInt i;
3619      for (i = 0; i < ARG3; i++)
3620         PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
3621                        (Addr)vec[i].iov_base, vec[i].iov_len );
3622   }
3623}
3624
3625POST(sys_process_vm_readv)
3626{
3627   const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
3628   UInt remains = RES;
3629   UInt i;
3630   for (i = 0; i < ARG3; i++) {
3631      UInt nReadThisBuf = vec[i].iov_len <= remains ?
3632                          vec[i].iov_len : remains;
3633      POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
3634      remains -= nReadThisBuf;
3635   }
3636}
3637
3638PRE(sys_process_vm_writev)
3639{
3640   PRINT("sys_process_vm_writev ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
3641         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3642   PRE_REG_READ6(ssize_t, "process_vm_writev",
3643                 vki_pid_t, pid,
3644                 const struct iovec *, lvec,
3645                 unsigned long, liovcnt,
3646                 const struct iovec *, rvec,
3647                 unsigned long, riovcnt,
3648                 unsigned long, flags);
3649   PRE_MEM_READ( "process_vm_writev(lvec)",
3650                 ARG2, ARG3 * sizeof(struct vki_iovec) );
3651   PRE_MEM_READ( "process_vm_writev(rvec)",
3652                 ARG4, ARG5 * sizeof(struct vki_iovec) );
3653   if (ARG2 != 0) {
3654      /* TODO: Don't do any of the following if lvec is invalid */
3655      const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
3656      UInt i;
3657      for (i = 0; i < ARG3; i++)
3658         PRE_MEM_READ( "process_vm_writev(lvec[...])",
3659                       (Addr)vec[i].iov_base, vec[i].iov_len );
3660   }
3661}
3662
3663/* ---------------------------------------------------------------------
3664   {send,recv}mmsg wrappers
3665   ------------------------------------------------------------------ */
3666
3667PRE(sys_sendmmsg)
3668{
3669   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
3670   Char name[32];
3671   UInt i;
3672   *flags |= SfMayBlock;
3673   PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
3674   PRE_REG_READ4(long, "sendmmsg",
3675                 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
3676   for (i = 0; i < ARG3; i++) {
3677      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
3678      ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
3679      VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
3680      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
3681   }
3682}
3683
3684POST(sys_sendmmsg)
3685{
3686   if (RES > 0) {
3687      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
3688      UInt i;
3689      for (i = 0; i < RES; i++) {
3690         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
3691      }
3692   }
3693}
3694
3695PRE(sys_recvmmsg)
3696{
3697   struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
3698   Char name[32];
3699   UInt i;
3700   *flags |= SfMayBlock;
3701   PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
3702   PRE_REG_READ5(long, "recvmmsg",
3703                 int, s, struct mmsghdr *, mmsg, int, vlen,
3704                 int, flags, struct timespec *, timeout);
3705   for (i = 0; i < ARG3; i++) {
3706      VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
3707      ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
3708      VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
3709      PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
3710   }
3711   if (ARG5)
3712      PRE_MEM_READ( "recvmmsg(timeout)", ARG5, sizeof(struct vki_timespec) );
3713}
3714
3715POST(sys_recvmmsg)
3716{
3717   if (RES > 0) {
3718      struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
3719      Char name[32];
3720      UInt i;
3721      for (i = 0; i < RES; i++) {
3722         VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
3723         ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
3724         POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
3725      }
3726   }
3727}
3728
3729/* ---------------------------------------------------------------------
3730   key retention service wrappers
3731   ------------------------------------------------------------------ */
3732
3733PRE(sys_request_key)
3734{
3735   PRINT("sys_request_key ( %#lx(%s), %#lx(%s), %#lx(%s), %ld )",
3736         ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,(char*)ARG3,ARG4);
3737   PRE_REG_READ4(long, "request_key",
3738                 const char *, type, const char *, description,
3739                 const char *, callout_info, vki_key_serial_t, keyring);
3740   PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
3741   PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
3742   if (ARG3 != (UWord)NULL)
3743      PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
3744}
3745
3746PRE(sys_add_key)
3747{
3748   PRINT("sys_add_key ( %#lx(%s), %#lx(%s), %#lx, %ld, %ld )",
3749         ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,ARG4,ARG5);
3750   PRE_REG_READ5(long, "add_key",
3751                 const char *, type, const char *, description,
3752                 const void *, payload, vki_size_t, plen,
3753                 vki_key_serial_t, keyring);
3754   PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
3755   PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
3756   if (ARG3 != (UWord)NULL)
3757      PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
3758}
3759
3760PRE(sys_keyctl)
3761{
3762   switch (ARG1 /* option */) {
3763   case VKI_KEYCTL_GET_KEYRING_ID:
3764      PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", ARG2,ARG3);
3765      PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
3766                    int, option, vki_key_serial_t, id, int, create);
3767      break;
3768   case VKI_KEYCTL_JOIN_SESSION_KEYRING:
3769      PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#lx(%s) )", ARG2,(char*)ARG2);
3770      PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
3771                    int, option, const char *, name);
3772      if (ARG2 != (UWord)NULL)
3773         PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
3774      break;
3775   case VKI_KEYCTL_UPDATE:
3776      PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
3777      PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
3778                    int, option, vki_key_serial_t, key,
3779                    const void *, payload, vki_size_t, plen);
3780      if (ARG3 != (UWord)NULL)
3781         PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
3782      break;
3783   case VKI_KEYCTL_REVOKE:
3784      PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", ARG2);
3785      PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
3786                    int, option, vki_key_serial_t, id);
3787      break;
3788   case VKI_KEYCTL_CHOWN:
3789      PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %ld, %ld )", ARG2,ARG3,ARG4);
3790      PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
3791                    int, option, vki_key_serial_t, id,
3792                    vki_uid_t, uid, vki_gid_t, gid);
3793      break;
3794   case VKI_KEYCTL_SETPERM:
3795      PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %ld )", ARG2,ARG3);
3796      PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
3797                    int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
3798      break;
3799   case VKI_KEYCTL_DESCRIBE:
3800      PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
3801      PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
3802                    int, option, vki_key_serial_t, id,
3803                    char *, buffer, vki_size_t, buflen);
3804      if (ARG3 != (UWord)NULL)
3805         PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
3806      break;
3807   case VKI_KEYCTL_CLEAR:
3808      PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", ARG2);
3809      PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
3810                    int, option, vki_key_serial_t, keyring);
3811      break;
3812   case VKI_KEYCTL_LINK:
3813      PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", ARG2,ARG3);
3814      PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
3815                    vki_key_serial_t, keyring, vki_key_serial_t, key);
3816      break;
3817   case VKI_KEYCTL_UNLINK:
3818      PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", ARG2,ARG3);
3819      PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
3820                    vki_key_serial_t, keyring, vki_key_serial_t, key);
3821      break;
3822   case VKI_KEYCTL_SEARCH:
3823      PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#lx(%s), %#lx(%s), %ld )",
3824            ARG2,ARG3,(char*)ARG3,ARG4,(char*)ARG4,ARG5);
3825      PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
3826                    int, option, vki_key_serial_t, keyring,
3827                    const char *, type, const char *, description,
3828                    vki_key_serial_t, destring);
3829      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
3830      PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
3831      break;
3832   case VKI_KEYCTL_READ:
3833      PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
3834      PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
3835                    int, option, vki_key_serial_t, keyring,
3836                    char *, buffer, vki_size_t, buflen);
3837      if (ARG3 != (UWord)NULL)
3838         PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
3839      break;
3840   case VKI_KEYCTL_INSTANTIATE:
3841      PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#lx, %ld, %ld )",
3842            ARG2,ARG3,ARG4,ARG5);
3843      PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
3844                    int, option, vki_key_serial_t, key,
3845                    char *, payload, vki_size_t, plen,
3846                    vki_key_serial_t, keyring);
3847      if (ARG3 != (UWord)NULL)
3848         PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
3849      break;
3850   case VKI_KEYCTL_NEGATE:
3851      PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %lu, %ld )", ARG2,ARG3,ARG4);
3852      PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
3853                    int, option, vki_key_serial_t, key,
3854                    unsigned, timeout, vki_key_serial_t, keyring);
3855      break;
3856   case VKI_KEYCTL_SET_REQKEY_KEYRING:
3857      PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", ARG2);
3858      PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
3859                    int, option, int, reqkey_defl);
3860      break;
3861   case VKI_KEYCTL_SET_TIMEOUT:
3862      PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %ld )", ARG2,ARG3);
3863      PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
3864                    int, option, vki_key_serial_t, key, unsigned, timeout);
3865      break;
3866   case VKI_KEYCTL_ASSUME_AUTHORITY:
3867      PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", ARG2);
3868      PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
3869                    int, option, vki_key_serial_t, key);
3870      break;
3871   default:
3872      PRINT("sys_keyctl ( %ld ) ", ARG1);
3873      PRE_REG_READ1(long, "keyctl", int, option);
3874      break;
3875   }
3876}
3877
3878POST(sys_keyctl)
3879{
3880   vg_assert(SUCCESS);
3881   switch (ARG1 /* option */) {
3882   case VKI_KEYCTL_DESCRIBE:
3883   case VKI_KEYCTL_READ:
3884      if (RES > ARG4)
3885         POST_MEM_WRITE(ARG3, ARG4);
3886      else
3887         POST_MEM_WRITE(ARG3, RES);
3888      break;
3889   default:
3890      break;
3891   }
3892}
3893
3894/* ---------------------------------------------------------------------
3895   ioprio_ wrappers
3896   ------------------------------------------------------------------ */
3897
3898PRE(sys_ioprio_set)
3899{
3900   PRINT("sys_ioprio_set ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
3901   PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
3902}
3903
3904PRE(sys_ioprio_get)
3905{
3906   PRINT("sys_ioprio_get ( %ld, %ld )", ARG1,ARG2);
3907   PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
3908}
3909
3910/* ---------------------------------------------------------------------
3911   _module wrappers
3912   ------------------------------------------------------------------ */
3913
3914PRE(sys_init_module)
3915{
3916   *flags |= SfMayBlock;
3917   PRINT("sys_init_module ( %#lx, %llu, %#lx(\"%s\") )",
3918         ARG1, (ULong)ARG2, ARG3, (char*)ARG3);
3919   PRE_REG_READ3(long, "init_module",
3920                 void *, umod, unsigned long, len, const char *, uargs);
3921   PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
3922   PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
3923}
3924
3925PRE(sys_delete_module)
3926{
3927   *flags |= SfMayBlock;
3928   PRINT("sys_delete_module ( %#lx(\"%s\"), 0x%lx )", ARG1,(char*)ARG1, ARG2);
3929   PRE_REG_READ2(long, "delete_module",
3930                 const char *, name_user, unsigned int, flags);
3931   PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
3932}
3933
3934/* ---------------------------------------------------------------------
3935   splice wrappers
3936   ------------------------------------------------------------------ */
3937
3938PRE(sys_splice)
3939{
3940   *flags |= SfMayBlock;
3941   PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %ld, %ld )",
3942         ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3943   PRE_REG_READ6(vki_ssize_t, "splice",
3944                 int, fd_in, vki_loff_t *, off_in,
3945                 int, fd_out, vki_loff_t *, off_out,
3946                 vki_size_t, len, unsigned int, flags);
3947   if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
3948       !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
3949      SET_STATUS_Failure( VKI_EBADF );
3950   } else {
3951      if (ARG2 != 0)
3952         PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
3953      if (ARG4 != 0)
3954         PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
3955   }
3956}
3957
3958PRE(sys_tee)
3959{
3960   *flags |= SfMayBlock;
3961   PRINT("sys_tree ( %ld, %ld, %ld, %ld )", ARG1,ARG2,ARG3,ARG4);
3962   PRE_REG_READ4(vki_ssize_t, "tee",
3963                 int, fd_in, int, fd_out,
3964                 vki_size_t, len, unsigned int, flags);
3965   if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
3966       !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
3967      SET_STATUS_Failure( VKI_EBADF );
3968   }
3969}
3970
3971PRE(sys_vmsplice)
3972{
3973   Int fdfl;
3974   *flags |= SfMayBlock;
3975   PRINT("sys_vmsplice ( %ld, %#lx, %ld, %ld )",
3976         ARG1,ARG2,ARG3,ARG4);
3977   PRE_REG_READ4(vki_ssize_t, "splice",
3978                 int, fd, struct vki_iovec *, iov,
3979                 unsigned long, nr_segs, unsigned int, flags);
3980   if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
3981      SET_STATUS_Failure( VKI_EBADF );
3982   } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
3983      SET_STATUS_Failure( VKI_EBADF );
3984   } else {
3985      const struct vki_iovec *iov;
3986      PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
3987      for (iov = (struct vki_iovec *)ARG2;
3988           iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
3989      {
3990         if ((fdfl & (VKI_O_WRONLY|VKI_O_RDWR)) != 0)
3991            PRE_MEM_READ( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
3992         else if ((fdfl & VKI_O_RDONLY) != 0)
3993            PRE_MEM_WRITE( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
3994      }
3995   }
3996}
3997
3998POST(sys_vmsplice)
3999{
4000   vg_assert(SUCCESS);
4001   if (RES > 0) {
4002      Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
4003      vg_assert(fdfl >= 0);
4004      if ((fdfl & VKI_O_RDONLY) != 0)
4005      {
4006         const struct vki_iovec *iov;
4007         for (iov = (struct vki_iovec *)ARG2;
4008              iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
4009         {
4010            POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
4011         }
4012      }
4013   }
4014}
4015
4016/* ---------------------------------------------------------------------
4017   oprofile-related wrappers
4018   ------------------------------------------------------------------ */
4019
4020#if defined(VGP_x86_linux)
4021PRE(sys_lookup_dcookie)
4022{
4023   PRINT("sys_lookup_dcookie (0x%llx, %#lx, %ld)",
4024         MERGE64(ARG1,ARG2), ARG3, ARG4);
4025   PRE_REG_READ4(long, "lookup_dcookie",
4026                 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
4027                 char *, buf, vki_size_t, len);
4028   PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
4029}
4030POST(sys_lookup_dcookie)
4031{
4032   vg_assert(SUCCESS);
4033   if (ARG3 != (Addr)NULL)
4034      POST_MEM_WRITE( ARG3, RES);
4035}
4036#endif
4037
4038#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
4039PRE(sys_lookup_dcookie)
4040{
4041   *flags |= SfMayBlock;
4042   PRINT("sys_lookup_dcookie ( %llu, %#lx, %llu )",
4043	 (ULong)ARG1, ARG2, (ULong)ARG3);
4044   PRE_REG_READ3(int, "lookup_dcookie",
4045                 unsigned long long, cookie, char *, buf, vki_size_t, len);
4046
4047   PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
4048}
4049
4050POST(sys_lookup_dcookie)
4051{
4052   vg_assert(SUCCESS);
4053   if (ARG2 != (Addr)NULL)
4054     POST_MEM_WRITE( ARG2, RES );
4055}
4056#endif
4057
4058/* ---------------------------------------------------------------------
4059   fcntl wrappers
4060   ------------------------------------------------------------------ */
4061
4062PRE(sys_fcntl)
4063{
4064   switch (ARG2) {
4065   // These ones ignore ARG3.
4066   case VKI_F_GETFD:
4067   case VKI_F_GETFL:
4068   case VKI_F_GETOWN:
4069   case VKI_F_GETSIG:
4070   case VKI_F_GETLEASE:
4071   case VKI_F_GETPIPE_SZ:
4072      PRINT("sys_fcntl ( %ld, %ld )", ARG1,ARG2);
4073      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
4074      break;
4075
4076   // These ones use ARG3 as "arg".
4077   case VKI_F_DUPFD:
4078   case VKI_F_DUPFD_CLOEXEC:
4079   case VKI_F_SETFD:
4080   case VKI_F_SETFL:
4081   case VKI_F_SETLEASE:
4082   case VKI_F_NOTIFY:
4083   case VKI_F_SETOWN:
4084   case VKI_F_SETSIG:
4085   case VKI_F_SETPIPE_SZ:
4086      PRINT("sys_fcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4087      PRE_REG_READ3(long, "fcntl",
4088                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
4089      break;
4090
4091   // These ones use ARG3 as "lock".
4092   case VKI_F_GETLK:
4093   case VKI_F_SETLK:
4094   case VKI_F_SETLKW:
4095#  if defined(VGP_x86_linux)
4096   case VKI_F_GETLK64:
4097   case VKI_F_SETLK64:
4098   case VKI_F_SETLKW64:
4099#  endif
4100      PRINT("sys_fcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
4101      PRE_REG_READ3(long, "fcntl",
4102                    unsigned int, fd, unsigned int, cmd,
4103                    struct flock64 *, lock);
4104      break;
4105
4106   case VKI_F_SETOWN_EX:
4107      PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4108      PRE_REG_READ3(long, "fcntl",
4109                    unsigned int, fd, unsigned int, cmd,
4110                    struct vki_f_owner_ex *, arg);
4111      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
4112      break;
4113
4114   case VKI_F_GETOWN_EX:
4115      PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4116      PRE_REG_READ3(long, "fcntl",
4117                    unsigned int, fd, unsigned int, cmd,
4118                    struct vki_f_owner_ex *, arg);
4119      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
4120      break;
4121
4122   default:
4123      PRINT("sys_fcntl[UNKNOWN] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4124      I_die_here;
4125      break;
4126   }
4127
4128#  if defined(VGP_x86_linux)
4129   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
4130#  else
4131   if (ARG2 == VKI_F_SETLKW)
4132#  endif
4133      *flags |= SfMayBlock;
4134}
4135
4136POST(sys_fcntl)
4137{
4138   vg_assert(SUCCESS);
4139   if (ARG2 == VKI_F_DUPFD) {
4140      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
4141         VG_(close)(RES);
4142         SET_STATUS_Failure( VKI_EMFILE );
4143      } else {
4144         if (VG_(clo_track_fds))
4145            ML_(record_fd_open_named)(tid, RES);
4146      }
4147   }
4148   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
4149      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
4150         VG_(close)(RES);
4151         SET_STATUS_Failure( VKI_EMFILE );
4152      } else {
4153         if (VG_(clo_track_fds))
4154            ML_(record_fd_open_named)(tid, RES);
4155      }
4156   } else if (ARG2 == VKI_F_GETOWN_EX) {
4157      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
4158   }
4159}
4160
4161// XXX: wrapper only suitable for 32-bit systems
4162PRE(sys_fcntl64)
4163{
4164   switch (ARG2) {
4165   // These ones ignore ARG3.
4166   case VKI_F_GETFD:
4167   case VKI_F_GETFL:
4168   case VKI_F_GETOWN:
4169   case VKI_F_SETOWN:
4170   case VKI_F_GETSIG:
4171   case VKI_F_SETSIG:
4172   case VKI_F_GETLEASE:
4173      PRINT("sys_fcntl64 ( %ld, %ld )", ARG1,ARG2);
4174      PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
4175      break;
4176
4177   // These ones use ARG3 as "arg".
4178   case VKI_F_DUPFD:
4179   case VKI_F_DUPFD_CLOEXEC:
4180   case VKI_F_SETFD:
4181   case VKI_F_SETFL:
4182   case VKI_F_SETLEASE:
4183   case VKI_F_NOTIFY:
4184      PRINT("sys_fcntl64[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4185      PRE_REG_READ3(long, "fcntl64",
4186                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
4187      break;
4188
4189   // These ones use ARG3 as "lock".
4190   case VKI_F_GETLK:
4191   case VKI_F_SETLK:
4192   case VKI_F_SETLKW:
4193#  if defined(VGP_x86_linux)
4194   case VKI_F_GETLK64:
4195   case VKI_F_SETLK64:
4196   case VKI_F_SETLKW64:
4197#  endif
4198      PRINT("sys_fcntl64[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
4199      PRE_REG_READ3(long, "fcntl64",
4200                    unsigned int, fd, unsigned int, cmd,
4201                    struct flock64 *, lock);
4202      break;
4203
4204   case VKI_F_SETOWN_EX:
4205      PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4206      PRE_REG_READ3(long, "fcntl",
4207                    unsigned int, fd, unsigned int, cmd,
4208                    struct vki_f_owner_ex *, arg);
4209      PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
4210      break;
4211
4212   case VKI_F_GETOWN_EX:
4213      PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
4214      PRE_REG_READ3(long, "fcntl",
4215                    unsigned int, fd, unsigned int, cmd,
4216                    struct vki_f_owner_ex *, arg);
4217      PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
4218      break;
4219   }
4220
4221#  if defined(VGP_x86_linux)
4222   if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
4223#  else
4224   if (ARG2 == VKI_F_SETLKW)
4225#  endif
4226      *flags |= SfMayBlock;
4227}
4228
4229POST(sys_fcntl64)
4230{
4231   vg_assert(SUCCESS);
4232   if (ARG2 == VKI_F_DUPFD) {
4233      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
4234         VG_(close)(RES);
4235         SET_STATUS_Failure( VKI_EMFILE );
4236      } else {
4237         if (VG_(clo_track_fds))
4238            ML_(record_fd_open_named)(tid, RES);
4239      }
4240   }
4241   else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
4242      if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
4243         VG_(close)(RES);
4244         SET_STATUS_Failure( VKI_EMFILE );
4245      } else {
4246         if (VG_(clo_track_fds))
4247            ML_(record_fd_open_named)(tid, RES);
4248      }
4249   } else if (ARG2 == VKI_F_GETOWN_EX) {
4250      POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
4251   }
4252}
4253
4254/* ---------------------------------------------------------------------
4255   ioctl wrappers
4256   ------------------------------------------------------------------ */
4257
4258PRE(sys_ioctl)
4259{
4260   *flags |= SfMayBlock;
4261
4262   // We first handle the ones that don't use ARG3 (even as a
4263   // scalar/non-pointer argument).
4264   switch (ARG2 /* request */) {
4265
4266      /* linux/soundcard interface (ALSA) */
4267   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
4268   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
4269   case VKI_SNDRV_PCM_IOCTL_PREPARE:
4270   case VKI_SNDRV_PCM_IOCTL_RESET:
4271   case VKI_SNDRV_PCM_IOCTL_START:
4272   case VKI_SNDRV_PCM_IOCTL_DROP:
4273   case VKI_SNDRV_PCM_IOCTL_DRAIN:
4274   case VKI_SNDRV_PCM_IOCTL_RESUME:
4275   case VKI_SNDRV_PCM_IOCTL_XRUN:
4276   case VKI_SNDRV_PCM_IOCTL_UNLINK:
4277   case VKI_SNDRV_TIMER_IOCTL_START:
4278   case VKI_SNDRV_TIMER_IOCTL_STOP:
4279   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
4280   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
4281
4282      /* SCSI no operand */
4283   case VKI_SCSI_IOCTL_DOORLOCK:
4284   case VKI_SCSI_IOCTL_DOORUNLOCK:
4285
4286   /* KVM ioctls that dont check for a numeric value as parameter */
4287   case VKI_KVM_S390_ENABLE_SIE:
4288   case VKI_KVM_S390_INITIAL_RESET:
4289
4290   /* User input device creation */
4291   case VKI_UI_DEV_CREATE:
4292   case VKI_UI_DEV_DESTROY:
4293      PRINT("sys_ioctl ( %ld, 0x%lx )",ARG1,ARG2);
4294      PRE_REG_READ2(long, "ioctl",
4295                    unsigned int, fd, unsigned int, request);
4296      return;
4297
4298#  if defined(ANDROID_HARDWARE_nexus_10)
4299   /* undocumented ioctl ids noted on the device */
4300   case 0x4d07:
4301   case 0x6101:
4302   case 0xfa01: /* used by NFC */
4303   case 0xfa05: /* used by NFC */
4304      return;
4305#  elif defined(ANDROID_HARDWARE_nexus_7)
4306   /* undocumented ioctl ids noted on the device */
4307   case 0x4e04:
4308   case 0x7231:
4309   case 0x4004e901: /* used by NFC */
4310      return;
4311#  elif defined(ANDROID_HARDWARE_nexus_4)
4312
4313#  endif
4314
4315   default:
4316      PRINT("sys_ioctl ( %ld, 0x%lx, 0x%lx )",ARG1,ARG2,ARG3);
4317      PRE_REG_READ3(long, "ioctl",
4318                    unsigned int, fd, unsigned int, request, unsigned long, arg);
4319      break;
4320   }
4321
4322
4323#  if defined(ANDROID_HARDWARE_nexus_10)
4324
4325   /* undocumented ioctl ids noted on the device */
4326   if (ARG2 >= 0xc0108000 && ARG2 <= 0xc1e8820b && ARG3 != 0) {
4327       int size = (ARG2 >> 16) & 0x3fff;
4328       PRE_MEM_WRITE("ioctl(GL_UNDOCUMENTED)", (Addr)ARG3,  size);
4329       return;
4330   }
4331
4332#  endif
4333
4334   // We now handle those that do look at ARG3 (and unknown ones fall into
4335   // this category).  Nb: some of these may well belong in the
4336   // doesn't-use-ARG3 switch above.
4337   switch (ARG2 /* request */) {
4338   case VKI_TCSETS:
4339   case VKI_TCSETSW:
4340   case VKI_TCSETSF:
4341      PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
4342      break;
4343   case VKI_TCGETS:
4344      PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
4345      break;
4346   case VKI_TCSETA:
4347   case VKI_TCSETAW:
4348   case VKI_TCSETAF:
4349      PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
4350      break;
4351   case VKI_TCGETA:
4352      PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
4353      break;
4354   case VKI_TCSBRK:
4355   case VKI_TCXONC:
4356   case VKI_TCSBRKP:
4357   case VKI_TCFLSH:
4358      /* These just take an int by value */
4359      break;
4360   case VKI_TIOCGWINSZ:
4361      PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
4362      break;
4363   case VKI_TIOCSWINSZ:
4364      PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
4365      break;
4366   case VKI_TIOCMBIS:
4367      PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
4368      break;
4369   case VKI_TIOCMBIC:
4370      PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
4371      break;
4372   case VKI_TIOCMSET:
4373      PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
4374      break;
4375   case VKI_TIOCMGET:
4376      PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
4377      break;
4378   case VKI_TIOCLINUX:
4379      PRE_MEM_READ( "ioctl(TIOCLINUX)",   ARG3, sizeof(char *) );
4380      if (*(char *)ARG3 == 11) {
4381	 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
4382      }
4383      break;
4384   case VKI_TIOCGPGRP:
4385      /* Get process group ID for foreground processing group. */
4386      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
4387      break;
4388   case VKI_TIOCSPGRP:
4389      /* Set a process group ID? */
4390      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
4391      break;
4392   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
4393      PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
4394      break;
4395   case VKI_TIOCSCTTY:
4396      /* Just takes an int value.  */
4397      break;
4398   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
4399      PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
4400      break;
4401   case VKI_FIONBIO:
4402      PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
4403      break;
4404   case VKI_FIOASYNC:
4405      PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
4406      break;
4407   case VKI_FIONREAD:                /* identical to SIOCINQ */
4408      PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
4409      break;
4410   case VKI_FIOQSIZE:
4411      PRE_MEM_WRITE( "ioctl(FIOQSIZE)",  ARG3, sizeof(vki_loff_t) );
4412      break;
4413
4414   case VKI_TIOCSERGETLSR:
4415      PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
4416      break;
4417   case VKI_TIOCGICOUNT:
4418      PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
4419                     sizeof(struct vki_serial_icounter_struct) );
4420      break;
4421
4422   case VKI_SG_SET_COMMAND_Q:
4423      PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
4424      break;
4425   case VKI_SG_IO:
4426      PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
4427      break;
4428   case VKI_SG_GET_SCSI_ID:
4429      PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
4430      break;
4431   case VKI_SG_SET_RESERVED_SIZE:
4432      PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
4433      break;
4434   case VKI_SG_SET_TIMEOUT:
4435      PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
4436      break;
4437   case VKI_SG_GET_RESERVED_SIZE:
4438      PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
4439      break;
4440   case VKI_SG_GET_TIMEOUT:
4441      break;
4442   case VKI_SG_GET_VERSION_NUM:
4443      PRE_MEM_WRITE(  "ioctl(SG_GET_VERSION_NUM)",  ARG3, sizeof(int) );
4444      break;
4445   case VKI_SG_EMULATED_HOST: /* 0x2203 */
4446      PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)",    ARG3, sizeof(int) );
4447      break;
4448   case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
4449      PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
4450      break;
4451
4452   case VKI_IIOCGETCPS:
4453      PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
4454		     VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
4455      break;
4456   case VKI_IIOCNETGPN:
4457      PRE_MEM_READ( "ioctl(IIOCNETGPN)",
4458		     (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
4459		     sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
4460      PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
4461		     sizeof(vki_isdn_net_ioctl_phone) );
4462      break;
4463
4464      /* These all use struct ifreq AFAIK */
4465   case VKI_SIOCGIFINDEX:        /* get iface index              */
4466      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
4467                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4468      PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
4469      break;
4470   case VKI_SIOCGIFFLAGS:        /* get flags                    */
4471      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
4472                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4473      PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
4474      break;
4475   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
4476      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
4477                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4478      PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
4479      break;
4480   case VKI_SIOCGIFMTU:          /* get MTU size                 */
4481      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
4482                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4483      PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
4484      break;
4485   case VKI_SIOCGIFADDR:         /* get PA address               */
4486      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
4487                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4488      PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
4489      break;
4490   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
4491      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
4492                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4493      PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
4494      break;
4495   case VKI_SIOCGIFMETRIC:       /* get metric                   */
4496      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
4497                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4498      PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
4499      break;
4500   case VKI_SIOCGIFMAP:          /* Get device parameters        */
4501      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
4502                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4503      PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
4504      break;
4505   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
4506      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
4507                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4508      PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
4509      break;
4510   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
4511      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
4512                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4513      PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
4514      break;
4515   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
4516      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
4517                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4518      PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
4519      break;
4520   case VKI_SIOCGIFNAME:         /* get iface name               */
4521      PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
4522                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
4523                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
4524      PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
4525      break;
4526   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
4527      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
4528                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4529      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
4530      break;
4531   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
4532      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
4533                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4534      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
4535                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
4536                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
4537      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
4538                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
4539                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
4540      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
4541		     sizeof(struct vki_ifreq));
4542      break;
4543   case VKI_SIOCGIFCONF:         /* get iface list               */
4544      /* WAS:
4545	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
4546	 KERNEL_DO_SYSCALL(tid,RES);
4547	 if (!VG_(is_kerror)(RES) && RES == 0)
4548	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
4549      */
4550      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
4551                    (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
4552                    sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
4553      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
4554                    (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
4555                    sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
4556      if ( ARG3 ) {
4557	 // TODO len must be readable and writable
4558	 // buf pointer only needs to be readable
4559	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
4560	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
4561			(Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
4562      }
4563      break;
4564   case VKI_SIOCGSTAMP:
4565      PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
4566      break;
4567   case VKI_SIOCGSTAMPNS:
4568      PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
4569      break;
4570      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
4571	 the number of bytes currently in that socket's send buffer.
4572	 It writes this value as an int to the memory location
4573	 indicated by the third argument of ioctl(2). */
4574   case VKI_SIOCOUTQ:
4575      PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
4576      break;
4577   case VKI_SIOCGRARP:           /* get RARP table entry         */
4578   case VKI_SIOCGARP:            /* get ARP table entry          */
4579      PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
4580      break;
4581
4582   case VKI_SIOCSIFFLAGS:        /* set flags                    */
4583      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
4584                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4585      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
4586                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
4587                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
4588      break;
4589   case VKI_SIOCSIFMAP:          /* Set device parameters        */
4590      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
4591                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4592      PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
4593                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
4594                     sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
4595      break;
4596   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
4597      PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
4598                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4599      PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
4600                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
4601                     sizeof(struct vki_hwtstamp_config) );
4602      break;
4603   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
4604      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
4605                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4606      PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
4607                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
4608                     sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
4609      break;
4610   case VKI_SIOCSIFADDR:         /* set PA address               */
4611   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
4612   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
4613   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
4614      PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
4615                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4616      PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
4617                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
4618                     sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
4619      break;
4620   case VKI_SIOCSIFMETRIC:       /* set metric                   */
4621      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
4622                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4623      PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
4624                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
4625                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
4626      break;
4627   case VKI_SIOCSIFMTU:          /* set MTU size                 */
4628      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
4629                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4630      PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
4631                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
4632                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
4633      break;
4634   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
4635      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
4636                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4637      PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
4638                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
4639                     sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
4640      break;
4641   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
4642      PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
4643                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4644      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4645                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
4646                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
4647      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4648                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
4649                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
4650      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4651                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
4652                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
4653      break;
4654      /* Routing table calls.  */
4655   case VKI_SIOCADDRT:           /* add routing table entry      */
4656   case VKI_SIOCDELRT:           /* delete routing table entry   */
4657      PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
4658		    sizeof(struct vki_rtentry));
4659      break;
4660
4661      /* RARP cache control calls. */
4662   case VKI_SIOCDRARP:           /* delete RARP table entry      */
4663   case VKI_SIOCSRARP:           /* set RARP table entry         */
4664      /* ARP cache control calls. */
4665   case VKI_SIOCSARP:            /* set ARP table entry          */
4666   case VKI_SIOCDARP:            /* delete ARP table entry       */
4667      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
4668      break;
4669
4670   case VKI_SIOCGPGRP:
4671      PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
4672      break;
4673   case VKI_SIOCSPGRP:
4674      PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
4675      //tst->sys_flags &= ~SfMayBlock;
4676      break;
4677
4678      /* linux/soundcard interface (OSS) */
4679   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4680   case VKI_SNDCTL_SEQ_GETINCOUNT:
4681   case VKI_SNDCTL_SEQ_PERCMODE:
4682   case VKI_SNDCTL_SEQ_TESTMIDI:
4683   case VKI_SNDCTL_SEQ_RESETSAMPLES:
4684   case VKI_SNDCTL_SEQ_NRSYNTHS:
4685   case VKI_SNDCTL_SEQ_NRMIDIS:
4686   case VKI_SNDCTL_SEQ_GETTIME:
4687   case VKI_SNDCTL_DSP_GETBLKSIZE:
4688   case VKI_SNDCTL_DSP_GETFMTS:
4689   case VKI_SNDCTL_DSP_GETTRIGGER:
4690   case VKI_SNDCTL_DSP_GETODELAY:
4691   case VKI_SNDCTL_DSP_GETSPDIF:
4692   case VKI_SNDCTL_DSP_GETCAPS:
4693   case VKI_SOUND_PCM_READ_RATE:
4694   case VKI_SOUND_PCM_READ_CHANNELS:
4695   case VKI_SOUND_PCM_READ_BITS:
4696   case VKI_SOUND_PCM_READ_FILTER:
4697      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
4698		     ARG3, sizeof(int));
4699      break;
4700   case VKI_SNDCTL_SEQ_CTRLRATE:
4701   case VKI_SNDCTL_DSP_SPEED:
4702   case VKI_SNDCTL_DSP_STEREO:
4703   case VKI_SNDCTL_DSP_CHANNELS:
4704   case VKI_SOUND_PCM_WRITE_FILTER:
4705   case VKI_SNDCTL_DSP_SUBDIVIDE:
4706   case VKI_SNDCTL_DSP_SETFRAGMENT:
4707   case VKI_SNDCTL_DSP_SETFMT:
4708   case VKI_SNDCTL_DSP_GETCHANNELMASK:
4709   case VKI_SNDCTL_DSP_BIND_CHANNEL:
4710   case VKI_SNDCTL_TMR_TIMEBASE:
4711   case VKI_SNDCTL_TMR_TEMPO:
4712   case VKI_SNDCTL_TMR_SOURCE:
4713   case VKI_SNDCTL_MIDI_PRETIME:
4714   case VKI_SNDCTL_MIDI_MPUMODE:
4715      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
4716		     ARG3, sizeof(int));
4717      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
4718		     ARG3, sizeof(int));
4719      break;
4720   case VKI_SNDCTL_DSP_GETOSPACE:
4721   case VKI_SNDCTL_DSP_GETISPACE:
4722      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
4723                     ARG3, sizeof(vki_audio_buf_info));
4724      break;
4725   case VKI_SNDCTL_DSP_NONBLOCK:
4726      break;
4727   case VKI_SNDCTL_DSP_SETTRIGGER:
4728      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
4729		     ARG3, sizeof(int));
4730      break;
4731
4732   case VKI_SNDCTL_DSP_POST:
4733   case VKI_SNDCTL_DSP_RESET:
4734   case VKI_SNDCTL_DSP_SYNC:
4735   case VKI_SNDCTL_DSP_SETSYNCRO:
4736   case VKI_SNDCTL_DSP_SETDUPLEX:
4737      break;
4738
4739      /* linux/soundcard interface (ALSA) */
4740   case VKI_SNDRV_PCM_IOCTL_PAUSE:
4741   case VKI_SNDRV_PCM_IOCTL_LINK:
4742      /* these just take an int by value */
4743      break;
4744
4745      /* Real Time Clock (/dev/rtc) ioctls */
4746   case VKI_RTC_UIE_ON:
4747   case VKI_RTC_UIE_OFF:
4748   case VKI_RTC_AIE_ON:
4749   case VKI_RTC_AIE_OFF:
4750   case VKI_RTC_PIE_ON:
4751   case VKI_RTC_PIE_OFF:
4752   case VKI_RTC_IRQP_SET:
4753      break;
4754   case VKI_RTC_RD_TIME:
4755   case VKI_RTC_ALM_READ:
4756      PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
4757		     ARG3, sizeof(struct vki_rtc_time));
4758      break;
4759   case VKI_RTC_ALM_SET:
4760      PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
4761      break;
4762   case VKI_RTC_IRQP_READ:
4763      PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
4764      break;
4765
4766      /* Block devices */
4767   case VKI_BLKROSET:
4768      PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
4769      break;
4770   case VKI_BLKROGET:
4771      PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
4772      break;
4773   case VKI_BLKGETSIZE:
4774      PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
4775      break;
4776   case VKI_BLKRASET:
4777      break;
4778   case VKI_BLKRAGET:
4779      PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
4780      break;
4781   case VKI_BLKFRASET:
4782      break;
4783   case VKI_BLKFRAGET:
4784      PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
4785      break;
4786   case VKI_BLKSECTGET:
4787      PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
4788      break;
4789   case VKI_BLKSSZGET:
4790      PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
4791      break;
4792   case VKI_BLKBSZGET:
4793      PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
4794      break;
4795   case VKI_BLKBSZSET:
4796      PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
4797      break;
4798   case VKI_BLKGETSIZE64:
4799      PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
4800      break;
4801
4802      /* Hard disks */
4803   case VKI_HDIO_GETGEO: /* 0x0301 */
4804      PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
4805      break;
4806   case VKI_HDIO_GET_DMA: /* 0x030b */
4807      PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
4808      break;
4809   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
4810      PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
4811                     VKI_SIZEOF_STRUCT_HD_DRIVEID );
4812      break;
4813
4814      /* SCSI */
4815   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
4816      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
4817      break;
4818   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
4819      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
4820      break;
4821
4822      /* CD ROM stuff (??)  */
4823   case VKI_CDROM_GET_MCN:
4824      PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
4825                    sizeof(struct vki_cdrom_mcn) );
4826      break;
4827   case VKI_CDROM_SEND_PACKET:
4828      PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
4829                    sizeof(struct vki_cdrom_generic_command));
4830      break;
4831   case VKI_CDROMSUBCHNL:
4832      PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
4833		    (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
4834		    sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
4835      PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
4836		     sizeof(struct vki_cdrom_subchnl));
4837      break;
4838   case VKI_CDROMREADMODE2:
4839      PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
4840      break;
4841   case VKI_CDROMREADTOCHDR:
4842      PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
4843		     sizeof(struct vki_cdrom_tochdr));
4844      break;
4845   case VKI_CDROMREADTOCENTRY:
4846      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
4847		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
4848		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
4849      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
4850		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
4851		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
4852      PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
4853		     sizeof(struct vki_cdrom_tocentry));
4854      break;
4855   case VKI_CDROMMULTISESSION: /* 0x5310 */
4856      PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
4857		     sizeof(struct vki_cdrom_multisession));
4858      break;
4859   case VKI_CDROMVOLREAD: /* 0x5313 */
4860      PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
4861		     sizeof(struct vki_cdrom_volctrl));
4862      break;
4863   case VKI_CDROMREADRAW: /* 0x5314 */
4864      PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
4865      PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
4866      break;
4867   case VKI_CDROMREADAUDIO: /* 0x530e */
4868      PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
4869		     sizeof (struct vki_cdrom_read_audio));
4870      if ( ARG3 ) {
4871         /* ToDo: don't do any of the following if the structure is invalid */
4872         struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
4873	 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
4874	                (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
4875      }
4876      break;
4877   case VKI_CDROMPLAYMSF:
4878      PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
4879      break;
4880      /* The following two are probably bogus (should check args
4881	 for readability).  JRS 20021117 */
4882   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4883   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
4884      break;
4885   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
4886      break;
4887
4888   case VKI_FIGETBSZ:
4889      PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
4890      break;
4891   case VKI_FIBMAP:
4892      PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
4893      break;
4894
4895   case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
4896      PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
4897                     sizeof(struct vki_fb_var_screeninfo));
4898      break;
4899   case VKI_FBIOPUT_VSCREENINFO:
4900      PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
4901                    sizeof(struct vki_fb_var_screeninfo));
4902      break;
4903   case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
4904      PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
4905                     sizeof(struct vki_fb_fix_screeninfo));
4906      break;
4907   case VKI_FBIOPAN_DISPLAY:
4908      PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
4909                    sizeof(struct vki_fb_var_screeninfo));
4910
4911      break;
4912   case VKI_PPCLAIM:
4913   case VKI_PPEXCL:
4914   case VKI_PPYIELD:
4915   case VKI_PPRELEASE:
4916      break;
4917   case VKI_PPSETMODE:
4918      PRE_MEM_READ( "ioctl(PPSETMODE)",   ARG3, sizeof(int) );
4919      break;
4920   case VKI_PPGETMODE:
4921      PRE_MEM_WRITE( "ioctl(PPGETMODE)",  ARG3, sizeof(int) );
4922      break;
4923   case VKI_PPSETPHASE:
4924      PRE_MEM_READ(  "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
4925      break;
4926   case VKI_PPGETPHASE:
4927      PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
4928      break;
4929   case VKI_PPGETMODES:
4930      PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
4931      break;
4932   case VKI_PPSETFLAGS:
4933      PRE_MEM_READ(  "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
4934      break;
4935   case VKI_PPGETFLAGS:
4936      PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
4937      break;
4938   case VKI_PPRSTATUS:
4939      PRE_MEM_WRITE( "ioctl(PPRSTATUS)",  ARG3, sizeof(unsigned char) );
4940      break;
4941   case VKI_PPRDATA:
4942      PRE_MEM_WRITE( "ioctl(PPRDATA)",    ARG3, sizeof(unsigned char) );
4943      break;
4944   case VKI_PPRCONTROL:
4945      PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
4946      break;
4947   case VKI_PPWDATA:
4948      PRE_MEM_READ(  "ioctl(PPWDATA)",    ARG3, sizeof(unsigned char) );
4949      break;
4950   case VKI_PPWCONTROL:
4951      PRE_MEM_READ(  "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
4952      break;
4953   case VKI_PPFCONTROL:
4954      PRE_MEM_READ(  "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
4955      break;
4956   case VKI_PPDATADIR:
4957      PRE_MEM_READ(  "ioctl(PPDATADIR)",  ARG3, sizeof(int) );
4958      break;
4959   case VKI_PPNEGOT:
4960      PRE_MEM_READ(  "ioctl(PPNEGOT)",    ARG3, sizeof(int) );
4961      break;
4962   case VKI_PPWCTLONIRQ:
4963      PRE_MEM_READ(  "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
4964      break;
4965   case VKI_PPCLRIRQ:
4966      PRE_MEM_WRITE( "ioctl(PPCLRIRQ)",   ARG3, sizeof(int) );
4967      break;
4968   case VKI_PPSETTIME:
4969      PRE_MEM_READ(  "ioctl(PPSETTIME)",  ARG3, sizeof(struct vki_timeval) );
4970      break;
4971   case VKI_PPGETTIME:
4972      PRE_MEM_WRITE( "ioctl(PPGETTIME)",  ARG3, sizeof(struct vki_timeval) );
4973      break;
4974
4975   case VKI_GIO_FONT:
4976      PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
4977      break;
4978   case VKI_PIO_FONT:
4979      PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
4980      break;
4981
4982   case VKI_GIO_FONTX:
4983      PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
4984      if ( ARG3 ) {
4985         /* ToDo: don't do any of the following if the structure is invalid */
4986         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
4987         PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
4988                        32 * cfd->charcount );
4989      }
4990      break;
4991   case VKI_PIO_FONTX:
4992      PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
4993      if ( ARG3 ) {
4994         /* ToDo: don't do any of the following if the structure is invalid */
4995         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
4996         PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
4997                       32 * cfd->charcount );
4998      }
4999      break;
5000
5001   case VKI_PIO_FONTRESET:
5002      break;
5003
5004   case VKI_GIO_CMAP:
5005      PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
5006      break;
5007   case VKI_PIO_CMAP:
5008      PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
5009      break;
5010
5011   case VKI_KIOCSOUND:
5012   case VKI_KDMKTONE:
5013      break;
5014
5015   case VKI_KDGETLED:
5016      PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
5017      break;
5018   case VKI_KDSETLED:
5019      break;
5020
5021   case VKI_KDGKBTYPE:
5022      PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
5023      break;
5024
5025   case VKI_KDADDIO:
5026   case VKI_KDDELIO:
5027   case VKI_KDENABIO:
5028   case VKI_KDDISABIO:
5029      break;
5030
5031   case VKI_KDSETMODE:
5032      break;
5033   case VKI_KDGETMODE:
5034      PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
5035      break;
5036
5037   case VKI_KDMAPDISP:
5038   case VKI_KDUNMAPDISP:
5039      break;
5040
5041   case VKI_GIO_SCRNMAP:
5042      PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
5043      break;
5044   case VKI_PIO_SCRNMAP:
5045      PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ  );
5046      break;
5047   case VKI_GIO_UNISCRNMAP:
5048      PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
5049                     VKI_E_TABSZ * sizeof(unsigned short) );
5050      break;
5051   case VKI_PIO_UNISCRNMAP:
5052      PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
5053                    VKI_E_TABSZ * sizeof(unsigned short) );
5054      break;
5055
5056   case VKI_GIO_UNIMAP:
5057      if ( ARG3 ) {
5058         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
5059         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
5060                       sizeof(unsigned short));
5061         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
5062                       sizeof(struct vki_unipair *));
5063         PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
5064                        desc->entry_ct * sizeof(struct vki_unipair));
5065      }
5066      break;
5067   case VKI_PIO_UNIMAP:
5068      if ( ARG3 ) {
5069         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
5070         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
5071                       sizeof(unsigned short) );
5072         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
5073                       sizeof(struct vki_unipair *) );
5074         PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
5075                       desc->entry_ct * sizeof(struct vki_unipair) );
5076      }
5077      break;
5078   case VKI_PIO_UNIMAPCLR:
5079      PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
5080      break;
5081
5082   case VKI_KDGKBMODE:
5083      PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
5084      break;
5085   case VKI_KDSKBMODE:
5086      break;
5087
5088   case VKI_KDGKBMETA:
5089      PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
5090      break;
5091   case VKI_KDSKBMETA:
5092      break;
5093
5094   case VKI_KDGKBLED:
5095      PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
5096      break;
5097   case VKI_KDSKBLED:
5098      break;
5099
5100   case VKI_KDGKBENT:
5101      PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
5102                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
5103                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
5104      PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
5105                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
5106                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
5107      PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
5108		     (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
5109		     sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
5110      break;
5111   case VKI_KDSKBENT:
5112      PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
5113                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
5114                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
5115      PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
5116                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
5117                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
5118      PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
5119                    (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
5120                    sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
5121      break;
5122
5123   case VKI_KDGKBSENT:
5124      PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
5125                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
5126                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
5127      PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
5128		     (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
5129		     sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
5130      break;
5131   case VKI_KDSKBSENT:
5132      PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
5133                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
5134                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
5135      PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
5136                       (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
5137      break;
5138
5139   case VKI_KDGKBDIACR:
5140      PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
5141      break;
5142   case VKI_KDSKBDIACR:
5143      PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
5144      break;
5145
5146   case VKI_KDGETKEYCODE:
5147      PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
5148                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
5149                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
5150      PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
5151		     (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
5152		     sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
5153      break;
5154   case VKI_KDSETKEYCODE:
5155      PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
5156                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
5157                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
5158      PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
5159                    (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
5160                    sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
5161      break;
5162
5163   case VKI_KDSIGACCEPT:
5164      break;
5165
5166   case VKI_KDKBDREP:
5167      PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
5168      break;
5169
5170   case VKI_KDFONTOP:
5171      if ( ARG3 ) {
5172         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
5173         PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
5174                       sizeof(struct vki_console_font_op) );
5175         switch ( op->op ) {
5176            case VKI_KD_FONT_OP_SET:
5177               PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
5178                             (Addr)op->data,
5179                             (op->width + 7) / 8 * 32 * op->charcount );
5180               break;
5181            case VKI_KD_FONT_OP_GET:
5182               if ( op->data )
5183                  PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
5184                                 (Addr)op->data,
5185                                 (op->width + 7) / 8 * 32 * op->charcount );
5186               break;
5187            case VKI_KD_FONT_OP_SET_DEFAULT:
5188               if ( op->data )
5189                  PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
5190                                   (Addr)op->data );
5191               break;
5192            case VKI_KD_FONT_OP_COPY:
5193               break;
5194         }
5195      }
5196      break;
5197
5198   case VKI_VT_OPENQRY:
5199      PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
5200      break;
5201   case VKI_VT_GETMODE:
5202      PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
5203      break;
5204   case VKI_VT_SETMODE:
5205      PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
5206      break;
5207   case VKI_VT_GETSTATE:
5208      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
5209                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
5210                     sizeof(((struct vki_vt_stat*) ARG3)->v_active));
5211      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
5212                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
5213                     sizeof(((struct vki_vt_stat*) ARG3)->v_state));
5214      break;
5215   case VKI_VT_RELDISP:
5216   case VKI_VT_ACTIVATE:
5217   case VKI_VT_WAITACTIVE:
5218   case VKI_VT_DISALLOCATE:
5219      break;
5220   case VKI_VT_RESIZE:
5221      PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
5222      break;
5223   case VKI_VT_RESIZEX:
5224      PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
5225      break;
5226   case VKI_VT_LOCKSWITCH:
5227   case VKI_VT_UNLOCKSWITCH:
5228      break;
5229
5230   case VKI_USBDEVFS_CONTROL:
5231      if ( ARG3 ) {
5232         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
5233         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
5234         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
5235         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
5236         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
5237         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
5238         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
5239         if (vkuc->bRequestType & 0x80)
5240            PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
5241         else
5242            PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
5243      }
5244      break;
5245   case VKI_USBDEVFS_BULK:
5246      if ( ARG3 ) {
5247         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
5248         PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
5249         if (vkub->ep & 0x80)
5250            PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
5251         else
5252            PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
5253      }
5254      break;
5255   case VKI_USBDEVFS_GETDRIVER:
5256      if ( ARG3 ) {
5257         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
5258         PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
5259      }
5260      break;
5261   case VKI_USBDEVFS_SUBMITURB:
5262      if ( ARG3 ) {
5263         struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
5264
5265         /* Not the whole struct needs to be initialized */
5266         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
5267         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
5268         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
5269         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
5270         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
5271         PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
5272         if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
5273            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
5274            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
5275            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
5276            if (vkusp->bRequestType & 0x80)
5277               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
5278            else
5279               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
5280            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
5281         } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
5282            int total_length = 0;
5283            int i;
5284            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
5285            for(i=0; i<vkuu->number_of_packets; i++) {
5286               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
5287               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));
5288               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
5289               total_length += vkuu->iso_frame_desc[i].length;
5290            }
5291            if (vkuu->endpoint & 0x80)
5292               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
5293            else
5294               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
5295            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
5296         } else {
5297            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
5298            if (vkuu->endpoint & 0x80)
5299               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
5300            else
5301               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
5302            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
5303         }
5304      }
5305      break;
5306   case VKI_USBDEVFS_DISCARDURB:
5307      break;
5308   case VKI_USBDEVFS_REAPURB:
5309      if ( ARG3 ) {
5310         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
5311      }
5312      break;
5313   case VKI_USBDEVFS_REAPURBNDELAY:
5314      if ( ARG3 ) {
5315         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
5316      }
5317      break;
5318   case VKI_USBDEVFS_CONNECTINFO:
5319      PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
5320      break;
5321   case VKI_USBDEVFS_IOCTL:
5322      if ( ARG3 ) {
5323         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
5324         UInt dir2, size2;
5325         PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
5326         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
5327         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
5328         if (size2 > 0) {
5329            if (dir2 & _VKI_IOC_WRITE)
5330               PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
5331            else if (dir2 & _VKI_IOC_READ)
5332               PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
5333         }
5334      }
5335      break;
5336   case VKI_USBDEVFS_RESET:
5337      break;
5338
5339      /* I2C (/dev/i2c-*) ioctls */
5340   case VKI_I2C_SLAVE:
5341   case VKI_I2C_SLAVE_FORCE:
5342   case VKI_I2C_TENBIT:
5343   case VKI_I2C_PEC:
5344      break;
5345   case VKI_I2C_FUNCS:
5346      PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
5347      break;
5348   case VKI_I2C_RDWR:
5349      if ( ARG3 ) {
5350          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
5351          UInt i;
5352          PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
5353          for (i=0; i < vkui->nmsgs; i++) {
5354              struct vki_i2c_msg *msg = vkui->msgs + i;
5355              PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
5356              if (msg->flags & VKI_I2C_M_RD)
5357                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
5358              else
5359                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
5360          }
5361      }
5362      break;
5363
5364      /* Wireless extensions ioctls */
5365   case VKI_SIOCSIWCOMMIT:
5366   case VKI_SIOCSIWNWID:
5367   case VKI_SIOCSIWFREQ:
5368   case VKI_SIOCSIWMODE:
5369   case VKI_SIOCSIWSENS:
5370   case VKI_SIOCSIWRANGE:
5371   case VKI_SIOCSIWPRIV:
5372   case VKI_SIOCSIWSTATS:
5373   case VKI_SIOCSIWSPY:
5374   case VKI_SIOCSIWTHRSPY:
5375   case VKI_SIOCSIWAP:
5376   case VKI_SIOCSIWSCAN:
5377   case VKI_SIOCSIWESSID:
5378   case VKI_SIOCSIWRATE:
5379   case VKI_SIOCSIWNICKN:
5380   case VKI_SIOCSIWRTS:
5381   case VKI_SIOCSIWFRAG:
5382   case VKI_SIOCSIWTXPOW:
5383   case VKI_SIOCSIWRETRY:
5384   case VKI_SIOCSIWENCODE:
5385   case VKI_SIOCSIWPOWER:
5386   case VKI_SIOCSIWGENIE:
5387   case VKI_SIOCSIWMLME:
5388   case VKI_SIOCSIWAUTH:
5389   case VKI_SIOCSIWENCODEEXT:
5390   case VKI_SIOCSIWPMKSA:
5391      break;
5392   case VKI_SIOCGIWNAME:
5393      if (ARG3) {
5394         PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
5395                       (Addr)((struct vki_iwreq *)ARG3)->u.name,
5396                       sizeof(((struct vki_iwreq *)ARG3)->u.name));
5397      }
5398      break;
5399   case VKI_SIOCGIWNWID:
5400   case VKI_SIOCGIWSENS:
5401   case VKI_SIOCGIWRATE:
5402   case VKI_SIOCGIWRTS:
5403   case VKI_SIOCGIWFRAG:
5404   case VKI_SIOCGIWTXPOW:
5405   case VKI_SIOCGIWRETRY:
5406   case VKI_SIOCGIWPOWER:
5407   case VKI_SIOCGIWAUTH:
5408      if (ARG3) {
5409         PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
5410                       "RETRY|PARAM|AUTH])",
5411                       (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
5412                       sizeof(struct vki_iw_param));
5413      }
5414      break;
5415   case VKI_SIOCGIWFREQ:
5416      if (ARG3) {
5417         PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
5418                       (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
5419                       sizeof(struct vki_iw_freq));
5420      }
5421      break;
5422   case VKI_SIOCGIWMODE:
5423      if (ARG3) {
5424         PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
5425                       (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
5426                       sizeof(__vki_u32));
5427      }
5428      break;
5429   case VKI_SIOCGIWRANGE:
5430   case VKI_SIOCGIWPRIV:
5431   case VKI_SIOCGIWSTATS:
5432   case VKI_SIOCGIWSPY:
5433   case VKI_SIOCGIWTHRSPY:
5434   case VKI_SIOCGIWAPLIST:
5435   case VKI_SIOCGIWSCAN:
5436   case VKI_SIOCGIWESSID:
5437   case VKI_SIOCGIWNICKN:
5438   case VKI_SIOCGIWENCODE:
5439   case VKI_SIOCGIWGENIE:
5440   case VKI_SIOCGIWENCODEEXT:
5441      if (ARG3) {
5442         struct vki_iw_point* point;
5443         point = &((struct vki_iwreq *)ARG3)->u.data;
5444         PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
5445                       "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
5446                       (Addr)point->pointer, point->length);
5447      }
5448      break;
5449   case VKI_SIOCGIWAP:
5450      if (ARG3) {
5451         PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
5452                       (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
5453                       sizeof(struct vki_sockaddr));
5454      }
5455      break;
5456
5457  /* User input device creation */
5458  case VKI_UI_SET_EVBIT:
5459  case VKI_UI_SET_KEYBIT:
5460  case VKI_UI_SET_RELBIT:
5461  case VKI_UI_SET_ABSBIT:
5462  case VKI_UI_SET_MSCBIT:
5463  case VKI_UI_SET_LEDBIT:
5464  case VKI_UI_SET_SNDBIT:
5465  case VKI_UI_SET_FFBIT:
5466  case VKI_UI_SET_SWBIT:
5467  case VKI_UI_SET_PROPBIT:
5468      /* These just take an int by value */
5469      break;
5470
5471#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
5472   /* ashmem */
5473   case VKI_ASHMEM_GET_SIZE:
5474   case VKI_ASHMEM_SET_SIZE:
5475   case VKI_ASHMEM_GET_PROT_MASK:
5476   case VKI_ASHMEM_SET_PROT_MASK:
5477   case VKI_ASHMEM_GET_PIN_STATUS:
5478   case VKI_ASHMEM_PURGE_ALL_CACHES:
5479       break;
5480   case VKI_ASHMEM_GET_NAME:
5481       PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
5482       break;
5483   case VKI_ASHMEM_SET_NAME:
5484       PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
5485       break;
5486   case VKI_ASHMEM_PIN:
5487   case VKI_ASHMEM_UNPIN:
5488       PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
5489                     ARG3, sizeof(struct vki_ashmem_pin) );
5490       break;
5491
5492   /* binder */
5493   case VKI_BINDER_WRITE_READ:
5494       if (ARG3) {
5495           struct vki_binder_write_read* bwr
5496              = (struct vki_binder_write_read*)ARG3;
5497
5498           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
5499                          bwr->write_buffer);
5500           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
5501                          bwr->write_size);
5502           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
5503                          bwr->write_consumed);
5504           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
5505                          bwr->read_buffer);
5506           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
5507                          bwr->read_size);
5508           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
5509                          bwr->read_consumed);
5510
5511           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
5512                           bwr->write_consumed);
5513           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
5514                           bwr->read_consumed);
5515
5516           if (bwr->read_size)
5517               PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
5518                             (Addr)bwr->read_buffer, bwr->read_size);
5519           if (bwr->write_size)
5520               PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
5521                            (Addr)bwr->write_buffer, bwr->write_size);
5522       }
5523       break;
5524
5525   case VKI_BINDER_SET_IDLE_TIMEOUT:
5526   case VKI_BINDER_SET_MAX_THREADS:
5527   case VKI_BINDER_SET_IDLE_PRIORITY:
5528   case VKI_BINDER_SET_CONTEXT_MGR:
5529   case VKI_BINDER_THREAD_EXIT:
5530       break;
5531   case VKI_BINDER_VERSION:
5532       if (ARG3) {
5533           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
5534           PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
5535       }
5536       break;
5537
5538#  endif /* defined(VGPV_*_linux_android) */
5539
5540   case VKI_HCIINQUIRY:
5541      if (ARG3) {
5542         struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
5543         PRE_MEM_READ("ioctl(HCIINQUIRY)",
5544                      (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
5545         PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
5546                       (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
5547                       ir->num_rsp * sizeof(struct vki_inquiry_info));
5548      }
5549      break;
5550
5551   /* KVM ioctls that check for a numeric value as parameter */
5552   case VKI_KVM_GET_API_VERSION:
5553   case VKI_KVM_CREATE_VM:
5554   case VKI_KVM_GET_VCPU_MMAP_SIZE:
5555   case VKI_KVM_CHECK_EXTENSION:
5556   case VKI_KVM_CREATE_VCPU:
5557   case VKI_KVM_RUN:
5558      break;
5559
5560   case VKI_EVIOCSSUSPENDBLOCK:
5561      break;
5562
5563   case VKI_MEDIA_IOC_DEVICE_INFO:
5564      if (ARG3) {
5565         PRE_MEM_WRITE("ioctl(MEDIA_IOC_DEVICE_INFO)", ARG3,
5566                       sizeof(struct vki_media_device_info));
5567      }
5568      break;
5569
5570   default:
5571      /* EVIOC* are variable length and return size written on success */
5572      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
5573      case VKI_EVIOCGNAME(0):
5574      case VKI_EVIOCGPHYS(0):
5575      case VKI_EVIOCGUNIQ(0):
5576      case VKI_EVIOCGKEY(0):
5577      case VKI_EVIOCGLED(0):
5578      case VKI_EVIOCGSND(0):
5579      case VKI_EVIOCGSW(0):
5580      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
5581      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
5582      case VKI_EVIOCGBIT(VKI_EV_REL,0):
5583      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
5584      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
5585      case VKI_EVIOCGBIT(VKI_EV_SW,0):
5586      case VKI_EVIOCGBIT(VKI_EV_LED,0):
5587      case VKI_EVIOCGBIT(VKI_EV_SND,0):
5588      case VKI_EVIOCGBIT(VKI_EV_REP,0):
5589      case VKI_EVIOCGBIT(VKI_EV_FF,0):
5590      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
5591      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
5592         PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
5593         break;
5594      default:
5595         ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
5596         break;
5597      }
5598      break;
5599   }
5600}
5601
5602POST(sys_ioctl)
5603{
5604   vg_assert(SUCCESS);
5605
5606   /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
5607
5608#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
5609
5610#  if defined(ANDROID_HARDWARE_nexus_s)
5611
5612   /* BEGIN undocumented ioctls for the graphics hardware (??)
5613      (libpvr) on Nexus S */
5614   if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
5615      /* What's going on here: there appear to be a bunch of ioctls of
5616         the form 0xC01C67xx which are undocumented, and if unhandled
5617         give rise to a vast number of false positives in Memcheck.
5618
5619         The "normal" intrepretation of an ioctl of this form would be
5620         that the 3rd arg is a pointer to an area of size 0x1C (28
5621         bytes) which is filled in by the kernel.  Hence you might
5622         think that "POST_MEM_WRITE(ARG3, 28)" would fix it.  But it
5623         doesn't.
5624
5625         It requires POST_MEM_WRITE(ARG3, 256) to silence them.  One
5626         interpretation of this is that ARG3 really does point to a 28
5627         byte struct, but inside that are pointers to other areas also
5628         filled in by the kernel.  If these happen to be allocated
5629         just back up the stack then the 256 byte paint might cover
5630         them too, somewhat indiscriminately.
5631
5632         By printing out ARG3 and also the 28 bytes that it points at,
5633         it's possible to guess that the 7 word structure has this form
5634
5635           0            1    2    3        4    5        6
5636           ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
5637
5638         Unfortunately that doesn't seem to work for some reason, so
5639         stay with the blunt-instrument approach for the time being.
5640      */
5641      if (1) {
5642         /* blunt-instrument approach */
5643         if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
5644                            " (%08lx, %08lx)\n", ARG2, ARG3);
5645         POST_MEM_WRITE(ARG3, 256);
5646      } else {
5647         /* be a bit more sophisticated */
5648         if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
5649                            " (%08lx, %08lx) (fancy)\n", ARG2, ARG3);
5650         POST_MEM_WRITE(ARG3, 28);
5651         UInt* word = (UInt*)ARG3;
5652         if (word && word[2] && word[3] < 0x200/*stay sane*/)
5653            POST_MEM_WRITE(word[2], word[3]); // "ptr1"
5654         if (word && word[4] && word[5] < 0x200/*stay sane*/)
5655            POST_MEM_WRITE(word[4], word[5]); // "ptr2"
5656      }
5657      if (0) {
5658         Int i;
5659         VG_(printf)("QQQQQQQQQQ ");
5660         for (i = 0; i < (0x1C/4); i++) {
5661            VG_(printf)("%08x ", ((UInt*)(ARG3))[i]);
5662         }
5663         VG_(printf)("\n");
5664      }
5665      return;
5666   }
5667   /* END Nexus S specific ioctls */
5668
5669
5670#  elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator)
5671
5672   /* BEGIN generic/emulator specific ioctls */
5673   /* currently none are known */
5674   /* END generic/emulator specific ioctls */
5675
5676
5677#  elif defined(ANDROID_HARDWARE_nexus_10)
5678
5679   /* undocumented ioctl ids noted on the device */
5680   if (ARG2 >= 0xc0108000 && ARG2 <= 0xc1e8820b && ARG3 != 0) {
5681      int size = (ARG2 >> 16) & 0x3fff;
5682      POST_MEM_WRITE(ARG3, size);
5683   }
5684
5685#  elif defined(ANDROID_HARDWARE_nexus_7)
5686
5687#  elif defined(ANDROID_HARDWARE_nexus_4)
5688
5689#  else /* no ANDROID_HARDWARE_anything defined */
5690
5691#   warning ""
5692#   warning "You need to define one the CPP symbols ANDROID_HARDWARE_blah"
5693#   warning "at configure time, to tell Valgrind what hardware you are"
5694#   warning "building for.  Currently known values are"
5695#   warning ""
5696#   warning "   ANDROID_HARDWARE_nexus_s       Samsung Nexus S"
5697#   warning "   ANDROID_HARDWARE_nexus_10      Samsung Nexus 10"
5698#   warning "   ANDROID_HARDWARE_nexus_7       ASUS Nexus 7"
5699#   warning "   ANDROID_HARDWARE_nexus_4       LG Nexus 4"
5700#   warning "   ANDROID_HARDWARE_generic       Generic device (eg, Pandaboard)"
5701#   warning "   ANDROID_HARDWARE_emulator      x86 or arm emulator"
5702#   warning ""
5703#   warning "Make sure you exactly follow the steps in README.android."
5704#   warning ""
5705#   error "No CPP symbol ANDROID_HARDWARE_blah defined.  Giving up."
5706
5707#  endif /* cases for ANDROID_HARDWARE_blah */
5708
5709#  endif /* defined(VGPV_*_linux_android) */
5710
5711   /* --- END special IOCTL handlers for specific Android hardware --- */
5712
5713   /* --- normal handling --- */
5714   switch (ARG2 /* request */) {
5715   case VKI_TCSETS:
5716   case VKI_TCSETSW:
5717   case VKI_TCSETSF:
5718      break;
5719   case VKI_TCGETS:
5720      POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
5721      break;
5722   case VKI_TCSETA:
5723   case VKI_TCSETAW:
5724   case VKI_TCSETAF:
5725      break;
5726   case VKI_TCGETA:
5727      POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
5728      break;
5729   case VKI_TCSBRK:
5730   case VKI_TCXONC:
5731   case VKI_TCSBRKP:
5732   case VKI_TCFLSH:
5733      break;
5734   case VKI_TIOCGWINSZ:
5735      POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
5736      break;
5737   case VKI_TIOCSWINSZ:
5738   case VKI_TIOCMBIS:
5739   case VKI_TIOCMBIC:
5740   case VKI_TIOCMSET:
5741      break;
5742   case VKI_TIOCMGET:
5743      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
5744      break;
5745   case VKI_TIOCLINUX:
5746      POST_MEM_WRITE( ARG3, sizeof(char *) );
5747      break;
5748   case VKI_TIOCGPGRP:
5749      /* Get process group ID for foreground processing group. */
5750      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
5751      break;
5752   case VKI_TIOCSPGRP:
5753      /* Set a process group ID? */
5754      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
5755      break;
5756   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
5757      POST_MEM_WRITE( ARG3, sizeof(int));
5758      break;
5759   case VKI_TIOCSCTTY:
5760      break;
5761   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
5762      break;
5763   case VKI_FIONBIO:
5764      break;
5765   case VKI_FIOASYNC:
5766      break;
5767   case VKI_FIONREAD:                /* identical to SIOCINQ */
5768      POST_MEM_WRITE( ARG3, sizeof(int) );
5769      break;
5770   case VKI_FIOQSIZE:
5771      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
5772      break;
5773
5774   case VKI_TIOCSERGETLSR:
5775      POST_MEM_WRITE( ARG3, sizeof(int) );
5776      break;
5777   case VKI_TIOCGICOUNT:
5778      POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
5779      break;
5780
5781   case VKI_SG_SET_COMMAND_Q:
5782      break;
5783   case VKI_SG_IO:
5784      POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
5785      break;
5786   case VKI_SG_GET_SCSI_ID:
5787      POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
5788      break;
5789   case VKI_SG_SET_RESERVED_SIZE:
5790      break;
5791   case VKI_SG_SET_TIMEOUT:
5792      break;
5793   case VKI_SG_GET_RESERVED_SIZE:
5794      POST_MEM_WRITE(ARG3, sizeof(int));
5795      break;
5796   case VKI_SG_GET_TIMEOUT:
5797      break;
5798   case VKI_SG_GET_VERSION_NUM:
5799      POST_MEM_WRITE(ARG3, sizeof(int));
5800      break;
5801   case VKI_SG_EMULATED_HOST:
5802      POST_MEM_WRITE(ARG3, sizeof(int));
5803      break;
5804   case VKI_SG_GET_SG_TABLESIZE:
5805      POST_MEM_WRITE(ARG3, sizeof(int));
5806      break;
5807
5808   case VKI_IIOCGETCPS:
5809      POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
5810      break;
5811   case VKI_IIOCNETGPN:
5812      POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
5813      break;
5814
5815      /* These all use struct ifreq AFAIK */
5816   case VKI_SIOCGIFINDEX:        /* get iface index              */
5817      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
5818                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
5819      break;
5820   case VKI_SIOCGIFFLAGS:        /* get flags                    */
5821      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
5822                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
5823      break;
5824   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
5825      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
5826                      sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
5827      break;
5828   case VKI_SIOCGIFMTU:          /* get MTU size                 */
5829      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
5830                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
5831      break;
5832   case VKI_SIOCGIFADDR:         /* get PA address               */
5833   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
5834   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
5835   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
5836      POST_MEM_WRITE(
5837                (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
5838                sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
5839      break;
5840   case VKI_SIOCGIFMETRIC:       /* get metric                   */
5841      POST_MEM_WRITE(
5842                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
5843                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
5844      break;
5845   case VKI_SIOCGIFMAP:          /* Get device parameters        */
5846      POST_MEM_WRITE(
5847                (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
5848                sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
5849      break;
5850     break;
5851   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
5852      POST_MEM_WRITE(
5853                (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
5854                sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
5855      break;
5856   case VKI_SIOCGIFNAME:         /* get iface name               */
5857      POST_MEM_WRITE(
5858                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
5859                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
5860      break;
5861   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
5862      POST_MEM_WRITE(
5863                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
5864                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
5865      break;
5866   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
5867      POST_MEM_WRITE(
5868                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
5869                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
5870      break;
5871   case VKI_SIOCGIFCONF:         /* get iface list               */
5872      /* WAS:
5873	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
5874	 KERNEL_DO_SYSCALL(tid,RES);
5875	 if (!VG_(is_kerror)(RES) && RES == 0)
5876	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
5877      */
5878      if (RES == 0 && ARG3 ) {
5879	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
5880	 if (ifc->vki_ifc_buf != NULL)
5881	    POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
5882      }
5883      break;
5884   case VKI_SIOCGSTAMP:
5885      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
5886      break;
5887   case VKI_SIOCGSTAMPNS:
5888      POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
5889      break;
5890      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
5891	 the number of bytes currently in that socket's send buffer.
5892	 It writes this value as an int to the memory location
5893	 indicated by the third argument of ioctl(2). */
5894   case VKI_SIOCOUTQ:
5895      POST_MEM_WRITE(ARG3, sizeof(int));
5896      break;
5897   case VKI_SIOCGRARP:           /* get RARP table entry         */
5898   case VKI_SIOCGARP:            /* get ARP table entry          */
5899      POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
5900      break;
5901
5902   case VKI_SIOCSIFFLAGS:        /* set flags                    */
5903   case VKI_SIOCSIFMAP:          /* Set device parameters        */
5904   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
5905   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
5906   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
5907   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
5908   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
5909   case VKI_SIOCSIFMETRIC:       /* set metric                   */
5910   case VKI_SIOCSIFADDR:         /* set PA address               */
5911   case VKI_SIOCSIFMTU:          /* set MTU size                 */
5912   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
5913   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
5914      break;
5915      /* Routing table calls.  */
5916   case VKI_SIOCADDRT:           /* add routing table entry      */
5917   case VKI_SIOCDELRT:           /* delete routing table entry   */
5918      break;
5919
5920      /* RARP cache control calls. */
5921   case VKI_SIOCDRARP:           /* delete RARP table entry      */
5922   case VKI_SIOCSRARP:           /* set RARP table entry         */
5923      /* ARP cache control calls. */
5924   case VKI_SIOCSARP:            /* set ARP table entry          */
5925   case VKI_SIOCDARP:            /* delete ARP table entry       */
5926      break;
5927
5928   case VKI_SIOCGPGRP:
5929      POST_MEM_WRITE(ARG3, sizeof(int));
5930      break;
5931   case VKI_SIOCSPGRP:
5932      break;
5933
5934      /* linux/soundcard interface (OSS) */
5935   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
5936   case VKI_SNDCTL_SEQ_GETINCOUNT:
5937   case VKI_SNDCTL_SEQ_PERCMODE:
5938   case VKI_SNDCTL_SEQ_TESTMIDI:
5939   case VKI_SNDCTL_SEQ_RESETSAMPLES:
5940   case VKI_SNDCTL_SEQ_NRSYNTHS:
5941   case VKI_SNDCTL_SEQ_NRMIDIS:
5942   case VKI_SNDCTL_SEQ_GETTIME:
5943   case VKI_SNDCTL_DSP_GETBLKSIZE:
5944   case VKI_SNDCTL_DSP_GETFMTS:
5945   case VKI_SNDCTL_DSP_SETFMT:
5946   case VKI_SNDCTL_DSP_GETTRIGGER:
5947   case VKI_SNDCTL_DSP_GETODELAY:
5948   case VKI_SNDCTL_DSP_GETSPDIF:
5949   case VKI_SNDCTL_DSP_GETCAPS:
5950   case VKI_SOUND_PCM_READ_RATE:
5951   case VKI_SOUND_PCM_READ_CHANNELS:
5952   case VKI_SOUND_PCM_READ_BITS:
5953   case VKI_SOUND_PCM_READ_FILTER:
5954      POST_MEM_WRITE(ARG3, sizeof(int));
5955      break;
5956   case VKI_SNDCTL_SEQ_CTRLRATE:
5957   case VKI_SNDCTL_DSP_SPEED:
5958   case VKI_SNDCTL_DSP_STEREO:
5959   case VKI_SNDCTL_DSP_CHANNELS:
5960   case VKI_SOUND_PCM_WRITE_FILTER:
5961   case VKI_SNDCTL_DSP_SUBDIVIDE:
5962   case VKI_SNDCTL_DSP_SETFRAGMENT:
5963   case VKI_SNDCTL_DSP_GETCHANNELMASK:
5964   case VKI_SNDCTL_DSP_BIND_CHANNEL:
5965   case VKI_SNDCTL_TMR_TIMEBASE:
5966   case VKI_SNDCTL_TMR_TEMPO:
5967   case VKI_SNDCTL_TMR_SOURCE:
5968   case VKI_SNDCTL_MIDI_PRETIME:
5969   case VKI_SNDCTL_MIDI_MPUMODE:
5970      break;
5971   case VKI_SNDCTL_DSP_GETOSPACE:
5972   case VKI_SNDCTL_DSP_GETISPACE:
5973      POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
5974      break;
5975   case VKI_SNDCTL_DSP_NONBLOCK:
5976      break;
5977   case VKI_SNDCTL_DSP_SETTRIGGER:
5978      break;
5979
5980   case VKI_SNDCTL_DSP_POST:
5981   case VKI_SNDCTL_DSP_RESET:
5982   case VKI_SNDCTL_DSP_SYNC:
5983   case VKI_SNDCTL_DSP_SETSYNCRO:
5984   case VKI_SNDCTL_DSP_SETDUPLEX:
5985      break;
5986
5987      /* linux/soundcard interface (ALSA) */
5988   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
5989   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
5990   case VKI_SNDRV_PCM_IOCTL_PREPARE:
5991   case VKI_SNDRV_PCM_IOCTL_RESET:
5992   case VKI_SNDRV_PCM_IOCTL_START:
5993   case VKI_SNDRV_PCM_IOCTL_DROP:
5994   case VKI_SNDRV_PCM_IOCTL_DRAIN:
5995   case VKI_SNDRV_PCM_IOCTL_RESUME:
5996   case VKI_SNDRV_PCM_IOCTL_XRUN:
5997   case VKI_SNDRV_PCM_IOCTL_UNLINK:
5998   case VKI_SNDRV_TIMER_IOCTL_START:
5999   case VKI_SNDRV_TIMER_IOCTL_STOP:
6000   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6001   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6002
6003      /* SCSI no operand */
6004   case VKI_SCSI_IOCTL_DOORLOCK:
6005   case VKI_SCSI_IOCTL_DOORUNLOCK:
6006      break;
6007
6008      /* Real Time Clock (/dev/rtc) ioctls */
6009   case VKI_RTC_UIE_ON:
6010   case VKI_RTC_UIE_OFF:
6011   case VKI_RTC_AIE_ON:
6012   case VKI_RTC_AIE_OFF:
6013   case VKI_RTC_PIE_ON:
6014   case VKI_RTC_PIE_OFF:
6015   case VKI_RTC_IRQP_SET:
6016      break;
6017   case VKI_RTC_RD_TIME:
6018   case VKI_RTC_ALM_READ:
6019      POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
6020      break;
6021   case VKI_RTC_ALM_SET:
6022      break;
6023   case VKI_RTC_IRQP_READ:
6024      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
6025      break;
6026
6027      /* Block devices */
6028   case VKI_BLKROSET:
6029      break;
6030   case VKI_BLKROGET:
6031      POST_MEM_WRITE(ARG3, sizeof(int));
6032      break;
6033   case VKI_BLKGETSIZE:
6034      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
6035      break;
6036   case VKI_BLKRASET:
6037      break;
6038   case VKI_BLKRAGET:
6039      POST_MEM_WRITE(ARG3, sizeof(long));
6040      break;
6041   case VKI_BLKFRASET:
6042      break;
6043   case VKI_BLKFRAGET:
6044      POST_MEM_WRITE(ARG3, sizeof(long));
6045      break;
6046   case VKI_BLKSECTGET:
6047      POST_MEM_WRITE(ARG3, sizeof(unsigned short));
6048      break;
6049   case VKI_BLKSSZGET:
6050      POST_MEM_WRITE(ARG3, sizeof(int));
6051      break;
6052   case VKI_BLKBSZGET:
6053      POST_MEM_WRITE(ARG3, sizeof(int));
6054      break;
6055   case VKI_BLKBSZSET:
6056      break;
6057   case VKI_BLKGETSIZE64:
6058      POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
6059      break;
6060
6061      /* Hard disks */
6062   case VKI_HDIO_GETGEO: /* 0x0301 */
6063      POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
6064      break;
6065   case VKI_HDIO_GET_DMA: /* 0x030b */
6066      POST_MEM_WRITE(ARG3, sizeof(long));
6067      break;
6068   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6069      POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
6070      break;
6071
6072      /* SCSI */
6073   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6074      POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
6075      break;
6076   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6077      POST_MEM_WRITE(ARG3, sizeof(int));
6078      break;
6079
6080      /* CD ROM stuff (??)  */
6081   case VKI_CDROMSUBCHNL:
6082      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
6083      break;
6084   case VKI_CDROMREADTOCHDR:
6085      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
6086      break;
6087   case VKI_CDROMREADTOCENTRY:
6088      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
6089      break;
6090   case VKI_CDROMMULTISESSION:
6091      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
6092      break;
6093   case VKI_CDROMVOLREAD:
6094      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
6095      break;
6096   case VKI_CDROMREADRAW:
6097      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
6098      break;
6099   case VKI_CDROMREADAUDIO:
6100   {
6101      struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6102      POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
6103      break;
6104   }
6105
6106   case VKI_CDROMPLAYMSF:
6107      break;
6108      /* The following two are probably bogus (should check args
6109	 for readability).  JRS 20021117 */
6110   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
6111   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
6112      break;
6113   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
6114      break;
6115
6116   case VKI_FIGETBSZ:
6117      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
6118      break;
6119   case VKI_FIBMAP:
6120      POST_MEM_WRITE(ARG3, sizeof(int));
6121      break;
6122
6123   case VKI_FBIOGET_VSCREENINFO: //0x4600
6124      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
6125      break;
6126   case VKI_FBIOGET_FSCREENINFO: //0x4602
6127      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
6128      break;
6129
6130   case VKI_PPCLAIM:
6131   case VKI_PPEXCL:
6132   case VKI_PPYIELD:
6133   case VKI_PPRELEASE:
6134   case VKI_PPSETMODE:
6135   case VKI_PPSETPHASE:
6136   case VKI_PPSETFLAGS:
6137   case VKI_PPWDATA:
6138   case VKI_PPWCONTROL:
6139   case VKI_PPFCONTROL:
6140   case VKI_PPDATADIR:
6141   case VKI_PPNEGOT:
6142   case VKI_PPWCTLONIRQ:
6143   case VKI_PPSETTIME:
6144      break;
6145   case VKI_PPGETMODE:
6146      POST_MEM_WRITE( ARG3, sizeof(int) );
6147      break;
6148   case VKI_PPGETPHASE:
6149      POST_MEM_WRITE( ARG3, sizeof(int) );
6150      break;
6151   case VKI_PPGETMODES:
6152      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
6153      break;
6154   case VKI_PPGETFLAGS:
6155      POST_MEM_WRITE( ARG3, sizeof(int) );
6156      break;
6157   case VKI_PPRSTATUS:
6158      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6159      break;
6160   case VKI_PPRDATA:
6161      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6162      break;
6163   case VKI_PPRCONTROL:
6164      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6165      break;
6166   case VKI_PPCLRIRQ:
6167      POST_MEM_WRITE( ARG3, sizeof(int) );
6168      break;
6169   case VKI_PPGETTIME:
6170      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
6171      break;
6172
6173   case VKI_GIO_FONT:
6174      POST_MEM_WRITE( ARG3, 32 * 256 );
6175      break;
6176   case VKI_PIO_FONT:
6177      break;
6178
6179   case VKI_GIO_FONTX:
6180      POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
6181                      32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
6182      break;
6183   case VKI_PIO_FONTX:
6184      break;
6185
6186   case VKI_PIO_FONTRESET:
6187      break;
6188
6189   case VKI_GIO_CMAP:
6190      POST_MEM_WRITE( ARG3, 16 * 3 );
6191      break;
6192   case VKI_PIO_CMAP:
6193      break;
6194
6195   case VKI_KIOCSOUND:
6196   case VKI_KDMKTONE:
6197      break;
6198
6199   case VKI_KDGETLED:
6200      POST_MEM_WRITE( ARG3, sizeof(char) );
6201      break;
6202   case VKI_KDSETLED:
6203      break;
6204
6205   case VKI_KDGKBTYPE:
6206      POST_MEM_WRITE( ARG3, sizeof(char) );
6207      break;
6208
6209   case VKI_KDADDIO:
6210   case VKI_KDDELIO:
6211   case VKI_KDENABIO:
6212   case VKI_KDDISABIO:
6213      break;
6214
6215   case VKI_KDSETMODE:
6216      break;
6217   case VKI_KDGETMODE:
6218      POST_MEM_WRITE( ARG3, sizeof(int) );
6219      break;
6220
6221   case VKI_KDMAPDISP:
6222   case VKI_KDUNMAPDISP:
6223      break;
6224
6225   case VKI_GIO_SCRNMAP:
6226      POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
6227      break;
6228   case VKI_PIO_SCRNMAP:
6229      break;
6230   case VKI_GIO_UNISCRNMAP:
6231      POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
6232      break;
6233   case VKI_PIO_UNISCRNMAP:
6234      break;
6235
6236   case VKI_GIO_UNIMAP:
6237      if ( ARG3 ) {
6238         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6239         POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
6240         POST_MEM_WRITE( (Addr)desc->entries,
6241      	                 desc->entry_ct * sizeof(struct vki_unipair) );
6242      }
6243      break;
6244   case VKI_PIO_UNIMAP:
6245      break;
6246   case VKI_PIO_UNIMAPCLR:
6247      break;
6248
6249   case VKI_KDGKBMODE:
6250      POST_MEM_WRITE( ARG3, sizeof(int) );
6251      break;
6252   case VKI_KDSKBMODE:
6253      break;
6254
6255   case VKI_KDGKBMETA:
6256      POST_MEM_WRITE( ARG3, sizeof(int) );
6257      break;
6258   case VKI_KDSKBMETA:
6259      break;
6260
6261   case VKI_KDGKBLED:
6262      POST_MEM_WRITE( ARG3, sizeof(char) );
6263      break;
6264   case VKI_KDSKBLED:
6265      break;
6266
6267   case VKI_KDGKBENT:
6268      POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6269                      sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6270      break;
6271   case VKI_KDSKBENT:
6272      break;
6273
6274   case VKI_KDGKBSENT:
6275      POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
6276                      sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
6277      break;
6278   case VKI_KDSKBSENT:
6279      break;
6280
6281   case VKI_KDGKBDIACR:
6282      POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
6283      break;
6284   case VKI_KDSKBDIACR:
6285      break;
6286
6287   case VKI_KDGETKEYCODE:
6288      POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6289                      sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6290      break;
6291   case VKI_KDSETKEYCODE:
6292      break;
6293
6294   case VKI_KDSIGACCEPT:
6295      break;
6296
6297   case VKI_KDKBDREP:
6298      break;
6299
6300   case VKI_KDFONTOP:
6301      if ( ARG3 ) {
6302         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
6303         switch ( op->op ) {
6304            case VKI_KD_FONT_OP_SET:
6305               break;
6306            case VKI_KD_FONT_OP_GET:
6307               if ( op->data )
6308                  POST_MEM_WRITE( (Addr) op->data,
6309                                  (op->width + 7) / 8 * 32 * op->charcount );
6310               break;
6311            case VKI_KD_FONT_OP_SET_DEFAULT:
6312               break;
6313            case VKI_KD_FONT_OP_COPY:
6314               break;
6315         }
6316         POST_MEM_WRITE( (Addr) op, sizeof(*op));
6317      }
6318      break;
6319
6320   case VKI_VT_OPENQRY:
6321      POST_MEM_WRITE( ARG3, sizeof(int) );
6322      break;
6323   case VKI_VT_GETMODE:
6324      POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
6325      break;
6326   case VKI_VT_SETMODE:
6327      break;
6328   case VKI_VT_GETSTATE:
6329      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
6330                      sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
6331      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
6332                      sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
6333      break;
6334   case VKI_VT_RELDISP:
6335   case VKI_VT_ACTIVATE:
6336   case VKI_VT_WAITACTIVE:
6337   case VKI_VT_DISALLOCATE:
6338      break;
6339   case VKI_VT_RESIZE:
6340      break;
6341   case VKI_VT_RESIZEX:
6342      break;
6343   case VKI_VT_LOCKSWITCH:
6344   case VKI_VT_UNLOCKSWITCH:
6345      break;
6346
6347   case VKI_USBDEVFS_CONTROL:
6348      if ( ARG3 ) {
6349         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
6350         if (vkuc->bRequestType & 0x80)
6351            POST_MEM_WRITE((Addr)vkuc->data, RES);
6352      }
6353      break;
6354   case VKI_USBDEVFS_BULK:
6355      if ( ARG3 ) {
6356         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
6357         if (vkub->ep & 0x80)
6358            POST_MEM_WRITE((Addr)vkub->data, RES);
6359      }
6360      break;
6361   case VKI_USBDEVFS_GETDRIVER:
6362      if ( ARG3 ) {
6363         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
6364         POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
6365      }
6366      break;
6367   case VKI_USBDEVFS_REAPURB:
6368   case VKI_USBDEVFS_REAPURBNDELAY:
6369      if ( ARG3 ) {
6370         struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
6371         POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
6372         if (!*vkuu)
6373            break;
6374         POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
6375         if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
6376            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
6377            if (vkusp->bRequestType & 0x80)
6378               POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
6379            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
6380         } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
6381            char *bp = (*vkuu)->buffer;
6382            int i;
6383            for(i=0; i<(*vkuu)->number_of_packets; i++) {
6384               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
6385               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
6386               if ((*vkuu)->endpoint & 0x80)
6387                  POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
6388               bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
6389            }
6390            POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
6391         } else {
6392            if ((*vkuu)->endpoint & 0x80)
6393               POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
6394            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
6395         }
6396      }
6397      break;
6398   case VKI_USBDEVFS_CONNECTINFO:
6399      POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
6400      break;
6401   case VKI_USBDEVFS_IOCTL:
6402      if ( ARG3 ) {
6403         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
6404         UInt dir2, size2;
6405         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
6406         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
6407         if (size2 > 0) {
6408            if (dir2 & _VKI_IOC_READ)
6409               POST_MEM_WRITE((Addr)vkui->data, size2);
6410         }
6411      }
6412      break;
6413
6414      /* I2C (/dev/i2c-*) ioctls */
6415   case VKI_I2C_SLAVE:
6416   case VKI_I2C_SLAVE_FORCE:
6417   case VKI_I2C_TENBIT:
6418   case VKI_I2C_PEC:
6419      break;
6420   case VKI_I2C_FUNCS:
6421      POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
6422      break;
6423   case VKI_I2C_RDWR:
6424      if ( ARG3 ) {
6425          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
6426          UInt i;
6427          for (i=0; i < vkui->nmsgs; i++) {
6428              struct vki_i2c_msg *msg = vkui->msgs + i;
6429              if (msg->flags & VKI_I2C_M_RD)
6430                  POST_MEM_WRITE((Addr)msg->buf, msg->len);
6431          }
6432      }
6433      break;
6434
6435      /* Wireless extensions ioctls */
6436   case VKI_SIOCSIWCOMMIT:
6437   case VKI_SIOCSIWNWID:
6438   case VKI_SIOCSIWFREQ:
6439   case VKI_SIOCSIWMODE:
6440   case VKI_SIOCSIWSENS:
6441   case VKI_SIOCSIWRANGE:
6442   case VKI_SIOCSIWPRIV:
6443   case VKI_SIOCSIWSTATS:
6444   case VKI_SIOCSIWSPY:
6445   case VKI_SIOCSIWTHRSPY:
6446   case VKI_SIOCSIWAP:
6447   case VKI_SIOCSIWSCAN:
6448   case VKI_SIOCSIWESSID:
6449   case VKI_SIOCSIWRATE:
6450   case VKI_SIOCSIWNICKN:
6451   case VKI_SIOCSIWRTS:
6452   case VKI_SIOCSIWFRAG:
6453   case VKI_SIOCSIWTXPOW:
6454   case VKI_SIOCSIWRETRY:
6455   case VKI_SIOCSIWENCODE:
6456   case VKI_SIOCSIWPOWER:
6457   case VKI_SIOCSIWGENIE:
6458   case VKI_SIOCSIWMLME:
6459   case VKI_SIOCSIWAUTH:
6460   case VKI_SIOCSIWENCODEEXT:
6461   case VKI_SIOCSIWPMKSA:
6462      break;
6463   case VKI_SIOCGIWNAME:
6464      if (ARG3) {
6465         POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
6466                        sizeof(((struct vki_iwreq *)ARG3)->u.name));
6467      }
6468      break;
6469   case VKI_SIOCGIWNWID:
6470   case VKI_SIOCGIWSENS:
6471   case VKI_SIOCGIWRATE:
6472   case VKI_SIOCGIWRTS:
6473   case VKI_SIOCGIWFRAG:
6474   case VKI_SIOCGIWTXPOW:
6475   case VKI_SIOCGIWRETRY:
6476   case VKI_SIOCGIWPOWER:
6477   case VKI_SIOCGIWAUTH:
6478      if (ARG3) {
6479         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
6480                        sizeof(struct vki_iw_param));
6481      }
6482      break;
6483   case VKI_SIOCGIWFREQ:
6484      if (ARG3) {
6485         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
6486                        sizeof(struct vki_iw_freq));
6487      }
6488      break;
6489   case VKI_SIOCGIWMODE:
6490      if (ARG3) {
6491         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
6492                       sizeof(__vki_u32));
6493      }
6494      break;
6495   case VKI_SIOCGIWRANGE:
6496   case VKI_SIOCGIWPRIV:
6497   case VKI_SIOCGIWSTATS:
6498   case VKI_SIOCGIWSPY:
6499   case VKI_SIOCGIWTHRSPY:
6500   case VKI_SIOCGIWAPLIST:
6501   case VKI_SIOCGIWSCAN:
6502   case VKI_SIOCGIWESSID:
6503   case VKI_SIOCGIWNICKN:
6504   case VKI_SIOCGIWENCODE:
6505   case VKI_SIOCGIWGENIE:
6506   case VKI_SIOCGIWENCODEEXT:
6507      if (ARG3) {
6508         struct vki_iw_point* point;
6509         point = &((struct vki_iwreq *)ARG3)->u.data;
6510         POST_MEM_WRITE((Addr)point->pointer, point->length);
6511      }
6512      break;
6513   case VKI_SIOCGIWAP:
6514      if (ARG3) {
6515         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
6516                        sizeof(struct vki_sockaddr));
6517      }
6518      break;
6519
6520#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
6521   /* ashmem */
6522   case VKI_ASHMEM_GET_SIZE:
6523   case VKI_ASHMEM_SET_SIZE:
6524   case VKI_ASHMEM_GET_PROT_MASK:
6525   case VKI_ASHMEM_SET_PROT_MASK:
6526   case VKI_ASHMEM_GET_PIN_STATUS:
6527   case VKI_ASHMEM_PURGE_ALL_CACHES:
6528   case VKI_ASHMEM_SET_NAME:
6529   case VKI_ASHMEM_PIN:
6530   case VKI_ASHMEM_UNPIN:
6531       break;
6532   case VKI_ASHMEM_GET_NAME:
6533       POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
6534       break;
6535
6536   /* binder */
6537   case VKI_BINDER_WRITE_READ:
6538       if (ARG3) {
6539           struct vki_binder_write_read* bwr
6540              = (struct vki_binder_write_read*)ARG3;
6541           POST_FIELD_WRITE(bwr->write_consumed);
6542           POST_FIELD_WRITE(bwr->read_consumed);
6543
6544           if (bwr->read_size)
6545               POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
6546       }
6547       break;
6548
6549   case VKI_BINDER_SET_IDLE_TIMEOUT:
6550   case VKI_BINDER_SET_MAX_THREADS:
6551   case VKI_BINDER_SET_IDLE_PRIORITY:
6552   case VKI_BINDER_SET_CONTEXT_MGR:
6553   case VKI_BINDER_THREAD_EXIT:
6554       break;
6555   case VKI_BINDER_VERSION:
6556       if (ARG3) {
6557           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
6558           POST_FIELD_WRITE(bv->protocol_version);
6559       }
6560       break;
6561#  endif /* defined(VGPV_*_linux_android) */
6562
6563   case VKI_HCIINQUIRY:
6564      if (ARG3) {
6565        struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
6566        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
6567                       ir->num_rsp * sizeof(struct vki_inquiry_info));
6568      }
6569      break;
6570
6571   /* KVM ioctls that only write the system call return value */
6572   case VKI_KVM_GET_API_VERSION:
6573   case VKI_KVM_CREATE_VM:
6574   case VKI_KVM_CHECK_EXTENSION:
6575   case VKI_KVM_GET_VCPU_MMAP_SIZE:
6576   case VKI_KVM_S390_ENABLE_SIE:
6577   case VKI_KVM_CREATE_VCPU:
6578   case VKI_KVM_RUN:
6579   case VKI_KVM_S390_INITIAL_RESET:
6580      break;
6581
6582   case VKI_EVIOCSSUSPENDBLOCK:
6583      POST_MEM_WRITE( ARG3, sizeof(int) );
6584      break;
6585
6586   case VKI_MEDIA_IOC_DEVICE_INFO:
6587      if (ARG3) {
6588         POST_MEM_WRITE(ARG3, sizeof(struct vki_media_device_info));
6589      }
6590      break;
6591
6592   default:
6593      /* EVIOC* are variable length and return size written on success */
6594      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
6595      case VKI_EVIOCGNAME(0):
6596      case VKI_EVIOCGPHYS(0):
6597      case VKI_EVIOCGUNIQ(0):
6598      case VKI_EVIOCGKEY(0):
6599      case VKI_EVIOCGLED(0):
6600      case VKI_EVIOCGSND(0):
6601      case VKI_EVIOCGSW(0):
6602      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
6603      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
6604      case VKI_EVIOCGBIT(VKI_EV_REL,0):
6605      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
6606      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
6607      case VKI_EVIOCGBIT(VKI_EV_SW,0):
6608      case VKI_EVIOCGBIT(VKI_EV_LED,0):
6609      case VKI_EVIOCGBIT(VKI_EV_SND,0):
6610      case VKI_EVIOCGBIT(VKI_EV_REP,0):
6611      case VKI_EVIOCGBIT(VKI_EV_FF,0):
6612      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
6613      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
6614         if (RES > 0)
6615            POST_MEM_WRITE(ARG3, RES);
6616         break;
6617      default:
6618         ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
6619         break;
6620      }
6621      break;
6622   }
6623}
6624
6625/* ---------------------------------------------------------------------
6626   socketcall wrapper helpers
6627   ------------------------------------------------------------------ */
6628
6629void
6630ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
6631                                UWord arg0, UWord arg1, UWord arg2,
6632                                UWord arg3, UWord arg4 )
6633{
6634   /* int getsockopt(int s, int level, int optname,
6635                     void *optval, socklen_t *optlen); */
6636   Addr optval_p = arg3;
6637   Addr optlen_p = arg4;
6638   /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
6639   if (optval_p != (Addr)NULL) {
6640      ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
6641                                   "socketcall.getsockopt(optval)",
6642                                   "socketcall.getsockopt(optlen)" );
6643      if (arg1 == VKI_SOL_SCTP &&
6644          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
6645           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
6646      {
6647         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
6648         int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
6649         PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
6650                        (Addr)ga->addrs, address_bytes );
6651      }
6652   }
6653}
6654
6655void
6656ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
6657                                 SysRes res,
6658                                 UWord arg0, UWord arg1, UWord arg2,
6659                                 UWord arg3, UWord arg4 )
6660{
6661   Addr optval_p = arg3;
6662   Addr optlen_p = arg4;
6663   vg_assert(!sr_isError(res)); /* guaranteed by caller */
6664   if (optval_p != (Addr)NULL) {
6665      ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
6666                                    "socketcall.getsockopt(optlen_out)" );
6667      if (arg1 == VKI_SOL_SCTP &&
6668          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
6669           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
6670      {
6671         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
6672         struct vki_sockaddr *a = ga->addrs;
6673         int i;
6674         for (i = 0; i < ga->addr_num; i++) {
6675            int sl = 0;
6676            if (a->sa_family == VKI_AF_INET)
6677               sl = sizeof(struct vki_sockaddr_in);
6678            else if (a->sa_family == VKI_AF_INET6)
6679               sl = sizeof(struct vki_sockaddr_in6);
6680            else {
6681               VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
6682                                        "address type %d\n", a->sa_family);
6683            }
6684            a = (struct vki_sockaddr*)((char*)a + sl);
6685         }
6686         POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
6687      }
6688   }
6689}
6690
6691#undef PRE
6692#undef POST
6693
6694#endif // defined(VGO_linux)
6695
6696/*--------------------------------------------------------------------*/
6697/*--- end                                                          ---*/
6698/*--------------------------------------------------------------------*/
6699