syswrap-linux.c revision 2d3c75979dd0bbf2606bf1a8e11b72ae6220e5db
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   default:
4299      PRINT("sys_ioctl ( %ld, 0x%lx, 0x%lx )",ARG1,ARG2,ARG3);
4300      PRE_REG_READ3(long, "ioctl",
4301                    unsigned int, fd, unsigned int, request, unsigned long, arg);
4302      break;
4303   }
4304
4305   // We now handle those that do look at ARG3 (and unknown ones fall into
4306   // this category).  Nb: some of these may well belong in the
4307   // doesn't-use-ARG3 switch above.
4308   switch (ARG2 /* request */) {
4309   case VKI_TCSETS:
4310   case VKI_TCSETSW:
4311   case VKI_TCSETSF:
4312      PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
4313      break;
4314   case VKI_TCGETS:
4315      PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
4316      break;
4317   case VKI_TCSETA:
4318   case VKI_TCSETAW:
4319   case VKI_TCSETAF:
4320      PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
4321      break;
4322   case VKI_TCGETA:
4323      PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
4324      break;
4325   case VKI_TCSBRK:
4326   case VKI_TCXONC:
4327   case VKI_TCSBRKP:
4328   case VKI_TCFLSH:
4329      /* These just take an int by value */
4330      break;
4331   case VKI_TIOCGWINSZ:
4332      PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
4333      break;
4334   case VKI_TIOCSWINSZ:
4335      PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
4336      break;
4337   case VKI_TIOCMBIS:
4338      PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
4339      break;
4340   case VKI_TIOCMBIC:
4341      PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
4342      break;
4343   case VKI_TIOCMSET:
4344      PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
4345      break;
4346   case VKI_TIOCMGET:
4347      PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
4348      break;
4349   case VKI_TIOCLINUX:
4350      PRE_MEM_READ( "ioctl(TIOCLINUX)",   ARG3, sizeof(char *) );
4351      if (*(char *)ARG3 == 11) {
4352	 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
4353      }
4354      break;
4355   case VKI_TIOCGPGRP:
4356      /* Get process group ID for foreground processing group. */
4357      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
4358      break;
4359   case VKI_TIOCSPGRP:
4360      /* Set a process group ID? */
4361      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
4362      break;
4363   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
4364      PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
4365      break;
4366   case VKI_TIOCSCTTY:
4367      /* Just takes an int value.  */
4368      break;
4369   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
4370      PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
4371      break;
4372   case VKI_FIONBIO:
4373      PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
4374      break;
4375   case VKI_FIOASYNC:
4376      PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
4377      break;
4378   case VKI_FIONREAD:                /* identical to SIOCINQ */
4379      PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
4380      break;
4381   case VKI_FIOQSIZE:
4382      PRE_MEM_WRITE( "ioctl(FIOQSIZE)",  ARG3, sizeof(vki_loff_t) );
4383      break;
4384
4385   case VKI_TIOCSERGETLSR:
4386      PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
4387      break;
4388   case VKI_TIOCGICOUNT:
4389      PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
4390                     sizeof(struct vki_serial_icounter_struct) );
4391      break;
4392
4393   case VKI_SG_SET_COMMAND_Q:
4394      PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
4395      break;
4396   case VKI_SG_IO:
4397      PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
4398      break;
4399   case VKI_SG_GET_SCSI_ID:
4400      PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
4401      break;
4402   case VKI_SG_SET_RESERVED_SIZE:
4403      PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
4404      break;
4405   case VKI_SG_SET_TIMEOUT:
4406      PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
4407      break;
4408   case VKI_SG_GET_RESERVED_SIZE:
4409      PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
4410      break;
4411   case VKI_SG_GET_TIMEOUT:
4412      break;
4413   case VKI_SG_GET_VERSION_NUM:
4414      PRE_MEM_WRITE(  "ioctl(SG_GET_VERSION_NUM)",  ARG3, sizeof(int) );
4415      break;
4416   case VKI_SG_EMULATED_HOST: /* 0x2203 */
4417      PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)",    ARG3, sizeof(int) );
4418      break;
4419   case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
4420      PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
4421      break;
4422
4423   case VKI_IIOCGETCPS:
4424      PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
4425		     VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
4426      break;
4427   case VKI_IIOCNETGPN:
4428      PRE_MEM_READ( "ioctl(IIOCNETGPN)",
4429		     (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
4430		     sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
4431      PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
4432		     sizeof(vki_isdn_net_ioctl_phone) );
4433      break;
4434
4435      /* These all use struct ifreq AFAIK */
4436   case VKI_SIOCGIFINDEX:        /* get iface index              */
4437      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
4438                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4439      PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
4440      break;
4441   case VKI_SIOCGIFFLAGS:        /* get flags                    */
4442      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
4443                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4444      PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
4445      break;
4446   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
4447      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
4448                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4449      PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
4450      break;
4451   case VKI_SIOCGIFMTU:          /* get MTU size                 */
4452      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
4453                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4454      PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
4455      break;
4456   case VKI_SIOCGIFADDR:         /* get PA address               */
4457      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
4458                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4459      PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
4460      break;
4461   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
4462      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
4463                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4464      PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
4465      break;
4466   case VKI_SIOCGIFMETRIC:       /* get metric                   */
4467      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
4468                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4469      PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
4470      break;
4471   case VKI_SIOCGIFMAP:          /* Get device parameters        */
4472      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
4473                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4474      PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
4475      break;
4476   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
4477      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
4478                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4479      PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
4480      break;
4481   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
4482      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
4483                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4484      PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
4485      break;
4486   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
4487      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
4488                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4489      PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
4490      break;
4491   case VKI_SIOCGIFNAME:         /* get iface name               */
4492      PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
4493                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
4494                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
4495      PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
4496      break;
4497   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
4498      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
4499                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4500      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
4501      break;
4502   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
4503      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
4504                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4505      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
4506                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
4507                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
4508      PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
4509                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
4510                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
4511      PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
4512		     sizeof(struct vki_ifreq));
4513      break;
4514   case VKI_SIOCGIFCONF:         /* get iface list               */
4515      /* WAS:
4516	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
4517	 KERNEL_DO_SYSCALL(tid,RES);
4518	 if (!VG_(is_kerror)(RES) && RES == 0)
4519	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
4520      */
4521      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
4522                    (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
4523                    sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
4524      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
4525                    (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
4526                    sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
4527      if ( ARG3 ) {
4528	 // TODO len must be readable and writable
4529	 // buf pointer only needs to be readable
4530	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
4531	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
4532			(Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
4533      }
4534      break;
4535   case VKI_SIOCGSTAMP:
4536      PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
4537      break;
4538   case VKI_SIOCGSTAMPNS:
4539      PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
4540      break;
4541      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
4542	 the number of bytes currently in that socket's send buffer.
4543	 It writes this value as an int to the memory location
4544	 indicated by the third argument of ioctl(2). */
4545   case VKI_SIOCOUTQ:
4546      PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
4547      break;
4548   case VKI_SIOCGRARP:           /* get RARP table entry         */
4549   case VKI_SIOCGARP:            /* get ARP table entry          */
4550      PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
4551      break;
4552
4553   case VKI_SIOCSIFFLAGS:        /* set flags                    */
4554      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
4555                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4556      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
4557                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
4558                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
4559      break;
4560   case VKI_SIOCSIFMAP:          /* Set device parameters        */
4561      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
4562                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4563      PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
4564                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
4565                     sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
4566      break;
4567   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
4568      PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
4569                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4570      PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
4571                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
4572                     sizeof(struct vki_hwtstamp_config) );
4573      break;
4574   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
4575      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
4576                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4577      PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
4578                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
4579                     sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
4580      break;
4581   case VKI_SIOCSIFADDR:         /* set PA address               */
4582   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
4583   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
4584   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
4585      PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
4586                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4587      PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
4588                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
4589                     sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
4590      break;
4591   case VKI_SIOCSIFMETRIC:       /* set metric                   */
4592      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
4593                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4594      PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
4595                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
4596                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
4597      break;
4598   case VKI_SIOCSIFMTU:          /* set MTU size                 */
4599      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
4600                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4601      PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
4602                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
4603                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
4604      break;
4605   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
4606      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
4607                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4608      PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
4609                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
4610                     sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
4611      break;
4612   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
4613      PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
4614                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
4615      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4616                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
4617                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
4618      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4619                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
4620                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
4621      PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
4622                     (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
4623                     sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
4624      break;
4625      /* Routing table calls.  */
4626   case VKI_SIOCADDRT:           /* add routing table entry      */
4627   case VKI_SIOCDELRT:           /* delete routing table entry   */
4628      PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
4629		    sizeof(struct vki_rtentry));
4630      break;
4631
4632      /* RARP cache control calls. */
4633   case VKI_SIOCDRARP:           /* delete RARP table entry      */
4634   case VKI_SIOCSRARP:           /* set RARP table entry         */
4635      /* ARP cache control calls. */
4636   case VKI_SIOCSARP:            /* set ARP table entry          */
4637   case VKI_SIOCDARP:            /* delete ARP table entry       */
4638      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
4639      break;
4640
4641   case VKI_SIOCGPGRP:
4642      PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
4643      break;
4644   case VKI_SIOCSPGRP:
4645      PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
4646      //tst->sys_flags &= ~SfMayBlock;
4647      break;
4648
4649      /* linux/soundcard interface (OSS) */
4650   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4651   case VKI_SNDCTL_SEQ_GETINCOUNT:
4652   case VKI_SNDCTL_SEQ_PERCMODE:
4653   case VKI_SNDCTL_SEQ_TESTMIDI:
4654   case VKI_SNDCTL_SEQ_RESETSAMPLES:
4655   case VKI_SNDCTL_SEQ_NRSYNTHS:
4656   case VKI_SNDCTL_SEQ_NRMIDIS:
4657   case VKI_SNDCTL_SEQ_GETTIME:
4658   case VKI_SNDCTL_DSP_GETBLKSIZE:
4659   case VKI_SNDCTL_DSP_GETFMTS:
4660   case VKI_SNDCTL_DSP_GETTRIGGER:
4661   case VKI_SNDCTL_DSP_GETODELAY:
4662   case VKI_SNDCTL_DSP_GETSPDIF:
4663   case VKI_SNDCTL_DSP_GETCAPS:
4664   case VKI_SOUND_PCM_READ_RATE:
4665   case VKI_SOUND_PCM_READ_CHANNELS:
4666   case VKI_SOUND_PCM_READ_BITS:
4667   case VKI_SOUND_PCM_READ_FILTER:
4668      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
4669		     ARG3, sizeof(int));
4670      break;
4671   case VKI_SNDCTL_SEQ_CTRLRATE:
4672   case VKI_SNDCTL_DSP_SPEED:
4673   case VKI_SNDCTL_DSP_STEREO:
4674   case VKI_SNDCTL_DSP_CHANNELS:
4675   case VKI_SOUND_PCM_WRITE_FILTER:
4676   case VKI_SNDCTL_DSP_SUBDIVIDE:
4677   case VKI_SNDCTL_DSP_SETFRAGMENT:
4678   case VKI_SNDCTL_DSP_SETFMT:
4679   case VKI_SNDCTL_DSP_GETCHANNELMASK:
4680   case VKI_SNDCTL_DSP_BIND_CHANNEL:
4681   case VKI_SNDCTL_TMR_TIMEBASE:
4682   case VKI_SNDCTL_TMR_TEMPO:
4683   case VKI_SNDCTL_TMR_SOURCE:
4684   case VKI_SNDCTL_MIDI_PRETIME:
4685   case VKI_SNDCTL_MIDI_MPUMODE:
4686      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
4687		     ARG3, sizeof(int));
4688      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
4689		     ARG3, sizeof(int));
4690      break;
4691   case VKI_SNDCTL_DSP_GETOSPACE:
4692   case VKI_SNDCTL_DSP_GETISPACE:
4693      PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
4694                     ARG3, sizeof(vki_audio_buf_info));
4695      break;
4696   case VKI_SNDCTL_DSP_NONBLOCK:
4697      break;
4698   case VKI_SNDCTL_DSP_SETTRIGGER:
4699      PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
4700		     ARG3, sizeof(int));
4701      break;
4702
4703   case VKI_SNDCTL_DSP_POST:
4704   case VKI_SNDCTL_DSP_RESET:
4705   case VKI_SNDCTL_DSP_SYNC:
4706   case VKI_SNDCTL_DSP_SETSYNCRO:
4707   case VKI_SNDCTL_DSP_SETDUPLEX:
4708      break;
4709
4710      /* linux/soundcard interface (ALSA) */
4711   case VKI_SNDRV_PCM_IOCTL_PAUSE:
4712   case VKI_SNDRV_PCM_IOCTL_LINK:
4713      /* these just take an int by value */
4714      break;
4715
4716      /* Real Time Clock (/dev/rtc) ioctls */
4717   case VKI_RTC_UIE_ON:
4718   case VKI_RTC_UIE_OFF:
4719   case VKI_RTC_AIE_ON:
4720   case VKI_RTC_AIE_OFF:
4721   case VKI_RTC_PIE_ON:
4722   case VKI_RTC_PIE_OFF:
4723   case VKI_RTC_IRQP_SET:
4724      break;
4725   case VKI_RTC_RD_TIME:
4726   case VKI_RTC_ALM_READ:
4727      PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
4728		     ARG3, sizeof(struct vki_rtc_time));
4729      break;
4730   case VKI_RTC_ALM_SET:
4731      PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
4732      break;
4733   case VKI_RTC_IRQP_READ:
4734      PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
4735      break;
4736
4737      /* Block devices */
4738   case VKI_BLKROSET:
4739      PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
4740      break;
4741   case VKI_BLKROGET:
4742      PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
4743      break;
4744   case VKI_BLKGETSIZE:
4745      PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
4746      break;
4747   case VKI_BLKRASET:
4748      break;
4749   case VKI_BLKRAGET:
4750      PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
4751      break;
4752   case VKI_BLKFRASET:
4753      break;
4754   case VKI_BLKFRAGET:
4755      PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
4756      break;
4757   case VKI_BLKSECTGET:
4758      PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
4759      break;
4760   case VKI_BLKSSZGET:
4761      PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
4762      break;
4763   case VKI_BLKBSZGET:
4764      PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
4765      break;
4766   case VKI_BLKBSZSET:
4767      PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
4768      break;
4769   case VKI_BLKGETSIZE64:
4770      PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
4771      break;
4772
4773      /* Hard disks */
4774   case VKI_HDIO_GETGEO: /* 0x0301 */
4775      PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
4776      break;
4777   case VKI_HDIO_GET_DMA: /* 0x030b */
4778      PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
4779      break;
4780   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
4781      PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
4782                     VKI_SIZEOF_STRUCT_HD_DRIVEID );
4783      break;
4784
4785      /* SCSI */
4786   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
4787      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
4788      break;
4789   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
4790      PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
4791      break;
4792
4793      /* CD ROM stuff (??)  */
4794   case VKI_CDROM_GET_MCN:
4795      PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
4796                    sizeof(struct vki_cdrom_mcn) );
4797      break;
4798   case VKI_CDROM_SEND_PACKET:
4799      PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
4800                    sizeof(struct vki_cdrom_generic_command));
4801      break;
4802   case VKI_CDROMSUBCHNL:
4803      PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
4804		    (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
4805		    sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
4806      PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
4807		     sizeof(struct vki_cdrom_subchnl));
4808      break;
4809   case VKI_CDROMREADMODE2:
4810      PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
4811      break;
4812   case VKI_CDROMREADTOCHDR:
4813      PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
4814		     sizeof(struct vki_cdrom_tochdr));
4815      break;
4816   case VKI_CDROMREADTOCENTRY:
4817      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
4818		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
4819		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
4820      PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
4821		    (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
4822		    sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
4823      PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
4824		     sizeof(struct vki_cdrom_tocentry));
4825      break;
4826   case VKI_CDROMMULTISESSION: /* 0x5310 */
4827      PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
4828		     sizeof(struct vki_cdrom_multisession));
4829      break;
4830   case VKI_CDROMVOLREAD: /* 0x5313 */
4831      PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
4832		     sizeof(struct vki_cdrom_volctrl));
4833      break;
4834   case VKI_CDROMREADRAW: /* 0x5314 */
4835      PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
4836      PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
4837      break;
4838   case VKI_CDROMREADAUDIO: /* 0x530e */
4839      PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
4840		     sizeof (struct vki_cdrom_read_audio));
4841      if ( ARG3 ) {
4842         /* ToDo: don't do any of the following if the structure is invalid */
4843         struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
4844	 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
4845	                (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
4846      }
4847      break;
4848   case VKI_CDROMPLAYMSF:
4849      PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
4850      break;
4851      /* The following two are probably bogus (should check args
4852	 for readability).  JRS 20021117 */
4853   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4854   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
4855      break;
4856   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
4857      break;
4858
4859   case VKI_FIGETBSZ:
4860      PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
4861      break;
4862   case VKI_FIBMAP:
4863      PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
4864      break;
4865
4866   case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
4867      PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
4868                     sizeof(struct vki_fb_var_screeninfo));
4869      break;
4870   case VKI_FBIOPUT_VSCREENINFO:
4871      PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
4872                    sizeof(struct vki_fb_var_screeninfo));
4873      break;
4874   case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
4875      PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
4876                     sizeof(struct vki_fb_fix_screeninfo));
4877      break;
4878   case VKI_FBIOPAN_DISPLAY:
4879      PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
4880                    sizeof(struct vki_fb_var_screeninfo));
4881
4882      break;
4883   case VKI_PPCLAIM:
4884   case VKI_PPEXCL:
4885   case VKI_PPYIELD:
4886   case VKI_PPRELEASE:
4887      break;
4888   case VKI_PPSETMODE:
4889      PRE_MEM_READ( "ioctl(PPSETMODE)",   ARG3, sizeof(int) );
4890      break;
4891   case VKI_PPGETMODE:
4892      PRE_MEM_WRITE( "ioctl(PPGETMODE)",  ARG3, sizeof(int) );
4893      break;
4894   case VKI_PPSETPHASE:
4895      PRE_MEM_READ(  "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
4896      break;
4897   case VKI_PPGETPHASE:
4898      PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
4899      break;
4900   case VKI_PPGETMODES:
4901      PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
4902      break;
4903   case VKI_PPSETFLAGS:
4904      PRE_MEM_READ(  "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
4905      break;
4906   case VKI_PPGETFLAGS:
4907      PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
4908      break;
4909   case VKI_PPRSTATUS:
4910      PRE_MEM_WRITE( "ioctl(PPRSTATUS)",  ARG3, sizeof(unsigned char) );
4911      break;
4912   case VKI_PPRDATA:
4913      PRE_MEM_WRITE( "ioctl(PPRDATA)",    ARG3, sizeof(unsigned char) );
4914      break;
4915   case VKI_PPRCONTROL:
4916      PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
4917      break;
4918   case VKI_PPWDATA:
4919      PRE_MEM_READ(  "ioctl(PPWDATA)",    ARG3, sizeof(unsigned char) );
4920      break;
4921   case VKI_PPWCONTROL:
4922      PRE_MEM_READ(  "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
4923      break;
4924   case VKI_PPFCONTROL:
4925      PRE_MEM_READ(  "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
4926      break;
4927   case VKI_PPDATADIR:
4928      PRE_MEM_READ(  "ioctl(PPDATADIR)",  ARG3, sizeof(int) );
4929      break;
4930   case VKI_PPNEGOT:
4931      PRE_MEM_READ(  "ioctl(PPNEGOT)",    ARG3, sizeof(int) );
4932      break;
4933   case VKI_PPWCTLONIRQ:
4934      PRE_MEM_READ(  "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
4935      break;
4936   case VKI_PPCLRIRQ:
4937      PRE_MEM_WRITE( "ioctl(PPCLRIRQ)",   ARG3, sizeof(int) );
4938      break;
4939   case VKI_PPSETTIME:
4940      PRE_MEM_READ(  "ioctl(PPSETTIME)",  ARG3, sizeof(struct vki_timeval) );
4941      break;
4942   case VKI_PPGETTIME:
4943      PRE_MEM_WRITE( "ioctl(PPGETTIME)",  ARG3, sizeof(struct vki_timeval) );
4944      break;
4945
4946   case VKI_GIO_FONT:
4947      PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
4948      break;
4949   case VKI_PIO_FONT:
4950      PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
4951      break;
4952
4953   case VKI_GIO_FONTX:
4954      PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
4955      if ( ARG3 ) {
4956         /* ToDo: don't do any of the following if the structure is invalid */
4957         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
4958         PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
4959                        32 * cfd->charcount );
4960      }
4961      break;
4962   case VKI_PIO_FONTX:
4963      PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
4964      if ( ARG3 ) {
4965         /* ToDo: don't do any of the following if the structure is invalid */
4966         struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
4967         PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
4968                       32 * cfd->charcount );
4969      }
4970      break;
4971
4972   case VKI_PIO_FONTRESET:
4973      break;
4974
4975   case VKI_GIO_CMAP:
4976      PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
4977      break;
4978   case VKI_PIO_CMAP:
4979      PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
4980      break;
4981
4982   case VKI_KIOCSOUND:
4983   case VKI_KDMKTONE:
4984      break;
4985
4986   case VKI_KDGETLED:
4987      PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
4988      break;
4989   case VKI_KDSETLED:
4990      break;
4991
4992   case VKI_KDGKBTYPE:
4993      PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
4994      break;
4995
4996   case VKI_KDADDIO:
4997   case VKI_KDDELIO:
4998   case VKI_KDENABIO:
4999   case VKI_KDDISABIO:
5000      break;
5001
5002   case VKI_KDSETMODE:
5003      break;
5004   case VKI_KDGETMODE:
5005      PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
5006      break;
5007
5008   case VKI_KDMAPDISP:
5009   case VKI_KDUNMAPDISP:
5010      break;
5011
5012   case VKI_GIO_SCRNMAP:
5013      PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
5014      break;
5015   case VKI_PIO_SCRNMAP:
5016      PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ  );
5017      break;
5018   case VKI_GIO_UNISCRNMAP:
5019      PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
5020                     VKI_E_TABSZ * sizeof(unsigned short) );
5021      break;
5022   case VKI_PIO_UNISCRNMAP:
5023      PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
5024                    VKI_E_TABSZ * sizeof(unsigned short) );
5025      break;
5026
5027   case VKI_GIO_UNIMAP:
5028      if ( ARG3 ) {
5029         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
5030         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
5031                       sizeof(unsigned short));
5032         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
5033                       sizeof(struct vki_unipair *));
5034         PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
5035                        desc->entry_ct * sizeof(struct vki_unipair));
5036      }
5037      break;
5038   case VKI_PIO_UNIMAP:
5039      if ( ARG3 ) {
5040         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
5041         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
5042                       sizeof(unsigned short) );
5043         PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
5044                       sizeof(struct vki_unipair *) );
5045         PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
5046                       desc->entry_ct * sizeof(struct vki_unipair) );
5047      }
5048      break;
5049   case VKI_PIO_UNIMAPCLR:
5050      PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
5051      break;
5052
5053   case VKI_KDGKBMODE:
5054      PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
5055      break;
5056   case VKI_KDSKBMODE:
5057      break;
5058
5059   case VKI_KDGKBMETA:
5060      PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
5061      break;
5062   case VKI_KDSKBMETA:
5063      break;
5064
5065   case VKI_KDGKBLED:
5066      PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
5067      break;
5068   case VKI_KDSKBLED:
5069      break;
5070
5071   case VKI_KDGKBENT:
5072      PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
5073                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
5074                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
5075      PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
5076                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
5077                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
5078      PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
5079		     (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
5080		     sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
5081      break;
5082   case VKI_KDSKBENT:
5083      PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
5084                    (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
5085                    sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
5086      PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
5087                    (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
5088                    sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
5089      PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
5090                    (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
5091                    sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
5092      break;
5093
5094   case VKI_KDGKBSENT:
5095      PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
5096                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
5097                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
5098      PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
5099		     (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
5100		     sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
5101      break;
5102   case VKI_KDSKBSENT:
5103      PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
5104                    (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
5105                    sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
5106      PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
5107                       (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
5108      break;
5109
5110   case VKI_KDGKBDIACR:
5111      PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
5112      break;
5113   case VKI_KDSKBDIACR:
5114      PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
5115      break;
5116
5117   case VKI_KDGETKEYCODE:
5118      PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
5119                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
5120                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
5121      PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
5122		     (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
5123		     sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
5124      break;
5125   case VKI_KDSETKEYCODE:
5126      PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
5127                    (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
5128                    sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
5129      PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
5130                    (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
5131                    sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
5132      break;
5133
5134   case VKI_KDSIGACCEPT:
5135      break;
5136
5137   case VKI_KDKBDREP:
5138      PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
5139      break;
5140
5141   case VKI_KDFONTOP:
5142      if ( ARG3 ) {
5143         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
5144         PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
5145                       sizeof(struct vki_console_font_op) );
5146         switch ( op->op ) {
5147            case VKI_KD_FONT_OP_SET:
5148               PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
5149                             (Addr)op->data,
5150                             (op->width + 7) / 8 * 32 * op->charcount );
5151               break;
5152            case VKI_KD_FONT_OP_GET:
5153               if ( op->data )
5154                  PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
5155                                 (Addr)op->data,
5156                                 (op->width + 7) / 8 * 32 * op->charcount );
5157               break;
5158            case VKI_KD_FONT_OP_SET_DEFAULT:
5159               if ( op->data )
5160                  PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
5161                                   (Addr)op->data );
5162               break;
5163            case VKI_KD_FONT_OP_COPY:
5164               break;
5165         }
5166      }
5167      break;
5168
5169   case VKI_VT_OPENQRY:
5170      PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
5171      break;
5172   case VKI_VT_GETMODE:
5173      PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
5174      break;
5175   case VKI_VT_SETMODE:
5176      PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
5177      break;
5178   case VKI_VT_GETSTATE:
5179      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
5180                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
5181                     sizeof(((struct vki_vt_stat*) ARG3)->v_active));
5182      PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
5183                     (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
5184                     sizeof(((struct vki_vt_stat*) ARG3)->v_state));
5185      break;
5186   case VKI_VT_RELDISP:
5187   case VKI_VT_ACTIVATE:
5188   case VKI_VT_WAITACTIVE:
5189   case VKI_VT_DISALLOCATE:
5190      break;
5191   case VKI_VT_RESIZE:
5192      PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
5193      break;
5194   case VKI_VT_RESIZEX:
5195      PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
5196      break;
5197   case VKI_VT_LOCKSWITCH:
5198   case VKI_VT_UNLOCKSWITCH:
5199      break;
5200
5201   case VKI_USBDEVFS_CONTROL:
5202      if ( ARG3 ) {
5203         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
5204         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
5205         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
5206         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
5207         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
5208         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
5209         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
5210         if (vkuc->bRequestType & 0x80)
5211            PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
5212         else
5213            PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
5214      }
5215      break;
5216   case VKI_USBDEVFS_BULK:
5217      if ( ARG3 ) {
5218         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
5219         PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
5220         if (vkub->ep & 0x80)
5221            PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
5222         else
5223            PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
5224      }
5225      break;
5226   case VKI_USBDEVFS_GETDRIVER:
5227      if ( ARG3 ) {
5228         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
5229         PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
5230      }
5231      break;
5232   case VKI_USBDEVFS_SUBMITURB:
5233      if ( ARG3 ) {
5234         struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
5235
5236         /* Not the whole struct needs to be initialized */
5237         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
5238         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
5239         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
5240         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
5241         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
5242         PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
5243         if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
5244            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
5245            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
5246            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
5247            if (vkusp->bRequestType & 0x80)
5248               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
5249            else
5250               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
5251            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
5252         } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
5253            int total_length = 0;
5254            int i;
5255            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
5256            for(i=0; i<vkuu->number_of_packets; i++) {
5257               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
5258               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));
5259               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
5260               total_length += vkuu->iso_frame_desc[i].length;
5261            }
5262            if (vkuu->endpoint & 0x80)
5263               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
5264            else
5265               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
5266            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
5267         } else {
5268            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
5269            if (vkuu->endpoint & 0x80)
5270               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
5271            else
5272               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
5273            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
5274         }
5275      }
5276      break;
5277   case VKI_USBDEVFS_DISCARDURB:
5278      break;
5279   case VKI_USBDEVFS_REAPURB:
5280      if ( ARG3 ) {
5281         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
5282      }
5283      break;
5284   case VKI_USBDEVFS_REAPURBNDELAY:
5285      if ( ARG3 ) {
5286         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
5287      }
5288      break;
5289   case VKI_USBDEVFS_CONNECTINFO:
5290      PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
5291      break;
5292   case VKI_USBDEVFS_IOCTL:
5293      if ( ARG3 ) {
5294         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
5295         UInt dir2, size2;
5296         PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
5297         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
5298         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
5299         if (size2 > 0) {
5300            if (dir2 & _VKI_IOC_WRITE)
5301               PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
5302            else if (dir2 & _VKI_IOC_READ)
5303               PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
5304         }
5305      }
5306      break;
5307   case VKI_USBDEVFS_RESET:
5308      break;
5309
5310      /* I2C (/dev/i2c-*) ioctls */
5311   case VKI_I2C_SLAVE:
5312   case VKI_I2C_SLAVE_FORCE:
5313   case VKI_I2C_TENBIT:
5314   case VKI_I2C_PEC:
5315      break;
5316   case VKI_I2C_FUNCS:
5317      PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
5318      break;
5319   case VKI_I2C_RDWR:
5320      if ( ARG3 ) {
5321          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
5322          UInt i;
5323          PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
5324          for (i=0; i < vkui->nmsgs; i++) {
5325              struct vki_i2c_msg *msg = vkui->msgs + i;
5326              PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
5327              if (msg->flags & VKI_I2C_M_RD)
5328                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
5329              else
5330                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
5331          }
5332      }
5333      break;
5334
5335      /* Wireless extensions ioctls */
5336   case VKI_SIOCSIWCOMMIT:
5337   case VKI_SIOCSIWNWID:
5338   case VKI_SIOCSIWFREQ:
5339   case VKI_SIOCSIWMODE:
5340   case VKI_SIOCSIWSENS:
5341   case VKI_SIOCSIWRANGE:
5342   case VKI_SIOCSIWPRIV:
5343   case VKI_SIOCSIWSTATS:
5344   case VKI_SIOCSIWSPY:
5345   case VKI_SIOCSIWTHRSPY:
5346   case VKI_SIOCSIWAP:
5347   case VKI_SIOCSIWSCAN:
5348   case VKI_SIOCSIWESSID:
5349   case VKI_SIOCSIWRATE:
5350   case VKI_SIOCSIWNICKN:
5351   case VKI_SIOCSIWRTS:
5352   case VKI_SIOCSIWFRAG:
5353   case VKI_SIOCSIWTXPOW:
5354   case VKI_SIOCSIWRETRY:
5355   case VKI_SIOCSIWENCODE:
5356   case VKI_SIOCSIWPOWER:
5357   case VKI_SIOCSIWGENIE:
5358   case VKI_SIOCSIWMLME:
5359   case VKI_SIOCSIWAUTH:
5360   case VKI_SIOCSIWENCODEEXT:
5361   case VKI_SIOCSIWPMKSA:
5362      break;
5363   case VKI_SIOCGIWNAME:
5364      if (ARG3) {
5365         PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
5366                       (Addr)((struct vki_iwreq *)ARG3)->u.name,
5367                       sizeof(((struct vki_iwreq *)ARG3)->u.name));
5368      }
5369      break;
5370   case VKI_SIOCGIWNWID:
5371   case VKI_SIOCGIWSENS:
5372   case VKI_SIOCGIWRATE:
5373   case VKI_SIOCGIWRTS:
5374   case VKI_SIOCGIWFRAG:
5375   case VKI_SIOCGIWTXPOW:
5376   case VKI_SIOCGIWRETRY:
5377   case VKI_SIOCGIWPOWER:
5378   case VKI_SIOCGIWAUTH:
5379      if (ARG3) {
5380         PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
5381                       "RETRY|PARAM|AUTH])",
5382                       (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
5383                       sizeof(struct vki_iw_param));
5384      }
5385      break;
5386   case VKI_SIOCGIWFREQ:
5387      if (ARG3) {
5388         PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
5389                       (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
5390                       sizeof(struct vki_iw_freq));
5391      }
5392      break;
5393   case VKI_SIOCGIWMODE:
5394      if (ARG3) {
5395         PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
5396                       (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
5397                       sizeof(__vki_u32));
5398      }
5399      break;
5400   case VKI_SIOCGIWRANGE:
5401   case VKI_SIOCGIWPRIV:
5402   case VKI_SIOCGIWSTATS:
5403   case VKI_SIOCGIWSPY:
5404   case VKI_SIOCGIWTHRSPY:
5405   case VKI_SIOCGIWAPLIST:
5406   case VKI_SIOCGIWSCAN:
5407   case VKI_SIOCGIWESSID:
5408   case VKI_SIOCGIWNICKN:
5409   case VKI_SIOCGIWENCODE:
5410   case VKI_SIOCGIWGENIE:
5411   case VKI_SIOCGIWENCODEEXT:
5412      if (ARG3) {
5413         struct vki_iw_point* point;
5414         point = &((struct vki_iwreq *)ARG3)->u.data;
5415         PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
5416                       "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
5417                       (Addr)point->pointer, point->length);
5418      }
5419      break;
5420   case VKI_SIOCGIWAP:
5421      if (ARG3) {
5422         PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
5423                       (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
5424                       sizeof(struct vki_sockaddr));
5425      }
5426      break;
5427
5428  /* User input device creation */
5429  case VKI_UI_SET_EVBIT:
5430  case VKI_UI_SET_KEYBIT:
5431  case VKI_UI_SET_RELBIT:
5432  case VKI_UI_SET_ABSBIT:
5433  case VKI_UI_SET_MSCBIT:
5434  case VKI_UI_SET_LEDBIT:
5435  case VKI_UI_SET_SNDBIT:
5436  case VKI_UI_SET_FFBIT:
5437  case VKI_UI_SET_SWBIT:
5438  case VKI_UI_SET_PROPBIT:
5439      /* These just take an int by value */
5440      break;
5441
5442#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
5443   /* ashmem */
5444   case VKI_ASHMEM_GET_SIZE:
5445   case VKI_ASHMEM_SET_SIZE:
5446   case VKI_ASHMEM_GET_PROT_MASK:
5447   case VKI_ASHMEM_SET_PROT_MASK:
5448   case VKI_ASHMEM_GET_PIN_STATUS:
5449   case VKI_ASHMEM_PURGE_ALL_CACHES:
5450       break;
5451   case VKI_ASHMEM_GET_NAME:
5452       PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
5453       break;
5454   case VKI_ASHMEM_SET_NAME:
5455       PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
5456       break;
5457   case VKI_ASHMEM_PIN:
5458   case VKI_ASHMEM_UNPIN:
5459       PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
5460                     ARG3, sizeof(struct vki_ashmem_pin) );
5461       break;
5462
5463   /* binder */
5464   case VKI_BINDER_WRITE_READ:
5465       if (ARG3) {
5466           struct vki_binder_write_read* bwr
5467              = (struct vki_binder_write_read*)ARG3;
5468
5469           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
5470                          bwr->write_buffer);
5471           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
5472                          bwr->write_size);
5473           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
5474                          bwr->write_consumed);
5475           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
5476                          bwr->read_buffer);
5477           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
5478                          bwr->read_size);
5479           PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
5480                          bwr->read_consumed);
5481
5482           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
5483                           bwr->write_consumed);
5484           PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
5485                           bwr->read_consumed);
5486
5487           if (bwr->read_size)
5488               PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
5489                             (Addr)bwr->read_buffer, bwr->read_size);
5490           if (bwr->write_size)
5491               PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
5492                            (Addr)bwr->write_buffer, bwr->write_size);
5493       }
5494       break;
5495
5496   case VKI_BINDER_SET_IDLE_TIMEOUT:
5497   case VKI_BINDER_SET_MAX_THREADS:
5498   case VKI_BINDER_SET_IDLE_PRIORITY:
5499   case VKI_BINDER_SET_CONTEXT_MGR:
5500   case VKI_BINDER_THREAD_EXIT:
5501       break;
5502   case VKI_BINDER_VERSION:
5503       if (ARG3) {
5504           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
5505           PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
5506       }
5507       break;
5508#  endif /* defined(VGPV_*_linux_android) */
5509
5510   case VKI_HCIINQUIRY:
5511      if (ARG3) {
5512         struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
5513         PRE_MEM_READ("ioctl(HCIINQUIRY)",
5514                      (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
5515         PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
5516                       (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
5517                       ir->num_rsp * sizeof(struct vki_inquiry_info));
5518      }
5519      break;
5520
5521   /* KVM ioctls that check for a numeric value as parameter */
5522   case VKI_KVM_GET_API_VERSION:
5523   case VKI_KVM_CREATE_VM:
5524   case VKI_KVM_GET_VCPU_MMAP_SIZE:
5525   case VKI_KVM_CHECK_EXTENSION:
5526   case VKI_KVM_CREATE_VCPU:
5527   case VKI_KVM_RUN:
5528      break;
5529
5530   default:
5531      /* EVIOC* are variable length and return size written on success */
5532      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
5533      case VKI_EVIOCGNAME(0):
5534      case VKI_EVIOCGPHYS(0):
5535      case VKI_EVIOCGUNIQ(0):
5536      case VKI_EVIOCGKEY(0):
5537      case VKI_EVIOCGLED(0):
5538      case VKI_EVIOCGSND(0):
5539      case VKI_EVIOCGSW(0):
5540      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
5541      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
5542      case VKI_EVIOCGBIT(VKI_EV_REL,0):
5543      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
5544      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
5545      case VKI_EVIOCGBIT(VKI_EV_SW,0):
5546      case VKI_EVIOCGBIT(VKI_EV_LED,0):
5547      case VKI_EVIOCGBIT(VKI_EV_SND,0):
5548      case VKI_EVIOCGBIT(VKI_EV_REP,0):
5549      case VKI_EVIOCGBIT(VKI_EV_FF,0):
5550      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
5551      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
5552         PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
5553         break;
5554      default:
5555         ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
5556         break;
5557      }
5558      break;
5559   }
5560}
5561
5562POST(sys_ioctl)
5563{
5564   vg_assert(SUCCESS);
5565
5566   /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
5567
5568#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
5569
5570#  if defined(ANDROID_HARDWARE_nexus_s)
5571
5572   /* BEGIN undocumented ioctls for the graphics hardware (??)
5573      (libpvr) on Nexus S */
5574   if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
5575      /* What's going on here: there appear to be a bunch of ioctls of
5576         the form 0xC01C67xx which are undocumented, and if unhandled
5577         give rise to a vast number of false positives in Memcheck.
5578
5579         The "normal" intrepretation of an ioctl of this form would be
5580         that the 3rd arg is a pointer to an area of size 0x1C (28
5581         bytes) which is filled in by the kernel.  Hence you might
5582         think that "POST_MEM_WRITE(ARG3, 28)" would fix it.  But it
5583         doesn't.
5584
5585         It requires POST_MEM_WRITE(ARG3, 256) to silence them.  One
5586         interpretation of this is that ARG3 really does point to a 28
5587         byte struct, but inside that are pointers to other areas also
5588         filled in by the kernel.  If these happen to be allocated
5589         just back up the stack then the 256 byte paint might cover
5590         them too, somewhat indiscriminately.
5591
5592         By printing out ARG3 and also the 28 bytes that it points at,
5593         it's possible to guess that the 7 word structure has this form
5594
5595           0            1    2    3        4    5        6
5596           ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
5597
5598         Unfortunately that doesn't seem to work for some reason, so
5599         stay with the blunt-instrument approach for the time being.
5600      */
5601      if (1) {
5602         /* blunt-instrument approach */
5603         if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
5604                            " (%08lx, %08lx)\n", ARG2, ARG3);
5605         POST_MEM_WRITE(ARG3, 256);
5606      } else {
5607         /* be a bit more sophisticated */
5608         if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
5609                            " (%08lx, %08lx) (fancy)\n", ARG2, ARG3);
5610         POST_MEM_WRITE(ARG3, 28);
5611         UInt* word = (UInt*)ARG3;
5612         if (word && word[2] && word[3] < 0x200/*stay sane*/)
5613            POST_MEM_WRITE(word[2], word[3]); // "ptr1"
5614         if (word && word[4] && word[5] < 0x200/*stay sane*/)
5615            POST_MEM_WRITE(word[4], word[5]); // "ptr2"
5616      }
5617      if (0) {
5618         Int i;
5619         VG_(printf)("QQQQQQQQQQ ");
5620         for (i = 0; i < (0x1C/4); i++) {
5621            VG_(printf)("%08x ", ((UInt*)(ARG3))[i]);
5622         }
5623         VG_(printf)("\n");
5624      }
5625      return;
5626   }
5627   /* END Nexus S specific ioctls */
5628
5629
5630#  elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator)
5631
5632   /* BEGIN generic/emulator specific ioctls */
5633   /* currently none are known */
5634   /* END generic/emulator specific ioctls */
5635
5636
5637#  else /* no ANDROID_HARDWARE_anything defined */
5638
5639#   warning ""
5640#   warning "You need to define one the CPP symbols ANDROID_HARDWARE_blah"
5641#   warning "at configure time, to tell Valgrind what hardware you are"
5642#   warning "building for.  Currently known values are"
5643#   warning ""
5644#   warning "   ANDROID_HARDWARE_nexus_s       Samsung Nexus S"
5645#   warning "   ANDROID_HARDWARE_generic       Generic device (eg, Pandaboard)"
5646#   warning "   ANDROID_HARDWARE_emulator      x86 or arm emulator"
5647#   warning ""
5648#   warning "Make sure you exactly follow the steps in README.android."
5649#   warning ""
5650#   error "No CPP symbol ANDROID_HARDWARE_blah defined.  Giving up."
5651
5652#  endif /* cases for ANDROID_HARDWARE_blah */
5653
5654#  endif /* defined(VGPV_*_linux_android) */
5655
5656   /* --- END special IOCTL handlers for specific Android hardware --- */
5657
5658   /* --- normal handling --- */
5659   switch (ARG2 /* request */) {
5660   case VKI_TCSETS:
5661   case VKI_TCSETSW:
5662   case VKI_TCSETSF:
5663      break;
5664   case VKI_TCGETS:
5665      POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
5666      break;
5667   case VKI_TCSETA:
5668   case VKI_TCSETAW:
5669   case VKI_TCSETAF:
5670      break;
5671   case VKI_TCGETA:
5672      POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
5673      break;
5674   case VKI_TCSBRK:
5675   case VKI_TCXONC:
5676   case VKI_TCSBRKP:
5677   case VKI_TCFLSH:
5678      break;
5679   case VKI_TIOCGWINSZ:
5680      POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
5681      break;
5682   case VKI_TIOCSWINSZ:
5683   case VKI_TIOCMBIS:
5684   case VKI_TIOCMBIC:
5685   case VKI_TIOCMSET:
5686      break;
5687   case VKI_TIOCMGET:
5688      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
5689      break;
5690   case VKI_TIOCLINUX:
5691      POST_MEM_WRITE( ARG3, sizeof(char *) );
5692      break;
5693   case VKI_TIOCGPGRP:
5694      /* Get process group ID for foreground processing group. */
5695      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
5696      break;
5697   case VKI_TIOCSPGRP:
5698      /* Set a process group ID? */
5699      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
5700      break;
5701   case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
5702      POST_MEM_WRITE( ARG3, sizeof(int));
5703      break;
5704   case VKI_TIOCSCTTY:
5705      break;
5706   case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
5707      break;
5708   case VKI_FIONBIO:
5709      break;
5710   case VKI_FIOASYNC:
5711      break;
5712   case VKI_FIONREAD:                /* identical to SIOCINQ */
5713      POST_MEM_WRITE( ARG3, sizeof(int) );
5714      break;
5715   case VKI_FIOQSIZE:
5716      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
5717      break;
5718
5719   case VKI_TIOCSERGETLSR:
5720      POST_MEM_WRITE( ARG3, sizeof(int) );
5721      break;
5722   case VKI_TIOCGICOUNT:
5723      POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
5724      break;
5725
5726   case VKI_SG_SET_COMMAND_Q:
5727      break;
5728   case VKI_SG_IO:
5729      POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
5730      break;
5731   case VKI_SG_GET_SCSI_ID:
5732      POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
5733      break;
5734   case VKI_SG_SET_RESERVED_SIZE:
5735      break;
5736   case VKI_SG_SET_TIMEOUT:
5737      break;
5738   case VKI_SG_GET_RESERVED_SIZE:
5739      POST_MEM_WRITE(ARG3, sizeof(int));
5740      break;
5741   case VKI_SG_GET_TIMEOUT:
5742      break;
5743   case VKI_SG_GET_VERSION_NUM:
5744      POST_MEM_WRITE(ARG3, sizeof(int));
5745      break;
5746   case VKI_SG_EMULATED_HOST:
5747      POST_MEM_WRITE(ARG3, sizeof(int));
5748      break;
5749   case VKI_SG_GET_SG_TABLESIZE:
5750      POST_MEM_WRITE(ARG3, sizeof(int));
5751      break;
5752
5753   case VKI_IIOCGETCPS:
5754      POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
5755      break;
5756   case VKI_IIOCNETGPN:
5757      POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
5758      break;
5759
5760      /* These all use struct ifreq AFAIK */
5761   case VKI_SIOCGIFINDEX:        /* get iface index              */
5762      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
5763                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
5764      break;
5765   case VKI_SIOCGIFFLAGS:        /* get flags                    */
5766      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
5767                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
5768      break;
5769   case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
5770      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
5771                      sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
5772      break;
5773   case VKI_SIOCGIFMTU:          /* get MTU size                 */
5774      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
5775                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
5776      break;
5777   case VKI_SIOCGIFADDR:         /* get PA address               */
5778   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
5779   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
5780   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
5781      POST_MEM_WRITE(
5782                (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
5783                sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
5784      break;
5785   case VKI_SIOCGIFMETRIC:       /* get metric                   */
5786      POST_MEM_WRITE(
5787                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
5788                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
5789      break;
5790   case VKI_SIOCGIFMAP:          /* Get device parameters        */
5791      POST_MEM_WRITE(
5792                (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
5793                sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
5794      break;
5795     break;
5796   case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
5797      POST_MEM_WRITE(
5798                (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
5799                sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
5800      break;
5801   case VKI_SIOCGIFNAME:         /* get iface name               */
5802      POST_MEM_WRITE(
5803                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
5804                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
5805      break;
5806   case VKI_SIOCGMIIPHY:         /* get hardware entry           */
5807      POST_MEM_WRITE(
5808                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
5809                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
5810      break;
5811   case VKI_SIOCGMIIREG:         /* get hardware entry registers */
5812      POST_MEM_WRITE(
5813                (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
5814                sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
5815      break;
5816   case VKI_SIOCGIFCONF:         /* get iface list               */
5817      /* WAS:
5818	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
5819	 KERNEL_DO_SYSCALL(tid,RES);
5820	 if (!VG_(is_kerror)(RES) && RES == 0)
5821	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
5822      */
5823      if (RES == 0 && ARG3 ) {
5824	 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
5825	 if (ifc->vki_ifc_buf != NULL)
5826	    POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
5827      }
5828      break;
5829   case VKI_SIOCGSTAMP:
5830      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
5831      break;
5832   case VKI_SIOCGSTAMPNS:
5833      POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
5834      break;
5835      /* SIOCOUTQ is an ioctl that, when called on a socket, returns
5836	 the number of bytes currently in that socket's send buffer.
5837	 It writes this value as an int to the memory location
5838	 indicated by the third argument of ioctl(2). */
5839   case VKI_SIOCOUTQ:
5840      POST_MEM_WRITE(ARG3, sizeof(int));
5841      break;
5842   case VKI_SIOCGRARP:           /* get RARP table entry         */
5843   case VKI_SIOCGARP:            /* get ARP table entry          */
5844      POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
5845      break;
5846
5847   case VKI_SIOCSIFFLAGS:        /* set flags                    */
5848   case VKI_SIOCSIFMAP:          /* Set device parameters        */
5849   case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
5850   case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
5851   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
5852   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
5853   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
5854   case VKI_SIOCSIFMETRIC:       /* set metric                   */
5855   case VKI_SIOCSIFADDR:         /* set PA address               */
5856   case VKI_SIOCSIFMTU:          /* set MTU size                 */
5857   case VKI_SIOCSIFHWADDR:       /* set hardware address         */
5858   case VKI_SIOCSMIIREG:         /* set hardware entry registers */
5859      break;
5860      /* Routing table calls.  */
5861   case VKI_SIOCADDRT:           /* add routing table entry      */
5862   case VKI_SIOCDELRT:           /* delete routing table entry   */
5863      break;
5864
5865      /* RARP cache control calls. */
5866   case VKI_SIOCDRARP:           /* delete RARP table entry      */
5867   case VKI_SIOCSRARP:           /* set RARP table entry         */
5868      /* ARP cache control calls. */
5869   case VKI_SIOCSARP:            /* set ARP table entry          */
5870   case VKI_SIOCDARP:            /* delete ARP table entry       */
5871      break;
5872
5873   case VKI_SIOCGPGRP:
5874      POST_MEM_WRITE(ARG3, sizeof(int));
5875      break;
5876   case VKI_SIOCSPGRP:
5877      break;
5878
5879      /* linux/soundcard interface (OSS) */
5880   case VKI_SNDCTL_SEQ_GETOUTCOUNT:
5881   case VKI_SNDCTL_SEQ_GETINCOUNT:
5882   case VKI_SNDCTL_SEQ_PERCMODE:
5883   case VKI_SNDCTL_SEQ_TESTMIDI:
5884   case VKI_SNDCTL_SEQ_RESETSAMPLES:
5885   case VKI_SNDCTL_SEQ_NRSYNTHS:
5886   case VKI_SNDCTL_SEQ_NRMIDIS:
5887   case VKI_SNDCTL_SEQ_GETTIME:
5888   case VKI_SNDCTL_DSP_GETBLKSIZE:
5889   case VKI_SNDCTL_DSP_GETFMTS:
5890   case VKI_SNDCTL_DSP_SETFMT:
5891   case VKI_SNDCTL_DSP_GETTRIGGER:
5892   case VKI_SNDCTL_DSP_GETODELAY:
5893   case VKI_SNDCTL_DSP_GETSPDIF:
5894   case VKI_SNDCTL_DSP_GETCAPS:
5895   case VKI_SOUND_PCM_READ_RATE:
5896   case VKI_SOUND_PCM_READ_CHANNELS:
5897   case VKI_SOUND_PCM_READ_BITS:
5898   case VKI_SOUND_PCM_READ_FILTER:
5899      POST_MEM_WRITE(ARG3, sizeof(int));
5900      break;
5901   case VKI_SNDCTL_SEQ_CTRLRATE:
5902   case VKI_SNDCTL_DSP_SPEED:
5903   case VKI_SNDCTL_DSP_STEREO:
5904   case VKI_SNDCTL_DSP_CHANNELS:
5905   case VKI_SOUND_PCM_WRITE_FILTER:
5906   case VKI_SNDCTL_DSP_SUBDIVIDE:
5907   case VKI_SNDCTL_DSP_SETFRAGMENT:
5908   case VKI_SNDCTL_DSP_GETCHANNELMASK:
5909   case VKI_SNDCTL_DSP_BIND_CHANNEL:
5910   case VKI_SNDCTL_TMR_TIMEBASE:
5911   case VKI_SNDCTL_TMR_TEMPO:
5912   case VKI_SNDCTL_TMR_SOURCE:
5913   case VKI_SNDCTL_MIDI_PRETIME:
5914   case VKI_SNDCTL_MIDI_MPUMODE:
5915      break;
5916   case VKI_SNDCTL_DSP_GETOSPACE:
5917   case VKI_SNDCTL_DSP_GETISPACE:
5918      POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
5919      break;
5920   case VKI_SNDCTL_DSP_NONBLOCK:
5921      break;
5922   case VKI_SNDCTL_DSP_SETTRIGGER:
5923      break;
5924
5925   case VKI_SNDCTL_DSP_POST:
5926   case VKI_SNDCTL_DSP_RESET:
5927   case VKI_SNDCTL_DSP_SYNC:
5928   case VKI_SNDCTL_DSP_SETSYNCRO:
5929   case VKI_SNDCTL_DSP_SETDUPLEX:
5930      break;
5931
5932      /* linux/soundcard interface (ALSA) */
5933   case VKI_SNDRV_PCM_IOCTL_HW_FREE:
5934   case VKI_SNDRV_PCM_IOCTL_HWSYNC:
5935   case VKI_SNDRV_PCM_IOCTL_PREPARE:
5936   case VKI_SNDRV_PCM_IOCTL_RESET:
5937   case VKI_SNDRV_PCM_IOCTL_START:
5938   case VKI_SNDRV_PCM_IOCTL_DROP:
5939   case VKI_SNDRV_PCM_IOCTL_DRAIN:
5940   case VKI_SNDRV_PCM_IOCTL_RESUME:
5941   case VKI_SNDRV_PCM_IOCTL_XRUN:
5942   case VKI_SNDRV_PCM_IOCTL_UNLINK:
5943   case VKI_SNDRV_TIMER_IOCTL_START:
5944   case VKI_SNDRV_TIMER_IOCTL_STOP:
5945   case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
5946   case VKI_SNDRV_TIMER_IOCTL_PAUSE:
5947
5948      /* SCSI no operand */
5949   case VKI_SCSI_IOCTL_DOORLOCK:
5950   case VKI_SCSI_IOCTL_DOORUNLOCK:
5951      break;
5952
5953      /* Real Time Clock (/dev/rtc) ioctls */
5954   case VKI_RTC_UIE_ON:
5955   case VKI_RTC_UIE_OFF:
5956   case VKI_RTC_AIE_ON:
5957   case VKI_RTC_AIE_OFF:
5958   case VKI_RTC_PIE_ON:
5959   case VKI_RTC_PIE_OFF:
5960   case VKI_RTC_IRQP_SET:
5961      break;
5962   case VKI_RTC_RD_TIME:
5963   case VKI_RTC_ALM_READ:
5964      POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
5965      break;
5966   case VKI_RTC_ALM_SET:
5967      break;
5968   case VKI_RTC_IRQP_READ:
5969      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
5970      break;
5971
5972      /* Block devices */
5973   case VKI_BLKROSET:
5974      break;
5975   case VKI_BLKROGET:
5976      POST_MEM_WRITE(ARG3, sizeof(int));
5977      break;
5978   case VKI_BLKGETSIZE:
5979      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
5980      break;
5981   case VKI_BLKRASET:
5982      break;
5983   case VKI_BLKRAGET:
5984      POST_MEM_WRITE(ARG3, sizeof(long));
5985      break;
5986   case VKI_BLKFRASET:
5987      break;
5988   case VKI_BLKFRAGET:
5989      POST_MEM_WRITE(ARG3, sizeof(long));
5990      break;
5991   case VKI_BLKSECTGET:
5992      POST_MEM_WRITE(ARG3, sizeof(unsigned short));
5993      break;
5994   case VKI_BLKSSZGET:
5995      POST_MEM_WRITE(ARG3, sizeof(int));
5996      break;
5997   case VKI_BLKBSZGET:
5998      POST_MEM_WRITE(ARG3, sizeof(int));
5999      break;
6000   case VKI_BLKBSZSET:
6001      break;
6002   case VKI_BLKGETSIZE64:
6003      POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
6004      break;
6005
6006      /* Hard disks */
6007   case VKI_HDIO_GETGEO: /* 0x0301 */
6008      POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
6009      break;
6010   case VKI_HDIO_GET_DMA: /* 0x030b */
6011      POST_MEM_WRITE(ARG3, sizeof(long));
6012      break;
6013   case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6014      POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
6015      break;
6016
6017      /* SCSI */
6018   case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6019      POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
6020      break;
6021   case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6022      POST_MEM_WRITE(ARG3, sizeof(int));
6023      break;
6024
6025      /* CD ROM stuff (??)  */
6026   case VKI_CDROMSUBCHNL:
6027      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
6028      break;
6029   case VKI_CDROMREADTOCHDR:
6030      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
6031      break;
6032   case VKI_CDROMREADTOCENTRY:
6033      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
6034      break;
6035   case VKI_CDROMMULTISESSION:
6036      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
6037      break;
6038   case VKI_CDROMVOLREAD:
6039      POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
6040      break;
6041   case VKI_CDROMREADRAW:
6042      POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
6043      break;
6044   case VKI_CDROMREADAUDIO:
6045   {
6046      struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6047      POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
6048      break;
6049   }
6050
6051   case VKI_CDROMPLAYMSF:
6052      break;
6053      /* The following two are probably bogus (should check args
6054	 for readability).  JRS 20021117 */
6055   case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
6056   case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
6057      break;
6058   case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
6059      break;
6060
6061   case VKI_FIGETBSZ:
6062      POST_MEM_WRITE(ARG3, sizeof(unsigned long));
6063      break;
6064   case VKI_FIBMAP:
6065      POST_MEM_WRITE(ARG3, sizeof(int));
6066      break;
6067
6068   case VKI_FBIOGET_VSCREENINFO: //0x4600
6069      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
6070      break;
6071   case VKI_FBIOGET_FSCREENINFO: //0x4602
6072      POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
6073      break;
6074
6075   case VKI_PPCLAIM:
6076   case VKI_PPEXCL:
6077   case VKI_PPYIELD:
6078   case VKI_PPRELEASE:
6079   case VKI_PPSETMODE:
6080   case VKI_PPSETPHASE:
6081   case VKI_PPSETFLAGS:
6082   case VKI_PPWDATA:
6083   case VKI_PPWCONTROL:
6084   case VKI_PPFCONTROL:
6085   case VKI_PPDATADIR:
6086   case VKI_PPNEGOT:
6087   case VKI_PPWCTLONIRQ:
6088   case VKI_PPSETTIME:
6089      break;
6090   case VKI_PPGETMODE:
6091      POST_MEM_WRITE( ARG3, sizeof(int) );
6092      break;
6093   case VKI_PPGETPHASE:
6094      POST_MEM_WRITE( ARG3, sizeof(int) );
6095      break;
6096   case VKI_PPGETMODES:
6097      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
6098      break;
6099   case VKI_PPGETFLAGS:
6100      POST_MEM_WRITE( ARG3, sizeof(int) );
6101      break;
6102   case VKI_PPRSTATUS:
6103      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6104      break;
6105   case VKI_PPRDATA:
6106      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6107      break;
6108   case VKI_PPRCONTROL:
6109      POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
6110      break;
6111   case VKI_PPCLRIRQ:
6112      POST_MEM_WRITE( ARG3, sizeof(int) );
6113      break;
6114   case VKI_PPGETTIME:
6115      POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
6116      break;
6117
6118   case VKI_GIO_FONT:
6119      POST_MEM_WRITE( ARG3, 32 * 256 );
6120      break;
6121   case VKI_PIO_FONT:
6122      break;
6123
6124   case VKI_GIO_FONTX:
6125      POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
6126                      32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
6127      break;
6128   case VKI_PIO_FONTX:
6129      break;
6130
6131   case VKI_PIO_FONTRESET:
6132      break;
6133
6134   case VKI_GIO_CMAP:
6135      POST_MEM_WRITE( ARG3, 16 * 3 );
6136      break;
6137   case VKI_PIO_CMAP:
6138      break;
6139
6140   case VKI_KIOCSOUND:
6141   case VKI_KDMKTONE:
6142      break;
6143
6144   case VKI_KDGETLED:
6145      POST_MEM_WRITE( ARG3, sizeof(char) );
6146      break;
6147   case VKI_KDSETLED:
6148      break;
6149
6150   case VKI_KDGKBTYPE:
6151      POST_MEM_WRITE( ARG3, sizeof(char) );
6152      break;
6153
6154   case VKI_KDADDIO:
6155   case VKI_KDDELIO:
6156   case VKI_KDENABIO:
6157   case VKI_KDDISABIO:
6158      break;
6159
6160   case VKI_KDSETMODE:
6161      break;
6162   case VKI_KDGETMODE:
6163      POST_MEM_WRITE( ARG3, sizeof(int) );
6164      break;
6165
6166   case VKI_KDMAPDISP:
6167   case VKI_KDUNMAPDISP:
6168      break;
6169
6170   case VKI_GIO_SCRNMAP:
6171      POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
6172      break;
6173   case VKI_PIO_SCRNMAP:
6174      break;
6175   case VKI_GIO_UNISCRNMAP:
6176      POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
6177      break;
6178   case VKI_PIO_UNISCRNMAP:
6179      break;
6180
6181   case VKI_GIO_UNIMAP:
6182      if ( ARG3 ) {
6183         struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6184         POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
6185         POST_MEM_WRITE( (Addr)desc->entries,
6186      	                 desc->entry_ct * sizeof(struct vki_unipair) );
6187      }
6188      break;
6189   case VKI_PIO_UNIMAP:
6190      break;
6191   case VKI_PIO_UNIMAPCLR:
6192      break;
6193
6194   case VKI_KDGKBMODE:
6195      POST_MEM_WRITE( ARG3, sizeof(int) );
6196      break;
6197   case VKI_KDSKBMODE:
6198      break;
6199
6200   case VKI_KDGKBMETA:
6201      POST_MEM_WRITE( ARG3, sizeof(int) );
6202      break;
6203   case VKI_KDSKBMETA:
6204      break;
6205
6206   case VKI_KDGKBLED:
6207      POST_MEM_WRITE( ARG3, sizeof(char) );
6208      break;
6209   case VKI_KDSKBLED:
6210      break;
6211
6212   case VKI_KDGKBENT:
6213      POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6214                      sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6215      break;
6216   case VKI_KDSKBENT:
6217      break;
6218
6219   case VKI_KDGKBSENT:
6220      POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
6221                      sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
6222      break;
6223   case VKI_KDSKBSENT:
6224      break;
6225
6226   case VKI_KDGKBDIACR:
6227      POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
6228      break;
6229   case VKI_KDSKBDIACR:
6230      break;
6231
6232   case VKI_KDGETKEYCODE:
6233      POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6234                      sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6235      break;
6236   case VKI_KDSETKEYCODE:
6237      break;
6238
6239   case VKI_KDSIGACCEPT:
6240      break;
6241
6242   case VKI_KDKBDREP:
6243      break;
6244
6245   case VKI_KDFONTOP:
6246      if ( ARG3 ) {
6247         struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
6248         switch ( op->op ) {
6249            case VKI_KD_FONT_OP_SET:
6250               break;
6251            case VKI_KD_FONT_OP_GET:
6252               if ( op->data )
6253                  POST_MEM_WRITE( (Addr) op->data,
6254                                  (op->width + 7) / 8 * 32 * op->charcount );
6255               break;
6256            case VKI_KD_FONT_OP_SET_DEFAULT:
6257               break;
6258            case VKI_KD_FONT_OP_COPY:
6259               break;
6260         }
6261         POST_MEM_WRITE( (Addr) op, sizeof(*op));
6262      }
6263      break;
6264
6265   case VKI_VT_OPENQRY:
6266      POST_MEM_WRITE( ARG3, sizeof(int) );
6267      break;
6268   case VKI_VT_GETMODE:
6269      POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
6270      break;
6271   case VKI_VT_SETMODE:
6272      break;
6273   case VKI_VT_GETSTATE:
6274      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
6275                      sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
6276      POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
6277                      sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
6278      break;
6279   case VKI_VT_RELDISP:
6280   case VKI_VT_ACTIVATE:
6281   case VKI_VT_WAITACTIVE:
6282   case VKI_VT_DISALLOCATE:
6283      break;
6284   case VKI_VT_RESIZE:
6285      break;
6286   case VKI_VT_RESIZEX:
6287      break;
6288   case VKI_VT_LOCKSWITCH:
6289   case VKI_VT_UNLOCKSWITCH:
6290      break;
6291
6292   case VKI_USBDEVFS_CONTROL:
6293      if ( ARG3 ) {
6294         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
6295         if (vkuc->bRequestType & 0x80)
6296            POST_MEM_WRITE((Addr)vkuc->data, RES);
6297      }
6298      break;
6299   case VKI_USBDEVFS_BULK:
6300      if ( ARG3 ) {
6301         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
6302         if (vkub->ep & 0x80)
6303            POST_MEM_WRITE((Addr)vkub->data, RES);
6304      }
6305      break;
6306   case VKI_USBDEVFS_GETDRIVER:
6307      if ( ARG3 ) {
6308         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
6309         POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
6310      }
6311      break;
6312   case VKI_USBDEVFS_REAPURB:
6313   case VKI_USBDEVFS_REAPURBNDELAY:
6314      if ( ARG3 ) {
6315         struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
6316         POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
6317         if (!*vkuu)
6318            break;
6319         POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
6320         if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
6321            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
6322            if (vkusp->bRequestType & 0x80)
6323               POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
6324            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
6325         } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
6326            char *bp = (*vkuu)->buffer;
6327            int i;
6328            for(i=0; i<(*vkuu)->number_of_packets; i++) {
6329               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
6330               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
6331               if ((*vkuu)->endpoint & 0x80)
6332                  POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
6333               bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
6334            }
6335            POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
6336         } else {
6337            if ((*vkuu)->endpoint & 0x80)
6338               POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
6339            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
6340         }
6341      }
6342      break;
6343   case VKI_USBDEVFS_CONNECTINFO:
6344      POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
6345      break;
6346   case VKI_USBDEVFS_IOCTL:
6347      if ( ARG3 ) {
6348         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
6349         UInt dir2, size2;
6350         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
6351         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
6352         if (size2 > 0) {
6353            if (dir2 & _VKI_IOC_READ)
6354               POST_MEM_WRITE((Addr)vkui->data, size2);
6355         }
6356      }
6357      break;
6358
6359      /* I2C (/dev/i2c-*) ioctls */
6360   case VKI_I2C_SLAVE:
6361   case VKI_I2C_SLAVE_FORCE:
6362   case VKI_I2C_TENBIT:
6363   case VKI_I2C_PEC:
6364      break;
6365   case VKI_I2C_FUNCS:
6366      POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
6367      break;
6368   case VKI_I2C_RDWR:
6369      if ( ARG3 ) {
6370          struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
6371          UInt i;
6372          for (i=0; i < vkui->nmsgs; i++) {
6373              struct vki_i2c_msg *msg = vkui->msgs + i;
6374              if (msg->flags & VKI_I2C_M_RD)
6375                  POST_MEM_WRITE((Addr)msg->buf, msg->len);
6376          }
6377      }
6378      break;
6379
6380      /* Wireless extensions ioctls */
6381   case VKI_SIOCSIWCOMMIT:
6382   case VKI_SIOCSIWNWID:
6383   case VKI_SIOCSIWFREQ:
6384   case VKI_SIOCSIWMODE:
6385   case VKI_SIOCSIWSENS:
6386   case VKI_SIOCSIWRANGE:
6387   case VKI_SIOCSIWPRIV:
6388   case VKI_SIOCSIWSTATS:
6389   case VKI_SIOCSIWSPY:
6390   case VKI_SIOCSIWTHRSPY:
6391   case VKI_SIOCSIWAP:
6392   case VKI_SIOCSIWSCAN:
6393   case VKI_SIOCSIWESSID:
6394   case VKI_SIOCSIWRATE:
6395   case VKI_SIOCSIWNICKN:
6396   case VKI_SIOCSIWRTS:
6397   case VKI_SIOCSIWFRAG:
6398   case VKI_SIOCSIWTXPOW:
6399   case VKI_SIOCSIWRETRY:
6400   case VKI_SIOCSIWENCODE:
6401   case VKI_SIOCSIWPOWER:
6402   case VKI_SIOCSIWGENIE:
6403   case VKI_SIOCSIWMLME:
6404   case VKI_SIOCSIWAUTH:
6405   case VKI_SIOCSIWENCODEEXT:
6406   case VKI_SIOCSIWPMKSA:
6407      break;
6408   case VKI_SIOCGIWNAME:
6409      if (ARG3) {
6410         POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
6411                        sizeof(((struct vki_iwreq *)ARG3)->u.name));
6412      }
6413      break;
6414   case VKI_SIOCGIWNWID:
6415   case VKI_SIOCGIWSENS:
6416   case VKI_SIOCGIWRATE:
6417   case VKI_SIOCGIWRTS:
6418   case VKI_SIOCGIWFRAG:
6419   case VKI_SIOCGIWTXPOW:
6420   case VKI_SIOCGIWRETRY:
6421   case VKI_SIOCGIWPOWER:
6422   case VKI_SIOCGIWAUTH:
6423      if (ARG3) {
6424         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
6425                        sizeof(struct vki_iw_param));
6426      }
6427      break;
6428   case VKI_SIOCGIWFREQ:
6429      if (ARG3) {
6430         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
6431                        sizeof(struct vki_iw_freq));
6432      }
6433      break;
6434   case VKI_SIOCGIWMODE:
6435      if (ARG3) {
6436         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
6437                       sizeof(__vki_u32));
6438      }
6439      break;
6440   case VKI_SIOCGIWRANGE:
6441   case VKI_SIOCGIWPRIV:
6442   case VKI_SIOCGIWSTATS:
6443   case VKI_SIOCGIWSPY:
6444   case VKI_SIOCGIWTHRSPY:
6445   case VKI_SIOCGIWAPLIST:
6446   case VKI_SIOCGIWSCAN:
6447   case VKI_SIOCGIWESSID:
6448   case VKI_SIOCGIWNICKN:
6449   case VKI_SIOCGIWENCODE:
6450   case VKI_SIOCGIWGENIE:
6451   case VKI_SIOCGIWENCODEEXT:
6452      if (ARG3) {
6453         struct vki_iw_point* point;
6454         point = &((struct vki_iwreq *)ARG3)->u.data;
6455         POST_MEM_WRITE((Addr)point->pointer, point->length);
6456      }
6457      break;
6458   case VKI_SIOCGIWAP:
6459      if (ARG3) {
6460         POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
6461                        sizeof(struct vki_sockaddr));
6462      }
6463      break;
6464
6465#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
6466   /* ashmem */
6467   case VKI_ASHMEM_GET_SIZE:
6468   case VKI_ASHMEM_SET_SIZE:
6469   case VKI_ASHMEM_GET_PROT_MASK:
6470   case VKI_ASHMEM_SET_PROT_MASK:
6471   case VKI_ASHMEM_GET_PIN_STATUS:
6472   case VKI_ASHMEM_PURGE_ALL_CACHES:
6473   case VKI_ASHMEM_SET_NAME:
6474   case VKI_ASHMEM_PIN:
6475   case VKI_ASHMEM_UNPIN:
6476       break;
6477   case VKI_ASHMEM_GET_NAME:
6478       POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
6479       break;
6480
6481   /* binder */
6482   case VKI_BINDER_WRITE_READ:
6483       if (ARG3) {
6484           struct vki_binder_write_read* bwr
6485              = (struct vki_binder_write_read*)ARG3;
6486           POST_FIELD_WRITE(bwr->write_consumed);
6487           POST_FIELD_WRITE(bwr->read_consumed);
6488
6489           if (bwr->read_size)
6490               POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
6491       }
6492       break;
6493
6494   case VKI_BINDER_SET_IDLE_TIMEOUT:
6495   case VKI_BINDER_SET_MAX_THREADS:
6496   case VKI_BINDER_SET_IDLE_PRIORITY:
6497   case VKI_BINDER_SET_CONTEXT_MGR:
6498   case VKI_BINDER_THREAD_EXIT:
6499       break;
6500   case VKI_BINDER_VERSION:
6501       if (ARG3) {
6502           struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
6503           POST_FIELD_WRITE(bv->protocol_version);
6504       }
6505       break;
6506#  endif /* defined(VGPV_*_linux_android) */
6507
6508   case VKI_HCIINQUIRY:
6509      if (ARG3) {
6510        struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
6511        POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
6512                       ir->num_rsp * sizeof(struct vki_inquiry_info));
6513      }
6514      break;
6515
6516   /* KVM ioctls that only write the system call return value */
6517   case VKI_KVM_GET_API_VERSION:
6518   case VKI_KVM_CREATE_VM:
6519   case VKI_KVM_CHECK_EXTENSION:
6520   case VKI_KVM_GET_VCPU_MMAP_SIZE:
6521   case VKI_KVM_S390_ENABLE_SIE:
6522   case VKI_KVM_CREATE_VCPU:
6523   case VKI_KVM_RUN:
6524   case VKI_KVM_S390_INITIAL_RESET:
6525      break;
6526
6527   default:
6528      /* EVIOC* are variable length and return size written on success */
6529      switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
6530      case VKI_EVIOCGNAME(0):
6531      case VKI_EVIOCGPHYS(0):
6532      case VKI_EVIOCGUNIQ(0):
6533      case VKI_EVIOCGKEY(0):
6534      case VKI_EVIOCGLED(0):
6535      case VKI_EVIOCGSND(0):
6536      case VKI_EVIOCGSW(0):
6537      case VKI_EVIOCGBIT(VKI_EV_SYN,0):
6538      case VKI_EVIOCGBIT(VKI_EV_KEY,0):
6539      case VKI_EVIOCGBIT(VKI_EV_REL,0):
6540      case VKI_EVIOCGBIT(VKI_EV_ABS,0):
6541      case VKI_EVIOCGBIT(VKI_EV_MSC,0):
6542      case VKI_EVIOCGBIT(VKI_EV_SW,0):
6543      case VKI_EVIOCGBIT(VKI_EV_LED,0):
6544      case VKI_EVIOCGBIT(VKI_EV_SND,0):
6545      case VKI_EVIOCGBIT(VKI_EV_REP,0):
6546      case VKI_EVIOCGBIT(VKI_EV_FF,0):
6547      case VKI_EVIOCGBIT(VKI_EV_PWR,0):
6548      case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
6549         if (RES > 0)
6550            POST_MEM_WRITE(ARG3, RES);
6551         break;
6552      default:
6553         ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
6554         break;
6555      }
6556      break;
6557   }
6558}
6559
6560/* ---------------------------------------------------------------------
6561   socketcall wrapper helpers
6562   ------------------------------------------------------------------ */
6563
6564void
6565ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
6566                                UWord arg0, UWord arg1, UWord arg2,
6567                                UWord arg3, UWord arg4 )
6568{
6569   /* int getsockopt(int s, int level, int optname,
6570                     void *optval, socklen_t *optlen); */
6571   Addr optval_p = arg3;
6572   Addr optlen_p = arg4;
6573   /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
6574   if (optval_p != (Addr)NULL) {
6575      ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
6576                                   "socketcall.getsockopt(optval)",
6577                                   "socketcall.getsockopt(optlen)" );
6578      if (arg1 == VKI_SOL_SCTP &&
6579          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
6580           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
6581      {
6582         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
6583         int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
6584         PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
6585                        (Addr)ga->addrs, address_bytes );
6586      }
6587   }
6588}
6589
6590void
6591ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
6592                                 SysRes res,
6593                                 UWord arg0, UWord arg1, UWord arg2,
6594                                 UWord arg3, UWord arg4 )
6595{
6596   Addr optval_p = arg3;
6597   Addr optlen_p = arg4;
6598   vg_assert(!sr_isError(res)); /* guaranteed by caller */
6599   if (optval_p != (Addr)NULL) {
6600      ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
6601                                    "socketcall.getsockopt(optlen_out)" );
6602      if (arg1 == VKI_SOL_SCTP &&
6603          (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
6604           arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
6605      {
6606         struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
6607         struct vki_sockaddr *a = ga->addrs;
6608         int i;
6609         for (i = 0; i < ga->addr_num; i++) {
6610            int sl = 0;
6611            if (a->sa_family == VKI_AF_INET)
6612               sl = sizeof(struct vki_sockaddr_in);
6613            else if (a->sa_family == VKI_AF_INET6)
6614               sl = sizeof(struct vki_sockaddr_in6);
6615            else {
6616               VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
6617                                        "address type %d\n", a->sa_family);
6618            }
6619            a = (struct vki_sockaddr*)((char*)a + sl);
6620         }
6621         POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
6622      }
6623   }
6624}
6625
6626#undef PRE
6627#undef POST
6628
6629#endif // defined(VGO_linux)
6630
6631/*--------------------------------------------------------------------*/
6632/*--- end                                                          ---*/
6633/*--------------------------------------------------------------------*/
6634