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