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