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