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-2017 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_machine.h"      // VG_(get_SP)
50 #include "pub_core_mallocfree.h"
51 #include "pub_core_tooliface.h"
52 #include "pub_core_options.h"
53 #include "pub_core_scheduler.h"
54 #include "pub_core_signals.h"
55 #include "pub_core_stacks.h"
56 #include "pub_core_syscall.h"
57 #include "pub_core_syswrap.h"
58 #include "pub_core_inner.h"
59 #if defined(ENABLE_INNER_CLIENT_REQUEST)
60 #include "pub_core_clreq.h"
61 #endif
62 
63 #include "priv_types_n_macros.h"
64 #include "priv_syswrap-generic.h"
65 #include "priv_syswrap-linux.h"
66 #include "priv_syswrap-main.h"
67 #include "priv_syswrap-xen.h"
68 
69 // Run a thread from beginning to end and return the thread's
70 // scheduler-return-code.
thread_wrapper(Word tidW)71 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
72 {
73    VgSchedReturnCode ret;
74    ThreadId     tid = (ThreadId)tidW;
75    ThreadState* tst = VG_(get_ThreadState)(tid);
76 
77    VG_(debugLog)(1, "syswrap-linux",
78                     "thread_wrapper(tid=%u): entry\n",
79                     tid);
80 
81    vg_assert(tst->status == VgTs_Init);
82 
83    /* make sure we get the CPU lock before doing anything significant */
84    VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
85 
86    if (0)
87       VG_(printf)("thread tid %u started: stack = %p\n",
88 		  tid, (void *)&tid);
89 
90    /* Make sure error reporting is enabled in the new thread. */
91    tst->err_disablement_level = 0;
92 
93    VG_TRACK(pre_thread_first_insn, tid);
94 
95    tst->os_state.lwpid = VG_(gettid)();
96    /* Set the threadgroup for real.  This overwrites the provisional value set
97       in do_clone().  See comments in do_clone for background, also #226116. */
98    tst->os_state.threadgroup = VG_(getpid)();
99 
100    /* Thread created with all signals blocked; scheduler will set the
101       appropriate mask */
102 
103    ret = VG_(scheduler)(tid);
104 
105    vg_assert(VG_(is_exiting)(tid));
106 
107    vg_assert(tst->status == VgTs_Runnable);
108    vg_assert(VG_(is_running_thread)(tid));
109 
110    VG_(debugLog)(1, "syswrap-linux",
111                     "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
112                     tid, VG_(name_of_VgSchedReturnCode)(ret));
113 
114    /* Return to caller, still holding the lock. */
115    return ret;
116 }
117 
118 
119 /* ---------------------------------------------------------------------
120    clone-related stuff
121    ------------------------------------------------------------------ */
122 
123 /* Run a thread all the way to the end, then do appropriate exit actions
124    (this is the last-one-out-turn-off-the-lights bit).  */
run_a_thread_NORETURN(Word tidW)125 static void run_a_thread_NORETURN ( Word tidW )
126 {
127    ThreadId          tid = (ThreadId)tidW;
128    VgSchedReturnCode src;
129    Int               c;
130    ThreadState*      tst;
131 #ifdef ENABLE_INNER_CLIENT_REQUEST
132    Int               registered_vgstack_id;
133 #endif
134 
135    VG_(debugLog)(1, "syswrap-linux",
136                     "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
137                     tid);
138 
139    tst = VG_(get_ThreadState)(tid);
140    vg_assert(tst);
141 
142    /* An thread has two stacks:
143       * the simulated stack (used by the synthetic cpu. Guest process
144         is using this stack).
145       * the valgrind stack (used by the real cpu. Valgrind code is running
146         on this stack).
147       When Valgrind runs as an inner, it must signals that its (real) stack
148       is the stack to use by the outer to e.g. do stacktraces.
149    */
150    INNER_REQUEST
151       (registered_vgstack_id
152        = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
153                                   tst->os_state.valgrind_stack_init_SP));
154 
155    /* Run the thread all the way through. */
156    src = thread_wrapper(tid);
157 
158    VG_(debugLog)(1, "syswrap-linux",
159                     "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
160                     tid);
161 
162    c = VG_(count_living_threads)();
163    vg_assert(c >= 1); /* stay sane */
164 
165    /* Deregister thread's stack. */
166    if (tst->os_state.stk_id != NULL_STK_ID)
167       VG_(deregister_stack)(tst->os_state.stk_id);
168 
169    // Tell the tool this thread is exiting
170    VG_TRACK( pre_thread_ll_exit, tid );
171 
172    /* If the thread is exiting with errors disabled, complain loudly;
173       doing so is bad (does the user know this has happened?)  Also,
174       in all cases, be paranoid and clear the flag anyway so that the
175       thread slot is safe in this respect if later reallocated.  This
176       should be unnecessary since the flag should be cleared when the
177       slot is reallocated, in thread_wrapper(). */
178    if (tst->err_disablement_level > 0) {
179       VG_(umsg)(
180          "WARNING: exiting thread has error reporting disabled.\n"
181          "WARNING: possibly as a result of some mistake in the use\n"
182          "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
183       );
184       VG_(debugLog)(
185          1, "syswrap-linux",
186             "run_a_thread_NORETURN(tid=%u): "
187             "WARNING: exiting thread has err_disablement_level = %u\n",
188             tid, tst->err_disablement_level
189       );
190    }
191    tst->err_disablement_level = 0;
192 
193    if (c == 1) {
194 
195       VG_(debugLog)(1, "syswrap-linux",
196                        "run_a_thread_NORETURN(tid=%u): "
197                           "last one standing\n",
198                           tid);
199 
200       /* We are the last one standing.  Keep hold of the lock and
201          carry on to show final tool results, then exit the entire system.
202          Use the continuation pointer set at startup in m_main. */
203       ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
204    } else {
205 
206       VG_(debugLog)(1, "syswrap-linux",
207                        "run_a_thread_NORETURN(tid=%u): "
208                           "not last one standing\n",
209                           tid);
210 
211       /* OK, thread is dead, but others still exist.  Just exit. */
212 
213       /* This releases the run lock */
214       VG_(exit_thread)(tid);
215       vg_assert(tst->status == VgTs_Zombie);
216       vg_assert(sizeof(tst->status) == 4);
217       vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
218 
219       INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
220 
221       /* We have to use this sequence to terminate the thread to
222          prevent a subtle race.  If VG_(exit_thread)() had left the
223          ThreadState as Empty, then it could have been reallocated,
224          reusing the stack while we're doing these last cleanups.
225          Instead, VG_(exit_thread) leaves it as Zombie to prevent
226          reallocation.  We need to make sure we don't touch the stack
227          between marking it Empty and exiting.  Hence the
228          assembler. */
229 #if defined(VGP_x86_linux)
230       asm volatile (
231          "pushl %%ebx\n"
232          "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
233          "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
234          "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
235          "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
236 	 "popl %%ebx\n"
237          : "=m" (tst->status)
238          : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
239          : "eax"
240       );
241 #elif defined(VGP_amd64_linux)
242       asm volatile (
243          "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
244          "movq	%2, %%rax\n"    /* set %rax = __NR_exit */
245          "movq	%3, %%rdi\n"    /* set %rdi = tst->os_state.exitcode */
246          "syscall\n"		/* exit(tst->os_state.exitcode) */
247          : "=m" (tst->status)
248          : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
249          : "rax", "rdi"
250       );
251 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
252       || defined(VGP_ppc64le_linux)
253       { UInt vgts_empty = (UInt)VgTs_Empty;
254         asm volatile (
255           "stw %1,%0\n\t"          /* set tst->status = VgTs_Empty */
256           "li  0,%2\n\t"           /* set r0 = __NR_exit */
257           "lwz 3,%3\n\t"           /* set r3 = tst->os_state.exitcode */
258           "sc\n\t"                 /* exit(tst->os_state.exitcode) */
259           : "=m" (tst->status)
260           : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
261           : "r0", "r3"
262         );
263       }
264 #elif defined(VGP_arm_linux)
265       asm volatile (
266          "str  %1, %0\n"      /* set tst->status = VgTs_Empty */
267          "mov  r7, %2\n"      /* set %r7 = __NR_exit */
268          "ldr  r0, %3\n"      /* set %r0 = tst->os_state.exitcode */
269          "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
270          : "=m" (tst->status)
271          : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
272          : "r0", "r7"
273       );
274 #elif defined(VGP_arm64_linux)
275       asm volatile (
276          "str  %w1, %0\n"     /* set tst->status = VgTs_Empty (32-bit store) */
277          "mov  x8,  %2\n"     /* set %x8 = __NR_exit */
278          "ldr  x0,  %3\n"     /* set %x0 = tst->os_state.exitcode */
279          "svc  0x00000000\n"  /* exit(tst->os_state.exitcode) */
280          : "=m" (tst->status)
281          : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
282          : "x0", "x8"
283       );
284 #elif defined(VGP_s390x_linux)
285       asm volatile (
286          "st   %1, %0\n"        /* set tst->status = VgTs_Empty */
287          "lg   2, %3\n"         /* set r2 = tst->os_state.exitcode */
288          "svc %2\n"             /* exit(tst->os_state.exitcode) */
289          : "=m" (tst->status)
290          : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
291          : "2"
292       );
293 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
294       asm volatile (
295          "sw   %1, %0\n\t"     /* set tst->status = VgTs_Empty */
296          "li   $2, %2\n\t"     /* set v0 = __NR_exit */
297          "lw   $4, %3\n\t"     /* set a0 = tst->os_state.exitcode */
298          "syscall\n\t"         /* exit(tst->os_state.exitcode) */
299          "nop"
300          : "=m" (tst->status)
301          : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
302          : "cc", "memory" , "v0", "a0"
303       );
304 #else
305 # error Unknown platform
306 #endif
307 
308       VG_(core_panic)("Thread exit failed?\n");
309    }
310 
311    /*NOTREACHED*/
312    vg_assert(0);
313 }
314 
ML_(start_thread_NORETURN)315 Word ML_(start_thread_NORETURN) ( void* arg )
316 {
317    ThreadState* tst = (ThreadState*)arg;
318    ThreadId     tid = tst->tid;
319 
320    run_a_thread_NORETURN ( (Word)tid );
321    /*NOTREACHED*/
322    vg_assert(0);
323 }
324 
325 /* Allocate a stack for this thread, if it doesn't already have one.
326    They're allocated lazily, and never freed.  Returns the initial stack
327    pointer value to use, or 0 if allocation failed. */
ML_(allocstack)328 Addr ML_(allocstack)(ThreadId tid)
329 {
330    ThreadState* tst = VG_(get_ThreadState)(tid);
331    VgStack*     stack;
332    Addr         initial_SP;
333 
334    /* Either the stack_base and stack_init_SP are both zero (in which
335       case a stack hasn't been allocated) or they are both non-zero,
336       in which case it has. */
337 
338    if (tst->os_state.valgrind_stack_base == 0)
339       vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
340 
341    if (tst->os_state.valgrind_stack_base != 0)
342       vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
343 
344    /* If no stack is present, allocate one. */
345 
346    if (tst->os_state.valgrind_stack_base == 0) {
347       stack = VG_(am_alloc_VgStack)( &initial_SP );
348       if (stack) {
349          tst->os_state.valgrind_stack_base    = (Addr)stack;
350          tst->os_state.valgrind_stack_init_SP = initial_SP;
351       }
352    }
353 
354    if (0)
355       VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
356                    tid,
357                    (void*)tst->os_state.valgrind_stack_base,
358                    (void*)tst->os_state.valgrind_stack_init_SP );
359 
360    return tst->os_state.valgrind_stack_init_SP;
361 }
362 
363 /* Allocate a stack for the main thread, and run it all the way to the
364    end.  Although we already have a working VgStack
365    (VG_(interim_stack)) it's better to allocate a new one, so that
366    overflow detection works uniformly for all threads.
367 */
VG_(main_thread_wrapper_NORETURN)368 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
369 {
370    Addr sp;
371    VG_(debugLog)(1, "syswrap-linux",
372                     "entering VG_(main_thread_wrapper_NORETURN)\n");
373 
374    sp = ML_(allocstack)(tid);
375 #if defined(ENABLE_INNER_CLIENT_REQUEST)
376    {
377       // we must register the main thread stack before the call
378       // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
379       // reports 'write error' on the non registered stack.
380       ThreadState* tst = VG_(get_ThreadState)(tid);
381       INNER_REQUEST
382          ((void)
383           VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
384                                    tst->os_state.valgrind_stack_init_SP));
385    }
386 #endif
387 
388 #if defined(VGP_ppc32_linux)
389    /* make a stack frame */
390    sp -= 16;
391    sp &= ~0xF;
392    *(UWord *)sp = 0;
393 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
394    /* make a stack frame */
395    sp -= 112;
396    sp &= ~((Addr)0xF);
397    *(UWord *)sp = 0;
398 #elif defined(VGP_s390x_linux)
399    /* make a stack frame */
400    sp -= 160;
401    sp &= ~((Addr)0xF);
402    *(UWord *)sp = 0;
403 #endif
404 
405    /* If we can't even allocate the first thread's stack, we're hosed.
406       Give up. */
407    vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
408 
409    /* shouldn't be any other threads around yet */
410    vg_assert( VG_(count_living_threads)() == 1 );
411 
412    ML_(call_on_new_stack_0_1)(
413       (Addr)sp,               /* stack */
414       0,                      /* bogus return address */
415       run_a_thread_NORETURN,  /* fn to call */
416       (Word)tid               /* arg to give it */
417    );
418 
419    /*NOTREACHED*/
420    vg_assert(0);
421 }
422 
423 /* Clone a new thread. Note that in the clone syscalls, we hard-code
424    tlsaddr argument as NULL : the guest TLS is emulated via guest
425    registers, and Valgrind itself has no thread local storage. */
clone_new_thread(Word (* fn)(void *),void * stack,Word flags,ThreadState * ctst,Int * child_tidptr,Int * parent_tidptr)426 static SysRes clone_new_thread ( Word (*fn)(void *),
427                                  void* stack,
428                                  Word  flags,
429                                  ThreadState* ctst,
430                                  Int* child_tidptr,
431                                  Int* parent_tidptr)
432 {
433    SysRes res;
434    /* Note that in all the below, we make sys_clone appear to have returned
435       Success(0) in the child, by assigning the relevant child guest
436       register(s) just before the clone syscall. */
437 #if defined(VGP_x86_linux)
438    Int          eax;
439    ctst->arch.vex.guest_EAX = 0;
440    eax = do_syscall_clone_x86_linux
441       (ML_(start_thread_NORETURN), stack, flags, ctst,
442        child_tidptr, parent_tidptr, NULL);
443    res = VG_(mk_SysRes_x86_linux)( eax );
444 #elif defined(VGP_amd64_linux)
445    Long         rax;
446    ctst->arch.vex.guest_RAX = 0;
447    rax = do_syscall_clone_amd64_linux
448       (ML_(start_thread_NORETURN), stack, flags, ctst,
449        child_tidptr, parent_tidptr, NULL);
450    res = VG_(mk_SysRes_amd64_linux)( rax );
451 #elif defined(VGP_ppc32_linux)
452    ULong        word64;
453    UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
454    /* %r3 = 0 */
455    ctst->arch.vex.guest_GPR3 = 0;
456    /* %cr0.so = 0 */
457    LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
458    word64 = do_syscall_clone_ppc32_linux
459       (ML_(start_thread_NORETURN), stack, flags, ctst,
460        child_tidptr, parent_tidptr, NULL);
461    /* High half word64 is syscall return value.  Low half is
462       the entire CR, from which we need to extract CR0.SO. */
463    /* VG_(printf)("word64 = 0x%llx\n", word64); */
464    res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
465                                     /*errflag*/ (((UInt)word64) >> 28) & 1);
466 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
467    ULong        word64;
468    UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
469    /* %r3 = 0 */
470    ctst->arch.vex.guest_GPR3 = 0;
471    /* %cr0.so = 0 */
472    LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
473    word64 = do_syscall_clone_ppc64_linux
474       (ML_(start_thread_NORETURN), stack, flags, ctst,
475        child_tidptr, parent_tidptr, NULL);
476    /* Low half word64 is syscall return value.  Hi half is
477       the entire CR, from which we need to extract CR0.SO. */
478    /* VG_(printf)("word64 = 0x%llx\n", word64); */
479    res = VG_(mk_SysRes_ppc64_linux)
480       (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
481        /*errflag*/ (UInt)((word64 >> (32+28)) & 1));
482 #elif defined(VGP_s390x_linux)
483    ULong        r2;
484    ctst->arch.vex.guest_r2 = 0;
485    r2 = do_syscall_clone_s390x_linux
486       (stack, flags, parent_tidptr, child_tidptr, NULL,
487        ML_(start_thread_NORETURN), ctst);
488    res = VG_(mk_SysRes_s390x_linux)( r2 );
489 #elif defined(VGP_arm64_linux)
490    ULong        x0;
491    ctst->arch.vex.guest_X0 = 0;
492    x0 = do_syscall_clone_arm64_linux
493       (ML_(start_thread_NORETURN), stack, flags, ctst,
494        child_tidptr, parent_tidptr, NULL);
495    res = VG_(mk_SysRes_arm64_linux)( x0 );
496 #elif defined(VGP_arm_linux)
497    UInt r0;
498    ctst->arch.vex.guest_R0 = 0;
499    r0 = do_syscall_clone_arm_linux
500       (ML_(start_thread_NORETURN), stack, flags, ctst,
501        child_tidptr, parent_tidptr, NULL);
502    res = VG_(mk_SysRes_arm_linux)( r0 );
503 #elif defined(VGP_mips64_linux)
504    UInt ret = 0;
505    ctst->arch.vex.guest_r2 = 0;
506    ctst->arch.vex.guest_r7 = 0;
507    ret = do_syscall_clone_mips64_linux
508       (ML_(start_thread_NORETURN), stack, flags, ctst,
509        parent_tidptr, NULL, child_tidptr);
510    res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
511 #elif defined(VGP_mips32_linux)
512    UInt ret = 0;
513    ctst->arch.vex.guest_r2 = 0;
514    ctst->arch.vex.guest_r7 = 0;
515    ret = do_syscall_clone_mips_linux
516       (ML_(start_thread_NORETURN), stack, flags, ctst,
517        child_tidptr, parent_tidptr, NULL);
518    /* High half word64 is syscall return value.  Low half is
519       the entire CR, from which we need to extract CR0.SO. */
520    res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
521 #else
522 # error Unknown platform
523 #endif
524    return res;
525 }
526 
setup_child(ThreadArchState * child,ThreadArchState * parent)527 static void setup_child ( /*OUT*/ ThreadArchState *child,
528                           /*IN*/  ThreadArchState *parent )
529 {
530    /* We inherit our parent's guest state. */
531    child->vex = parent->vex;
532    child->vex_shadow1 = parent->vex_shadow1;
533    child->vex_shadow2 = parent->vex_shadow2;
534 
535 #if defined(VGP_x86_linux)
536    extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
537                                         /*IN*/  ThreadArchState *parent );
538    ML_(x86_setup_LDT_GDT)(child, parent);
539 #endif
540 }
541 
setup_child_tls(ThreadId ctid,Addr tlsaddr)542 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
543 {
544    static const Bool debug = False;
545    ThreadState* ctst = VG_(get_ThreadState)(ctid);
546    // res is succesful by default, overriden if a real syscall is needed/done.
547    SysRes res = VG_(mk_SysRes_Success)(0);
548 
549    if (debug)
550       VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
551 
552 #if defined(VGP_x86_linux)
553    vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
554    if (debug)
555       VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
556                   "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
557                   tlsinfo, tlsinfo->entry_number,
558                   tlsinfo->base_addr, tlsinfo->limit,
559                   ctst->arch.vex.guest_ESP,
560                   ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
561    res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
562 #elif defined(VGP_amd64_linux)
563    ctst->arch.vex.guest_FS_CONST = tlsaddr;
564 #elif defined(VGP_ppc32_linux)
565    ctst->arch.vex.guest_GPR2 = tlsaddr;
566 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
567    ctst->arch.vex.guest_GPR13 = tlsaddr;
568 #elif defined(VGP_s390x_linux)
569    ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
570    ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
571 #elif defined(VGP_arm64_linux)
572    /* Just assign the tls pointer in the guest TPIDR_EL0. */
573    ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
574 #elif defined(VGP_arm_linux)
575    /* Just assign the tls pointer in the guest TPIDRURO. */
576    ctst->arch.vex.guest_TPIDRURO = tlsaddr;
577 #elif defined(VGP_mips64_linux)
578    ctst->arch.vex.guest_ULR = tlsaddr;
579    ctst->arch.vex.guest_r27 = tlsaddr;
580 #elif defined(VGP_mips32_linux)
581    ctst->arch.vex.guest_ULR = tlsaddr;
582    ctst->arch.vex.guest_r27 = tlsaddr;
583 #else
584 # error Unknown platform
585 #endif
586    return res;
587 }
588 
589 /*
590    When a client clones, we need to keep track of the new thread.  This means:
591    1. allocate a ThreadId+ThreadState+stack for the thread
592 
593    2. initialize the thread's new VCPU state
594 
595    3. create the thread using the same args as the client requested,
596    but using the scheduler entrypoint for EIP, and a separate stack
597    for ESP.
598  */
do_clone(ThreadId ptid,UWord flags,Addr sp,Int * parent_tidptr,Int * child_tidptr,Addr tlsaddr)599 static SysRes do_clone ( ThreadId ptid,
600                          UWord flags, Addr sp,
601                          Int* parent_tidptr,
602                          Int* child_tidptr,
603                          Addr tlsaddr)
604 {
605    ThreadId     ctid = VG_(alloc_ThreadState)();
606    ThreadState* ptst = VG_(get_ThreadState)(ptid);
607    ThreadState* ctst = VG_(get_ThreadState)(ctid);
608    UWord*       stack;
609    SysRes       res;
610    vki_sigset_t blockall, savedmask;
611 
612    VG_(sigfillset)(&blockall);
613 
614    vg_assert(VG_(is_running_thread)(ptid));
615    vg_assert(VG_(is_valid_tid)(ctid));
616 
617    stack = (UWord*)ML_(allocstack)(ctid);
618    if (stack == NULL) {
619       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
620       goto out;
621    }
622 
623    /* Copy register state
624 
625       Both parent and child return to the same place, and the code
626       following the clone syscall works out which is which, so we
627       don't need to worry about it.
628 
629       The parent gets the child's new tid returned from clone, but the
630       child gets 0.
631 
632       If the clone call specifies a NULL sp for the new thread, then
633       it actually gets a copy of the parent's sp.
634    */
635    setup_child( &ctst->arch, &ptst->arch );
636 
637    if (sp != 0)
638       VG_(set_SP)(ctid, sp);
639 
640    ctst->os_state.parent = ptid;
641 
642    /* inherit signal mask */
643    ctst->sig_mask     = ptst->sig_mask;
644    ctst->tmp_sig_mask = ptst->sig_mask;
645 
646    /* Start the child with its threadgroup being the same as the
647       parent's.  This is so that any exit_group calls that happen
648       after the child is created but before it sets its
649       os_state.threadgroup field for real (in thread_wrapper in
650       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
651       a race condition in which the thread is unkillable (via
652       exit_group) because its threadgroup is not set.  The race window
653       is probably only a few hundred or a few thousand cycles long.
654       See #226116. */
655    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
656 
657    ML_(guess_and_register_stack) (sp, ctst);
658 
659    /* Assume the clone will succeed, and tell any tool that wants to
660       know that this thread has come into existence.  We cannot defer
661       it beyond this point because setup_tls, just below,
662       causes checks to assert by making references to the new ThreadId
663       if we don't state the new thread exists prior to that point.
664       If the clone fails, we'll send out a ll_exit notification for it
665       at the out: label below, to clean up. */
666    vg_assert(VG_(owns_BigLock_LL)(ptid));
667    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
668 
669    if (flags & VKI_CLONE_SETTLS) {
670       res = setup_child_tls(ctid, tlsaddr);
671       if (sr_isError(res))
672 	 goto out;
673    }
674    flags &= ~VKI_CLONE_SETTLS;
675 
676    /* start the thread with everything blocked */
677    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
678 
679    /* Create the new thread */
680    res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
681                             child_tidptr, parent_tidptr);
682 
683    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
684 
685   out:
686    if (sr_isError(res)) {
687       /* clone failed */
688       VG_(cleanup_thread)(&ctst->arch);
689       ctst->status = VgTs_Empty;
690       /* oops.  Better tell the tool the thread exited in a hurry :-) */
691       VG_TRACK( pre_thread_ll_exit, ctid );
692    }
693 
694    return res;
695 }
696 
697 /* Do a clone which is really a fork().
698    ML_(do_fork_clone) uses the clone syscall to fork a child process.
699    Note that this should not be called for a thread creation.
700    Also, some flags combinations are not supported, and such combinations
701    are handled either by masking the non supported flags or by asserting.
702 
703    The CLONE_VFORK flag is accepted, as this just tells that the parent is
704    suspended till the child exits or calls execve. We better keep this flag,
705    just in case the guests parent/client code depends on this synchronisation.
706 
707    We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
708    instructions in the child process, that will mess up the parent host
709    memory. So, we hope for the best and assumes that the guest application does
710    not (really) depends on sharing the memory between parent and child in the
711    interval between clone and exits/execve.
712 
713    If child_sp != 0, the child (guest) sp will be set to child_sp just after the
714    clone syscall, before child guest instructions are executed. */
ML_(do_fork_clone)715 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
716                                    Int* parent_tidptr, Int* child_tidptr,
717                                    Addr child_sp)
718 {
719    vki_sigset_t fork_saved_mask;
720    vki_sigset_t mask;
721    SysRes       res;
722 
723    if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
724                 | VKI_CLONE_FILES))
725       return VG_(mk_SysRes_Error)( VKI_EINVAL );
726 
727    /* Block all signals during fork, so that we can fix things up in
728       the child without being interrupted. */
729    VG_(sigfillset)(&mask);
730    VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
731 
732    VG_(do_atfork_pre)(tid);
733 
734    /* Since this is the fork() form of clone, we don't need all that
735       VG_(clone) stuff */
736 #if defined(VGP_x86_linux) \
737     || defined(VGP_ppc32_linux) \
738     || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
739     || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
740     || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
741    res = VG_(do_syscall5)( __NR_clone, flags,
742                            (UWord)NULL, (UWord)parent_tidptr,
743                            (UWord)NULL, (UWord)child_tidptr );
744 #elif defined(VGP_amd64_linux)
745    /* note that the last two arguments are the opposite way round to x86 and
746       ppc32 as the amd64 kernel expects the arguments in a different order */
747    res = VG_(do_syscall5)( __NR_clone, flags,
748                            (UWord)NULL, (UWord)parent_tidptr,
749                            (UWord)child_tidptr, (UWord)NULL );
750 #elif defined(VGP_s390x_linux)
751    /* Note that s390 has the stack first and then the flags */
752    res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
753                           (UWord)parent_tidptr, (UWord)child_tidptr);
754 #else
755 # error Unknown platform
756 #endif
757 
758    if (!sr_isError(res) && sr_Res(res) == 0) {
759       /* child */
760       if (child_sp != 0)
761           VG_(set_SP)(tid, child_sp);
762       VG_(do_atfork_child)(tid);
763 
764       /* restore signal mask */
765       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
766    }
767    else
768    if (!sr_isError(res) && sr_Res(res) > 0) {
769       /* parent */
770       VG_(do_atfork_parent)(tid);
771 
772       if (VG_(clo_trace_syscalls))
773          VG_(printf)("   clone(fork): process %d created child %" FMT_REGWORD "u\n",
774                      VG_(getpid)(), (RegWord)sr_Res(res));
775 
776       /* restore signal mask */
777       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
778    }
779 
780    return res;
781 }
782 
783 /* ---------------------------------------------------------------------
784    PRE/POST wrappers for arch-generic, Linux-specific syscalls
785    ------------------------------------------------------------------ */
786 
787 // Nb: See the comment above the generic PRE/POST wrappers in
788 // m_syswrap/syswrap-generic.c for notes about how they work.
789 
790 #define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
791 #define POST(name)      DEFN_POST_TEMPLATE(linux, name)
792 
PRE(sys_clone)793 PRE(sys_clone)
794 {
795    UInt cloneflags;
796    Bool badarg = False;
797 
798    PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
799          "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
800          ARG4, ARG5);
801 
802 // Order of arguments differs between platforms.
803 #if defined(VGP_x86_linux) \
804     || defined(VGP_ppc32_linux) \
805     || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)	\
806     || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
807     || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
808 #define ARG_CHILD_TIDPTR ARG5
809 #define PRA_CHILD_TIDPTR PRA5
810 #define ARG_TLS          ARG4
811 #define PRA_TLS          PRA4
812 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
813 #define ARG_CHILD_TIDPTR ARG4
814 #define PRA_CHILD_TIDPTR PRA4
815 #define ARG_TLS          ARG5
816 #define PRA_TLS          PRA5
817 #else
818 # error Unknown platform
819 #endif
820 // And s390x is even more special, and inverts flags and child stack args
821 #if defined(VGP_s390x_linux)
822 #define ARG_FLAGS       ARG2
823 #define PRA_FLAGS       PRA2
824 #define ARG_CHILD_STACK ARG1
825 #define PRA_CHILD_STACK PRA1
826 #else
827 #define ARG_FLAGS       ARG1
828 #define PRA_FLAGS       PRA1
829 #define ARG_CHILD_STACK ARG2
830 #define PRA_CHILD_STACK PRA2
831 #endif
832 
833    if (VG_(tdict).track_pre_reg_read) {
834       PRA_FLAGS("clone", unsigned long, flags);
835       PRA_CHILD_STACK("clone",  void *, child_stack);
836    }
837 
838    if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID) {
839       if (VG_(tdict).track_pre_reg_read) {
840          PRA3("clone", int *, parent_tidptr);
841       }
842       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
843       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
844                                              VKI_PROT_WRITE)) {
845          badarg = True;
846       }
847    }
848    if (ARG_FLAGS & VKI_CLONE_SETTLS) {
849       if (VG_(tdict).track_pre_reg_read) {
850          PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
851       }
852       /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
853          dummy type (that we define as a char). We only dereference/check the
854          ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
855       if (sizeof(vki_modify_ldt_t) > 1) {
856          PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
857          if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
858                                           VKI_PROT_READ)) {
859             badarg = True;
860          }
861       }
862    }
863    if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
864       if (VG_(tdict).track_pre_reg_read) {
865          PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
866       }
867       PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
868       if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
869                                              VKI_PROT_WRITE)) {
870          badarg = True;
871       }
872    }
873 
874    if (badarg) {
875       SET_STATUS_Failure( VKI_EFAULT );
876       return;
877    }
878 
879    cloneflags = ARG_FLAGS;
880 
881    if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
882       SET_STATUS_Failure( VKI_EINVAL );
883       return;
884    }
885 
886    /* Only look at the flags we really care about */
887    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
888                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
889    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
890       /* thread creation */
891       SET_STATUS_from_SysRes(
892          do_clone(tid,
893                   ARG_FLAGS,               /* flags */
894                   (Addr)ARG_CHILD_STACK,   /* child ESP */
895                   (Int*)(Addr)ARG3,              /* parent_tidptr */
896                   (Int*)(Addr)ARG_CHILD_TIDPTR,  /* child_tidptr */
897                   (Addr)ARG_TLS));         /* set_tls */
898       break;
899 
900    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
901       // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
902       cloneflags &= ~VKI_CLONE_VM;
903 
904    case 0: /* plain fork */
905       SET_STATUS_from_SysRes(
906          ML_(do_fork_clone)(tid,
907                        cloneflags,      /* flags */
908                        (Int*)(Addr)ARG3,     /* parent_tidptr */
909                        (Int*)(Addr)ARG_CHILD_TIDPTR,     /* child_tidptr */
910                        (Addr)ARG_CHILD_STACK));
911       break;
912 
913    default:
914       /* should we just ENOSYS? */
915       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
916                    "x\n", ARG_FLAGS);
917       VG_(message)(Vg_UserMsg, "\n");
918       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
919       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
920       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
921       VG_(unimplemented)
922          ("Valgrind does not support general clone().");
923    }
924 
925    if (SUCCESS) {
926       if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
927          POST_MEM_WRITE(ARG3, sizeof(Int));
928       if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
929          POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
930 
931       /* Thread creation was successful; let the child have the chance
932          to run */
933       *flags |= SfYieldAfter;
934    }
935 
936 #undef ARG_CHILD_TIDPTR
937 #undef PRA_CHILD_TIDPTR
938 #undef ARG_TLS
939 #undef PRA_TLS
940 #undef ARG_FLAGS
941 #undef PRA_FLAGS
942 #undef ARG_CHILD_STACK
943 #undef PRA_CHILD_STACK
944 }
945 
946 /* ---------------------------------------------------------------------
947    *mount wrappers
948    ------------------------------------------------------------------ */
949 
PRE(sys_mount)950 PRE(sys_mount)
951 {
952    // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
953    // We are conservative and check everything, except the memory pointed to
954    // by 'data'.
955    *flags |= SfMayBlock;
956    PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
957          FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
958          ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
959          (HChar*)(Addr)ARG3, ARG4, ARG5);
960    PRE_REG_READ5(long, "mount",
961                  char *, source, char *, target, char *, type,
962                  unsigned long, flags, void *, data);
963    if (ARG1)
964       PRE_MEM_RASCIIZ( "mount(source)", ARG1);
965    PRE_MEM_RASCIIZ( "mount(target)", ARG2);
966    PRE_MEM_RASCIIZ( "mount(type)", ARG3);
967 }
968 
PRE(sys_oldumount)969 PRE(sys_oldumount)
970 {
971    PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
972    PRE_REG_READ1(long, "umount", char *, path);
973    PRE_MEM_RASCIIZ( "umount(path)", ARG1);
974 }
975 
PRE(sys_umount)976 PRE(sys_umount)
977 {
978    PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
979    PRE_REG_READ2(long, "umount2", char *, path, int, flags);
980    PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
981 }
982 
983 /* Not actually wrapped by GLibc but does things with the system
984  * mounts so it is put here.
985  */
PRE(sys_pivot_root)986 PRE(sys_pivot_root)
987 {
988    PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
989    PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
990    PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
991    PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
992 }
993 
994 
995 /* ---------------------------------------------------------------------
996    16- and 32-bit uid/gid wrappers
997    ------------------------------------------------------------------ */
998 
PRE(sys_setfsuid16)999 PRE(sys_setfsuid16)
1000 {
1001    PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1002    PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1003 }
1004 
PRE(sys_setfsuid)1005 PRE(sys_setfsuid)
1006 {
1007    PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1008    PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1009 }
1010 
PRE(sys_setfsgid16)1011 PRE(sys_setfsgid16)
1012 {
1013    PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1014    PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1015 }
1016 
PRE(sys_setfsgid)1017 PRE(sys_setfsgid)
1018 {
1019    PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1020    PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1021 }
1022 
PRE(sys_setresuid16)1023 PRE(sys_setresuid16)
1024 {
1025    PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1026          FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1027    PRE_REG_READ3(long, "setresuid16",
1028                  vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1029 }
1030 
PRE(sys_setresuid)1031 PRE(sys_setresuid)
1032 {
1033    PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1034          FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1035    PRE_REG_READ3(long, "setresuid",
1036                  vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1037 }
1038 
PRE(sys_getresuid16)1039 PRE(sys_getresuid16)
1040 {
1041    PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1042          FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1043    PRE_REG_READ3(long, "getresuid16",
1044                  vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1045                  vki_old_uid_t *, suid);
1046    PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1047    PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1048    PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1049 }
POST(sys_getresuid16)1050 POST(sys_getresuid16)
1051 {
1052    vg_assert(SUCCESS);
1053    if (RES == 0) {
1054       POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1055       POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1056       POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1057    }
1058 }
1059 
PRE(sys_getresuid)1060 PRE(sys_getresuid)
1061 {
1062    PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1063          FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1064    PRE_REG_READ3(long, "getresuid",
1065                  vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1066    PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1067    PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1068    PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1069 }
POST(sys_getresuid)1070 POST(sys_getresuid)
1071 {
1072    vg_assert(SUCCESS);
1073    if (RES == 0) {
1074       POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1075       POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1076       POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1077    }
1078 }
1079 
PRE(sys_setresgid16)1080 PRE(sys_setresgid16)
1081 {
1082    PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1083          FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1084    PRE_REG_READ3(long, "setresgid16",
1085                  vki_old_gid_t, rgid,
1086                  vki_old_gid_t, egid, vki_old_gid_t, sgid);
1087 }
1088 
PRE(sys_setresgid)1089 PRE(sys_setresgid)
1090 {
1091    PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1092          FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1093    PRE_REG_READ3(long, "setresgid",
1094                  vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1095 }
1096 
PRE(sys_getresgid16)1097 PRE(sys_getresgid16)
1098 {
1099    PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1100          FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1101    PRE_REG_READ3(long, "getresgid16",
1102                  vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1103                  vki_old_gid_t *, sgid);
1104    PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1105    PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1106    PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1107 }
POST(sys_getresgid16)1108 POST(sys_getresgid16)
1109 {
1110    vg_assert(SUCCESS);
1111    if (RES == 0) {
1112       POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1113       POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1114       POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1115    }
1116 }
1117 
PRE(sys_getresgid)1118 PRE(sys_getresgid)
1119 {
1120    PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1121          FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1122    PRE_REG_READ3(long, "getresgid",
1123                  vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1124    PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1125    PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1126    PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1127 }
POST(sys_getresgid)1128 POST(sys_getresgid)
1129 {
1130    vg_assert(SUCCESS);
1131    if (RES == 0) {
1132       POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1133       POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1134       POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1135    }
1136 }
1137 
1138 /* ---------------------------------------------------------------------
1139    miscellaneous wrappers
1140    ------------------------------------------------------------------ */
1141 
PRE(sys_exit_group)1142 PRE(sys_exit_group)
1143 {
1144    ThreadId     t;
1145    ThreadState* tst;
1146 
1147    PRINT("exit_group( %ld )", SARG1);
1148    PRE_REG_READ1(void, "exit_group", int, status);
1149 
1150    tst = VG_(get_ThreadState)(tid);
1151    /* A little complex; find all the threads with the same threadgroup
1152       as this one (including this one), and mark them to exit */
1153    /* It is unclear how one can get a threadgroup in this process which
1154       is not the threadgroup of the calling thread:
1155       The assignments to threadgroups are:
1156         = 0; /// scheduler.c os_state_clear
1157         = getpid(); /// scheduler.c in child after fork
1158         = getpid(); /// this file, in thread_wrapper
1159         = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1160                            copying the thread group of the thread doing clone
1161       So, the only case where the threadgroup might be different to the getpid
1162       value is in the child, just after fork. But then the fork syscall is
1163       still going on, the forked thread has had no chance yet to make this
1164       syscall. */
1165    for (t = 1; t < VG_N_THREADS; t++) {
1166       if ( /* not alive */
1167            VG_(threads)[t].status == VgTs_Empty
1168            ||
1169 	   /* not our group */
1170            VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1171          )
1172          continue;
1173       /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1174          the exitreason. */
1175       VG_(threads)[t].os_state.exitcode = ARG1;
1176    }
1177 
1178    /* Indicate in all other threads that the process is exiting.
1179       Then wait using VG_(reap_threads) for these threads to disappear.
1180 
1181       Can this give a deadlock if another thread is calling exit in parallel
1182       and would then wait for this thread to disappear ?
1183       The answer is no:
1184       Other threads are either blocked in a syscall or have yielded the CPU.
1185 
1186       A thread that has yielded the CPU is trying to get the big lock in
1187       VG_(scheduler). This thread will get the CPU thanks to the call
1188       to VG_(reap_threads). The scheduler will then check for signals,
1189       kill the process if this is a fatal signal, and otherwise prepare
1190       the thread for handling this signal. After this preparation, if
1191       the thread status is VG_(is_exiting), the scheduler exits the thread.
1192       So, a thread that has yielded the CPU does not have a chance to
1193       call exit => no deadlock for this thread.
1194 
1195       VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1196       to all threads blocked in a syscall.
1197       The syscall will be interrupted, and the control will go to the
1198       scheduler. The scheduler will then return, as the thread is in
1199       exiting state. */
1200 
1201    VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1202    VG_(reap_threads)(tid);
1203    VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1204    /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1205       is the thread calling exit_group and so its registers must be considered
1206       as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1207 
1208    /* We have to claim the syscall already succeeded. */
1209    SET_STATUS_Success(0);
1210 }
1211 
PRE(sys_llseek)1212 PRE(sys_llseek)
1213 {
1214    PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1215          FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1216          ARG1, ARG2, ARG3, ARG4, ARG5);
1217    PRE_REG_READ5(long, "llseek",
1218                  unsigned int, fd, unsigned long, offset_high,
1219                  unsigned long, offset_low, vki_loff_t *, result,
1220                  unsigned int, whence);
1221    if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1222       SET_STATUS_Failure( VKI_EBADF );
1223    else
1224       PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1225 }
POST(sys_llseek)1226 POST(sys_llseek)
1227 {
1228    vg_assert(SUCCESS);
1229    if (RES == 0)
1230       POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1231 }
1232 
PRE(sys_adjtimex)1233 PRE(sys_adjtimex)
1234 {
1235    struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1236    PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1237    PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1238 
1239    if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1240       PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1241 
1242 #define ADJX(bits,field) 				\
1243          if (tx->modes & (bits))                              \
1244          PRE_MEM_READ( "adjtimex(timex->"#field")",	\
1245 		       (Addr)&tx->field, sizeof(tx->field))
1246 
1247       if (tx->modes & VKI_ADJ_ADJTIME) {
1248          if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1249             PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1250       } else {
1251          ADJX(VKI_ADJ_OFFSET, offset);
1252          ADJX(VKI_ADJ_FREQUENCY, freq);
1253          ADJX(VKI_ADJ_MAXERROR, maxerror);
1254          ADJX(VKI_ADJ_ESTERROR, esterror);
1255          ADJX(VKI_ADJ_STATUS, status);
1256          ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1257          ADJX(VKI_ADJ_TICK, tick);
1258       }
1259 #undef ADJX
1260    }
1261 
1262    PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1263 }
1264 
POST(sys_adjtimex)1265 POST(sys_adjtimex)
1266 {
1267    POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1268 }
1269 
PRE(sys_clock_adjtime)1270 PRE(sys_clock_adjtime)
1271 {
1272    struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1273    PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1274    PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1275    PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1276 
1277 #define ADJX(bits,field)                                \
1278    if (tx->modes & (bits))                              \
1279       PRE_MEM_READ( "clock_adjtime(timex->"#field")",   \
1280                     (Addr)&tx->field, sizeof(tx->field))
1281 
1282    if (tx->modes & VKI_ADJ_ADJTIME) {
1283       if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1284          PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1285    } else {
1286       ADJX(VKI_ADJ_OFFSET, offset);
1287       ADJX(VKI_ADJ_FREQUENCY, freq);
1288       ADJX(VKI_ADJ_MAXERROR, maxerror);
1289       ADJX(VKI_ADJ_ESTERROR, esterror);
1290       ADJX(VKI_ADJ_STATUS, status);
1291       ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1292       ADJX(VKI_ADJ_TICK, tick);
1293    }
1294 #undef ADJX
1295 
1296    PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1297 }
1298 
POST(sys_clock_adjtime)1299 POST(sys_clock_adjtime)
1300 {
1301    POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1302 }
1303 
PRE(sys_ioperm)1304 PRE(sys_ioperm)
1305 {
1306    PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1307          ARG1, ARG2, SARG3 );
1308    PRE_REG_READ3(long, "ioperm",
1309                  unsigned long, from, unsigned long, num, int, turn_on);
1310 }
1311 
PRE(sys_syslog)1312 PRE(sys_syslog)
1313 {
1314    *flags |= SfMayBlock;
1315    PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1316    PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1317    switch (ARG1) {
1318    // The kernel uses magic numbers here, rather than named constants,
1319    // therefore so do we.
1320    case 2: case 3: case 4:
1321       PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1322       break;
1323    default:
1324       break;
1325    }
1326 }
POST(sys_syslog)1327 POST(sys_syslog)
1328 {
1329    switch (ARG1) {
1330    case 2: case 3: case 4:
1331       POST_MEM_WRITE( ARG2, ARG3 );
1332       break;
1333    default:
1334       break;
1335    }
1336 }
1337 
PRE(sys_vhangup)1338 PRE(sys_vhangup)
1339 {
1340    PRINT("sys_vhangup ( )");
1341    PRE_REG_READ0(long, "vhangup");
1342 }
1343 
PRE(sys_sysinfo)1344 PRE(sys_sysinfo)
1345 {
1346    PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1347    PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1348    PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1349 }
POST(sys_sysinfo)1350 POST(sys_sysinfo)
1351 {
1352    POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1353 }
1354 
PRE(sys_personality)1355 PRE(sys_personality)
1356 {
1357    PRINT("sys_personality ( %llu )", (ULong)ARG1);
1358    PRE_REG_READ1(long, "personality", vki_u_long, persona);
1359 }
1360 
PRE(sys_sysctl)1361 PRE(sys_sysctl)
1362 {
1363    struct __vki_sysctl_args *args;
1364    PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1365    args = (struct __vki_sysctl_args *)(Addr)ARG1;
1366    PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1367    PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1368    if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1369                                           VKI_PROT_READ)) {
1370       SET_STATUS_Failure( VKI_EFAULT );
1371       return;
1372    }
1373 
1374    PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1375    if (args->newval != NULL)
1376       PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1377    if (args->oldlenp != NULL) {
1378       PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1379       PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1380    }
1381 }
POST(sys_sysctl)1382 POST(sys_sysctl)
1383 {
1384    struct __vki_sysctl_args *args;
1385    args = (struct __vki_sysctl_args *)(Addr)ARG1;
1386    if (args->oldlenp != NULL) {
1387       POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1388       POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1389    }
1390 }
1391 
pre_asciiz_str(ThreadId tid,Addr str,SizeT maxlen,const char * attr_name)1392 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1393                            const char *attr_name)
1394 {
1395    const HChar *step_str = (const HChar *)str;
1396    SizeT len;
1397    UInt i;
1398 
1399    /*
1400     * The name can be up to maxlen bytes long, including the terminating null
1401     * byte. So do not check more than maxlen bytes.
1402     */
1403    if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1404       len = VG_(strnlen)((const HChar *)str, maxlen);
1405       if (len < maxlen)
1406          PRE_MEM_RASCIIZ(attr_name, str);
1407       else
1408          PRE_MEM_READ(attr_name, str, maxlen);
1409    } else {
1410       /*
1411        * Do it the slow way, one byte at a time, while checking for terminating
1412        * '\0'.
1413        */
1414       for (i = 0; i < maxlen; i++) {
1415          PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1416          if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1417             break;
1418       }
1419    }
1420 }
1421 
PRE(sys_prctl)1422 PRE(sys_prctl)
1423 {
1424    *flags |= SfMayBlock;
1425    PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1426    switch (ARG1) {
1427    case VKI_PR_SET_PDEATHSIG:
1428       PRE_REG_READ2(int, "prctl", int, option, int, signal);
1429       break;
1430    case VKI_PR_GET_PDEATHSIG:
1431       PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1432       PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1433       break;
1434    case VKI_PR_GET_DUMPABLE:
1435       PRE_REG_READ1(int, "prctl", int, option);
1436       break;
1437    case VKI_PR_SET_DUMPABLE:
1438       PRE_REG_READ2(int, "prctl", int, option, int, dump);
1439       break;
1440    case VKI_PR_GET_UNALIGN:
1441       PRE_REG_READ2(int, "prctl", int, option, int *, value);
1442       PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1443       break;
1444    case VKI_PR_SET_UNALIGN:
1445       PRE_REG_READ2(int, "prctl", int, option, int, value);
1446       break;
1447    case VKI_PR_GET_KEEPCAPS:
1448       PRE_REG_READ1(int, "prctl", int, option);
1449       break;
1450    case VKI_PR_SET_KEEPCAPS:
1451       PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1452       break;
1453    case VKI_PR_GET_FPEMU:
1454       PRE_REG_READ2(int, "prctl", int, option, int *, value);
1455       PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1456       break;
1457    case VKI_PR_SET_FPEMU:
1458       PRE_REG_READ2(int, "prctl", int, option, int, value);
1459       break;
1460    case VKI_PR_GET_FPEXC:
1461       PRE_REG_READ2(int, "prctl", int, option, int *, value);
1462       PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1463       break;
1464    case VKI_PR_SET_FPEXC:
1465       PRE_REG_READ2(int, "prctl", int, option, int, value);
1466       break;
1467    case VKI_PR_GET_TIMING:
1468       PRE_REG_READ1(int, "prctl", int, option);
1469       break;
1470    case VKI_PR_SET_TIMING:
1471       PRE_REG_READ2(int, "prctl", int, option, int, timing);
1472       break;
1473    case VKI_PR_SET_NAME:
1474       PRE_REG_READ2(int, "prctl", int, option, char *, name);
1475       pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1476       break;
1477    case VKI_PR_GET_NAME:
1478       PRE_REG_READ2(int, "prctl", int, option, char *, name);
1479       PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1480       break;
1481    case VKI_PR_GET_ENDIAN:
1482       PRE_REG_READ2(int, "prctl", int, option, int *, value);
1483       PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1484       break;
1485    case VKI_PR_SET_ENDIAN:
1486       PRE_REG_READ2(int, "prctl", int, option, int, value);
1487       break;
1488    case VKI_PR_SET_PTRACER:
1489       PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1490       break;
1491    case VKI_PR_SET_SECCOMP:
1492       /* This is a bit feeble in that it uses |option| before checking
1493          it, but at least both sides of the conditional check it. */
1494       if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1495          PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1496          if (ARG3) {
1497             /* Should check that ARG3 points at a valid struct sock_fprog.
1498                Sounds complex; hence be lame. */
1499             PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1500                           ARG3, 1 );
1501          }
1502       } else {
1503          PRE_REG_READ2(int, "prctl", int, option, int, mode);
1504       }
1505       break;
1506    default:
1507       PRE_REG_READ5(long, "prctl",
1508                     int, option, unsigned long, arg2, unsigned long, arg3,
1509                     unsigned long, arg4, unsigned long, arg5);
1510       break;
1511    }
1512 }
POST(sys_prctl)1513 POST(sys_prctl)
1514 {
1515    switch (ARG1) {
1516    case VKI_PR_GET_PDEATHSIG:
1517       POST_MEM_WRITE(ARG2, sizeof(Int));
1518       break;
1519    case VKI_PR_GET_UNALIGN:
1520       POST_MEM_WRITE(ARG2, sizeof(Int));
1521       break;
1522    case VKI_PR_GET_FPEMU:
1523       POST_MEM_WRITE(ARG2, sizeof(Int));
1524       break;
1525    case VKI_PR_GET_FPEXC:
1526       POST_MEM_WRITE(ARG2, sizeof(Int));
1527       break;
1528    case VKI_PR_GET_NAME:
1529       POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1530       break;
1531    case VKI_PR_GET_ENDIAN:
1532       POST_MEM_WRITE(ARG2, sizeof(Int));
1533       break;
1534    case VKI_PR_SET_NAME:
1535       {
1536          const HChar* new_name = (const HChar*) (Addr)ARG2;
1537          if (new_name) {    // Paranoia
1538             ThreadState* tst = VG_(get_ThreadState)(tid);
1539             SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1540 
1541             /* Don't bother reusing the memory. This is a rare event. */
1542             tst->thread_name =
1543               VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1544             VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1545          }
1546       }
1547       break;
1548    }
1549 }
1550 
PRE(sys_sendfile)1551 PRE(sys_sendfile)
1552 {
1553    *flags |= SfMayBlock;
1554    PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1555          SARG1, SARG2, ARG3, ARG4);
1556    PRE_REG_READ4(ssize_t, "sendfile",
1557                  int, out_fd, int, in_fd, vki_off_t *, offset,
1558                  vki_size_t, count);
1559    if (ARG3 != 0)
1560       PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1561 }
POST(sys_sendfile)1562 POST(sys_sendfile)
1563 {
1564    if (ARG3 != 0 ) {
1565       POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1566    }
1567 }
1568 
PRE(sys_sendfile64)1569 PRE(sys_sendfile64)
1570 {
1571    *flags |= SfMayBlock;
1572    PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1573          SARG1, SARG2, ARG3, ARG4);
1574    PRE_REG_READ4(ssize_t, "sendfile64",
1575                  int, out_fd, int, in_fd, vki_loff_t *, offset,
1576                  vki_size_t, count);
1577    if (ARG3 != 0)
1578       PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1579 }
POST(sys_sendfile64)1580 POST(sys_sendfile64)
1581 {
1582    if (ARG3 != 0 ) {
1583       POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1584    }
1585 }
1586 
PRE(sys_futex)1587 PRE(sys_futex)
1588 {
1589    /*
1590       arg    param                              used by ops
1591 
1592       ARG1 - u32 *futex				all
1593       ARG2 - int op
1594       ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1595       ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
1596       ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
1597       ARG6 - int val3				CMP_REQUEUE
1598     */
1599    PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1600          "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1601    switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1602    case VKI_FUTEX_CMP_REQUEUE:
1603    case VKI_FUTEX_WAKE_OP:
1604    case VKI_FUTEX_CMP_REQUEUE_PI:
1605       PRE_REG_READ6(long, "futex",
1606                     vki_u32 *, futex, int, op, int, val,
1607                     struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1608       break;
1609    case VKI_FUTEX_REQUEUE:
1610    case VKI_FUTEX_WAIT_REQUEUE_PI:
1611       PRE_REG_READ5(long, "futex",
1612                     vki_u32 *, futex, int, op, int, val,
1613                     struct timespec *, utime, vki_u32 *, uaddr2);
1614       break;
1615    case VKI_FUTEX_WAIT_BITSET:
1616       /* Check that the address at least begins in client-accessible area. */
1617       if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1618             SET_STATUS_Failure( VKI_EFAULT );
1619             return;
1620       }
1621       if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1622          PRE_REG_READ4(long, "futex",
1623                        vki_u32 *, futex, int, op, int, val,
1624                        struct timespec *, utime);
1625       } else {
1626         /* Note argument 5 is unused, but argument 6 is used.
1627            So we cannot just PRE_REG_READ6. Read argument 6 separately.  */
1628          PRE_REG_READ4(long, "futex",
1629                        vki_u32 *, futex, int, op, int, val,
1630                        struct timespec *, utime);
1631          if (VG_(tdict).track_pre_reg_read)
1632             PRA6("futex",int,val3);
1633       }
1634       break;
1635    case VKI_FUTEX_WAKE_BITSET:
1636       PRE_REG_READ3(long, "futex",
1637                     vki_u32 *, futex, int, op, int, val);
1638       if (VG_(tdict).track_pre_reg_read) {
1639          PRA6("futex", int, val3);
1640       }
1641       break;
1642    case VKI_FUTEX_WAIT:
1643    case VKI_FUTEX_LOCK_PI:
1644       PRE_REG_READ4(long, "futex",
1645                     vki_u32 *, futex, int, op, int, val,
1646                     struct timespec *, utime);
1647       break;
1648    case VKI_FUTEX_WAKE:
1649    case VKI_FUTEX_FD:
1650       PRE_REG_READ3(long, "futex",
1651                     vki_u32 *, futex, int, op, int, val);
1652       break;
1653    case VKI_FUTEX_TRYLOCK_PI:
1654    case VKI_FUTEX_UNLOCK_PI:
1655    default:
1656       PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1657       break;
1658    }
1659 
1660    *flags |= SfMayBlock;
1661 
1662    switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1663    case VKI_FUTEX_WAIT:
1664    case VKI_FUTEX_LOCK_PI:
1665    case VKI_FUTEX_WAIT_BITSET:
1666    case VKI_FUTEX_WAIT_REQUEUE_PI:
1667       PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1668       if (ARG4 != 0)
1669 	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1670       break;
1671 
1672    case VKI_FUTEX_REQUEUE:
1673    case VKI_FUTEX_CMP_REQUEUE:
1674    case VKI_FUTEX_CMP_REQUEUE_PI:
1675    case VKI_FUTEX_WAKE_OP:
1676       PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1677       PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1678       break;
1679 
1680    case VKI_FUTEX_FD:
1681    case VKI_FUTEX_TRYLOCK_PI:
1682    case VKI_FUTEX_UNLOCK_PI:
1683    case VKI_FUTEX_WAKE:
1684    case VKI_FUTEX_WAKE_BITSET:
1685       PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1686      break;
1687 
1688    default:
1689       SET_STATUS_Failure( VKI_ENOSYS );   // some futex function we don't understand
1690       break;
1691    }
1692 }
POST(sys_futex)1693 POST(sys_futex)
1694 {
1695    vg_assert(SUCCESS);
1696    POST_MEM_WRITE( ARG1, sizeof(int) );
1697    if (ARG2 == VKI_FUTEX_FD) {
1698       if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1699          VG_(close)(RES);
1700          SET_STATUS_Failure( VKI_EMFILE );
1701       } else {
1702          if (VG_(clo_track_fds))
1703             ML_(record_fd_open_nameless)(tid, RES);
1704       }
1705    }
1706 }
1707 
PRE(sys_set_robust_list)1708 PRE(sys_set_robust_list)
1709 {
1710    PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1711          FMT_REGWORD "u )", ARG1, ARG2);
1712    PRE_REG_READ2(long, "set_robust_list",
1713                  struct vki_robust_list_head *, head, vki_size_t, len);
1714 
1715    /* Just check the robust_list_head structure is readable - don't
1716       try and chase the list as the kernel will only read it when
1717       the thread exits so the current contents is irrelevant. */
1718    if (ARG1 != 0)
1719       PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1720 }
1721 
PRE(sys_get_robust_list)1722 PRE(sys_get_robust_list)
1723 {
1724    PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1725          FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1726    PRE_REG_READ3(long, "get_robust_list",
1727                  int, pid,
1728                  struct vki_robust_list_head **, head_ptr,
1729                  vki_size_t *, len_ptr);
1730    PRE_MEM_WRITE("get_robust_list(head_ptr)",
1731                  ARG2, sizeof(struct vki_robust_list_head *));
1732    PRE_MEM_WRITE("get_robust_list(len_ptr)",
1733                  ARG3, sizeof(struct vki_size_t *));
1734 }
POST(sys_get_robust_list)1735 POST(sys_get_robust_list)
1736 {
1737    POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1738    POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1739 }
1740 
1741 struct pselect_sized_sigset {
1742     const vki_sigset_t *ss;
1743     vki_size_t ss_len;
1744 };
1745 struct pselect_adjusted_sigset {
1746     struct pselect_sized_sigset ss; /* The actual syscall arg */
1747     vki_sigset_t adjusted_ss;
1748 };
1749 
PRE(sys_pselect6)1750 PRE(sys_pselect6)
1751 {
1752    *flags |= SfMayBlock | SfPostOnFail;
1753    PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1754          FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1755          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1756    PRE_REG_READ6(long, "pselect6",
1757                  int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1758                  vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1759                  void *, sig);
1760    // XXX: this possibly understates how much memory is read.
1761    if (ARG2 != 0)
1762       PRE_MEM_READ( "pselect6(readfds)",
1763 		     ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1764    if (ARG3 != 0)
1765       PRE_MEM_READ( "pselect6(writefds)",
1766 		     ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1767    if (ARG4 != 0)
1768       PRE_MEM_READ( "pselect6(exceptfds)",
1769 		     ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1770    if (ARG5 != 0)
1771       PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1772    if (ARG6 != 0) {
1773       const struct pselect_sized_sigset *pss =
1774           (struct pselect_sized_sigset *)(Addr)ARG6;
1775       PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1776       if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1777          ARG6 = 1; /* Something recognisable to POST() hook. */
1778       } else {
1779          struct pselect_adjusted_sigset *pas;
1780          pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1781          ARG6 = (Addr)pas;
1782          pas->ss.ss = (void *)1;
1783          pas->ss.ss_len = pss->ss_len;
1784          if (pss->ss_len == sizeof(*pss->ss)) {
1785             if (pss->ss == NULL) {
1786                pas->ss.ss = NULL;
1787             } else {
1788                PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1789                if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1790                   pas->adjusted_ss = *pss->ss;
1791                   pas->ss.ss = &pas->adjusted_ss;
1792                   VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1793                }
1794             }
1795          }
1796       }
1797    }
1798 }
POST(sys_pselect6)1799 POST(sys_pselect6)
1800 {
1801    if (ARG6 != 0 && ARG6 != 1) {
1802        VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1803    }
1804 }
1805 
PRE(sys_ppoll)1806 PRE(sys_ppoll)
1807 {
1808    UInt i;
1809    struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1810    *flags |= SfMayBlock | SfPostOnFail;
1811    PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1812          "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1813          ARG1, ARG2, ARG3, ARG4, ARG5);
1814    PRE_REG_READ5(long, "ppoll",
1815                  struct vki_pollfd *, ufds, unsigned int, nfds,
1816                  struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1817                  vki_size_t, sigsetsize);
1818 
1819    for (i = 0; i < ARG2; i++) {
1820       PRE_MEM_READ( "ppoll(ufds.fd)",
1821                     (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1822       PRE_MEM_READ( "ppoll(ufds.events)",
1823                     (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1824       PRE_MEM_WRITE( "ppoll(ufds.revents)",
1825                      (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1826    }
1827 
1828    if (ARG3)
1829       PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1830    if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1831       const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1832       PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1833       if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1834          ARG4 = 1; /* Something recognisable to POST() hook. */
1835       } else {
1836          vki_sigset_t *vg_sigmask =
1837              VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1838          ARG4 = (Addr)vg_sigmask;
1839          *vg_sigmask = *guest_sigmask;
1840          VG_(sanitize_client_sigmask)(vg_sigmask);
1841       }
1842    }
1843 }
1844 
POST(sys_ppoll)1845 POST(sys_ppoll)
1846 {
1847    vg_assert(SUCCESS || FAILURE);
1848    if (SUCCESS && (RES >= 0)) {
1849       UInt i;
1850       struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1851       for (i = 0; i < ARG2; i++)
1852 	 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1853    }
1854    if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1855       VG_(free)((vki_sigset_t *) (Addr)ARG4);
1856    }
1857 }
1858 
1859 
1860 /* ---------------------------------------------------------------------
1861    epoll_* wrappers
1862    ------------------------------------------------------------------ */
1863 
PRE(sys_epoll_create)1864 PRE(sys_epoll_create)
1865 {
1866    PRINT("sys_epoll_create ( %ld )", SARG1);
1867    PRE_REG_READ1(long, "epoll_create", int, size);
1868 }
POST(sys_epoll_create)1869 POST(sys_epoll_create)
1870 {
1871    vg_assert(SUCCESS);
1872    if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1873       VG_(close)(RES);
1874       SET_STATUS_Failure( VKI_EMFILE );
1875    } else {
1876       if (VG_(clo_track_fds))
1877          ML_(record_fd_open_nameless) (tid, RES);
1878    }
1879 }
1880 
PRE(sys_epoll_create1)1881 PRE(sys_epoll_create1)
1882 {
1883    PRINT("sys_epoll_create1 ( %ld )", SARG1);
1884    PRE_REG_READ1(long, "epoll_create1", int, flags);
1885 }
POST(sys_epoll_create1)1886 POST(sys_epoll_create1)
1887 {
1888    vg_assert(SUCCESS);
1889    if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1890       VG_(close)(RES);
1891       SET_STATUS_Failure( VKI_EMFILE );
1892    } else {
1893       if (VG_(clo_track_fds))
1894          ML_(record_fd_open_nameless) (tid, RES);
1895    }
1896 }
1897 
PRE(sys_epoll_ctl)1898 PRE(sys_epoll_ctl)
1899 {
1900    static const HChar* epoll_ctl_s[3] = {
1901       "EPOLL_CTL_ADD",
1902       "EPOLL_CTL_DEL",
1903       "EPOLL_CTL_MOD"
1904    };
1905    PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
1906          SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1907    PRE_REG_READ4(long, "epoll_ctl",
1908                  int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1909    if (ARG2 != VKI_EPOLL_CTL_DEL)
1910       PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1911 }
1912 
PRE(sys_epoll_wait)1913 PRE(sys_epoll_wait)
1914 {
1915    *flags |= SfMayBlock;
1916    PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
1917          SARG1, ARG2, SARG3, SARG4);
1918    PRE_REG_READ4(long, "epoll_wait",
1919                  int, epfd, struct vki_epoll_event *, events,
1920                  int, maxevents, int, timeout);
1921    PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1922 }
POST(sys_epoll_wait)1923 POST(sys_epoll_wait)
1924 {
1925    vg_assert(SUCCESS);
1926    if (RES > 0)
1927       POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1928 }
1929 
PRE(sys_epoll_pwait)1930 PRE(sys_epoll_pwait)
1931 {
1932    *flags |= SfMayBlock;
1933    PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
1934           FMT_REGWORD "x, %" FMT_REGWORD "u )",
1935          SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1936    PRE_REG_READ6(long, "epoll_pwait",
1937                  int, epfd, struct vki_epoll_event *, events,
1938                  int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1939                  vki_size_t, sigsetsize);
1940    PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1941    if (ARG5)
1942       PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1943 }
POST(sys_epoll_pwait)1944 POST(sys_epoll_pwait)
1945 {
1946    vg_assert(SUCCESS);
1947    if (RES > 0)
1948       POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1949 }
1950 
PRE(sys_eventfd)1951 PRE(sys_eventfd)
1952 {
1953    PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
1954    PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1955 }
POST(sys_eventfd)1956 POST(sys_eventfd)
1957 {
1958    if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1959       VG_(close)(RES);
1960       SET_STATUS_Failure( VKI_EMFILE );
1961    } else {
1962       if (VG_(clo_track_fds))
1963          ML_(record_fd_open_nameless) (tid, RES);
1964    }
1965 }
1966 
PRE(sys_eventfd2)1967 PRE(sys_eventfd2)
1968 {
1969    PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
1970    PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1971 }
POST(sys_eventfd2)1972 POST(sys_eventfd2)
1973 {
1974    if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1975       VG_(close)(RES);
1976       SET_STATUS_Failure( VKI_EMFILE );
1977    } else {
1978       if (VG_(clo_track_fds))
1979          ML_(record_fd_open_nameless) (tid, RES);
1980    }
1981 }
1982 
PRE(sys_fallocate)1983 PRE(sys_fallocate)
1984 {
1985    *flags |= SfMayBlock;
1986 #if VG_WORDSIZE == 4
1987    PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1988          SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
1989    PRE_REG_READ6(long, "fallocate",
1990                  int, fd, int, mode,
1991                  unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1992                  unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1993 #elif VG_WORDSIZE == 8
1994    PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
1995          SARG1, SARG2, SARG3, SARG4);
1996    PRE_REG_READ4(long, "fallocate",
1997                  int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1998 #else
1999 #  error Unexpected word size
2000 #endif
2001    if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2002       SET_STATUS_Failure( VKI_EBADF );
2003 }
2004 
PRE(sys_prlimit64)2005 PRE(sys_prlimit64)
2006 {
2007    PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2008           FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2009    PRE_REG_READ4(long, "prlimit64",
2010                  vki_pid_t, pid, unsigned int, resource,
2011                  const struct rlimit64 *, new_rlim,
2012                  struct rlimit64 *, old_rlim);
2013    if (ARG3)
2014       PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2015    if (ARG4)
2016       PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2017 
2018    if (ARG3 &&
2019        ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2020         > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2021       SET_STATUS_Failure( VKI_EINVAL );
2022    }
2023    else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2024       switch (ARG2) {
2025       case VKI_RLIMIT_NOFILE:
2026          SET_STATUS_Success( 0 );
2027          if (ARG4) {
2028             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2029             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2030          }
2031          if (ARG3) {
2032             if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2033                   > VG_(fd_hard_limit) ||
2034                 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2035                   != VG_(fd_hard_limit)) {
2036                SET_STATUS_Failure( VKI_EPERM );
2037             }
2038             else {
2039                VG_(fd_soft_limit) =
2040                   ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2041             }
2042          }
2043          break;
2044 
2045       case VKI_RLIMIT_DATA:
2046          SET_STATUS_Success( 0 );
2047          if (ARG4) {
2048             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2049                VG_(client_rlimit_data).rlim_cur;
2050             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2051                VG_(client_rlimit_data).rlim_max;
2052          }
2053          if (ARG3) {
2054             if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2055                > VG_(client_rlimit_data).rlim_max ||
2056             ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2057                > VG_(client_rlimit_data).rlim_max) {
2058                SET_STATUS_Failure( VKI_EPERM );
2059             }
2060             else {
2061                VG_(client_rlimit_data).rlim_cur =
2062                   ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2063                VG_(client_rlimit_data).rlim_max =
2064                   ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2065             }
2066          }
2067          break;
2068 
2069       case VKI_RLIMIT_STACK:
2070          SET_STATUS_Success( 0 );
2071          if (ARG4) {
2072             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2073                VG_(client_rlimit_stack).rlim_cur;
2074             ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2075                VG_(client_rlimit_stack).rlim_max;
2076          }
2077          if (ARG3) {
2078             if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2079                > VG_(client_rlimit_stack).rlim_max ||
2080             ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2081                > VG_(client_rlimit_stack).rlim_max) {
2082                SET_STATUS_Failure( VKI_EPERM );
2083             }
2084             else {
2085                VG_(threads)[tid].client_stack_szB =
2086                   ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2087                VG_(client_rlimit_stack).rlim_cur =
2088                    ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2089                VG_(client_rlimit_stack).rlim_max =
2090                    ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2091            }
2092          }
2093          break;
2094       }
2095    }
2096 }
2097 
POST(sys_prlimit64)2098 POST(sys_prlimit64)
2099 {
2100    if (ARG4)
2101       POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2102 }
2103 
2104 /* ---------------------------------------------------------------------
2105    tid-related wrappers
2106    ------------------------------------------------------------------ */
2107 
PRE(sys_gettid)2108 PRE(sys_gettid)
2109 {
2110    PRINT("sys_gettid ()");
2111    PRE_REG_READ0(long, "gettid");
2112 }
2113 
PRE(sys_set_tid_address)2114 PRE(sys_set_tid_address)
2115 {
2116    PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2117    PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2118 }
2119 
PRE(sys_tkill)2120 PRE(sys_tkill)
2121 {
2122    PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2123    PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2124    if (!ML_(client_signal_OK)(ARG2)) {
2125       SET_STATUS_Failure( VKI_EINVAL );
2126       return;
2127    }
2128 
2129    /* Check to see if this kill gave us a pending signal */
2130    *flags |= SfPollAfter;
2131 
2132    if (VG_(clo_trace_signals))
2133       VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2134 		   SARG2, SARG1);
2135 
2136    /* If we're sending SIGKILL, check to see if the target is one of
2137       our threads and handle it specially. */
2138    if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2139       SET_STATUS_Success(0);
2140       return;
2141    }
2142 
2143    /* Ask to handle this syscall via the slow route, since that's the
2144       only one that sets tst->status to VgTs_WaitSys.  If the result
2145       of doing the syscall is an immediate run of
2146       async_signalhandler() in m_signals, then we need the thread to
2147       be properly tidied away.  I have the impression the previous
2148       version of this wrapper worked on x86/amd64 only because the
2149       kernel did not immediately deliver the async signal to this
2150       thread (on ppc it did, which broke the assertion re tst->status
2151       at the top of async_signalhandler()). */
2152    *flags |= SfMayBlock;
2153 }
POST(sys_tkill)2154 POST(sys_tkill)
2155 {
2156    if (VG_(clo_trace_signals))
2157       VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2158                    SARG2, SARG1);
2159 }
2160 
PRE(sys_tgkill)2161 PRE(sys_tgkill)
2162 {
2163    PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2164    PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2165    if (!ML_(client_signal_OK)(ARG3)) {
2166       SET_STATUS_Failure( VKI_EINVAL );
2167       return;
2168    }
2169 
2170    /* Check to see if this kill gave us a pending signal */
2171    *flags |= SfPollAfter;
2172 
2173    if (VG_(clo_trace_signals))
2174       VG_(message)(Vg_DebugMsg,
2175                    "tgkill: sending signal %ld to pid %ld/%ld\n",
2176 		   SARG3, SARG1, SARG2);
2177 
2178    /* If we're sending SIGKILL, check to see if the target is one of
2179       our threads and handle it specially. */
2180    if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2181       SET_STATUS_Success(0);
2182       return;
2183    }
2184 
2185    /* Ask to handle this syscall via the slow route, since that's the
2186       only one that sets tst->status to VgTs_WaitSys.  If the result
2187       of doing the syscall is an immediate run of
2188       async_signalhandler() in m_signals, then we need the thread to
2189       be properly tidied away.  I have the impression the previous
2190       version of this wrapper worked on x86/amd64 only because the
2191       kernel did not immediately deliver the async signal to this
2192       thread (on ppc it did, which broke the assertion re tst->status
2193       at the top of async_signalhandler()). */
2194    *flags |= SfMayBlock;
2195 }
POST(sys_tgkill)2196 POST(sys_tgkill)
2197 {
2198    if (VG_(clo_trace_signals))
2199       VG_(message)(Vg_DebugMsg,
2200                    "tgkill: sent signal %ld to pid %ld/%ld\n",
2201                    SARG3, SARG1, SARG2);
2202 }
2203 
2204 /* ---------------------------------------------------------------------
2205    fadvise64* wrappers
2206    ------------------------------------------------------------------ */
2207 
PRE(sys_fadvise64)2208 PRE(sys_fadvise64)
2209 {
2210    PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2211          SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2212    PRE_REG_READ5(long, "fadvise64",
2213                  int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2214                  vki_size_t, len, int, advice);
2215 }
2216 
PRE(sys_fadvise64_64)2217 PRE(sys_fadvise64_64)
2218 {
2219    PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2220          SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2221    PRE_REG_READ6(long, "fadvise64_64",
2222                  int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2223                  vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2224 }
2225 
2226 /* ---------------------------------------------------------------------
2227    io_* wrappers
2228    ------------------------------------------------------------------ */
2229 
2230 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2231 // and this allows us to control exactly the code that gets run while
2232 // the padding is in place.
2233 
PRE(sys_io_setup)2234 PRE(sys_io_setup)
2235 {
2236    PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2237    PRE_REG_READ2(long, "io_setup",
2238                  unsigned, nr_events, vki_aio_context_t *, ctxp);
2239    PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2240 }
2241 
POST(sys_io_setup)2242 POST(sys_io_setup)
2243 {
2244    SizeT size;
2245    struct vki_aio_ring *r;
2246 
2247    size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2248                        ARG1*sizeof(struct vki_io_event));
2249    r = *(struct vki_aio_ring **)(Addr)ARG2;
2250    vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2251 
2252    ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2253                                       VKI_PROT_READ | VKI_PROT_WRITE,
2254                                       VKI_MAP_ANONYMOUS, -1, 0 );
2255 
2256    POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2257 }
2258 
2259 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2260 // after the syscall.  We must get 'size' from the aio_ring structure,
2261 // before the syscall, while the aio_ring structure still exists.  (And we
2262 // know that we must look at the aio_ring structure because Tom inspected the
2263 // kernel and glibc sources to see what they do, yuk.)
2264 //
2265 // XXX This segment can be implicitly unmapped when aio
2266 // file-descriptors are closed...
PRE(sys_io_destroy)2267 PRE(sys_io_destroy)
2268 {
2269    SizeT size = 0;
2270 
2271    PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2272    PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2273 
2274    // If we are going to seg fault (due to a bogus ARG1) do it as late as
2275    // possible...
2276    if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2277       struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2278       size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2279                           r->nr*sizeof(struct vki_io_event));
2280    }
2281 
2282    SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2283 
2284    if (SUCCESS && RES == 0) {
2285       Bool d = VG_(am_notify_munmap)( ARG1, size );
2286       VG_TRACK( die_mem_munmap, ARG1, size );
2287       if (d)
2288         VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2289                                     "PRE(sys_io_destroy)" );
2290    }
2291 }
2292 
PRE(sys_io_getevents)2293 PRE(sys_io_getevents)
2294 {
2295    *flags |= SfMayBlock;
2296    PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2297          FMT_REGWORD "x )",
2298          (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2299    PRE_REG_READ5(long, "io_getevents",
2300                  vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2301                  struct io_event *, events,
2302                  struct timespec *, timeout);
2303    if (ARG3 > 0)
2304       PRE_MEM_WRITE( "io_getevents(events)",
2305                      ARG4, sizeof(struct vki_io_event)*ARG3 );
2306    if (ARG5 != 0)
2307       PRE_MEM_READ( "io_getevents(timeout)",
2308                     ARG5, sizeof(struct vki_timespec));
2309 }
POST(sys_io_getevents)2310 POST(sys_io_getevents)
2311 {
2312    Int i;
2313    vg_assert(SUCCESS);
2314    if (RES > 0) {
2315       POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2316       for (i = 0; i < RES; i++) {
2317          const struct vki_io_event *vev =
2318             ((struct vki_io_event *)(Addr)ARG4) + i;
2319          const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2320 
2321          switch (cb->aio_lio_opcode) {
2322          case VKI_IOCB_CMD_PREAD:
2323             if (vev->result > 0)
2324                POST_MEM_WRITE( cb->aio_buf, vev->result );
2325             break;
2326 
2327          case VKI_IOCB_CMD_PWRITE:
2328             break;
2329 
2330          case VKI_IOCB_CMD_FSYNC:
2331             break;
2332 
2333          case VKI_IOCB_CMD_FDSYNC:
2334             break;
2335 
2336          case VKI_IOCB_CMD_PREADV:
2337 	     if (vev->result > 0) {
2338                   struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2339                   Int remains = vev->result;
2340                   Int j;
2341 
2342                   for (j = 0; j < cb->aio_nbytes; j++) {
2343                        Int nReadThisBuf = vec[j].iov_len;
2344                        if (nReadThisBuf > remains) nReadThisBuf = remains;
2345                        POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2346                        remains -= nReadThisBuf;
2347                        if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2348                   }
2349 	     }
2350              break;
2351 
2352          case VKI_IOCB_CMD_PWRITEV:
2353              break;
2354 
2355          default:
2356             VG_(message)(Vg_DebugMsg,
2357                         "Warning: unhandled io_getevents opcode: %u\n",
2358                         cb->aio_lio_opcode);
2359             break;
2360          }
2361       }
2362    }
2363 }
2364 
PRE(sys_io_submit)2365 PRE(sys_io_submit)
2366 {
2367    Int i, j;
2368 
2369    PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2370          ARG1, SARG2, ARG3);
2371    PRE_REG_READ3(long, "io_submit",
2372                  vki_aio_context_t, ctx_id, long, nr,
2373                  struct iocb **, iocbpp);
2374    PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2375    if (ARG3 != 0) {
2376       for (i = 0; i < ARG2; i++) {
2377          struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2378          struct vki_iovec *iov;
2379 
2380          PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2381          switch (cb->aio_lio_opcode) {
2382          case VKI_IOCB_CMD_PREAD:
2383             PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2384             break;
2385 
2386          case VKI_IOCB_CMD_PWRITE:
2387             PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2388             break;
2389 
2390          case VKI_IOCB_CMD_FSYNC:
2391             break;
2392 
2393          case VKI_IOCB_CMD_FDSYNC:
2394             break;
2395 
2396          case VKI_IOCB_CMD_PREADV:
2397             iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2398             PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2399             for (j = 0; j < cb->aio_nbytes; j++)
2400                 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2401             break;
2402 
2403          case VKI_IOCB_CMD_PWRITEV:
2404             iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2405             PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2406             for (j = 0; j < cb->aio_nbytes; j++)
2407                 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2408             break;
2409 
2410          default:
2411             VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2412                          cb->aio_lio_opcode);
2413             break;
2414          }
2415       }
2416    }
2417 }
2418 
PRE(sys_io_cancel)2419 PRE(sys_io_cancel)
2420 {
2421    PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2422          (ULong)ARG1, ARG2, ARG3);
2423    PRE_REG_READ3(long, "io_cancel",
2424                  vki_aio_context_t, ctx_id, struct iocb *, iocb,
2425                  struct io_event *, result);
2426    PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2427    PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2428 }
POST(sys_io_cancel)2429 POST(sys_io_cancel)
2430 {
2431    POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2432 }
2433 
2434 /* ---------------------------------------------------------------------
2435    *_mempolicy wrappers
2436    ------------------------------------------------------------------ */
2437 
PRE(sys_mbind)2438 PRE(sys_mbind)
2439 {
2440    PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2441          "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2442          ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2443    PRE_REG_READ6(long, "mbind",
2444                  unsigned long, start, unsigned long, len,
2445                  unsigned long, policy, unsigned long *, nodemask,
2446                  unsigned long, maxnode, unsigned, flags);
2447    if (ARG1 != 0)
2448       PRE_MEM_READ( "mbind(nodemask)", ARG4,
2449                     VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2450 }
2451 
PRE(sys_set_mempolicy)2452 PRE(sys_set_mempolicy)
2453 {
2454    PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2455          SARG1, ARG2, ARG3);
2456    PRE_REG_READ3(long, "set_mempolicy",
2457                  int, policy, unsigned long *, nodemask,
2458                  unsigned long, maxnode);
2459    PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2460                  VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2461 }
2462 
PRE(sys_get_mempolicy)2463 PRE(sys_get_mempolicy)
2464 {
2465    PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2466          FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2467          ARG1, ARG2, ARG3, ARG4, ARG5);
2468    PRE_REG_READ5(long, "get_mempolicy",
2469                  int *, policy, unsigned long *, nodemask,
2470                  unsigned long, maxnode, unsigned long, addr,
2471                  unsigned long, flags);
2472    if (ARG1 != 0)
2473       PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2474    if (ARG2 != 0)
2475       PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2476                      VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2477 }
POST(sys_get_mempolicy)2478 POST(sys_get_mempolicy)
2479 {
2480    if (ARG1 != 0)
2481       POST_MEM_WRITE( ARG1, sizeof(Int) );
2482    if (ARG2 != 0)
2483       POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2484 }
2485 
2486 /* ---------------------------------------------------------------------
2487    fanotify_* wrappers
2488    ------------------------------------------------------------------ */
2489 
PRE(sys_fanotify_init)2490 PRE(sys_fanotify_init)
2491 {
2492    PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2493          ARG1, ARG2);
2494    PRE_REG_READ2(long, "fanotify_init",
2495                  unsigned int, flags, unsigned int, event_f_flags);
2496 }
2497 
POST(sys_fanotify_init)2498 POST(sys_fanotify_init)
2499 {
2500    vg_assert(SUCCESS);
2501    if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2502       VG_(close)(RES);
2503       SET_STATUS_Failure( VKI_EMFILE );
2504    } else {
2505       if (VG_(clo_track_fds))
2506          ML_(record_fd_open_nameless) (tid, RES);
2507    }
2508 }
2509 
PRE(sys_fanotify_mark)2510 PRE(sys_fanotify_mark)
2511 {
2512 #if VG_WORDSIZE == 4
2513    PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2514           FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2515           (HChar *)(Addr)ARG6);
2516    PRE_REG_READ6(long, "sys_fanotify_mark",
2517                  int, fanotify_fd, unsigned int, flags,
2518                  __vki_u32, mask0, __vki_u32, mask1,
2519                  int, dfd, const char *, pathname);
2520    if (ARG6)
2521       PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2522 #elif VG_WORDSIZE == 8
2523    PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2524           SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2525    PRE_REG_READ5(long, "sys_fanotify_mark",
2526                  int, fanotify_fd, unsigned int, flags,
2527                  __vki_u64, mask,
2528                  int, dfd, const char *, pathname);
2529    if (ARG5)
2530       PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2531 #else
2532 #  error Unexpected word size
2533 #endif
2534 }
2535 
2536 /* ---------------------------------------------------------------------
2537    inotify_* wrappers
2538    ------------------------------------------------------------------ */
2539 
PRE(sys_inotify_init)2540 PRE(sys_inotify_init)
2541 {
2542    PRINT("sys_inotify_init ( )");
2543    PRE_REG_READ0(long, "inotify_init");
2544 }
POST(sys_inotify_init)2545 POST(sys_inotify_init)
2546 {
2547    vg_assert(SUCCESS);
2548    if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2549       VG_(close)(RES);
2550       SET_STATUS_Failure( VKI_EMFILE );
2551    } else {
2552       if (VG_(clo_track_fds))
2553          ML_(record_fd_open_nameless) (tid, RES);
2554    }
2555 }
2556 
PRE(sys_inotify_init1)2557 PRE(sys_inotify_init1)
2558 {
2559    PRINT("sys_inotify_init ( %ld )", SARG1);
2560    PRE_REG_READ1(long, "inotify_init", int, flag);
2561 }
2562 
POST(sys_inotify_init1)2563 POST(sys_inotify_init1)
2564 {
2565    vg_assert(SUCCESS);
2566    if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2567       VG_(close)(RES);
2568       SET_STATUS_Failure( VKI_EMFILE );
2569    } else {
2570       if (VG_(clo_track_fds))
2571          ML_(record_fd_open_nameless) (tid, RES);
2572    }
2573 }
2574 
PRE(sys_inotify_add_watch)2575 PRE(sys_inotify_add_watch)
2576 {
2577    PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2578            FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2579    PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2580    PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2581 }
2582 
PRE(sys_inotify_rm_watch)2583 PRE(sys_inotify_rm_watch)
2584 {
2585    PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2586    PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2587 }
2588 
2589 /* ---------------------------------------------------------------------
2590    mq_* wrappers
2591    ------------------------------------------------------------------ */
2592 
PRE(sys_mq_open)2593 PRE(sys_mq_open)
2594 {
2595    PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2596          FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2597    PRE_REG_READ4(long, "mq_open",
2598                  const char *, name, int, oflag, vki_mode_t, mode,
2599                  struct mq_attr *, attr);
2600    PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2601    if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2602       const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2603       PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2604                      (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2605       PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2606                      (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2607    }
2608 }
POST(sys_mq_open)2609 POST(sys_mq_open)
2610 {
2611    vg_assert(SUCCESS);
2612    if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2613       VG_(close)(RES);
2614       SET_STATUS_Failure( VKI_EMFILE );
2615    } else {
2616       if (VG_(clo_track_fds))
2617          ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2618    }
2619 }
2620 
PRE(sys_mq_unlink)2621 PRE(sys_mq_unlink)
2622 {
2623    PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2624    PRE_REG_READ1(long, "mq_unlink", const char *, name);
2625    PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2626 }
2627 
PRE(sys_mq_timedsend)2628 PRE(sys_mq_timedsend)
2629 {
2630    *flags |= SfMayBlock;
2631    PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2632          FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2633          SARG1,ARG2,ARG3,ARG4,ARG5);
2634    PRE_REG_READ5(long, "mq_timedsend",
2635                  vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2636                  unsigned int, msg_prio, const struct timespec *, abs_timeout);
2637    if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2638       SET_STATUS_Failure( VKI_EBADF );
2639    } else {
2640       PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2641       if (ARG5 != 0)
2642          PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2643                         sizeof(struct vki_timespec) );
2644    }
2645 }
2646 
PRE(sys_mq_timedreceive)2647 PRE(sys_mq_timedreceive)
2648 {
2649    *flags |= SfMayBlock;
2650    PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2651          FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2652          SARG1,ARG2,ARG3,ARG4,ARG5);
2653    PRE_REG_READ5(ssize_t, "mq_timedreceive",
2654                  vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2655                  unsigned int *, msg_prio,
2656                  const struct timespec *, abs_timeout);
2657    if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2658       SET_STATUS_Failure( VKI_EBADF );
2659    } else {
2660       PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2661       if (ARG4 != 0)
2662          PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2663                         ARG4, sizeof(unsigned int) );
2664       if (ARG5 != 0)
2665          PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2666                         ARG5, sizeof(struct vki_timespec) );
2667    }
2668 }
POST(sys_mq_timedreceive)2669 POST(sys_mq_timedreceive)
2670 {
2671    POST_MEM_WRITE( ARG2, RES );
2672    if (ARG4 != 0)
2673       POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2674 }
2675 
PRE(sys_mq_notify)2676 PRE(sys_mq_notify)
2677 {
2678    PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2679    PRE_REG_READ2(long, "mq_notify",
2680                  vki_mqd_t, mqdes, const struct sigevent *, notification);
2681    if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2682       SET_STATUS_Failure( VKI_EBADF );
2683    else if (ARG2 != 0)
2684       PRE_MEM_READ( "mq_notify(notification)",
2685                     ARG2, sizeof(struct vki_sigevent) );
2686 }
2687 
PRE(sys_mq_getsetattr)2688 PRE(sys_mq_getsetattr)
2689 {
2690    PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2691          SARG1, ARG2, ARG3 );
2692    PRE_REG_READ3(long, "mq_getsetattr",
2693                  vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2694                  struct mq_attr *, omqstat);
2695    if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2696       SET_STATUS_Failure( VKI_EBADF );
2697    } else {
2698       if (ARG2 != 0) {
2699          const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2700          PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2701                         (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2702       }
2703       if (ARG3 != 0)
2704          PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2705                         sizeof(struct vki_mq_attr) );
2706    }
2707 }
POST(sys_mq_getsetattr)2708 POST(sys_mq_getsetattr)
2709 {
2710    if (ARG3 != 0)
2711       POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2712 }
2713 
2714 /* ---------------------------------------------------------------------
2715    clock_* wrappers
2716    ------------------------------------------------------------------ */
2717 
PRE(sys_clock_settime)2718 PRE(sys_clock_settime)
2719 {
2720    PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2721    PRE_REG_READ2(long, "clock_settime",
2722                  vki_clockid_t, clk_id, const struct timespec *, tp);
2723    PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2724 }
2725 
PRE(sys_clock_gettime)2726 PRE(sys_clock_gettime)
2727 {
2728    PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2729    PRE_REG_READ2(long, "clock_gettime",
2730                  vki_clockid_t, clk_id, struct timespec *, tp);
2731    PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2732 }
POST(sys_clock_gettime)2733 POST(sys_clock_gettime)
2734 {
2735    POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2736 }
2737 
PRE(sys_clock_getres)2738 PRE(sys_clock_getres)
2739 {
2740    PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2741    // Nb: we can't use "RES" as the param name because that's a macro
2742    // defined above!
2743    PRE_REG_READ2(long, "clock_getres",
2744                  vki_clockid_t, clk_id, struct timespec *, res);
2745    if (ARG2 != 0)
2746       PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2747 }
POST(sys_clock_getres)2748 POST(sys_clock_getres)
2749 {
2750    if (ARG2 != 0)
2751       POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2752 }
2753 
PRE(sys_clock_nanosleep)2754 PRE(sys_clock_nanosleep)
2755 {
2756    *flags |= SfMayBlock|SfPostOnFail;
2757    PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
2758          FMT_REGWORD "x )",
2759          SARG1, SARG2, ARG3, ARG4);
2760    PRE_REG_READ4(int32_t, "clock_nanosleep",
2761                  vki_clockid_t, clkid, int, flags,
2762                  const struct timespec *, rqtp, struct timespec *, rmtp);
2763    PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2764    if (ARG4 != 0)
2765       PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2766 }
POST(sys_clock_nanosleep)2767 POST(sys_clock_nanosleep)
2768 {
2769    if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2770       POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2771 }
2772 
2773 /* ---------------------------------------------------------------------
2774    timer_* wrappers
2775    ------------------------------------------------------------------ */
2776 
PRE(sys_timer_create)2777 PRE(sys_timer_create)
2778 {
2779    PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2780          SARG1, ARG2, ARG3);
2781    PRE_REG_READ3(long, "timer_create",
2782                  vki_clockid_t, clockid, struct sigevent *, evp,
2783                  vki_timer_t *, timerid);
2784    if (ARG2 != 0) {
2785       struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
2786       PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2787                     sizeof(vki_sigval_t) );
2788       PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2789                     sizeof(int) );
2790       PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2791                     sizeof(int) );
2792       if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2793           && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2794          PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2795                        (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2796    }
2797    PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2798 }
POST(sys_timer_create)2799 POST(sys_timer_create)
2800 {
2801    POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2802 }
2803 
PRE(sys_timer_settime)2804 PRE(sys_timer_settime)
2805 {
2806    PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
2807           FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
2808    PRE_REG_READ4(long, "timer_settime",
2809                  vki_timer_t, timerid, int, flags,
2810                  const struct itimerspec *, value,
2811                  struct itimerspec *, ovalue);
2812    PRE_MEM_READ( "timer_settime(value)", ARG3,
2813                   sizeof(struct vki_itimerspec) );
2814    if (ARG4 != 0)
2815        PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2816                       sizeof(struct vki_itimerspec) );
2817 }
POST(sys_timer_settime)2818 POST(sys_timer_settime)
2819 {
2820    if (ARG4 != 0)
2821       POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2822 }
2823 
PRE(sys_timer_gettime)2824 PRE(sys_timer_gettime)
2825 {
2826    PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2827    PRE_REG_READ2(long, "timer_gettime",
2828                  vki_timer_t, timerid, struct itimerspec *, value);
2829    PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2830                   sizeof(struct vki_itimerspec));
2831 }
POST(sys_timer_gettime)2832 POST(sys_timer_gettime)
2833 {
2834    POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2835 }
2836 
PRE(sys_timer_getoverrun)2837 PRE(sys_timer_getoverrun)
2838 {
2839    PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
2840    PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2841 }
2842 
PRE(sys_timer_delete)2843 PRE(sys_timer_delete)
2844 {
2845    PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
2846    PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2847 }
2848 
2849 /* ---------------------------------------------------------------------
2850    timerfd* wrappers
2851    See also http://lwn.net/Articles/260172/ for an overview.
2852    See also /usr/src/linux/fs/timerfd.c for the implementation.
2853    ------------------------------------------------------------------ */
2854 
2855 /* Returns True if running on 2.6.22, else False (or False if
2856    cannot be determined). */
linux_kernel_2_6_22(void)2857 static Bool linux_kernel_2_6_22(void)
2858 {
2859    static Int result = -1;
2860    Int fd, read;
2861    HChar release[64];   // large enough
2862    SysRes res;
2863 
2864    if (result == -1) {
2865       res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2866       if (sr_isError(res))
2867          return False;
2868       fd = sr_Res(res);
2869       read = VG_(read)(fd, release, sizeof(release) - 1);
2870       if (read < 0)
2871          return False;
2872       release[read] = 0;
2873       VG_(close)(fd);
2874       //VG_(printf)("kernel release = %s\n", release);
2875       result = VG_(strncmp)(release, "2.6.22", 6) == 0
2876                && ! VG_(isdigit)(release[6]);
2877    }
2878    vg_assert(result == 0 || result == 1);
2879    return result == 1;
2880 }
2881 
PRE(sys_timerfd_create)2882 PRE(sys_timerfd_create)
2883 {
2884    if (linux_kernel_2_6_22()) {
2885       /* 2.6.22 kernel: timerfd system call. */
2886       PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
2887       PRE_REG_READ3(long, "sys_timerfd",
2888                     int, fd, int, clockid, const struct itimerspec *, tmr);
2889       PRE_MEM_READ("timerfd(tmr)", ARG3,
2890                    sizeof(struct vki_itimerspec) );
2891       if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2892          SET_STATUS_Failure( VKI_EBADF );
2893    } else {
2894       /* 2.6.24 and later kernels: timerfd_create system call. */
2895       PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2896       PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2897    }
2898 }
POST(sys_timerfd_create)2899 POST(sys_timerfd_create)
2900 {
2901    if (linux_kernel_2_6_22())
2902    {
2903       /* 2.6.22 kernel: timerfd system call. */
2904       if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2905          VG_(close)(RES);
2906          SET_STATUS_Failure( VKI_EMFILE );
2907       } else {
2908          if (VG_(clo_track_fds))
2909             ML_(record_fd_open_nameless) (tid, RES);
2910       }
2911    }
2912    else
2913    {
2914       /* 2.6.24 and later kernels: timerfd_create system call. */
2915       if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2916          VG_(close)(RES);
2917          SET_STATUS_Failure( VKI_EMFILE );
2918       } else {
2919          if (VG_(clo_track_fds))
2920             ML_(record_fd_open_nameless) (tid, RES);
2921       }
2922    }
2923 }
2924 
PRE(sys_timerfd_gettime)2925 PRE(sys_timerfd_gettime)
2926 {
2927    PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2928    PRE_REG_READ2(long, "timerfd_gettime",
2929                  int, ufd,
2930                  struct vki_itimerspec*, otmr);
2931    if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2932       SET_STATUS_Failure(VKI_EBADF);
2933    else
2934       PRE_MEM_WRITE("timerfd_gettime(result)",
2935                     ARG2, sizeof(struct vki_itimerspec));
2936 }
POST(sys_timerfd_gettime)2937 POST(sys_timerfd_gettime)
2938 {
2939    if (RES == 0)
2940       POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2941 }
2942 
PRE(sys_timerfd_settime)2943 PRE(sys_timerfd_settime)
2944 {
2945    PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
2946          FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
2947    PRE_REG_READ4(long, "timerfd_settime",
2948                  int, ufd,
2949                  int, flags,
2950                  const struct vki_itimerspec*, utmr,
2951                  struct vki_itimerspec*, otmr);
2952    if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2953       SET_STATUS_Failure(VKI_EBADF);
2954    else
2955    {
2956       PRE_MEM_READ("timerfd_settime(result)",
2957                    ARG3, sizeof(struct vki_itimerspec));
2958       if (ARG4)
2959       {
2960          PRE_MEM_WRITE("timerfd_settime(result)",
2961                        ARG4, sizeof(struct vki_itimerspec));
2962       }
2963    }
2964 }
POST(sys_timerfd_settime)2965 POST(sys_timerfd_settime)
2966 {
2967    if (RES == 0 && ARG4 != 0)
2968       POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2969 }
2970 
2971 /* ---------------------------------------------------------------------
2972    capabilities wrappers
2973    ------------------------------------------------------------------ */
2974 
PRE(sys_capget)2975 PRE(sys_capget)
2976 {
2977    PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2978    PRE_REG_READ2(long, "capget",
2979                  vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2980    PRE_MEM_READ( "capget(header)", ARG1,
2981                   sizeof(struct __vki_user_cap_header_struct) );
2982    if (ARG2 != (Addr)NULL)
2983       PRE_MEM_WRITE( "capget(data)", ARG2,
2984                      sizeof(struct __vki_user_cap_data_struct) );
2985 }
POST(sys_capget)2986 POST(sys_capget)
2987 {
2988    if (ARG2 != (Addr)NULL)
2989       POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2990 }
2991 
PRE(sys_capset)2992 PRE(sys_capset)
2993 {
2994    PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2995    PRE_REG_READ2(long, "capset",
2996                  vki_cap_user_header_t, header,
2997                  const vki_cap_user_data_t, data);
2998    PRE_MEM_READ( "capset(header)",
2999                   ARG1, sizeof(struct __vki_user_cap_header_struct) );
3000    PRE_MEM_READ( "capset(data)",
3001                   ARG2, sizeof(struct __vki_user_cap_data_struct) );
3002 }
3003 
3004 /* ---------------------------------------------------------------------
3005    16-bit uid/gid/groups wrappers
3006    ------------------------------------------------------------------ */
3007 
PRE(sys_getuid16)3008 PRE(sys_getuid16)
3009 {
3010    PRINT("sys_getuid16 ( )");
3011    PRE_REG_READ0(long, "getuid16");
3012 }
3013 
PRE(sys_setuid16)3014 PRE(sys_setuid16)
3015 {
3016    PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3017    PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3018 }
3019 
PRE(sys_getgid16)3020 PRE(sys_getgid16)
3021 {
3022    PRINT("sys_getgid16 ( )");
3023    PRE_REG_READ0(long, "getgid16");
3024 }
3025 
PRE(sys_setgid16)3026 PRE(sys_setgid16)
3027 {
3028    PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3029    PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3030 }
3031 
PRE(sys_geteuid16)3032 PRE(sys_geteuid16)
3033 {
3034    PRINT("sys_geteuid16 ( )");
3035    PRE_REG_READ0(long, "geteuid16");
3036 }
3037 
PRE(sys_getegid16)3038 PRE(sys_getegid16)
3039 {
3040    PRINT("sys_getegid16 ( )");
3041    PRE_REG_READ0(long, "getegid16");
3042 }
3043 
PRE(sys_setreuid16)3044 PRE(sys_setreuid16)
3045 {
3046    PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3047    PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3048 }
3049 
PRE(sys_setregid16)3050 PRE(sys_setregid16)
3051 {
3052    PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3053    PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3054 }
3055 
PRE(sys_getgroups16)3056 PRE(sys_getgroups16)
3057 {
3058    PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3059    PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3060    if (ARG1 > 0)
3061       PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3062 }
POST(sys_getgroups16)3063 POST(sys_getgroups16)
3064 {
3065    vg_assert(SUCCESS);
3066    if (ARG1 > 0 && RES > 0)
3067       POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3068 }
3069 
PRE(sys_setgroups16)3070 PRE(sys_setgroups16)
3071 {
3072    PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3073    PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3074    if (ARG1 > 0)
3075       PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3076 }
3077 
3078 /* ---------------------------------------------------------------------
3079    *chown16 wrappers
3080    ------------------------------------------------------------------ */
3081 
PRE(sys_chown16)3082 PRE(sys_chown16)
3083 {
3084    PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3085          FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3086    PRE_REG_READ3(long, "chown16",
3087                  const char *, path,
3088                  vki_old_uid_t, owner, vki_old_gid_t, group);
3089    PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3090 }
3091 
PRE(sys_fchown16)3092 PRE(sys_fchown16)
3093 {
3094    PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3095          FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3096    PRE_REG_READ3(long, "fchown16",
3097                  unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3098 }
3099 
3100 /* ---------------------------------------------------------------------
3101    *xattr wrappers
3102    ------------------------------------------------------------------ */
3103 
PRE(sys_setxattr)3104 PRE(sys_setxattr)
3105 {
3106    *flags |= SfMayBlock;
3107    PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3108          FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3109          ARG4, SARG5);
3110    PRE_REG_READ5(long, "setxattr",
3111                  char *, path, char *, name,
3112                  void *, value, vki_size_t, size, int, flags);
3113    PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3114    PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3115    PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3116 }
3117 
PRE(sys_lsetxattr)3118 PRE(sys_lsetxattr)
3119 {
3120    *flags |= SfMayBlock;
3121    PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3122          FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3123          ARG1, ARG2, ARG3, ARG4, SARG5);
3124    PRE_REG_READ5(long, "lsetxattr",
3125                  char *, path, char *, name,
3126                  void *, value, vki_size_t, size, int, flags);
3127    PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3128    PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3129    PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3130 }
3131 
PRE(sys_fsetxattr)3132 PRE(sys_fsetxattr)
3133 {
3134    *flags |= SfMayBlock;
3135    PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3136          FMT_REGWORD "u, %ld )",
3137          SARG1, ARG2, ARG3, ARG4, SARG5);
3138    PRE_REG_READ5(long, "fsetxattr",
3139                  int, fd, char *, name, void *, value,
3140                  vki_size_t, size, int, flags);
3141    PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3142    PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3143 }
3144 
PRE(sys_getxattr)3145 PRE(sys_getxattr)
3146 {
3147    *flags |= SfMayBlock;
3148    PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3149          FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3150    PRE_REG_READ4(ssize_t, "getxattr",
3151                  char *, path, char *, name, void *, value, vki_size_t, size);
3152    PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3153    PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3154    PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3155 }
POST(sys_getxattr)3156 POST(sys_getxattr)
3157 {
3158    vg_assert(SUCCESS);
3159    if (RES > 0 && ARG3 != (Addr)NULL) {
3160       POST_MEM_WRITE( ARG3, RES );
3161    }
3162 }
3163 
PRE(sys_lgetxattr)3164 PRE(sys_lgetxattr)
3165 {
3166    *flags |= SfMayBlock;
3167    PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3168          FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3169    PRE_REG_READ4(ssize_t, "lgetxattr",
3170                  char *, path, char *, name, void *, value, vki_size_t, size);
3171    PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3172    PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3173    PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3174 }
POST(sys_lgetxattr)3175 POST(sys_lgetxattr)
3176 {
3177    vg_assert(SUCCESS);
3178    if (RES > 0 && ARG3 != (Addr)NULL) {
3179       POST_MEM_WRITE( ARG3, RES );
3180    }
3181 }
3182 
PRE(sys_fgetxattr)3183 PRE(sys_fgetxattr)
3184 {
3185    *flags |= SfMayBlock;
3186    PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3187          FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3188    PRE_REG_READ4(ssize_t, "fgetxattr",
3189                  int, fd, char *, name, void *, value, vki_size_t, size);
3190    PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3191    PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3192 }
POST(sys_fgetxattr)3193 POST(sys_fgetxattr)
3194 {
3195    if (RES > 0 && ARG3 != (Addr)NULL)
3196       POST_MEM_WRITE( ARG3, RES );
3197 }
3198 
PRE(sys_listxattr)3199 PRE(sys_listxattr)
3200 {
3201    *flags |= SfMayBlock;
3202    PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3203          ARG1, ARG2, (ULong)ARG3);
3204    PRE_REG_READ3(ssize_t, "listxattr",
3205                  char *, path, char *, list, vki_size_t, size);
3206    PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3207    PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3208 }
POST(sys_listxattr)3209 POST(sys_listxattr)
3210 {
3211    if (RES > 0 && ARG2 != (Addr)NULL)
3212       POST_MEM_WRITE( ARG2, RES );
3213 }
3214 
PRE(sys_llistxattr)3215 PRE(sys_llistxattr)
3216 {
3217    *flags |= SfMayBlock;
3218    PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3219          ARG1, ARG2, (ULong)ARG3);
3220    PRE_REG_READ3(ssize_t, "llistxattr",
3221                  char *, path, char *, list, vki_size_t, size);
3222    PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3223    PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3224 }
POST(sys_llistxattr)3225 POST(sys_llistxattr)
3226 {
3227    if (RES > 0 && ARG2 != (Addr)NULL)
3228       POST_MEM_WRITE( ARG2, RES );
3229 }
3230 
PRE(sys_flistxattr)3231 PRE(sys_flistxattr)
3232 {
3233    *flags |= SfMayBlock;
3234    PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3235          SARG1, ARG2, ARG3);
3236    PRE_REG_READ3(ssize_t, "flistxattr",
3237                  int, fd, char *, list, vki_size_t, size);
3238    PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3239 }
POST(sys_flistxattr)3240 POST(sys_flistxattr)
3241 {
3242    if (RES > 0 && ARG2 != (Addr)NULL)
3243       POST_MEM_WRITE( ARG2, RES );
3244 }
3245 
PRE(sys_removexattr)3246 PRE(sys_removexattr)
3247 {
3248    *flags |= SfMayBlock;
3249    PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3250          ARG1, ARG2);
3251    PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3252    PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3253    PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3254 }
3255 
PRE(sys_lremovexattr)3256 PRE(sys_lremovexattr)
3257 {
3258    *flags |= SfMayBlock;
3259    PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3260          ARG1, ARG2);
3261    PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3262    PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3263    PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3264 }
3265 
PRE(sys_fremovexattr)3266 PRE(sys_fremovexattr)
3267 {
3268    *flags |= SfMayBlock;
3269    PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3270    PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3271    PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3272 }
3273 
3274 /* ---------------------------------------------------------------------
3275    sched_* wrappers
3276    ------------------------------------------------------------------ */
3277 
PRE(sys_sched_setparam)3278 PRE(sys_sched_setparam)
3279 {
3280    PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3281    PRE_REG_READ2(long, "sched_setparam",
3282                  vki_pid_t, pid, struct sched_param *, p);
3283    PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3284 }
POST(sys_sched_setparam)3285 POST(sys_sched_setparam)
3286 {
3287    POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3288 }
3289 
PRE(sys_sched_getparam)3290 PRE(sys_sched_getparam)
3291 {
3292    PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3293    PRE_REG_READ2(long, "sched_getparam",
3294                  vki_pid_t, pid, struct sched_param *, p);
3295    PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3296 }
POST(sys_sched_getparam)3297 POST(sys_sched_getparam)
3298 {
3299    POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3300 }
3301 
PRE(sys_sched_getscheduler)3302 PRE(sys_sched_getscheduler)
3303 {
3304    PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3305    PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3306 }
3307 
PRE(sys_sched_setscheduler)3308 PRE(sys_sched_setscheduler)
3309 {
3310    PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3311          SARG1, SARG2, ARG3);
3312    PRE_REG_READ3(long, "sched_setscheduler",
3313                  vki_pid_t, pid, int, policy, struct sched_param *, p);
3314    if (ARG3 != 0)
3315       PRE_MEM_READ( "sched_setscheduler(p)",
3316 		    ARG3, sizeof(struct vki_sched_param));
3317 }
3318 
PRE(sys_sched_yield)3319 PRE(sys_sched_yield)
3320 {
3321    *flags |= SfMayBlock;
3322    PRINT("sched_yield()");
3323    PRE_REG_READ0(long, "sys_sched_yield");
3324 }
3325 
PRE(sys_sched_get_priority_max)3326 PRE(sys_sched_get_priority_max)
3327 {
3328    PRINT("sched_get_priority_max ( %ld )", SARG1);
3329    PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3330 }
3331 
PRE(sys_sched_get_priority_min)3332 PRE(sys_sched_get_priority_min)
3333 {
3334    PRINT("sched_get_priority_min ( %ld )", SARG1);
3335    PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3336 }
3337 
PRE(sys_sched_rr_get_interval)3338 PRE(sys_sched_rr_get_interval)
3339 {
3340    PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3341    PRE_REG_READ2(int, "sched_rr_get_interval",
3342                  vki_pid_t, pid,
3343                  struct vki_timespec *, tp);
3344    PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3345                  ARG2, sizeof(struct vki_timespec));
3346 }
3347 
POST(sys_sched_rr_get_interval)3348 POST(sys_sched_rr_get_interval)
3349 {
3350    POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3351 }
3352 
PRE(sys_sched_setaffinity)3353 PRE(sys_sched_setaffinity)
3354 {
3355    PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3356          SARG1, ARG2, ARG3);
3357    PRE_REG_READ3(long, "sched_setaffinity",
3358                  vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3359    PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3360 }
3361 
PRE(sys_sched_getaffinity)3362 PRE(sys_sched_getaffinity)
3363 {
3364    PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3365          SARG1, ARG2, ARG3);
3366    PRE_REG_READ3(long, "sched_getaffinity",
3367                  vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3368    PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3369 }
POST(sys_sched_getaffinity)3370 POST(sys_sched_getaffinity)
3371 {
3372    POST_MEM_WRITE(ARG3, ARG2);
3373 }
3374 
PRE(sys_unshare)3375 PRE(sys_unshare)
3376 {
3377    PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3378    PRE_REG_READ1(int, "unshare", unsigned long, flags);
3379 }
3380 
3381 /* ---------------------------------------------------------------------
3382    miscellaneous wrappers
3383    ------------------------------------------------------------------ */
3384 
PRE(sys_munlockall)3385 PRE(sys_munlockall)
3386 {
3387    *flags |= SfMayBlock;
3388    PRINT("sys_munlockall ( )");
3389    PRE_REG_READ0(long, "munlockall");
3390 }
3391 
3392 // This has different signatures for different platforms.
3393 //
3394 //  x86:   int  sys_pipe(unsigned long __user *fildes);
3395 //  AMD64: long sys_pipe(int *fildes);
3396 //  ppc32: int  sys_pipe(int __user *fildes);
3397 //  ppc64: int  sys_pipe(int __user *fildes);
3398 //
3399 // The type of the argument is most important, and it is an array of 32 bit
3400 // values in all cases.  (The return type differs across platforms, but it
3401 // is not used.)  So we use 'int' as its type.  This fixed bug #113230 which
3402 // was caused by using an array of 'unsigned long's, which didn't work on
3403 // AMD64.
PRE(sys_pipe)3404 PRE(sys_pipe)
3405 {
3406    PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3407    PRE_REG_READ1(int, "pipe", int *, filedes);
3408    PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3409 }
POST(sys_pipe)3410 POST(sys_pipe)
3411 {
3412    Int *p = (Int *)(Addr)ARG1;
3413    if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3414        !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3415       VG_(close)(p[0]);
3416       VG_(close)(p[1]);
3417       SET_STATUS_Failure( VKI_EMFILE );
3418    } else {
3419       POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3420       if (VG_(clo_track_fds)) {
3421          ML_(record_fd_open_nameless)(tid, p[0]);
3422          ML_(record_fd_open_nameless)(tid, p[1]);
3423       }
3424    }
3425 }
3426 
3427 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3428    there's a second arg containing flags to be applied to the new file
3429    descriptors.  It hardly seems worth the effort to factor out the
3430    duplicated code, hence: */
PRE(sys_pipe2)3431 PRE(sys_pipe2)
3432 {
3433    PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3434    PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3435    PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3436 }
POST(sys_pipe2)3437 POST(sys_pipe2)
3438 {
3439    Int *p = (Int *)(Addr)ARG1;
3440    if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3441        !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3442       VG_(close)(p[0]);
3443       VG_(close)(p[1]);
3444       SET_STATUS_Failure( VKI_EMFILE );
3445    } else {
3446       POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3447       if (VG_(clo_track_fds)) {
3448          ML_(record_fd_open_nameless)(tid, p[0]);
3449          ML_(record_fd_open_nameless)(tid, p[1]);
3450       }
3451    }
3452 }
3453 
PRE(sys_dup3)3454 PRE(sys_dup3)
3455 {
3456    PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3457          FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3458    PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3459    if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3460       SET_STATUS_Failure( VKI_EBADF );
3461 }
3462 
POST(sys_dup3)3463 POST(sys_dup3)
3464 {
3465    vg_assert(SUCCESS);
3466    if (VG_(clo_track_fds))
3467       ML_(record_fd_open_named)(tid, RES);
3468 }
3469 
PRE(sys_quotactl)3470 PRE(sys_quotactl)
3471 {
3472    PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3473          FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3474    PRE_REG_READ4(long, "quotactl",
3475                  unsigned int, cmd, const char *, special, vki_qid_t, id,
3476                  void *, addr);
3477    PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3478 }
3479 
PRE(sys_waitid)3480 PRE(sys_waitid)
3481 {
3482    *flags |= SfMayBlock;
3483    PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3484          SARG1, SARG2, ARG3, SARG4, ARG5);
3485    PRE_REG_READ5(int32_t, "sys_waitid",
3486                  int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3487                  int, options, struct vki_rusage *, ru);
3488    PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3489    if (ARG5 != 0)
3490       PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3491 }
POST(sys_waitid)3492 POST(sys_waitid)
3493 {
3494    POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3495    if (ARG5 != 0)
3496       POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3497 }
3498 
PRE(sys_sync_file_range)3499 PRE(sys_sync_file_range)
3500 {
3501    *flags |= SfMayBlock;
3502 #if VG_WORDSIZE == 4
3503    PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3504          SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3505    PRE_REG_READ6(long, "sync_file_range",
3506                  int, fd,
3507                  unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3508                  unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3509                  unsigned int, flags);
3510 #elif VG_WORDSIZE == 8
3511    PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3512          SARG1, SARG2, SARG3, ARG4);
3513    PRE_REG_READ4(long, "sync_file_range",
3514                  int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3515                  unsigned int, flags);
3516 #else
3517 #  error Unexpected word size
3518 #endif
3519    if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3520       SET_STATUS_Failure( VKI_EBADF );
3521 }
3522 
PRE(sys_sync_file_range2)3523 PRE(sys_sync_file_range2)
3524 {
3525    *flags |= SfMayBlock;
3526 #if VG_WORDSIZE == 4
3527    PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3528          SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3529    PRE_REG_READ6(long, "sync_file_range2",
3530                  int, fd, unsigned int, flags,
3531                  unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3532                  unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3533 #elif VG_WORDSIZE == 8
3534    PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3535          SARG1, ARG2, SARG3, SARG4);
3536    PRE_REG_READ4(long, "sync_file_range2",
3537                  int, fd, unsigned int, flags,
3538                  vki_loff_t, offset, vki_loff_t, nbytes);
3539 #else
3540 #  error Unexpected word size
3541 #endif
3542    if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3543       SET_STATUS_Failure( VKI_EBADF );
3544 }
3545 
PRE(sys_stime)3546 PRE(sys_stime)
3547 {
3548    PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
3549    PRE_REG_READ1(int, "stime", vki_time_t*, t);
3550    PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3551 }
3552 
PRE(sys_perf_event_open)3553 PRE(sys_perf_event_open)
3554 {
3555    struct vki_perf_event_attr *attr;
3556    PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
3557          FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
3558    PRE_REG_READ5(long, "perf_event_open",
3559                  struct vki_perf_event_attr *, attr,
3560                  vki_pid_t, pid, int, cpu, int, group_fd,
3561                  unsigned long, flags);
3562    attr = (struct vki_perf_event_attr *)(Addr)ARG1;
3563    PRE_MEM_READ( "perf_event_open(attr->size)",
3564                  (Addr)&attr->size, sizeof(attr->size) );
3565    PRE_MEM_READ( "perf_event_open(attr)",
3566                  (Addr)attr, attr->size );
3567 }
3568 
POST(sys_perf_event_open)3569 POST(sys_perf_event_open)
3570 {
3571    vg_assert(SUCCESS);
3572    if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3573       VG_(close)(RES);
3574       SET_STATUS_Failure( VKI_EMFILE );
3575    } else {
3576       if (VG_(clo_track_fds))
3577          ML_(record_fd_open_nameless)(tid, RES);
3578    }
3579 }
3580 
PRE(sys_getcpu)3581 PRE(sys_getcpu)
3582 {
3583    PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3584          FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
3585    PRE_REG_READ3(int, "getcpu",
3586                  unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3587    if (ARG1 != 0)
3588       PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3589    if (ARG2 != 0)
3590       PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3591    if (ARG3 != 0)
3592       PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3593 }
3594 
POST(sys_getcpu)3595 POST(sys_getcpu)
3596 {
3597    if (ARG1 != 0)
3598       POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3599    if (ARG2 != 0)
3600       POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3601    if (ARG3 != 0)
3602       POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3603 }
3604 
PRE(sys_move_pages)3605 PRE(sys_move_pages)
3606 {
3607    PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
3608          FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3609          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3610    PRE_REG_READ6(int, "move_pages",
3611                  vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3612                  const int *, nodes, int *, status, int, flags);
3613    PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3614    if (ARG4)
3615       PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3616    PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3617 }
3618 
POST(sys_move_pages)3619 POST(sys_move_pages)
3620 {
3621    POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3622 }
3623 
PRE(sys_getrandom)3624 PRE(sys_getrandom)
3625 {
3626    PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3627          FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
3628    PRE_REG_READ3(int, "getrandom",
3629                  char *, buf, vki_size_t, count, unsigned int, flags);
3630    PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3631 }
3632 
POST(sys_getrandom)3633 POST(sys_getrandom)
3634 {
3635    POST_MEM_WRITE( ARG1, ARG2 );
3636 }
3637 
PRE(sys_memfd_create)3638 PRE(sys_memfd_create)
3639 {
3640    PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
3641          ARG1, ARG2);
3642    PRE_REG_READ2(int, "memfd_create",
3643                  char *, uname, unsigned int, flags);
3644    PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3645 }
3646 
POST(sys_memfd_create)3647 POST(sys_memfd_create)
3648 {
3649    vg_assert(SUCCESS);
3650    if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3651       VG_(close)(RES);
3652       SET_STATUS_Failure( VKI_EMFILE );
3653    } else {
3654       if (VG_(clo_track_fds))
3655          ML_(record_fd_open_nameless)(tid, RES);
3656    }
3657 }
3658 
PRE(sys_membarrier)3659 PRE(sys_membarrier)
3660 {
3661    PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
3662    PRE_REG_READ1(int, "membarrier", int, flags);
3663 }
3664 
PRE(sys_syncfs)3665 PRE(sys_syncfs)
3666 {
3667    *flags |= SfMayBlock;
3668    PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
3669    PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3670 }
3671 
PRE(sys_statx)3672 PRE(sys_statx)
3673 {
3674    FUSE_COMPATIBLE_MAY_BLOCK();
3675    PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
3676          ARG1,ARG2,(char*)(Addr)ARG2,ARG3,ARG4,ARG5);
3677    PRE_REG_READ5(long, "statx",
3678                  int, dirfd, char *, file_name, int, flags,
3679                  unsigned int, mask, struct statx *, buf);
3680    PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 );
3681    PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
3682 }
POST(sys_statx)3683 POST(sys_statx)
3684 {
3685    POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
3686 }
3687 
3688 /* ---------------------------------------------------------------------
3689    utime wrapper
3690    ------------------------------------------------------------------ */
3691 
PRE(sys_utime)3692 PRE(sys_utime)
3693 {
3694    *flags |= SfMayBlock;
3695    PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
3696    PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3697    PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3698    if (ARG2 != 0)
3699       PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3700 }
3701 
3702 /* ---------------------------------------------------------------------
3703    lseek wrapper
3704    ------------------------------------------------------------------ */
3705 
PRE(sys_lseek)3706 PRE(sys_lseek)
3707 {
3708    PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
3709          ARG1, SARG2, ARG3);
3710    PRE_REG_READ3(vki_off_t, "lseek",
3711                  unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3712 }
3713 
3714 /* ---------------------------------------------------------------------
3715    readahead wrapper
3716    ------------------------------------------------------------------ */
3717 
PRE(sys_readahead)3718 PRE(sys_readahead)
3719 {
3720    *flags |= SfMayBlock;
3721 #if VG_WORDSIZE == 4
3722    PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
3723          SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3724    PRE_REG_READ4(vki_off_t, "readahead",
3725                  int, fd, unsigned, MERGE64_FIRST(offset),
3726                  unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3727 #elif VG_WORDSIZE == 8
3728    PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3729    PRE_REG_READ3(vki_off_t, "readahead",
3730                  int, fd, vki_loff_t, offset, vki_size_t, count);
3731 #else
3732 #  error Unexpected word size
3733 #endif
3734    if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3735       SET_STATUS_Failure( VKI_EBADF );
3736 }
3737 
3738 /* ---------------------------------------------------------------------
3739    sig* wrappers
3740    ------------------------------------------------------------------ */
3741 
PRE(sys_sigpending)3742 PRE(sys_sigpending)
3743 {
3744    PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
3745    PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3746    PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3747 }
POST(sys_sigpending)3748 POST(sys_sigpending)
3749 {
3750    POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3751 }
3752 
3753 // This syscall is not used on amd64/Linux -- it only provides
3754 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3755 // This wrapper is only suitable for 32-bit architectures.
3756 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3757 // conditional compilation like this?)
3758 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3759     || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
PRE(sys_sigprocmask)3760 PRE(sys_sigprocmask)
3761 {
3762    vki_old_sigset_t* set;
3763    vki_old_sigset_t* oldset;
3764    vki_sigset_t bigger_set;
3765    vki_sigset_t bigger_oldset;
3766 
3767    PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3768    PRE_REG_READ3(long, "sigprocmask",
3769                  int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3770    if (ARG2 != 0)
3771       PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3772    if (ARG3 != 0)
3773       PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3774 
3775    // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3776    // vki_sigset_t params.
3777    set    = (vki_old_sigset_t*)(Addr)ARG2;
3778    oldset = (vki_old_sigset_t*)(Addr)ARG3;
3779 
3780    VG_(memset)(&bigger_set,    0, sizeof(vki_sigset_t));
3781    VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3782    if (set)
3783       bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3784 
3785    SET_STATUS_from_SysRes(
3786       VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3787                                 set ? &bigger_set    : NULL,
3788                              oldset ? &bigger_oldset : NULL)
3789    );
3790 
3791    if (oldset)
3792       *oldset = bigger_oldset.sig[0];
3793 
3794    if (SUCCESS)
3795       *flags |= SfPollAfter;
3796 }
POST(sys_sigprocmask)3797 POST(sys_sigprocmask)
3798 {
3799    vg_assert(SUCCESS);
3800    if (RES == 0 && ARG3 != 0)
3801       POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3802 }
3803 
3804 /* Convert from non-RT to RT sigset_t's */
3805 static
convert_sigset_to_rt(const vki_old_sigset_t * oldset,vki_sigset_t * set)3806 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3807 {
3808    VG_(sigemptyset)(set);
3809    set->sig[0] = *oldset;
3810 }
PRE(sys_sigaction)3811 PRE(sys_sigaction)
3812 {
3813    vki_sigaction_toK_t   new, *newp;
3814    vki_sigaction_fromK_t old, *oldp;
3815 
3816    PRINT("sys_sigaction ( %ld, %#lx, %#lx )",  SARG1, ARG2, ARG3);
3817    PRE_REG_READ3(int, "sigaction",
3818                  int, signum, const struct old_sigaction *, act,
3819                  struct old_sigaction *, oldact);
3820 
3821    newp = oldp = NULL;
3822 
3823    if (ARG2 != 0) {
3824       struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
3825       PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3826       PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3827       PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3828       if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3829           && (sa->sa_flags & VKI_SA_RESTORER))
3830          PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3831    }
3832 
3833    if (ARG3 != 0) {
3834       PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3835       oldp = &old;
3836    }
3837 
3838    /* If the new or old sigaction is not NULL, but the structs
3839       aren't accessible then sigaction returns EFAULT and we cannot
3840       use either struct for our own bookkeeping. Just fail early. */
3841    if (ARG2 != 0
3842        && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3843                                sizeof(struct vki_old_sigaction))) {
3844       VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3845                 (void *)(Addr)ARG2);
3846       SET_STATUS_Failure ( VKI_EFAULT );
3847    } else if ((ARG3 != 0
3848                && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3849                                        sizeof(struct vki_old_sigaction)))) {
3850       VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3851                 (void *)(Addr)ARG3);
3852       SET_STATUS_Failure ( VKI_EFAULT );
3853    } else {
3854       if (ARG2 != 0) {
3855          struct vki_old_sigaction *oldnew =
3856             (struct vki_old_sigaction *)(Addr)ARG2;
3857 
3858          new.ksa_handler = oldnew->ksa_handler;
3859          new.sa_flags = oldnew->sa_flags;
3860          new.sa_restorer = oldnew->sa_restorer;
3861          convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3862          newp = &new;
3863       }
3864 
3865       SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3866 
3867       if (ARG3 != 0 && SUCCESS && RES == 0) {
3868          struct vki_old_sigaction *oldold =
3869             (struct vki_old_sigaction *)(Addr)ARG3;
3870 
3871          oldold->ksa_handler = oldp->ksa_handler;
3872          oldold->sa_flags = oldp->sa_flags;
3873          oldold->sa_restorer = oldp->sa_restorer;
3874          oldold->sa_mask = oldp->sa_mask.sig[0];
3875       }
3876   }
3877 }
POST(sys_sigaction)3878 POST(sys_sigaction)
3879 {
3880    vg_assert(SUCCESS);
3881    if (RES == 0 && ARG3 != 0)
3882       POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3883 }
3884 #endif
3885 
PRE(sys_signalfd)3886 PRE(sys_signalfd)
3887 {
3888    PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
3889          (ULong)ARG3);
3890    PRE_REG_READ3(long, "sys_signalfd",
3891                  int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3892    PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3893    if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3894       SET_STATUS_Failure( VKI_EBADF );
3895 }
POST(sys_signalfd)3896 POST(sys_signalfd)
3897 {
3898    if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3899       VG_(close)(RES);
3900       SET_STATUS_Failure( VKI_EMFILE );
3901    } else {
3902       if (VG_(clo_track_fds))
3903          ML_(record_fd_open_nameless) (tid, RES);
3904    }
3905 }
3906 
PRE(sys_signalfd4)3907 PRE(sys_signalfd4)
3908 {
3909    PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3910          SARG1, ARG2, ARG3, SARG4);
3911    PRE_REG_READ4(long, "sys_signalfd4",
3912                  int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3913    PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3914    if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3915       SET_STATUS_Failure( VKI_EBADF );
3916 }
POST(sys_signalfd4)3917 POST(sys_signalfd4)
3918 {
3919    if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3920       VG_(close)(RES);
3921       SET_STATUS_Failure( VKI_EMFILE );
3922    } else {
3923       if (VG_(clo_track_fds))
3924          ML_(record_fd_open_nameless) (tid, RES);
3925    }
3926 }
3927 
3928 
3929 /* ---------------------------------------------------------------------
3930    rt_sig* wrappers
3931    ------------------------------------------------------------------ */
3932 
PRE(sys_rt_sigaction)3933 PRE(sys_rt_sigaction)
3934 {
3935    PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3936          FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3937    PRE_REG_READ4(long, "rt_sigaction",
3938                  int, signum, const struct sigaction *, act,
3939                  struct sigaction *, oldact, vki_size_t, sigsetsize);
3940 
3941    if (ARG2 != 0) {
3942       vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
3943       PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3944       PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3945       PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3946       if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3947           && (sa->sa_flags & VKI_SA_RESTORER))
3948          PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3949    }
3950    if (ARG3 != 0)
3951       PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3952 
3953    /* If the new or old sigaction is not NULL, but the structs
3954       aren't accessible then sigaction returns EFAULT and we cannot
3955       use either struct for our own bookkeeping. Just fail early. */
3956    if (ARG2 != 0
3957        && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3958                                sizeof(vki_sigaction_toK_t))) {
3959       VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3960                 (void *)(Addr)ARG2);
3961       SET_STATUS_Failure ( VKI_EFAULT );
3962    } else if ((ARG3 != 0
3963                && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3964                                        sizeof(vki_sigaction_fromK_t)))) {
3965       VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3966                 (void *)(Addr)ARG3);
3967       SET_STATUS_Failure ( VKI_EFAULT );
3968    } else {
3969 
3970       // XXX: doesn't seem right to be calling do_sys_sigaction for
3971       // sys_rt_sigaction... perhaps this function should be renamed
3972       // VG_(do_sys_rt_sigaction)()  --njn
3973 
3974       SET_STATUS_from_SysRes(
3975          VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
3976                                (vki_sigaction_fromK_t *)(Addr)ARG3)
3977       );
3978    }
3979 }
POST(sys_rt_sigaction)3980 POST(sys_rt_sigaction)
3981 {
3982    vg_assert(SUCCESS);
3983    if (RES == 0 && ARG3 != 0)
3984       POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3985 }
3986 
PRE(sys_rt_sigprocmask)3987 PRE(sys_rt_sigprocmask)
3988 {
3989    PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3990          FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3991    PRE_REG_READ4(long, "rt_sigprocmask",
3992                  int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3993                  vki_size_t, sigsetsize);
3994    if (ARG2 != 0)
3995       PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3996    if (ARG3 != 0)
3997       PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3998 
3999    // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4000    // Since we want to use the set and oldset for bookkeeping we also want
4001    // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4002    if (sizeof(vki_sigset_t) != ARG4)
4003       SET_STATUS_Failure( VKI_EINVAL );
4004    else if (ARG2 != 0
4005              && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4006             VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4007                       (void *)(Addr)ARG2);
4008             SET_STATUS_Failure ( VKI_EFAULT );
4009          }
4010    else if (ARG3 != 0
4011              && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4012             VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4013                       (void *)(Addr)ARG3);
4014             SET_STATUS_Failure ( VKI_EFAULT );
4015          }
4016 
4017    else {
4018       SET_STATUS_from_SysRes(
4019                   VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4020                                             (vki_sigset_t*) (Addr)ARG2,
4021                                             (vki_sigset_t*) (Addr)ARG3 )
4022       );
4023    }
4024 
4025    if (SUCCESS)
4026       *flags |= SfPollAfter;
4027 }
POST(sys_rt_sigprocmask)4028 POST(sys_rt_sigprocmask)
4029 {
4030    vg_assert(SUCCESS);
4031    if (RES == 0 && ARG3 != 0)
4032       POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4033 }
4034 
PRE(sys_rt_sigpending)4035 PRE(sys_rt_sigpending)
4036 {
4037    PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4038    PRE_REG_READ2(long, "rt_sigpending",
4039                  vki_sigset_t *, set, vki_size_t, sigsetsize);
4040    PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4041 }
POST(sys_rt_sigpending)4042 POST(sys_rt_sigpending)
4043 {
4044    POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4045 }
4046 
PRE(sys_rt_sigtimedwait)4047 PRE(sys_rt_sigtimedwait)
4048 {
4049    *flags |= SfMayBlock;
4050    PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4051          FMT_REGWORD "x, %" FMT_REGWORD "u )",
4052          ARG1, ARG2, ARG3, ARG4);
4053    PRE_REG_READ4(long, "rt_sigtimedwait",
4054                  const vki_sigset_t *, set, vki_siginfo_t *, info,
4055                  const struct timespec *, timeout, vki_size_t, sigsetsize);
4056    if (ARG1 != 0)
4057       PRE_MEM_READ(  "rt_sigtimedwait(set)",  ARG1, sizeof(vki_sigset_t));
4058    if (ARG2 != 0)
4059       PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4060    if (ARG3 != 0)
4061       PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4062                     ARG3, sizeof(struct vki_timespec) );
4063 }
POST(sys_rt_sigtimedwait)4064 POST(sys_rt_sigtimedwait)
4065 {
4066    if (ARG2 != 0)
4067       POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4068 }
4069 
PRE(sys_rt_sigqueueinfo)4070 PRE(sys_rt_sigqueueinfo)
4071 {
4072    PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4073          SARG1, SARG2, ARG3);
4074    PRE_REG_READ3(long, "rt_sigqueueinfo",
4075                  int, pid, int, sig, vki_siginfo_t *, uinfo);
4076    if (ARG2 != 0)
4077       PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4078 }
POST(sys_rt_sigqueueinfo)4079 POST(sys_rt_sigqueueinfo)
4080 {
4081    if (!ML_(client_signal_OK)(ARG2))
4082       SET_STATUS_Failure( VKI_EINVAL );
4083 }
4084 
PRE(sys_rt_tgsigqueueinfo)4085 PRE(sys_rt_tgsigqueueinfo)
4086 {
4087    PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4088          SARG1, SARG2, SARG3, ARG4);
4089    PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4090                  int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4091    if (ARG3 != 0)
4092       PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4093 }
4094 
POST(sys_rt_tgsigqueueinfo)4095 POST(sys_rt_tgsigqueueinfo)
4096 {
4097    if (!ML_(client_signal_OK)(ARG3))
4098       SET_STATUS_Failure( VKI_EINVAL );
4099 }
4100 
4101 // XXX: x86-specific?  The kernel prototypes for the different archs are
4102 //      hard to decipher.
PRE(sys_rt_sigsuspend)4103 PRE(sys_rt_sigsuspend)
4104 {
4105    /* The C library interface to sigsuspend just takes a pointer to
4106       a signal mask but this system call has two arguments - a pointer
4107       to the mask and the number of bytes used by it. The kernel insists
4108       on the size being equal to sizeof(sigset_t) however and will just
4109       return EINVAL if it isn't.
4110     */
4111    *flags |= SfMayBlock;
4112    PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4113          ARG1, ARG2 );
4114    PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4115    if (ARG1 != (Addr)NULL) {
4116       PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4117       if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4118          VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4119          /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4120             be killable by VG_(nuke_all_threads_except).
4121             We thus silently ignore the user request to mask this signal.
4122             Note that this is similar to what is done for e.g.
4123             sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4124       } else {
4125          SET_STATUS_Failure(VKI_EFAULT);
4126       }
4127    }
4128 }
4129 
4130 /* ---------------------------------------------------------------------
4131    linux msg* wrapper helpers
4132    ------------------------------------------------------------------ */
4133 
4134 void
ML_(linux_PRE_sys_msgsnd)4135 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4136                             UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4137 {
4138    /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4139    struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4140    PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4141    PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4142 }
4143 
4144 void
ML_(linux_PRE_sys_msgrcv)4145 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4146                             UWord arg0, UWord arg1, UWord arg2,
4147                             UWord arg3, UWord arg4 )
4148 {
4149    /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4150                      long msgtyp, int msgflg); */
4151    struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4152    PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4153    PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4154 }
4155 void
ML_(linux_POST_sys_msgrcv)4156 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4157                              UWord res,
4158                              UWord arg0, UWord arg1, UWord arg2,
4159                              UWord arg3, UWord arg4 )
4160 {
4161    struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4162    POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4163    POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4164 }
4165 
4166 void
ML_(linux_PRE_sys_msgctl)4167 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4168                             UWord arg0, UWord arg1, UWord arg2 )
4169 {
4170    /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4171    switch (arg1 /* cmd */) {
4172    case VKI_IPC_INFO:
4173    case VKI_MSG_INFO:
4174    case VKI_IPC_INFO|VKI_IPC_64:
4175    case VKI_MSG_INFO|VKI_IPC_64:
4176       PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4177                      arg2, sizeof(struct vki_msginfo) );
4178       break;
4179    case VKI_IPC_STAT:
4180    case VKI_MSG_STAT:
4181       PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4182                      arg2, sizeof(struct vki_msqid_ds) );
4183       break;
4184    case VKI_IPC_STAT|VKI_IPC_64:
4185    case VKI_MSG_STAT|VKI_IPC_64:
4186       PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4187                      arg2, sizeof(struct vki_msqid64_ds) );
4188       break;
4189    case VKI_IPC_SET:
4190       PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4191                     arg2, sizeof(struct vki_msqid_ds) );
4192       break;
4193    case VKI_IPC_SET|VKI_IPC_64:
4194       PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4195                     arg2, sizeof(struct vki_msqid64_ds) );
4196       break;
4197    }
4198 }
4199 void
ML_(linux_POST_sys_msgctl)4200 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4201                              UWord res,
4202                              UWord arg0, UWord arg1, UWord arg2 )
4203 {
4204    switch (arg1 /* cmd */) {
4205    case VKI_IPC_INFO:
4206    case VKI_MSG_INFO:
4207    case VKI_IPC_INFO|VKI_IPC_64:
4208    case VKI_MSG_INFO|VKI_IPC_64:
4209       POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4210       break;
4211    case VKI_IPC_STAT:
4212    case VKI_MSG_STAT:
4213       POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4214       break;
4215    case VKI_IPC_STAT|VKI_IPC_64:
4216    case VKI_MSG_STAT|VKI_IPC_64:
4217       POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4218       break;
4219    }
4220 }
4221 
4222 /* ---------------------------------------------------------------------
4223    Generic handler for sys_ipc
4224    Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4225    are either direct system calls, or are all implemented via sys_ipc.
4226    ------------------------------------------------------------------ */
4227 #ifdef __NR_ipc
deref_Addr(ThreadId tid,Addr a,const HChar * s)4228 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4229 {
4230    Addr* a_p = (Addr*)a;
4231    PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4232    return *a_p;
4233 }
4234 
semctl_cmd_has_4args(UWord cmd)4235 static Bool semctl_cmd_has_4args (UWord cmd)
4236 {
4237    switch (cmd & ~VKI_IPC_64)
4238    {
4239    case VKI_IPC_INFO:
4240    case VKI_SEM_INFO:
4241    case VKI_IPC_STAT:
4242    case VKI_SEM_STAT:
4243    case VKI_IPC_SET:
4244    case VKI_GETALL:
4245    case VKI_SETALL:
4246       return True;
4247    default:
4248       return False;
4249    }
4250 }
4251 
PRE(sys_ipc)4252 PRE(sys_ipc)
4253 {
4254    PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4255          ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4256 
4257    switch (ARG1 /* call */) {
4258    case VKI_SEMOP:
4259       PRE_REG_READ5(int, "ipc",
4260                     vki_uint, call, int, first, int, second, int, third,
4261                     void *, ptr);
4262       ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4263       *flags |= SfMayBlock;
4264       break;
4265    case VKI_SEMGET:
4266       PRE_REG_READ4(int, "ipc",
4267                     vki_uint, call, int, first, int, second, int, third);
4268       break;
4269    case VKI_SEMCTL:
4270    {
4271       PRE_REG_READ5(int, "ipc",
4272                     vki_uint, call, int, first, int, second, int, third,
4273                     void *, ptr);
4274       UWord arg;
4275       if (semctl_cmd_has_4args(ARG4))
4276          arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4277       else
4278          arg = 0;
4279       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4280       break;
4281    }
4282    case VKI_SEMTIMEDOP:
4283       PRE_REG_READ6(int, "ipc",
4284                     vki_uint, call, int, first, int, second, int, third,
4285                     void *, ptr, long, fifth);
4286       ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4287       *flags |= SfMayBlock;
4288       break;
4289    case VKI_MSGSND:
4290       PRE_REG_READ5(int, "ipc",
4291                     vki_uint, call, int, first, int, second, int, third,
4292                     void *, ptr);
4293       ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4294       if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4295          *flags |= SfMayBlock;
4296       break;
4297    case VKI_MSGRCV:
4298    {
4299       PRE_REG_READ5(int, "ipc",
4300                     vki_uint, call, int, first, int, second, int, third,
4301                     void *, ptr);
4302       Addr msgp;
4303       Word msgtyp;
4304 
4305       msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4306                          "msgrcv(msgp)" );
4307       msgtyp = deref_Addr( tid,
4308                            (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4309                            "msgrcv(msgp)" );
4310 
4311       ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4312 
4313       if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4314          *flags |= SfMayBlock;
4315       break;
4316    }
4317    case VKI_MSGGET:
4318       PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4319       break;
4320    case VKI_MSGCTL:
4321       PRE_REG_READ5(int, "ipc",
4322                     vki_uint, call, int, first, int, second, int, third,
4323                     void *, ptr);
4324       ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4325       break;
4326    case VKI_SHMAT:
4327    {
4328       PRE_REG_READ5(int, "ipc",
4329                     vki_uint, call, int, first, int, second, int, third,
4330                     void *, ptr);
4331       UWord w;
4332       PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4333       w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4334       if (w == 0)
4335          SET_STATUS_Failure( VKI_EINVAL );
4336       else
4337          ARG5 = w;
4338       break;
4339    }
4340    case VKI_SHMDT:
4341       PRE_REG_READ5(int, "ipc",
4342                     vki_uint, call, int, first, int, second, int, third,
4343                     void *, ptr);
4344       if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4345 	 SET_STATUS_Failure( VKI_EINVAL );
4346       break;
4347    case VKI_SHMGET:
4348       PRE_REG_READ4(int, "ipc",
4349                     vki_uint, call, int, first, int, second, int, third);
4350       if (ARG4 & VKI_SHM_HUGETLB) {
4351          static Bool warning_given = False;
4352          ARG4 &= ~VKI_SHM_HUGETLB;
4353          if (!warning_given) {
4354             warning_given = True;
4355             VG_(umsg)(
4356                "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4357          }
4358       }
4359       break;
4360    case VKI_SHMCTL: /* IPCOP_shmctl */
4361       PRE_REG_READ5(int, "ipc",
4362                     vki_uint, call, int, first, int, second, int, third,
4363                     void *, ptr);
4364       ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4365       break;
4366    default:
4367       VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4368       VG_(core_panic)("... bye!\n");
4369       break; /*NOTREACHED*/
4370    }
4371 }
4372 
POST(sys_ipc)4373 POST(sys_ipc)
4374 {
4375    vg_assert(SUCCESS);
4376    switch (ARG1 /* call */) {
4377    case VKI_SEMOP:
4378    case VKI_SEMGET:
4379       break;
4380    case VKI_SEMCTL:
4381    {
4382       UWord arg;
4383       if (semctl_cmd_has_4args(ARG4))
4384          arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4385       else
4386          arg = 0;
4387       ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4388       break;
4389    }
4390    case VKI_SEMTIMEDOP:
4391    case VKI_MSGSND:
4392       break;
4393    case VKI_MSGRCV:
4394    {
4395       Addr msgp;
4396       Word msgtyp;
4397 
4398       msgp = deref_Addr( tid,
4399 			 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4400 			 "msgrcv(msgp)" );
4401       msgtyp = deref_Addr( tid,
4402 			   (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4403 			   "msgrcv(msgp)" );
4404 
4405       ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4406       break;
4407    }
4408    case VKI_MSGGET:
4409       break;
4410    case VKI_MSGCTL:
4411       ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4412       break;
4413    case VKI_SHMAT:
4414    {
4415       Addr addr;
4416 
4417       /* force readability. before the syscall it is
4418        * indeed uninitialized, as can be seen in
4419        * glibc/sysdeps/unix/sysv/linux/shmat.c */
4420       POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4421 
4422       addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4423       ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4424       break;
4425    }
4426    case VKI_SHMDT:
4427       ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4428       break;
4429    case VKI_SHMGET:
4430       break;
4431    case VKI_SHMCTL:
4432       ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4433       break;
4434    default:
4435       VG_(message)(Vg_DebugMsg,
4436 		   "FATAL: unhandled syscall(ipc) %lu\n",
4437 		   ARG1 );
4438       VG_(core_panic)("... bye!\n");
4439       break; /*NOTREACHED*/
4440    }
4441 }
4442 #endif
4443 
PRE(sys_semget)4444 PRE(sys_semget)
4445 {
4446    PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4447    PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4448 }
4449 
PRE(sys_semop)4450 PRE(sys_semop)
4451 {
4452    *flags |= SfMayBlock;
4453    PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4454          SARG1, ARG2, ARG3);
4455    PRE_REG_READ3(long, "semop",
4456                  int, semid, struct sembuf *, sops, unsigned, nsoops);
4457    ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4458 }
4459 
PRE(sys_semctl)4460 PRE(sys_semctl)
4461 {
4462    switch (ARG3 & ~VKI_IPC_64) {
4463    case VKI_IPC_INFO:
4464    case VKI_SEM_INFO:
4465       PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4466             SARG3, ARG4);
4467       PRE_REG_READ4(long, "semctl",
4468                     int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4469       break;
4470    case VKI_IPC_STAT:
4471    case VKI_SEM_STAT:
4472    case VKI_IPC_SET:
4473       PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4474             SARG3, ARG4);
4475       PRE_REG_READ4(long, "semctl",
4476                     int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4477       break;
4478    case VKI_GETALL:
4479    case VKI_SETALL:
4480       PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4481             SARG3, ARG4);
4482       PRE_REG_READ4(long, "semctl",
4483                     int, semid, int, semnum, int, cmd, unsigned short *, arg);
4484       break;
4485    default:
4486       PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4487       PRE_REG_READ3(long, "semctl",
4488                     int, semid, int, semnum, int, cmd);
4489       break;
4490    }
4491 #ifdef VGP_amd64_linux
4492    ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4493 #else
4494    ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4495 #endif
4496 }
4497 
POST(sys_semctl)4498 POST(sys_semctl)
4499 {
4500 #ifdef VGP_amd64_linux
4501    ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4502 #else
4503    ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4504 #endif
4505 }
4506 
PRE(sys_semtimedop)4507 PRE(sys_semtimedop)
4508 {
4509    *flags |= SfMayBlock;
4510    PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
4511          FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4512    PRE_REG_READ4(long, "semtimedop",
4513                  int, semid, struct sembuf *, sops, unsigned, nsoops,
4514                  struct timespec *, timeout);
4515    ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4516 }
4517 
PRE(sys_msgget)4518 PRE(sys_msgget)
4519 {
4520    PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4521    PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4522 }
4523 
PRE(sys_msgsnd)4524 PRE(sys_msgsnd)
4525 {
4526    PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4527          SARG1, ARG2, ARG3, SARG4);
4528    PRE_REG_READ4(long, "msgsnd",
4529                  int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4530    ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4531    if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4532       *flags |= SfMayBlock;
4533 }
4534 
PRE(sys_msgrcv)4535 PRE(sys_msgrcv)
4536 {
4537    PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
4538          SARG1, ARG2, ARG3, SARG4, SARG5);
4539    PRE_REG_READ5(long, "msgrcv",
4540                  int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4541                  long, msgytp, int, msgflg);
4542    ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4543    if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4544       *flags |= SfMayBlock;
4545 }
POST(sys_msgrcv)4546 POST(sys_msgrcv)
4547 {
4548    ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4549 }
4550 
PRE(sys_msgctl)4551 PRE(sys_msgctl)
4552 {
4553    PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4554    PRE_REG_READ3(long, "msgctl",
4555                  int, msqid, int, cmd, struct msqid_ds *, buf);
4556    ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4557 }
4558 
POST(sys_msgctl)4559 POST(sys_msgctl)
4560 {
4561    ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4562 }
4563 
PRE(sys_shmget)4564 PRE(sys_shmget)
4565 {
4566    PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
4567    PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4568    if (ARG3 & VKI_SHM_HUGETLB) {
4569       static Bool warning_given = False;
4570       ARG3 &= ~VKI_SHM_HUGETLB;
4571       if (!warning_given) {
4572          warning_given = True;
4573          VG_(umsg)(
4574             "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4575       }
4576    }
4577 }
4578 
PRE(sys_shmat)4579 PRE(sys_shmat)
4580 {
4581    UWord arg2tmp;
4582    PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4583    PRE_REG_READ3(long, "shmat",
4584                  int, shmid, const void *, shmaddr, int, shmflg);
4585 #if defined(VGP_arm_linux)
4586    /* Round the attach address down to an VKI_SHMLBA boundary if the
4587       client requested rounding.  See #222545.  This is necessary only
4588       on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4589       other linux targets it is the same as the page size. */
4590    if (ARG3 & VKI_SHM_RND)
4591       ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4592 #endif
4593    arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4594    if (arg2tmp == 0)
4595       SET_STATUS_Failure( VKI_EINVAL );
4596    else
4597       ARG2 = arg2tmp;  // used in POST
4598 }
4599 
POST(sys_shmat)4600 POST(sys_shmat)
4601 {
4602    ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4603 }
4604 
PRE(sys_shmdt)4605 PRE(sys_shmdt)
4606 {
4607    PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
4608    PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4609    if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4610       SET_STATUS_Failure( VKI_EINVAL );
4611 }
4612 
POST(sys_shmdt)4613 POST(sys_shmdt)
4614 {
4615    ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4616 }
4617 
PRE(sys_shmctl)4618 PRE(sys_shmctl)
4619 {
4620    PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4621    PRE_REG_READ3(long, "shmctl",
4622                  int, shmid, int, cmd, struct shmid_ds *, buf);
4623 #ifdef VGP_amd64_linux
4624    ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4625 #else
4626    ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4627 #endif
4628 }
4629 
POST(sys_shmctl)4630 POST(sys_shmctl)
4631 {
4632 #ifdef VGP_amd64_linux
4633    ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4634 #else
4635    ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4636 #endif
4637 }
4638 
4639 
4640 /* ---------------------------------------------------------------------
4641    Generic handler for sys_socketcall
4642    Depending on the platform, some socket related syscalls (e.g. socketpair,
4643    socket, bind, ...)
4644    are either direct system calls, or are all implemented via sys_socketcall.
4645    ------------------------------------------------------------------ */
4646 #ifdef __NR_socketcall
PRE(sys_socketcall)4647 PRE(sys_socketcall)
4648 {
4649 #  define ARG2_0  (((UWord*)(Addr)ARG2)[0])
4650 #  define ARG2_1  (((UWord*)(Addr)ARG2)[1])
4651 #  define ARG2_2  (((UWord*)(Addr)ARG2)[2])
4652 #  define ARG2_3  (((UWord*)(Addr)ARG2)[3])
4653 #  define ARG2_4  (((UWord*)(Addr)ARG2)[4])
4654 #  define ARG2_5  (((UWord*)(Addr)ARG2)[5])
4655 
4656 // call PRE_MEM_READ and check for EFAULT result.
4657 #define PRE_MEM_READ_ef(msg, arg, size)                         \
4658    {                                                            \
4659       PRE_MEM_READ( msg, arg, size);                            \
4660       if (!ML_(valid_client_addr)(arg, size, tid, NULL)) {      \
4661          SET_STATUS_Failure( VKI_EFAULT );                      \
4662          break;                                                 \
4663       }                                                         \
4664    }
4665 
4666    *flags |= SfMayBlock;
4667    PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4668    PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4669 
4670    switch (ARG1 /* request */) {
4671 
4672    case VKI_SYS_SOCKETPAIR:
4673       /* int socketpair(int d, int type, int protocol, int sv[2]); */
4674       PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4675       ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4676       break;
4677 
4678    case VKI_SYS_SOCKET:
4679       /* int socket(int domain, int type, int protocol); */
4680       PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4681       break;
4682 
4683    case VKI_SYS_BIND:
4684       /* int bind(int sockfd, struct sockaddr *my_addr,
4685                   int addrlen); */
4686       PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4687       ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4688       break;
4689 
4690    case VKI_SYS_LISTEN:
4691       /* int listen(int s, int backlog); */
4692       PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4693       break;
4694 
4695    case VKI_SYS_ACCEPT:
4696       /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4697       PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4698       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4699       break;
4700 
4701    case VKI_SYS_ACCEPT4:
4702       /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4703       PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4704       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4705       break;
4706 
4707    case VKI_SYS_SENDTO:
4708       /* int sendto(int s, const void *msg, int len,
4709                     unsigned int flags,
4710                     const struct sockaddr *to, int tolen); */
4711       PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4712       ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4713                                    ARG2_3, ARG2_4, ARG2_5 );
4714       break;
4715 
4716    case VKI_SYS_SEND:
4717       /* int send(int s, const void *msg, size_t len, int flags); */
4718       PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4719       ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4720       break;
4721 
4722    case VKI_SYS_RECVFROM:
4723       /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4724          struct sockaddr *from, int *fromlen); */
4725       PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4726       ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4727                                      ARG2_3, ARG2_4, ARG2_5 );
4728       break;
4729 
4730    case VKI_SYS_RECV:
4731       /* int recv(int s, void *buf, int len, unsigned int flags); */
4732       /* man 2 recv says:
4733          The  recv call is normally used only on a connected socket
4734          (see connect(2)) and is identical to recvfrom with a  NULL
4735          from parameter.
4736       */
4737       PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4738       ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4739       break;
4740 
4741    case VKI_SYS_CONNECT:
4742       /* int connect(int sockfd,
4743                      struct sockaddr *serv_addr, int addrlen ); */
4744       PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4745       ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4746       break;
4747 
4748    case VKI_SYS_SETSOCKOPT:
4749       /* int setsockopt(int s, int level, int optname,
4750                         const void *optval, int optlen); */
4751       PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4752       ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4753                                      ARG2_3, ARG2_4 );
4754       break;
4755 
4756    case VKI_SYS_GETSOCKOPT:
4757       /* int getsockopt(int s, int level, int optname,
4758                         void *optval, socklen_t *optlen); */
4759       PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4760       ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4761                                      ARG2_3, ARG2_4 );
4762       break;
4763 
4764    case VKI_SYS_GETSOCKNAME:
4765       /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4766       PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4767       ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4768       break;
4769 
4770    case VKI_SYS_GETPEERNAME:
4771       /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4772       PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4773       ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4774       break;
4775 
4776    case VKI_SYS_SHUTDOWN:
4777       /* int shutdown(int s, int how); */
4778       PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4779       break;
4780 
4781    case VKI_SYS_SENDMSG:
4782       /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4783       PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4784       ML_(generic_PRE_sys_sendmsg)( tid, "msg",
4785                                     (struct vki_msghdr *)(Addr)ARG2_1 );
4786       break;
4787 
4788    case VKI_SYS_RECVMSG:
4789       /* int recvmsg(int s, struct msghdr *msg, int flags); */
4790       PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4791       ML_(generic_PRE_sys_recvmsg)( tid, "msg",
4792                                     (struct vki_msghdr *)(Addr)ARG2_1 );
4793       break;
4794 
4795    case VKI_SYS_RECVMMSG:
4796       /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4797                       struct timespec *timeout); */
4798       PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4799       ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4800                                    ARG2_4 );
4801       break;
4802 
4803    case VKI_SYS_SENDMMSG:
4804       /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4805       PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4806       ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4807       break;
4808 
4809    default:
4810       VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4811       SET_STATUS_Failure( VKI_EINVAL );
4812       break;
4813    }
4814 #  undef ARG2_0
4815 #  undef ARG2_1
4816 #  undef ARG2_2
4817 #  undef ARG2_3
4818 #  undef ARG2_4
4819 #  undef ARG2_5
4820 }
4821 
POST(sys_socketcall)4822 POST(sys_socketcall)
4823 {
4824 #  define ARG2_0  (((UWord*)(Addr)ARG2)[0])
4825 #  define ARG2_1  (((UWord*)(Addr)ARG2)[1])
4826 #  define ARG2_2  (((UWord*)(Addr)ARG2)[2])
4827 #  define ARG2_3  (((UWord*)(Addr)ARG2)[3])
4828 #  define ARG2_4  (((UWord*)(Addr)ARG2)[4])
4829 #  define ARG2_5  (((UWord*)(Addr)ARG2)[5])
4830 
4831    SysRes r;
4832    vg_assert(SUCCESS);
4833    switch (ARG1 /* request */) {
4834 
4835    case VKI_SYS_SOCKETPAIR:
4836       r = ML_(generic_POST_sys_socketpair)(
4837              tid, VG_(mk_SysRes_Success)(RES),
4838              ARG2_0, ARG2_1, ARG2_2, ARG2_3
4839           );
4840       SET_STATUS_from_SysRes(r);
4841       break;
4842 
4843    case VKI_SYS_SOCKET:
4844       r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4845       SET_STATUS_from_SysRes(r);
4846       break;
4847 
4848    case VKI_SYS_BIND:
4849       /* int bind(int sockfd, struct sockaddr *my_addr,
4850 			int addrlen); */
4851       break;
4852 
4853    case VKI_SYS_LISTEN:
4854       /* int listen(int s, int backlog); */
4855       break;
4856 
4857    case VKI_SYS_ACCEPT:
4858    case VKI_SYS_ACCEPT4:
4859       /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4860       /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4861      r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4862                                             ARG2_0, ARG2_1, ARG2_2 );
4863      SET_STATUS_from_SysRes(r);
4864      break;
4865 
4866    case VKI_SYS_SENDTO:
4867       break;
4868 
4869    case VKI_SYS_SEND:
4870       break;
4871 
4872    case VKI_SYS_RECVFROM:
4873       ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4874                                            ARG2_0, ARG2_1, ARG2_2,
4875                                            ARG2_3, ARG2_4, ARG2_5 );
4876       break;
4877 
4878    case VKI_SYS_RECV:
4879       ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4880       break;
4881 
4882    case VKI_SYS_CONNECT:
4883       break;
4884 
4885    case VKI_SYS_SETSOCKOPT:
4886       break;
4887 
4888    case VKI_SYS_GETSOCKOPT:
4889       ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4890                                       ARG2_0, ARG2_1,
4891                                       ARG2_2, ARG2_3, ARG2_4 );
4892       break;
4893 
4894    case VKI_SYS_GETSOCKNAME:
4895       ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4896                                               ARG2_0, ARG2_1, ARG2_2 );
4897       break;
4898 
4899    case VKI_SYS_GETPEERNAME:
4900       ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4901                                               ARG2_0, ARG2_1, ARG2_2 );
4902       break;
4903 
4904    case VKI_SYS_SHUTDOWN:
4905       break;
4906 
4907    case VKI_SYS_SENDMSG:
4908       break;
4909 
4910    case VKI_SYS_RECVMSG:
4911       ML_(generic_POST_sys_recvmsg)( tid, "msg",
4912                                      (struct vki_msghdr *)(Addr)ARG2_1, RES );
4913       break;
4914 
4915    case VKI_SYS_RECVMMSG:
4916       ML_(linux_POST_sys_recvmmsg)( tid, RES,
4917                                     ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4918       break;
4919 
4920    case VKI_SYS_SENDMMSG:
4921       ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4922       break;
4923 
4924    default:
4925       VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4926       VG_(core_panic)("... bye!\n");
4927       break; /*NOTREACHED*/
4928    }
4929 #  undef ARG2_0
4930 #  undef ARG2_1
4931 #  undef ARG2_2
4932 #  undef ARG2_3
4933 #  undef ARG2_4
4934 #  undef ARG2_5
4935 }
4936 #endif
4937 
PRE(sys_socket)4938 PRE(sys_socket)
4939 {
4940    PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4941    PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4942 }
POST(sys_socket)4943 POST(sys_socket)
4944 {
4945    SysRes r;
4946    vg_assert(SUCCESS);
4947    r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4948    SET_STATUS_from_SysRes(r);
4949 }
4950 
PRE(sys_setsockopt)4951 PRE(sys_setsockopt)
4952 {
4953    PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
4954          "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
4955    PRE_REG_READ5(long, "setsockopt",
4956                  int, s, int, level, int, optname,
4957                  const void *, optval, unsigned, optlen); // socklen_t
4958    ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4959 }
4960 
PRE(sys_getsockopt)4961 PRE(sys_getsockopt)
4962 {
4963    PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
4964          SARG1, SARG2, SARG3, ARG4, SARG5);
4965    PRE_REG_READ5(long, "getsockopt",
4966                  int, s, int, level, int, optname,
4967                  void *, optval, int, *optlen);
4968    ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4969 }
POST(sys_getsockopt)4970 POST(sys_getsockopt)
4971 {
4972    vg_assert(SUCCESS);
4973    ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4974                                        ARG1,ARG2,ARG3,ARG4,ARG5);
4975 }
4976 
PRE(sys_connect)4977 PRE(sys_connect)
4978 {
4979    *flags |= SfMayBlock;
4980    PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4981    PRE_REG_READ3(long, "connect",
4982                  int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4983    ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4984 }
4985 
PRE(sys_accept)4986 PRE(sys_accept)
4987 {
4988    *flags |= SfMayBlock;
4989    PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4990          SARG1, ARG2, ARG3);
4991    PRE_REG_READ3(long, "accept",
4992                  int, s, struct sockaddr *, addr, int *, addrlen);
4993    ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4994 }
POST(sys_accept)4995 POST(sys_accept)
4996 {
4997    SysRes r;
4998    vg_assert(SUCCESS);
4999    r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5000                                          ARG1,ARG2,ARG3);
5001    SET_STATUS_from_SysRes(r);
5002 }
5003 
PRE(sys_accept4)5004 PRE(sys_accept4)
5005 {
5006    *flags |= SfMayBlock;
5007    PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5008          SARG1, ARG2, ARG3, SARG4);
5009    PRE_REG_READ4(long, "accept4",
5010                  int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5011    ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5012 }
POST(sys_accept4)5013 POST(sys_accept4)
5014 {
5015    SysRes r;
5016    vg_assert(SUCCESS);
5017    r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5018                                          ARG1,ARG2,ARG3);
5019    SET_STATUS_from_SysRes(r);
5020 }
5021 
PRE(sys_send)5022 PRE(sys_send)
5023 {
5024    *flags |= SfMayBlock;
5025    PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5026          FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5027    PRE_REG_READ4(long, "send",
5028                  int, s, const void *, msg, vki_size_t, len,
5029                  int, flags);
5030 
5031    ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5032 }
5033 
PRE(sys_sendto)5034 PRE(sys_sendto)
5035 {
5036    *flags |= SfMayBlock;
5037    PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5038          FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5039          SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5040    PRE_REG_READ6(long, "sendto",
5041                  int, s, const void *, msg, vki_size_t, len,
5042                  unsigned int, flags,
5043                  const struct sockaddr *, to, int, tolen);
5044    ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5045 }
5046 
PRE(sys_recv)5047 PRE (sys_recv)
5048 {
5049   *flags |= SfMayBlock;
5050   PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5051          FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5052   PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5053                  unsigned int, flags);
5054   ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5055 }
5056 
POST(sys_recv)5057 POST (sys_recv)
5058 {
5059   ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5060 }
5061 
PRE(sys_recvfrom)5062 PRE(sys_recvfrom)
5063 {
5064    *flags |= SfMayBlock;
5065    PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5066          FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5067          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5068    PRE_REG_READ6(long, "recvfrom",
5069                  int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5070                  struct sockaddr *, from, int *, fromlen);
5071    ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5072 }
POST(sys_recvfrom)5073 POST(sys_recvfrom)
5074 {
5075    vg_assert(SUCCESS);
5076    ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5077                                        ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5078 }
5079 
PRE(sys_sendmsg)5080 PRE(sys_sendmsg)
5081 {
5082    *flags |= SfMayBlock;
5083    PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5084          SARG1, ARG2, ARG3);
5085    PRE_REG_READ3(long, "sendmsg",
5086                  int, s, const struct msghdr *, msg, unsigned int, flags);
5087    ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5088 }
5089 
PRE(sys_recvmsg)5090 PRE(sys_recvmsg)
5091 {
5092    *flags |= SfMayBlock;
5093    PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5094          SARG1, ARG2, ARG3);
5095    PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5096                  unsigned int, flags);
5097    ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5098 }
POST(sys_recvmsg)5099 POST(sys_recvmsg)
5100 {
5101    ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5102                                  RES);
5103 }
5104 
PRE(sys_shutdown)5105 PRE(sys_shutdown)
5106 {
5107    *flags |= SfMayBlock;
5108    PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5109    PRE_REG_READ2(int, "shutdown", int, s, int, how);
5110 }
5111 
PRE(sys_bind)5112 PRE(sys_bind)
5113 {
5114    PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5115    PRE_REG_READ3(long, "bind",
5116                  int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5117    ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5118 }
5119 
PRE(sys_listen)5120 PRE(sys_listen)
5121 {
5122    PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5123    PRE_REG_READ2(long, "listen", int, s, int, backlog);
5124 }
5125 
PRE(sys_getsockname)5126 PRE(sys_getsockname)
5127 {
5128    PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5129          SARG1, ARG2, ARG3);
5130    PRE_REG_READ3(long, "getsockname",
5131                  int, s, struct sockaddr *, name, int *, namelen);
5132    ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5133 }
POST(sys_getsockname)5134 POST(sys_getsockname)
5135 {
5136    vg_assert(SUCCESS);
5137    ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5138                                           ARG1,ARG2,ARG3);
5139 }
5140 
PRE(sys_getpeername)5141 PRE(sys_getpeername)
5142 {
5143    PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5144          SARG1, ARG2, ARG3);
5145    PRE_REG_READ3(long, "getpeername",
5146                  int, s, struct sockaddr *, name, int *, namelen);
5147    ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5148 }
POST(sys_getpeername)5149 POST(sys_getpeername)
5150 {
5151    vg_assert(SUCCESS);
5152    ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5153                                           ARG1,ARG2,ARG3);
5154 }
5155 
PRE(sys_socketpair)5156 PRE(sys_socketpair)
5157 {
5158    PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5159          SARG3, ARG4);
5160    PRE_REG_READ4(long, "socketpair",
5161                  int, d, int, type, int, protocol, int*, sv);
5162    ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5163 }
POST(sys_socketpair)5164 POST(sys_socketpair)
5165 {
5166    vg_assert(SUCCESS);
5167    ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5168                                          ARG1,ARG2,ARG3,ARG4);
5169 }
5170 
5171 
5172 /* ---------------------------------------------------------------------
5173    *at wrappers
5174    ------------------------------------------------------------------ */
5175 
PRE(sys_openat)5176 PRE(sys_openat)
5177 {
5178    HChar  name[30];   // large enough
5179    SysRes sres;
5180 
5181    if (ARG3 & VKI_O_CREAT) {
5182       // 4-arg version
5183       PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5184             SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5185       PRE_REG_READ4(long, "openat",
5186                     int, dfd, const char *, filename, int, flags, int, mode);
5187    } else {
5188       // 3-arg version
5189       PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5190             SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5191       PRE_REG_READ3(long, "openat",
5192                     int, dfd, const char *, filename, int, flags);
5193    }
5194 
5195    PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5196 
5197    /* For absolute filenames, dfd is ignored.  If dfd is AT_FDCWD,
5198       filename is relative to cwd.  When comparing dfd against AT_FDCWD,
5199       be sure only to compare the bottom 32 bits. */
5200    if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5201        && *(Char *)(Addr)ARG2 != '/'
5202        && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5203        && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5204       SET_STATUS_Failure( VKI_EBADF );
5205 
5206    /* Handle the case where the open is of /proc/self/cmdline or
5207       /proc/<pid>/cmdline, and just give it a copy of the fd for the
5208       fake file we cooked up at startup (in m_main).  Also, seek the
5209       cloned fd back to the start. */
5210 
5211    VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5212    if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5213        && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5214            || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5215       sres = VG_(dup)( VG_(cl_cmdline_fd) );
5216       SET_STATUS_from_SysRes( sres );
5217       if (!sr_isError(sres)) {
5218          OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5219          if (off < 0)
5220             SET_STATUS_Failure( VKI_EMFILE );
5221       }
5222       return;
5223    }
5224 
5225    /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5226 
5227    VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5228    if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5229        && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5230            || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5231       sres = VG_(dup)( VG_(cl_auxv_fd) );
5232       SET_STATUS_from_SysRes( sres );
5233       if (!sr_isError(sres)) {
5234          OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5235          if (off < 0)
5236             SET_STATUS_Failure( VKI_EMFILE );
5237       }
5238       return;
5239    }
5240 
5241    /* Otherwise handle normally */
5242    *flags |= SfMayBlock;
5243 }
5244 
POST(sys_openat)5245 POST(sys_openat)
5246 {
5247    vg_assert(SUCCESS);
5248    if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5249       VG_(close)(RES);
5250       SET_STATUS_Failure( VKI_EMFILE );
5251    } else {
5252       if (VG_(clo_track_fds))
5253          ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5254    }
5255 }
5256 
PRE(sys_mkdirat)5257 PRE(sys_mkdirat)
5258 {
5259    *flags |= SfMayBlock;
5260    PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5261          SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5262    PRE_REG_READ3(long, "mkdirat",
5263                  int, dfd, const char *, pathname, int, mode);
5264    PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5265 }
5266 
PRE(sys_mknodat)5267 PRE(sys_mknodat)
5268 {
5269    PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5270          FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5271    PRE_REG_READ4(long, "mknodat",
5272                  int, dfd, const char *, pathname, int, mode, unsigned, dev);
5273    PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5274 }
5275 
PRE(sys_fchownat)5276 PRE(sys_fchownat)
5277 {
5278    PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5279           FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5280    PRE_REG_READ4(long, "fchownat",
5281                  int, dfd, const char *, path,
5282                  vki_uid_t, owner, vki_gid_t, group);
5283    PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5284 }
5285 
PRE(sys_futimesat)5286 PRE(sys_futimesat)
5287 {
5288    PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5289          SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5290    PRE_REG_READ3(long, "futimesat",
5291                  int, dfd, char *, filename, struct timeval *, tvp);
5292    if (ARG2 != 0)
5293       PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5294    if (ARG3 != 0)
5295       PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5296 }
5297 
PRE(sys_utimensat)5298 PRE(sys_utimensat)
5299 {
5300    PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5301           FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5302    PRE_REG_READ4(long, "utimensat",
5303                  int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5304    if (ARG2 != 0)
5305       PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5306    if (ARG3 != 0) {
5307       /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5308          then the tv_sec field is ignored.  */
5309       struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5310       PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5311                     (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5312       PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5313                     (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5314       if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5315          if (times[0].tv_nsec != VKI_UTIME_NOW
5316              && times[0].tv_nsec != VKI_UTIME_OMIT)
5317             PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5318                           (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5319          if (times[1].tv_nsec != VKI_UTIME_NOW
5320              && times[1].tv_nsec != VKI_UTIME_OMIT)
5321             PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5322                           (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5323       }
5324    }
5325 }
5326 
PRE(sys_newfstatat)5327 PRE(sys_newfstatat)
5328 {
5329    FUSE_COMPATIBLE_MAY_BLOCK();
5330    PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5331          SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5332    PRE_REG_READ3(long, "fstatat",
5333                  int, dfd, char *, file_name, struct stat *, buf);
5334    PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5335    PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5336 }
5337 
POST(sys_newfstatat)5338 POST(sys_newfstatat)
5339 {
5340    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5341 }
5342 
PRE(sys_unlinkat)5343 PRE(sys_unlinkat)
5344 {
5345    *flags |= SfMayBlock;
5346    PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5347          (HChar*)(Addr)ARG2);
5348    PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5349    PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5350 }
5351 
PRE(sys_renameat)5352 PRE(sys_renameat)
5353 {
5354    PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5355          FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5356          ARG4, (HChar*)(Addr)ARG4);
5357    PRE_REG_READ4(long, "renameat",
5358                  int, olddfd, const char *, oldpath,
5359                  int, newdfd, const char *, newpath);
5360    PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5361    PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5362 }
5363 
PRE(sys_renameat2)5364 PRE(sys_renameat2)
5365 {
5366    PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5367          "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5368          ARG4, (HChar*)(Addr)ARG4, ARG5);
5369    PRE_REG_READ5(long, "renameat2",
5370                  int, olddfd, const char *, oldpath,
5371                  int, newdfd, const char *, newpath,
5372                  unsigned int, flags);
5373    PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5374    PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5375 }
5376 
PRE(sys_linkat)5377 PRE(sys_linkat)
5378 {
5379    *flags |= SfMayBlock;
5380    PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5381          "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5382          (HChar*)(Addr)ARG4, SARG5);
5383    PRE_REG_READ5(long, "linkat",
5384                  int, olddfd, const char *, oldpath,
5385                  int, newdfd, const char *, newpath,
5386                  int, flags);
5387    PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5388    PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5389 }
5390 
PRE(sys_symlinkat)5391 PRE(sys_symlinkat)
5392 {
5393    *flags |= SfMayBlock;
5394    PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5395          "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5396    PRE_REG_READ3(long, "symlinkat",
5397                  const char *, oldpath, int, newdfd, const char *, newpath);
5398    PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5399    PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5400 }
5401 
PRE(sys_readlinkat)5402 PRE(sys_readlinkat)
5403 {
5404    HChar name[30];       // large enough
5405    Word  saved = SYSNO;
5406 
5407    PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5408           FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5409    PRE_REG_READ4(long, "readlinkat",
5410                  int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5411    PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5412    PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5413 
5414    /*
5415     * Handle the case where readlinkat is looking at /proc/self/exe or
5416     * /proc/<pid>/exe.
5417     */
5418    VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5419    if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5420        && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5421            || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5422       VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5423       SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5424                                                       ARG3, ARG4));
5425    } else {
5426       /* Normal case */
5427       SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5428    }
5429 
5430    if (SUCCESS && RES > 0)
5431       POST_MEM_WRITE( ARG3, RES );
5432 }
5433 
PRE(sys_fchmodat)5434 PRE(sys_fchmodat)
5435 {
5436    PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5437          SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5438    PRE_REG_READ3(long, "fchmodat",
5439                  int, dfd, const char *, path, vki_mode_t, mode);
5440    PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5441 }
5442 
PRE(sys_faccessat)5443 PRE(sys_faccessat)
5444 {
5445    PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5446          SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5447    PRE_REG_READ3(long, "faccessat",
5448                  int, dfd, const char *, pathname, int, mode);
5449    PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5450 }
5451 
PRE(sys_name_to_handle_at)5452 PRE(sys_name_to_handle_at)
5453 {
5454    PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
5455           FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
5456           (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5457    PRE_REG_READ5(int, "name_to_handle_at",
5458                  int, dfd, const char *, name,
5459                  struct vki_file_handle *, handle,
5460                  int *, mnt_id, int, flag);
5461    PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5462    if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
5463       struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5464       PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5465       PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5466    }
5467    PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5468 }
5469 
POST(sys_name_to_handle_at)5470 POST(sys_name_to_handle_at)
5471 {
5472    struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5473    POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5474    POST_MEM_WRITE( ARG4, sizeof(int) );
5475 }
5476 
PRE(sys_open_by_handle_at)5477 PRE(sys_open_by_handle_at)
5478 {
5479    *flags |= SfMayBlock;
5480    PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
5481          ARG2, SARG3);
5482    PRE_REG_READ3(int, "open_by_handle_at",
5483                  int, mountdirfd,
5484                  struct vki_file_handle *, handle,
5485                  int, flags);
5486    PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
5487                  sizeof(struct vki_file_handle) +
5488                  ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
5489 }
5490 
POST(sys_open_by_handle_at)5491 POST(sys_open_by_handle_at)
5492 {
5493    vg_assert(SUCCESS);
5494    if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5495       VG_(close)(RES);
5496       SET_STATUS_Failure( VKI_EMFILE );
5497    } else {
5498       if (VG_(clo_track_fds))
5499          ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5500    }
5501 }
5502 
5503 /* ---------------------------------------------------------------------
5504    p{read,write}v wrappers
5505    ------------------------------------------------------------------ */
5506 
PRE(sys_preadv)5507 PRE(sys_preadv)
5508 {
5509    Int i;
5510    struct vki_iovec * vec;
5511    *flags |= SfMayBlock;
5512 #if VG_WORDSIZE == 4
5513    /* Note that the offset argument here is in lo+hi order on both
5514       big and little endian platforms... */
5515    PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5516          "u, %lld )",
5517          ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5518    PRE_REG_READ5(ssize_t, "preadv",
5519                  unsigned long, fd, const struct iovec *, vector,
5520                  unsigned long, count, vki_u32, offset_low,
5521                  vki_u32, offset_high);
5522 #elif VG_WORDSIZE == 8
5523    PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5524    PRE_REG_READ4(ssize_t, "preadv",
5525                  unsigned long, fd, const struct iovec *, vector,
5526                  unsigned long, count, Word, offset);
5527 #else
5528 #  error Unexpected word size
5529 #endif
5530    if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
5531       SET_STATUS_Failure( VKI_EBADF );
5532    } else {
5533       PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5534 
5535       if (ARG2 != 0) {
5536          /* ToDo: don't do any of the following if the vector is invalid */
5537          vec = (struct vki_iovec *)(Addr)ARG2;
5538          for (i = 0; i < (Int)ARG3; i++)
5539             PRE_MEM_WRITE( "preadv(vector[...])",
5540                            (Addr)vec[i].iov_base, vec[i].iov_len );
5541       }
5542    }
5543 }
5544 
POST(sys_preadv)5545 POST(sys_preadv)
5546 {
5547    vg_assert(SUCCESS);
5548    if (RES > 0) {
5549       Int i;
5550       struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
5551       Int remains = RES;
5552 
5553       /* RES holds the number of bytes read. */
5554       for (i = 0; i < (Int)ARG3; i++) {
5555 	 Int nReadThisBuf = vec[i].iov_len;
5556 	 if (nReadThisBuf > remains) nReadThisBuf = remains;
5557 	 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5558 	 remains -= nReadThisBuf;
5559 	 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5560       }
5561    }
5562 }
5563 
PRE(sys_pwritev)5564 PRE(sys_pwritev)
5565 {
5566    Int i;
5567    struct vki_iovec * vec;
5568    *flags |= SfMayBlock;
5569 #if VG_WORDSIZE == 4
5570    /* Note that the offset argument here is in lo+hi order on both
5571       big and little endian platforms... */
5572    PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5573          "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5574    PRE_REG_READ5(ssize_t, "pwritev",
5575                  unsigned long, fd, const struct iovec *, vector,
5576                  unsigned long, count, vki_u32, offset_low,
5577                  vki_u32, offset_high);
5578 #elif VG_WORDSIZE == 8
5579    PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5580    PRE_REG_READ4(ssize_t, "pwritev",
5581                  unsigned long, fd, const struct iovec *, vector,
5582                  unsigned long, count, Word, offset);
5583 #else
5584 #  error Unexpected word size
5585 #endif
5586    if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
5587       SET_STATUS_Failure( VKI_EBADF );
5588    } else {
5589       PRE_MEM_READ( "pwritev(vector)",
5590 		     ARG2, ARG3 * sizeof(struct vki_iovec) );
5591       if (ARG2 != 0) {
5592          /* ToDo: don't do any of the following if the vector is invalid */
5593          vec = (struct vki_iovec *)(Addr)ARG2;
5594          for (i = 0; i < (Int)ARG3; i++)
5595             PRE_MEM_READ( "pwritev(vector[...])",
5596                            (Addr)vec[i].iov_base, vec[i].iov_len );
5597       }
5598    }
5599 }
5600 
5601 /* ---------------------------------------------------------------------
5602    process_vm_{read,write}v wrappers
5603    ------------------------------------------------------------------ */
5604 
PRE(sys_process_vm_readv)5605 PRE(sys_process_vm_readv)
5606 {
5607    PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5608          "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5609          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5610    PRE_REG_READ6(ssize_t, "process_vm_readv",
5611                  vki_pid_t, pid,
5612                  const struct iovec *, lvec,
5613                  unsigned long, liovcnt,
5614                  const struct iovec *, rvec,
5615                  unsigned long, riovcnt,
5616                  unsigned long, flags);
5617    PRE_MEM_READ( "process_vm_readv(lvec)",
5618                  ARG2, ARG3 * sizeof(struct vki_iovec) );
5619    PRE_MEM_READ( "process_vm_readv(rvec)",
5620                  ARG4, ARG5 * sizeof(struct vki_iovec) );
5621    if (ARG2 != 0
5622        && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5623                               sizeof(struct vki_iovec) * ARG3)) {
5624       const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5625       UInt i;
5626       for (i = 0; i < ARG3; i++)
5627          PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5628                         (Addr)vec[i].iov_base, vec[i].iov_len );
5629    }
5630 }
5631 
POST(sys_process_vm_readv)5632 POST(sys_process_vm_readv)
5633 {
5634    const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5635    UInt remains = RES;
5636    UInt i;
5637    for (i = 0; i < ARG3; i++) {
5638       UInt nReadThisBuf = vec[i].iov_len <= remains ?
5639                           vec[i].iov_len : remains;
5640       POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5641       remains -= nReadThisBuf;
5642    }
5643 }
5644 
PRE(sys_process_vm_writev)5645 PRE(sys_process_vm_writev)
5646 {
5647    PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5648          "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5649          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5650    PRE_REG_READ6(ssize_t, "process_vm_writev",
5651                  vki_pid_t, pid,
5652                  const struct iovec *, lvec,
5653                  unsigned long, liovcnt,
5654                  const struct iovec *, rvec,
5655                  unsigned long, riovcnt,
5656                  unsigned long, flags);
5657    PRE_MEM_READ( "process_vm_writev(lvec)",
5658                  ARG2, ARG3 * sizeof(struct vki_iovec) );
5659    PRE_MEM_READ( "process_vm_writev(rvec)",
5660                  ARG4, ARG5 * sizeof(struct vki_iovec) );
5661    if (ARG2 != 0
5662        && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5663                               sizeof(struct vki_iovec) * ARG3)) {
5664       const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5665       UInt i;
5666       for (i = 0; i < ARG3; i++)
5667          PRE_MEM_READ( "process_vm_writev(lvec[...])",
5668                        (Addr)vec[i].iov_base, vec[i].iov_len );
5669    }
5670 }
5671 
5672 /* ---------------------------------------------------------------------
5673    {send,recv}mmsg wrappers
5674    ------------------------------------------------------------------ */
5675 
PRE(sys_sendmmsg)5676 PRE(sys_sendmmsg)
5677 {
5678    *flags |= SfMayBlock;
5679    PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
5680          SARG3, SARG4);
5681    PRE_REG_READ4(long, "sendmmsg",
5682                  int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5683    ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5684 }
5685 
POST(sys_sendmmsg)5686 POST(sys_sendmmsg)
5687 {
5688    ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5689 }
5690 
PRE(sys_recvmmsg)5691 PRE(sys_recvmmsg)
5692 {
5693    *flags |= SfMayBlock;
5694    PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
5695          FMT_REGWORD "x )",
5696          SARG1, ARG2, SARG3, SARG4, ARG5);
5697    PRE_REG_READ5(long, "recvmmsg",
5698                  int, s, struct mmsghdr *, mmsg, int, vlen,
5699                  int, flags, struct timespec *, timeout);
5700    ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5701 }
5702 
POST(sys_recvmmsg)5703 POST(sys_recvmmsg)
5704 {
5705    ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5706 }
5707 
5708 /* ---------------------------------------------------------------------
5709    key retention service wrappers
5710    ------------------------------------------------------------------ */
5711 
PRE(sys_request_key)5712 PRE(sys_request_key)
5713 {
5714    PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5715          FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
5716          (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
5717    PRE_REG_READ4(long, "request_key",
5718                  const char *, type, const char *, description,
5719                  const char *, callout_info, vki_key_serial_t, keyring);
5720    PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5721    PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5722    if (ARG3 != (UWord)NULL)
5723       PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5724 }
5725 
PRE(sys_add_key)5726 PRE(sys_add_key)
5727 {
5728    PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5729          FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
5730           ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5731    PRE_REG_READ5(long, "add_key",
5732                  const char *, type, const char *, description,
5733                  const void *, payload, vki_size_t, plen,
5734                  vki_key_serial_t, keyring);
5735    PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5736    PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5737    if (ARG3 != (UWord)NULL)
5738       PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5739 }
5740 
PRE(sys_keyctl)5741 PRE(sys_keyctl)
5742 {
5743    switch (ARG1 /* option */) {
5744    case VKI_KEYCTL_GET_KEYRING_ID:
5745       PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5746       PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5747                     int, option, vki_key_serial_t, id, int, create);
5748       break;
5749    case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5750       PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
5751             "x(%s) )", ARG2,(char*)(Addr)ARG2);
5752       PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5753                     int, option, const char *, name);
5754       if (ARG2 != (UWord)NULL)
5755          PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5756       break;
5757    case VKI_KEYCTL_UPDATE:
5758       PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
5759             FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5760       PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5761                     int, option, vki_key_serial_t, key,
5762                     const void *, payload, vki_size_t, plen);
5763       if (ARG3 != (UWord)NULL)
5764          PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5765       break;
5766    case VKI_KEYCTL_REVOKE:
5767       PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5768       PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5769                     int, option, vki_key_serial_t, id);
5770       break;
5771    case VKI_KEYCTL_CHOWN:
5772       PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
5773             FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5774       PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5775                     int, option, vki_key_serial_t, id,
5776                     vki_uid_t, uid, vki_gid_t, gid);
5777       break;
5778    case VKI_KEYCTL_SETPERM:
5779       PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
5780             SARG2, ARG3);
5781       PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5782                     int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5783       break;
5784    case VKI_KEYCTL_DESCRIBE:
5785       PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
5786             FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5787       PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5788                     int, option, vki_key_serial_t, id,
5789                     char *, buffer, vki_size_t, buflen);
5790       if (ARG3 != (UWord)NULL)
5791          PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5792       break;
5793    case VKI_KEYCTL_CLEAR:
5794       PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5795       PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5796                     int, option, vki_key_serial_t, keyring);
5797       break;
5798    case VKI_KEYCTL_LINK:
5799       PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5800       PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5801                     vki_key_serial_t, keyring, vki_key_serial_t, key);
5802       break;
5803    case VKI_KEYCTL_UNLINK:
5804       PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5805       PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5806                     vki_key_serial_t, keyring, vki_key_serial_t, key);
5807       break;
5808    case VKI_KEYCTL_SEARCH:
5809       PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
5810             FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
5811             ARG4, (HChar*)(Addr)ARG4, SARG5);
5812       PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5813                     int, option, vki_key_serial_t, keyring,
5814                     const char *, type, const char *, description,
5815                     vki_key_serial_t, destring);
5816       PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5817       PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5818       break;
5819    case VKI_KEYCTL_READ:
5820       PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5821             "u )", SARG2, ARG3, ARG4);
5822       PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5823                     int, option, vki_key_serial_t, keyring,
5824                     char *, buffer, vki_size_t, buflen);
5825       if (ARG3 != (UWord)NULL)
5826          PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5827       break;
5828    case VKI_KEYCTL_INSTANTIATE:
5829       PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
5830             FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
5831       PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5832                     int, option, vki_key_serial_t, key,
5833                     char *, payload, vki_size_t, plen,
5834                     vki_key_serial_t, keyring);
5835       if (ARG3 != (UWord)NULL)
5836          PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5837       break;
5838    case VKI_KEYCTL_NEGATE:
5839       PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
5840             SARG2, ARG3, SARG4);
5841       PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5842                     int, option, vki_key_serial_t, key,
5843                     unsigned, timeout, vki_key_serial_t, keyring);
5844       break;
5845    case VKI_KEYCTL_SET_REQKEY_KEYRING:
5846       PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5847       PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5848                     int, option, int, reqkey_defl);
5849       break;
5850    case VKI_KEYCTL_SET_TIMEOUT:
5851       PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
5852             SARG2, ARG3);
5853       PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5854                     int, option, vki_key_serial_t, key, unsigned, timeout);
5855       break;
5856    case VKI_KEYCTL_ASSUME_AUTHORITY:
5857       PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5858       PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5859                     int, option, vki_key_serial_t, key);
5860       break;
5861    default:
5862       PRINT("sys_keyctl ( %ld ) ", SARG1);
5863       PRE_REG_READ1(long, "keyctl", int, option);
5864       break;
5865    }
5866 }
5867 
POST(sys_keyctl)5868 POST(sys_keyctl)
5869 {
5870    vg_assert(SUCCESS);
5871    switch (ARG1 /* option */) {
5872    case VKI_KEYCTL_DESCRIBE:
5873    case VKI_KEYCTL_READ:
5874       if (RES > ARG4)
5875          POST_MEM_WRITE(ARG3, ARG4);
5876       else
5877          POST_MEM_WRITE(ARG3, RES);
5878       break;
5879    default:
5880       break;
5881    }
5882 }
5883 
5884 /* ---------------------------------------------------------------------
5885    ioprio_ wrappers
5886    ------------------------------------------------------------------ */
5887 
PRE(sys_ioprio_set)5888 PRE(sys_ioprio_set)
5889 {
5890    PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5891    PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5892 }
5893 
PRE(sys_ioprio_get)5894 PRE(sys_ioprio_get)
5895 {
5896    PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
5897    PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5898 }
5899 
5900 /* ---------------------------------------------------------------------
5901    _module wrappers
5902    ------------------------------------------------------------------ */
5903 
PRE(sys_init_module)5904 PRE(sys_init_module)
5905 {
5906    *flags |= SfMayBlock;
5907    PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5908          FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
5909    PRE_REG_READ3(long, "init_module",
5910                  void *, umod, unsigned long, len, const char *, uargs);
5911    PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5912    PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5913 }
5914 
PRE(sys_finit_module)5915 PRE(sys_finit_module)
5916 {
5917    *flags |= SfMayBlock;
5918 
5919    PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
5920           FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5921    PRE_REG_READ3(long, "finit_module",
5922                  int, fd, const char *, params, int, flags);
5923    PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
5924 }
5925 
PRE(sys_delete_module)5926 PRE(sys_delete_module)
5927 {
5928    *flags |= SfMayBlock;
5929    PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
5930          "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
5931    PRE_REG_READ2(long, "delete_module",
5932                  const char *, name_user, unsigned int, flags);
5933    PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5934 }
5935 
5936 /* ---------------------------------------------------------------------
5937    splice wrappers
5938    ------------------------------------------------------------------ */
5939 
PRE(sys_splice)5940 PRE(sys_splice)
5941 {
5942    *flags |= SfMayBlock;
5943    PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
5944          FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5945          SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
5946    PRE_REG_READ6(vki_ssize_t, "splice",
5947                  int, fd_in, vki_loff_t *, off_in,
5948                  int, fd_out, vki_loff_t *, off_out,
5949                  vki_size_t, len, unsigned int, flags);
5950    if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5951        !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5952       SET_STATUS_Failure( VKI_EBADF );
5953    } else {
5954       if (ARG2 != 0)
5955          PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5956       if (ARG4 != 0)
5957          PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5958    }
5959 }
5960 
PRE(sys_tee)5961 PRE(sys_tee)
5962 {
5963    *flags |= SfMayBlock;
5964    PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5965          SARG1, SARG2, ARG3, ARG4);
5966    PRE_REG_READ4(vki_ssize_t, "tee",
5967                  int, fd_in, int, fd_out,
5968                  vki_size_t, len, unsigned int, flags);
5969    if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5970        !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5971       SET_STATUS_Failure( VKI_EBADF );
5972    }
5973 }
5974 
PRE(sys_vmsplice)5975 PRE(sys_vmsplice)
5976 {
5977    Int fdfl;
5978    *flags |= SfMayBlock;
5979    PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5980          FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5981    PRE_REG_READ4(vki_ssize_t, "splice",
5982                  int, fd, struct vki_iovec *, iov,
5983                  unsigned long, nr_segs, unsigned int, flags);
5984    if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5985       SET_STATUS_Failure( VKI_EBADF );
5986    } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5987       SET_STATUS_Failure( VKI_EBADF );
5988    } else {
5989       const struct vki_iovec *iov;
5990       PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5991       for (iov = (struct vki_iovec *)(Addr)ARG2;
5992            iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
5993       {
5994          if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
5995             if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5996                PRE_MEM_WRITE( "vmsplice(iov[...])",
5997                              (Addr)iov->iov_base, iov->iov_len );
5998             else
5999                PRE_MEM_READ( "vmsplice(iov[...])",
6000                             (Addr)iov->iov_base, iov->iov_len );
6001          }
6002       }
6003    }
6004 }
6005 
POST(sys_vmsplice)6006 POST(sys_vmsplice)
6007 {
6008    vg_assert(SUCCESS);
6009    if (RES > 0) {
6010       Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6011       vg_assert(fdfl >= 0);
6012       if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6013       {
6014          const struct vki_iovec *iov;
6015          for (iov = (struct vki_iovec *)(Addr)ARG2;
6016               iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6017          {
6018             POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6019          }
6020       }
6021    }
6022 }
6023 
6024 /* ---------------------------------------------------------------------
6025    oprofile-related wrappers
6026    ------------------------------------------------------------------ */
6027 
6028 #if defined(VGP_x86_linux)
PRE(sys_lookup_dcookie)6029 PRE(sys_lookup_dcookie)
6030 {
6031    PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6032          MERGE64(ARG1,ARG2), ARG3, ARG4);
6033    PRE_REG_READ4(long, "lookup_dcookie",
6034                  vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6035                  char *, buf, vki_size_t, len);
6036    PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6037 }
POST(sys_lookup_dcookie)6038 POST(sys_lookup_dcookie)
6039 {
6040    vg_assert(SUCCESS);
6041    if (ARG3 != (Addr)NULL)
6042       POST_MEM_WRITE( ARG3, RES);
6043 }
6044 #endif
6045 
6046 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)        \
6047       || defined(VGP_arm64_linux)
PRE(sys_lookup_dcookie)6048 PRE(sys_lookup_dcookie)
6049 {
6050    *flags |= SfMayBlock;
6051    PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6052    PRE_REG_READ3(int, "lookup_dcookie",
6053                  unsigned long long, cookie, char *, buf, vki_size_t, len);
6054 
6055    PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6056 }
6057 
POST(sys_lookup_dcookie)6058 POST(sys_lookup_dcookie)
6059 {
6060    vg_assert(SUCCESS);
6061    if (ARG2 != (Addr)NULL)
6062      POST_MEM_WRITE( ARG2, RES );
6063 }
6064 #endif
6065 
6066 /* ---------------------------------------------------------------------
6067    fcntl wrappers
6068    ------------------------------------------------------------------ */
6069 
PRE(sys_fcntl)6070 PRE(sys_fcntl)
6071 {
6072    switch (ARG2) {
6073    // These ones ignore ARG3.
6074    case VKI_F_GETFD:
6075    case VKI_F_GETFL:
6076    case VKI_F_GETOWN:
6077    case VKI_F_GETSIG:
6078    case VKI_F_GETLEASE:
6079    case VKI_F_GETPIPE_SZ:
6080       PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6081       PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6082       break;
6083 
6084    // These ones use ARG3 as "arg".
6085    case VKI_F_DUPFD:
6086    case VKI_F_DUPFD_CLOEXEC:
6087    case VKI_F_SETFD:
6088    case VKI_F_SETFL:
6089    case VKI_F_SETLEASE:
6090    case VKI_F_NOTIFY:
6091    case VKI_F_SETOWN:
6092    case VKI_F_SETSIG:
6093    case VKI_F_SETPIPE_SZ:
6094       PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6095             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6096       PRE_REG_READ3(long, "fcntl",
6097                     unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6098       break;
6099 
6100    // These ones use ARG3 as "lock".
6101    case VKI_F_GETLK:
6102    case VKI_F_SETLK:
6103    case VKI_F_SETLKW:
6104    case VKI_F_OFD_GETLK:
6105    case VKI_F_OFD_SETLK:
6106    case VKI_F_OFD_SETLKW:
6107       PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6108             "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6109       PRE_REG_READ3(long, "fcntl",
6110                     unsigned int, fd, unsigned int, cmd,
6111                     struct vki_flock *, lock);
6112       {
6113          struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6114          PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6115          PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6116          PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6117          PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6118          if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6119             PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6120          }
6121       }
6122       break;
6123 
6124 #  if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6125    case VKI_F_GETLK64:
6126    case VKI_F_SETLK64:
6127    case VKI_F_SETLKW64:
6128       PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6129             "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6130       PRE_REG_READ3(long, "fcntl",
6131                     unsigned int, fd, unsigned int, cmd,
6132                     struct flock64 *, lock);
6133       {
6134          struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6135          PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6136          PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6137          PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6138          PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6139          if (ARG2 == VKI_F_GETLK64) {
6140             PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6141          }
6142       }
6143       break;
6144 #  endif
6145 
6146    case VKI_F_SETOWN_EX:
6147       PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6148             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6149       PRE_REG_READ3(long, "fcntl",
6150                     unsigned int, fd, unsigned int, cmd,
6151                     struct vki_f_owner_ex *, arg);
6152       PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6153       break;
6154 
6155    case VKI_F_GETOWN_EX:
6156       PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6157             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6158       PRE_REG_READ3(long, "fcntl",
6159                     unsigned int, fd, unsigned int, cmd,
6160                     struct vki_f_owner_ex *, arg);
6161       PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6162       break;
6163 
6164    default:
6165       PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6166             FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6167       VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6168                 ARG2);
6169       SET_STATUS_Failure( VKI_EINVAL );
6170       break;
6171    }
6172 
6173 #  if defined(VGP_x86_linux)
6174    if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6175 #  else
6176    if (ARG2 == VKI_F_SETLKW)
6177 #  endif
6178       *flags |= SfMayBlock;
6179 }
6180 
POST(sys_fcntl)6181 POST(sys_fcntl)
6182 {
6183    vg_assert(SUCCESS);
6184    if (ARG2 == VKI_F_DUPFD) {
6185       if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6186          VG_(close)(RES);
6187          SET_STATUS_Failure( VKI_EMFILE );
6188       } else {
6189          if (VG_(clo_track_fds))
6190             ML_(record_fd_open_named)(tid, RES);
6191       }
6192    }
6193    else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6194       if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6195          VG_(close)(RES);
6196          SET_STATUS_Failure( VKI_EMFILE );
6197       } else {
6198          if (VG_(clo_track_fds))
6199             ML_(record_fd_open_named)(tid, RES);
6200       }
6201    } else if (ARG2 == VKI_F_GETOWN_EX) {
6202       POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6203    } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6204       struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6205       POST_FIELD_WRITE(lock->l_pid);
6206 #  if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6207    } else if (ARG2 == VKI_F_GETLK64) {
6208       struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6209       PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6210 #  endif
6211    }
6212 }
6213 
6214 // XXX: wrapper only suitable for 32-bit systems
PRE(sys_fcntl64)6215 PRE(sys_fcntl64)
6216 {
6217    switch (ARG2) {
6218    // These ones ignore ARG3.
6219    case VKI_F_GETFD:
6220    case VKI_F_GETFL:
6221    case VKI_F_GETOWN:
6222    case VKI_F_SETOWN:
6223    case VKI_F_GETSIG:
6224    case VKI_F_SETSIG:
6225    case VKI_F_GETLEASE:
6226       PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6227       PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6228       break;
6229 
6230    // These ones use ARG3 as "arg".
6231    case VKI_F_DUPFD:
6232    case VKI_F_DUPFD_CLOEXEC:
6233    case VKI_F_SETFD:
6234    case VKI_F_SETFL:
6235    case VKI_F_SETLEASE:
6236    case VKI_F_NOTIFY:
6237       PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6238             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6239       PRE_REG_READ3(long, "fcntl64",
6240                     unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6241       break;
6242 
6243    // These ones use ARG3 as "lock".
6244    case VKI_F_GETLK:
6245    case VKI_F_SETLK:
6246    case VKI_F_SETLKW:
6247 #  if defined(VGP_x86_linux)
6248    case VKI_F_GETLK64:
6249    case VKI_F_SETLK64:
6250    case VKI_F_SETLKW64:
6251 #  endif
6252    case VKI_F_OFD_GETLK:
6253    case VKI_F_OFD_SETLK:
6254    case VKI_F_OFD_SETLKW:
6255       PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6256             "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6257       PRE_REG_READ3(long, "fcntl64",
6258                     unsigned int, fd, unsigned int, cmd,
6259                     struct flock64 *, lock);
6260       break;
6261 
6262    case VKI_F_SETOWN_EX:
6263       PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6264             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6265       PRE_REG_READ3(long, "fcntl",
6266                     unsigned int, fd, unsigned int, cmd,
6267                     struct vki_f_owner_ex *, arg);
6268       PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6269       break;
6270 
6271    case VKI_F_GETOWN_EX:
6272       PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6273             "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6274       PRE_REG_READ3(long, "fcntl",
6275                     unsigned int, fd, unsigned int, cmd,
6276                     struct vki_f_owner_ex *, arg);
6277       PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6278       break;
6279    }
6280 
6281 #  if defined(VGP_x86_linux)
6282    if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6283 #  else
6284    if (ARG2 == VKI_F_SETLKW)
6285 #  endif
6286       *flags |= SfMayBlock;
6287 }
6288 
POST(sys_fcntl64)6289 POST(sys_fcntl64)
6290 {
6291    vg_assert(SUCCESS);
6292    if (ARG2 == VKI_F_DUPFD) {
6293       if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6294          VG_(close)(RES);
6295          SET_STATUS_Failure( VKI_EMFILE );
6296       } else {
6297          if (VG_(clo_track_fds))
6298             ML_(record_fd_open_named)(tid, RES);
6299       }
6300    }
6301    else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6302       if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6303          VG_(close)(RES);
6304          SET_STATUS_Failure( VKI_EMFILE );
6305       } else {
6306          if (VG_(clo_track_fds))
6307             ML_(record_fd_open_named)(tid, RES);
6308       }
6309    } else if (ARG2 == VKI_F_GETOWN_EX) {
6310       POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6311    }
6312 }
6313 
6314 /* ---------------------------------------------------------------------
6315    ioctl wrappers
6316    ------------------------------------------------------------------ */
6317 
6318 struct vg_drm_version_info {
6319    struct vki_drm_version data;
6320    struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6321 };
6322 
PRE(sys_ioctl)6323 PRE(sys_ioctl)
6324 {
6325    *flags |= SfMayBlock;
6326 
6327    ARG2 = (UInt)ARG2;
6328 
6329    // We first handle the ones that don't use ARG3 (even as a
6330    // scalar/non-pointer argument).
6331    switch (ARG2 /* request */) {
6332 
6333       /* asm-generic/ioctls.h */
6334    case VKI_FIOCLEX:
6335    case VKI_FIONCLEX:
6336    case VKI_TIOCNOTTY:
6337 
6338    /* linux perf_event ioctls */
6339    case VKI_PERF_EVENT_IOC_ENABLE:
6340    case VKI_PERF_EVENT_IOC_DISABLE:
6341 
6342       /* linux/soundcard interface (ALSA) */
6343    case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6344    case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6345    case VKI_SNDRV_PCM_IOCTL_PREPARE:
6346    case VKI_SNDRV_PCM_IOCTL_RESET:
6347    case VKI_SNDRV_PCM_IOCTL_START:
6348    case VKI_SNDRV_PCM_IOCTL_DROP:
6349    case VKI_SNDRV_PCM_IOCTL_DRAIN:
6350    case VKI_SNDRV_PCM_IOCTL_RESUME:
6351    case VKI_SNDRV_PCM_IOCTL_XRUN:
6352    case VKI_SNDRV_PCM_IOCTL_UNLINK:
6353    case VKI_SNDRV_TIMER_IOCTL_START:
6354    case VKI_SNDRV_TIMER_IOCTL_STOP:
6355    case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6356    case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6357 
6358       /* SCSI no operand */
6359    case VKI_SCSI_IOCTL_DOORLOCK:
6360    case VKI_SCSI_IOCTL_DOORUNLOCK:
6361 
6362    /* CDROM stuff. */
6363    case VKI_CDROM_DISC_STATUS:
6364    case VKI_CDROMSTOP:
6365 
6366    /* DVD stuff */
6367    case VKI_DVD_READ_STRUCT:
6368 
6369    /* KVM ioctls that don't check for a numeric value as parameter */
6370    case VKI_KVM_S390_ENABLE_SIE:
6371    case VKI_KVM_CREATE_IRQCHIP:
6372    case VKI_KVM_S390_INITIAL_RESET:
6373    case VKI_KVM_KVMCLOCK_CTRL:
6374 
6375    /* vhost without parameter */
6376    case VKI_VHOST_SET_OWNER:
6377    case VKI_VHOST_RESET_OWNER:
6378 
6379    /* User input device creation */
6380    case VKI_UI_DEV_CREATE:
6381    case VKI_UI_DEV_DESTROY:
6382 
6383    /* InfiniBand */
6384    case VKI_IB_USER_MAD_ENABLE_PKEY:
6385 
6386    /* Lustre */
6387    case VKI_LL_IOC_GROUP_LOCK:
6388    case VKI_LL_IOC_GROUP_UNLOCK:
6389 
6390    /* V4L2 */
6391    case VKI_V4L2_LOG_STATUS:
6392 
6393    /* DVB */
6394    case VKI_DMX_STOP:
6395       PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
6396       PRE_REG_READ2(long, "ioctl",
6397                     unsigned int, fd, unsigned int, request);
6398       return;
6399 
6400    default:
6401       PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
6402             FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6403       PRE_REG_READ3(long, "ioctl",
6404                     unsigned int, fd, unsigned int, request, unsigned long, arg);
6405       break;
6406    }
6407 
6408    // We now handle those that do look at ARG3 (and unknown ones fall into
6409    // this category).  Nb: some of these may well belong in the
6410    // doesn't-use-ARG3 switch above.
6411    switch (ARG2 /* request */) {
6412 
6413    case VKI_ION_IOC_ALLOC: {
6414       struct vki_ion_allocation_data* data
6415          = (struct vki_ion_allocation_data*)(Addr)ARG3;
6416       PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len",          data->len);
6417       PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align",        data->align);
6418       PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6419       PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags",        data->flags);
6420       PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle",       data->handle);
6421       break;
6422    }
6423    case VKI_ION_IOC_MAP: {
6424       struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6425       PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6426       PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd",     data->fd);
6427       break;
6428    }
6429    case VKI_ION_IOC_IMPORT: {
6430       struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6431       PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd",     data->fd);
6432       PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6433       break;
6434    }
6435 
6436    case VKI_SYNC_IOC_MERGE: {
6437       struct vki_sync_merge_data* data =
6438          (struct vki_sync_merge_data*)(Addr)ARG3;
6439       PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2",   data->fd2);
6440       PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name",  (Addr)(&data->name[0]));
6441       PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6442       break;
6443    }
6444 
6445    case VKI_TCSETS:
6446    case VKI_TCSETSW:
6447    case VKI_TCSETSF:
6448       PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6449       break;
6450    case VKI_TCGETS:
6451       PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6452       break;
6453    case VKI_TCSETA:
6454    case VKI_TCSETAW:
6455    case VKI_TCSETAF:
6456       PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6457       break;
6458    case VKI_TCGETA:
6459       PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6460       break;
6461    case VKI_TCSBRK:
6462    case VKI_TCXONC:
6463    case VKI_TCSBRKP:
6464    case VKI_TCFLSH:
6465    case VKI_TIOCSIG:
6466       /* These just take an int by value */
6467       break;
6468    case VKI_TIOCGWINSZ:
6469       PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6470       break;
6471    case VKI_TIOCSWINSZ:
6472       PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
6473       break;
6474    case VKI_TIOCMBIS:
6475       PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
6476       break;
6477    case VKI_TIOCMBIC:
6478       PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
6479       break;
6480    case VKI_TIOCMSET:
6481       PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
6482       break;
6483    case VKI_TIOCMGET:
6484       PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
6485       break;
6486    case VKI_TIOCLINUX:
6487       PRE_MEM_READ( "ioctl(TIOCLINUX)",   ARG3, sizeof(char *) );
6488       if (*(char *)(Addr)ARG3 == 11) {
6489 	 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6490       }
6491       break;
6492    case VKI_TIOCGPGRP:
6493       /* Get process group ID for foreground processing group. */
6494       PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6495       break;
6496    case VKI_TIOCSPGRP:
6497       /* Set a process group ID? */
6498       PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6499       break;
6500    case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6501       PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6502       break;
6503    case VKI_TIOCSCTTY:
6504       /* Just takes an int value.  */
6505       break;
6506    case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6507       PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6508       break;
6509    case VKI_FIONBIO:
6510       PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
6511       break;
6512    case VKI_FIOASYNC:
6513       PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
6514       break;
6515    case VKI_FIONREAD:                /* identical to SIOCINQ */
6516       PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
6517       break;
6518    case VKI_FIOQSIZE:
6519       PRE_MEM_WRITE( "ioctl(FIOQSIZE)",  ARG3, sizeof(vki_loff_t) );
6520       break;
6521 
6522    case VKI_TIOCSERGETLSR:
6523       PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6524       break;
6525    case VKI_TIOCGICOUNT:
6526       PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6527                      sizeof(struct vki_serial_icounter_struct) );
6528       break;
6529 
6530    case VKI_SG_SET_COMMAND_Q:
6531       PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6532       break;
6533    case VKI_SG_IO:
6534       PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6535       {
6536          vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
6537          PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6538          if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6539               sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6540             PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6541          }
6542       }
6543       break;
6544    case VKI_SG_GET_SCSI_ID:
6545       PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6546       break;
6547    case VKI_SG_SET_RESERVED_SIZE:
6548       PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6549       break;
6550    case VKI_SG_SET_TIMEOUT:
6551       PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6552       break;
6553    case VKI_SG_GET_RESERVED_SIZE:
6554       PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6555       break;
6556    case VKI_SG_GET_TIMEOUT:
6557       break;
6558    case VKI_SG_GET_VERSION_NUM:
6559       PRE_MEM_WRITE(  "ioctl(SG_GET_VERSION_NUM)",  ARG3, sizeof(int) );
6560       break;
6561    case VKI_SG_EMULATED_HOST: /* 0x2203 */
6562       PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)",    ARG3, sizeof(int) );
6563       break;
6564    case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6565       PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6566       break;
6567 
6568    case VKI_IIOCGETCPS:
6569       PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6570 		     VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6571       break;
6572    case VKI_IIOCNETGPN:
6573       PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6574 		     (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
6575 		     sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
6576       PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6577 		     sizeof(vki_isdn_net_ioctl_phone) );
6578       break;
6579 
6580       /* These all use struct ifreq AFAIK */
6581    case VKI_SIOCGIFINDEX:        /* get iface index              */
6582       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6583                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6584       PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6585       break;
6586    case VKI_SIOCGIFFLAGS:        /* get flags                    */
6587       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6588                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6589       PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6590       break;
6591    case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
6592       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6593                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6594       PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6595       break;
6596    case VKI_SIOCGIFMTU:          /* get MTU size                 */
6597       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6598                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6599       PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6600       break;
6601    case VKI_SIOCGIFADDR:         /* get PA address               */
6602       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6603                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6604       PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6605       break;
6606    case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
6607       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6608                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6609       PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6610       break;
6611    case VKI_SIOCGIFMETRIC:       /* get metric                   */
6612       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6613                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6614       PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6615       break;
6616    case VKI_SIOCGIFMAP:          /* Get device parameters        */
6617       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6618                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6619       PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6620       break;
6621    case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
6622       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6623                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6624       PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6625       break;
6626    case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
6627       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6628                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6629       PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6630       break;
6631    case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
6632       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6633                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6634       PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6635       break;
6636    case VKI_SIOCGIFNAME:         /* get iface name               */
6637       PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6638                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
6639                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
6640       PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6641       break;
6642    case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
6643       struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
6644       PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
6645       PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
6646       PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6647       PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6648       switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6649       case VKI_ETHTOOL_GSET:
6650          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6651                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6652          break;
6653       case VKI_ETHTOOL_SSET:
6654          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6655                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6656          break;
6657       case VKI_ETHTOOL_GDRVINFO:
6658          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6659                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6660          break;
6661       case VKI_ETHTOOL_GREGS:
6662          PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6663                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6664          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6665                         (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6666                         ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6667          break;
6668       case VKI_ETHTOOL_GWOL:
6669          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6670                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6671          break;
6672       case VKI_ETHTOOL_SWOL:
6673          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6674                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6675          break;
6676       case VKI_ETHTOOL_GMSGLVL:
6677       case VKI_ETHTOOL_GLINK:
6678       case VKI_ETHTOOL_GRXCSUM:
6679       case VKI_ETHTOOL_GSG:
6680       case VKI_ETHTOOL_GTSO:
6681       case VKI_ETHTOOL_GUFO:
6682       case VKI_ETHTOOL_GGSO:
6683       case VKI_ETHTOOL_GFLAGS:
6684       case VKI_ETHTOOL_GGRO:
6685          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6686                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6687          break;
6688       case VKI_ETHTOOL_SMSGLVL:
6689       case VKI_ETHTOOL_SRXCSUM:
6690       case VKI_ETHTOOL_SSG:
6691       case VKI_ETHTOOL_STSO:
6692       case VKI_ETHTOOL_SUFO:
6693       case VKI_ETHTOOL_SGSO:
6694       case VKI_ETHTOOL_SFLAGS:
6695       case VKI_ETHTOOL_SGRO:
6696          PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6697                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6698          break;
6699       case VKI_ETHTOOL_NWAY_RST:
6700          break;
6701       case VKI_ETHTOOL_GRINGPARAM:
6702          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6703                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6704          break;
6705       case VKI_ETHTOOL_SRINGPARAM:
6706          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6707                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6708          break;
6709       case VKI_ETHTOOL_TEST:
6710          PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6711                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6712          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6713                         (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6714                         ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6715          break;
6716       case VKI_ETHTOOL_PHYS_ID:
6717          break;
6718       case VKI_ETHTOOL_GPERMADDR:
6719          PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6720                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6721          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6722                         (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6723                         ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6724          break;
6725       case VKI_ETHTOOL_RESET:
6726          break;
6727       case VKI_ETHTOOL_GSSET_INFO:
6728          PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6729                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6730          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6731                         (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6732                         __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6733          break;
6734       case VKI_ETHTOOL_GFEATURES:
6735          PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6736                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6737          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6738                         (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6739                         ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6740          break;
6741       case VKI_ETHTOOL_SFEATURES:
6742          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6743                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6744          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6745                        (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6746                        ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6747          break;
6748       case VKI_ETHTOOL_GCHANNELS:
6749          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6750                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6751          break;
6752       case VKI_ETHTOOL_SCHANNELS:
6753          PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6754                        (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6755          break;
6756       case VKI_ETHTOOL_GET_TS_INFO:
6757          PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6758                         (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6759          break;
6760       }
6761       break;
6762    }
6763    case VKI_SIOCGMIIPHY:         /* get hardware entry           */
6764       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6765                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6766       PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6767       break;
6768    case VKI_SIOCGMIIREG:         /* get hardware entry registers */
6769       PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6770                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6771       PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6772                      (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6773                      sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6774       PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6775                      (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6776                      sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6777       PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6778 		     sizeof(struct vki_ifreq));
6779       break;
6780    case VKI_SIOCGIFCONF:         /* get iface list               */
6781       /* WAS:
6782 	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6783 	 KERNEL_DO_SYSCALL(tid,RES);
6784 	 if (!VG_(is_kerror)(RES) && RES == 0)
6785 	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6786       */
6787       PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6788                     (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
6789                     sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
6790       PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6791                     (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
6792                     sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
6793       if ( ARG3 ) {
6794 	 // TODO len must be readable and writable
6795 	 // buf pointer only needs to be readable
6796 	 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
6797 	 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6798 			(Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6799       }
6800       break;
6801    case VKI_SIOCGSTAMP:
6802       PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6803       break;
6804    case VKI_SIOCGSTAMPNS:
6805       PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6806       break;
6807       /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6808 	 the number of bytes currently in that socket's send buffer.
6809 	 It writes this value as an int to the memory location
6810 	 indicated by the third argument of ioctl(2). */
6811    case VKI_SIOCOUTQ:
6812       PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6813       break;
6814    case VKI_SIOCGRARP:           /* get RARP table entry         */
6815    case VKI_SIOCGARP:            /* get ARP table entry          */
6816       PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6817       break;
6818 
6819    case VKI_SIOCSIFFLAGS:        /* set flags                    */
6820       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6821                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6822       PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6823                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6824                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6825       break;
6826    case VKI_SIOCSIFMAP:          /* Set device parameters        */
6827       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6828                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6829       PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6830                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
6831                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
6832       break;
6833    case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
6834       PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
6835                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6836       PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
6837                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
6838                      sizeof(struct vki_hwtstamp_config) );
6839       break;
6840    case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
6841       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
6842                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6843       PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
6844                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
6845                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
6846       break;
6847    case VKI_SIOCSIFADDR:         /* set PA address               */
6848    case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
6849    case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
6850    case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
6851       PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
6852                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6853       PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
6854                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
6855                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
6856       break;
6857    case VKI_SIOCSIFMETRIC:       /* set metric                   */
6858       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
6859                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6860       PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
6861                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
6862                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
6863       break;
6864    case VKI_SIOCSIFMTU:          /* set MTU size                 */
6865       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
6866                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6867       PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
6868                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
6869                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
6870       break;
6871    case VKI_SIOCSIFHWADDR:       /* set hardware address         */
6872       PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6873                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6874       PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6875                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
6876                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
6877       break;
6878    case VKI_SIOCSMIIREG:         /* set hardware entry registers */
6879       PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6880                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6881       PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6882                      (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6883                      sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6884       PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6885                      (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6886                      sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6887       PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6888                      (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
6889                      sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
6890       break;
6891       /* Routing table calls.  */
6892    case VKI_SIOCADDRT:           /* add routing table entry      */
6893    case VKI_SIOCDELRT:           /* delete routing table entry   */
6894       PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6895 		    sizeof(struct vki_rtentry));
6896       break;
6897 
6898       /* tun/tap related ioctls */
6899    case VKI_TUNSETNOCSUM:
6900    case VKI_TUNSETDEBUG:
6901       break;
6902    case VKI_TUNSETIFF:
6903       PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6904                      (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6905       PRE_MEM_READ( "ioctl(TUNSETIFF)",
6906                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6907                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6908       PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6909       break;
6910    case VKI_TUNSETPERSIST:
6911    case VKI_TUNSETOWNER:
6912    case VKI_TUNSETLINK:
6913    case VKI_TUNSETGROUP:
6914       break;
6915    case VKI_TUNGETFEATURES:
6916       PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6917       break;
6918    case VKI_TUNSETOFFLOAD:
6919       break;
6920    case VKI_TUNGETIFF:
6921       PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6922       break;
6923    case VKI_TUNGETSNDBUF:
6924       PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6925       break;
6926    case VKI_TUNSETSNDBUF:
6927       PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6928       break;
6929    case VKI_TUNGETVNETHDRSZ:
6930       PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6931       break;
6932    case VKI_TUNSETVNETHDRSZ:
6933       PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6934       break;
6935    case VKI_TUNSETQUEUE:
6936       PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6937                      (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6938                      sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6939       break;
6940    case VKI_TUNSETIFINDEX:
6941       PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6942       break;
6943 
6944       /* RARP cache control calls. */
6945    case VKI_SIOCDRARP:           /* delete RARP table entry      */
6946    case VKI_SIOCSRARP:           /* set RARP table entry         */
6947       /* ARP cache control calls. */
6948    case VKI_SIOCSARP:            /* set ARP table entry          */
6949    case VKI_SIOCDARP:            /* delete ARP table entry       */
6950       PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6951       break;
6952 
6953    case VKI_SIOCGPGRP:
6954       PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6955       break;
6956    case VKI_SIOCSPGRP:
6957       PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6958       //tst->sys_flags &= ~SfMayBlock;
6959       break;
6960 
6961     case VKI_SIOCATMARK:
6962       PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6963       break;
6964 
6965       /* linux/soundcard interface (OSS) */
6966    case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6967    case VKI_SNDCTL_SEQ_GETINCOUNT:
6968    case VKI_SNDCTL_SEQ_PERCMODE:
6969    case VKI_SNDCTL_SEQ_TESTMIDI:
6970    case VKI_SNDCTL_SEQ_RESETSAMPLES:
6971    case VKI_SNDCTL_SEQ_NRSYNTHS:
6972    case VKI_SNDCTL_SEQ_NRMIDIS:
6973    case VKI_SNDCTL_SEQ_GETTIME:
6974    case VKI_SNDCTL_DSP_GETBLKSIZE:
6975    case VKI_SNDCTL_DSP_GETFMTS:
6976    case VKI_SNDCTL_DSP_GETTRIGGER:
6977    case VKI_SNDCTL_DSP_GETODELAY:
6978    case VKI_SNDCTL_DSP_GETSPDIF:
6979    case VKI_SNDCTL_DSP_GETCAPS:
6980    case VKI_SOUND_PCM_READ_RATE:
6981    case VKI_SOUND_PCM_READ_CHANNELS:
6982    case VKI_SOUND_PCM_READ_BITS:
6983    case VKI_SOUND_PCM_READ_FILTER:
6984       PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6985 		     ARG3, sizeof(int));
6986       break;
6987    case VKI_SNDCTL_SEQ_CTRLRATE:
6988    case VKI_SNDCTL_DSP_SPEED:
6989    case VKI_SNDCTL_DSP_STEREO:
6990    case VKI_SNDCTL_DSP_CHANNELS:
6991    case VKI_SOUND_PCM_WRITE_FILTER:
6992    case VKI_SNDCTL_DSP_SUBDIVIDE:
6993    case VKI_SNDCTL_DSP_SETFRAGMENT:
6994    case VKI_SNDCTL_DSP_SETFMT:
6995    case VKI_SNDCTL_DSP_GETCHANNELMASK:
6996    case VKI_SNDCTL_DSP_BIND_CHANNEL:
6997    case VKI_SNDCTL_TMR_TIMEBASE:
6998    case VKI_SNDCTL_TMR_TEMPO:
6999    case VKI_SNDCTL_TMR_SOURCE:
7000    case VKI_SNDCTL_MIDI_PRETIME:
7001    case VKI_SNDCTL_MIDI_MPUMODE:
7002       PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7003 		     ARG3, sizeof(int));
7004       PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7005 		     ARG3, sizeof(int));
7006       break;
7007    case VKI_SNDCTL_DSP_GETOSPACE:
7008    case VKI_SNDCTL_DSP_GETISPACE:
7009       PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7010                      ARG3, sizeof(vki_audio_buf_info));
7011       break;
7012    case VKI_SNDCTL_DSP_NONBLOCK:
7013       break;
7014    case VKI_SNDCTL_DSP_SETTRIGGER:
7015       PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7016 		     ARG3, sizeof(int));
7017       break;
7018 
7019    case VKI_SNDCTL_DSP_POST:
7020    case VKI_SNDCTL_DSP_RESET:
7021    case VKI_SNDCTL_DSP_SYNC:
7022    case VKI_SNDCTL_DSP_SETSYNCRO:
7023    case VKI_SNDCTL_DSP_SETDUPLEX:
7024       break;
7025 
7026       /* linux/soundcard interface (ALSA) */
7027    case VKI_SNDRV_PCM_IOCTL_PAUSE:
7028    case VKI_SNDRV_PCM_IOCTL_LINK:
7029       /* these just take an int by value */
7030       break;
7031    case VKI_SNDRV_CTL_IOCTL_PVERSION:
7032       PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7033       break;
7034    case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7035       PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7036       break;
7037    case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7038       struct vki_snd_ctl_elem_list *data =
7039          (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7040       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7041       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7042       PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7043       PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7044       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7045       if (data->pids) {
7046          PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7047       }
7048       break;
7049    }
7050    case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7051       struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7052       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7053       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7054       PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7055       break;
7056    }
7057    case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7058    case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7059       struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7060       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7061       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7062       PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7063       break;
7064    }
7065 
7066       /* Real Time Clock (/dev/rtc) ioctls */
7067    case VKI_RTC_UIE_ON:
7068    case VKI_RTC_UIE_OFF:
7069    case VKI_RTC_AIE_ON:
7070    case VKI_RTC_AIE_OFF:
7071    case VKI_RTC_PIE_ON:
7072    case VKI_RTC_PIE_OFF:
7073    case VKI_RTC_IRQP_SET:
7074       break;
7075    case VKI_RTC_RD_TIME:
7076    case VKI_RTC_ALM_READ:
7077       PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7078 		     ARG3, sizeof(struct vki_rtc_time));
7079       break;
7080    case VKI_RTC_ALM_SET:
7081       PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7082       break;
7083    case VKI_RTC_IRQP_READ:
7084       PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7085       break;
7086 
7087       /* Block devices */
7088    case VKI_BLKROSET:
7089       PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7090       break;
7091    case VKI_BLKROGET:
7092       PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7093       break;
7094    case VKI_BLKGETSIZE:
7095       PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7096       break;
7097    case VKI_BLKFLSBUF:
7098       break;
7099    case VKI_BLKRASET:
7100       break;
7101    case VKI_BLKRAGET:
7102       PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7103       break;
7104    case VKI_BLKFRASET:
7105       break;
7106    case VKI_BLKFRAGET:
7107       PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7108       break;
7109    case VKI_BLKSECTGET:
7110       PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7111       break;
7112    case VKI_BLKSSZGET:
7113       PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7114       break;
7115    case VKI_BLKBSZGET:
7116       PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7117       break;
7118    case VKI_BLKBSZSET:
7119       PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7120       break;
7121    case VKI_BLKGETSIZE64:
7122       PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7123       break;
7124    case VKI_BLKPBSZGET:
7125       PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7126       break;
7127    case VKI_BLKDISCARDZEROES:
7128       PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7129       break;
7130    case VKI_BLKREPORTZONE:
7131       PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7132 		   sizeof(struct vki_blk_zone_report));
7133       break;
7134    case VKI_BLKRESETZONE:
7135       PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7136 		   sizeof(struct vki_blk_zone_range));
7137       break;
7138 
7139       /* Hard disks */
7140    case VKI_HDIO_GETGEO: /* 0x0301 */
7141       PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7142       break;
7143    case VKI_HDIO_GET_DMA: /* 0x030b */
7144       PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7145       break;
7146    case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7147       PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7148                      VKI_SIZEOF_STRUCT_HD_DRIVEID );
7149       break;
7150 
7151       /* SCSI */
7152    case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7153       PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7154       break;
7155    case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7156       PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7157       break;
7158 
7159       /* CD ROM stuff (??)  */
7160    case VKI_CDROM_GET_MCN:
7161       PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7162                     sizeof(struct vki_cdrom_mcn) );
7163       break;
7164    case VKI_CDROM_SEND_PACKET:
7165       PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7166                     sizeof(struct vki_cdrom_generic_command));
7167       break;
7168    case VKI_CDROMSUBCHNL:
7169       PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7170 		    (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7171 		    sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7172       PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7173 		     sizeof(struct vki_cdrom_subchnl));
7174       break;
7175    case VKI_CDROMREADMODE1: /*0x530d*/
7176       PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7177       PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7178       break;
7179    case VKI_CDROMREADMODE2: /*0x530c*/
7180       PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7181       PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7182       break;
7183    case VKI_CDROMREADTOCHDR:
7184       PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7185 		     sizeof(struct vki_cdrom_tochdr));
7186       break;
7187    case VKI_CDROMREADTOCENTRY:
7188       PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7189 		    (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7190 		    sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7191       PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7192 		    (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7193 		    sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7194       PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7195 		     sizeof(struct vki_cdrom_tocentry));
7196       break;
7197    case VKI_CDROMMULTISESSION: /* 0x5310 */
7198       PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7199 		     sizeof(struct vki_cdrom_multisession));
7200       break;
7201    case VKI_CDROMVOLREAD: /* 0x5313 */
7202       PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7203 		     sizeof(struct vki_cdrom_volctrl));
7204       break;
7205    case VKI_CDROMREADRAW: /* 0x5314 */
7206       PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7207       PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7208       break;
7209    case VKI_CDROMREADAUDIO: /* 0x530e */
7210       PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7211 		     sizeof (struct vki_cdrom_read_audio));
7212       if ( ARG3 ) {
7213          /* ToDo: don't do any of the following if the structure is invalid */
7214          struct vki_cdrom_read_audio *cra =
7215             (struct vki_cdrom_read_audio *) (Addr)ARG3;
7216 	 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7217 	                (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7218       }
7219       break;
7220    case VKI_CDROMPLAYMSF:
7221       PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7222       break;
7223       /* The following two are probably bogus (should check args
7224 	 for readability).  JRS 20021117 */
7225    case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7226    case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7227       break;
7228    case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7229       break;
7230 
7231    case VKI_FIGETBSZ:
7232       PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7233       break;
7234    case VKI_FIBMAP:
7235       PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7236       break;
7237 
7238    case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7239       PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7240                      sizeof(struct vki_fb_var_screeninfo));
7241       break;
7242    case VKI_FBIOPUT_VSCREENINFO:
7243       PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7244                     sizeof(struct vki_fb_var_screeninfo));
7245       break;
7246    case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7247       PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7248                      sizeof(struct vki_fb_fix_screeninfo));
7249       break;
7250    case VKI_FBIOPAN_DISPLAY:
7251       PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7252                     sizeof(struct vki_fb_var_screeninfo));
7253 
7254       break;
7255    case VKI_PPCLAIM:
7256    case VKI_PPEXCL:
7257    case VKI_PPYIELD:
7258    case VKI_PPRELEASE:
7259       break;
7260    case VKI_PPSETMODE:
7261       PRE_MEM_READ( "ioctl(PPSETMODE)",   ARG3, sizeof(int) );
7262       break;
7263    case VKI_PPGETMODE:
7264       PRE_MEM_WRITE( "ioctl(PPGETMODE)",  ARG3, sizeof(int) );
7265       break;
7266    case VKI_PPSETPHASE:
7267       PRE_MEM_READ(  "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7268       break;
7269    case VKI_PPGETPHASE:
7270       PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7271       break;
7272    case VKI_PPGETMODES:
7273       PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7274       break;
7275    case VKI_PPSETFLAGS:
7276       PRE_MEM_READ(  "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7277       break;
7278    case VKI_PPGETFLAGS:
7279       PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7280       break;
7281    case VKI_PPRSTATUS:
7282       PRE_MEM_WRITE( "ioctl(PPRSTATUS)",  ARG3, sizeof(unsigned char) );
7283       break;
7284    case VKI_PPRDATA:
7285       PRE_MEM_WRITE( "ioctl(PPRDATA)",    ARG3, sizeof(unsigned char) );
7286       break;
7287    case VKI_PPRCONTROL:
7288       PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7289       break;
7290    case VKI_PPWDATA:
7291       PRE_MEM_READ(  "ioctl(PPWDATA)",    ARG3, sizeof(unsigned char) );
7292       break;
7293    case VKI_PPWCONTROL:
7294       PRE_MEM_READ(  "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7295       break;
7296    case VKI_PPFCONTROL:
7297       PRE_MEM_READ(  "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7298       break;
7299    case VKI_PPDATADIR:
7300       PRE_MEM_READ(  "ioctl(PPDATADIR)",  ARG3, sizeof(int) );
7301       break;
7302    case VKI_PPNEGOT:
7303       PRE_MEM_READ(  "ioctl(PPNEGOT)",    ARG3, sizeof(int) );
7304       break;
7305    case VKI_PPWCTLONIRQ:
7306       PRE_MEM_READ(  "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7307       break;
7308    case VKI_PPCLRIRQ:
7309       PRE_MEM_WRITE( "ioctl(PPCLRIRQ)",   ARG3, sizeof(int) );
7310       break;
7311    case VKI_PPSETTIME:
7312       PRE_MEM_READ(  "ioctl(PPSETTIME)",  ARG3, sizeof(struct vki_timeval) );
7313       break;
7314    case VKI_PPGETTIME:
7315       PRE_MEM_WRITE( "ioctl(PPGETTIME)",  ARG3, sizeof(struct vki_timeval) );
7316       break;
7317 
7318    case VKI_GIO_FONT:
7319       PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7320       break;
7321    case VKI_PIO_FONT:
7322       PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7323       break;
7324 
7325    case VKI_GIO_FONTX:
7326       PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7327       if ( ARG3 ) {
7328          /* ToDo: don't do any of the following if the structure is invalid */
7329          struct vki_consolefontdesc *cfd =
7330             (struct vki_consolefontdesc *)(Addr)ARG3;
7331          PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7332                         32 * cfd->charcount );
7333       }
7334       break;
7335    case VKI_PIO_FONTX:
7336       PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7337       if ( ARG3 ) {
7338          /* ToDo: don't do any of the following if the structure is invalid */
7339          struct vki_consolefontdesc *cfd =
7340             (struct vki_consolefontdesc *)(Addr)ARG3;
7341          PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7342                        32 * cfd->charcount );
7343       }
7344       break;
7345 
7346    case VKI_PIO_FONTRESET:
7347       break;
7348 
7349    case VKI_GIO_CMAP:
7350       PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7351       break;
7352    case VKI_PIO_CMAP:
7353       PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7354       break;
7355 
7356    case VKI_KIOCSOUND:
7357    case VKI_KDMKTONE:
7358       break;
7359 
7360    case VKI_KDGETLED:
7361       PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7362       break;
7363    case VKI_KDSETLED:
7364       break;
7365 
7366    case VKI_KDGKBTYPE:
7367       PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7368       break;
7369 
7370    case VKI_KDADDIO:
7371    case VKI_KDDELIO:
7372    case VKI_KDENABIO:
7373    case VKI_KDDISABIO:
7374       break;
7375 
7376    case VKI_KDSETMODE:
7377       break;
7378    case VKI_KDGETMODE:
7379       PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7380       break;
7381 
7382    case VKI_KDMAPDISP:
7383    case VKI_KDUNMAPDISP:
7384       break;
7385 
7386    case VKI_GIO_SCRNMAP:
7387       PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7388       break;
7389    case VKI_PIO_SCRNMAP:
7390       PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ  );
7391       break;
7392    case VKI_GIO_UNISCRNMAP:
7393       PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7394                      VKI_E_TABSZ * sizeof(unsigned short) );
7395       break;
7396    case VKI_PIO_UNISCRNMAP:
7397       PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7398                     VKI_E_TABSZ * sizeof(unsigned short) );
7399       break;
7400 
7401    case VKI_GIO_UNIMAP:
7402       if ( ARG3 ) {
7403          struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7404          PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7405                        sizeof(unsigned short));
7406          PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7407                        sizeof(struct vki_unipair *));
7408          PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7409                         desc->entry_ct * sizeof(struct vki_unipair));
7410       }
7411       break;
7412    case VKI_PIO_UNIMAP:
7413       if ( ARG3 ) {
7414          struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7415          PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7416                        sizeof(unsigned short) );
7417          PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7418                        sizeof(struct vki_unipair *) );
7419          PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7420                        desc->entry_ct * sizeof(struct vki_unipair) );
7421       }
7422       break;
7423    case VKI_PIO_UNIMAPCLR:
7424       PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7425       break;
7426 
7427    case VKI_KDGKBMODE:
7428       PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7429       break;
7430    case VKI_KDSKBMODE:
7431       break;
7432 
7433    case VKI_KDGKBMETA:
7434       PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7435       break;
7436    case VKI_KDSKBMETA:
7437       break;
7438 
7439    case VKI_KDGKBLED:
7440       PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7441       break;
7442    case VKI_KDSKBLED:
7443       break;
7444 
7445    case VKI_KDGKBENT:
7446       PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7447                     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7448                     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7449       PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7450                     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7451                     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7452       PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7453 		     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7454 		     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7455       break;
7456    case VKI_KDSKBENT:
7457       PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7458                     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7459                     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7460       PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7461                     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7462                     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7463       PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7464                     (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7465                     sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7466       break;
7467 
7468    case VKI_KDGKBSENT:
7469       PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7470                     (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7471                     sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7472       PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7473 		     (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
7474 		     sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
7475       break;
7476    case VKI_KDSKBSENT:
7477       PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7478                     (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7479                     sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7480       PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7481                        (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
7482       break;
7483 
7484    case VKI_KDGKBDIACR:
7485       PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7486       break;
7487    case VKI_KDSKBDIACR:
7488       PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7489       break;
7490 
7491    case VKI_KDGETKEYCODE:
7492       PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7493                     (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7494                     sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7495       PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7496 		     (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7497 		     sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7498       break;
7499    case VKI_KDSETKEYCODE:
7500       PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7501                     (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7502                     sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7503       PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7504                     (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7505                     sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7506       break;
7507 
7508    case VKI_KDSIGACCEPT:
7509       break;
7510 
7511    case VKI_KDKBDREP:
7512       PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7513       break;
7514 
7515    case VKI_KDFONTOP:
7516       if ( ARG3 ) {
7517          struct vki_console_font_op *op =
7518             (struct vki_console_font_op *) (Addr)ARG3;
7519          PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7520                        sizeof(struct vki_console_font_op) );
7521          switch ( op->op ) {
7522             case VKI_KD_FONT_OP_SET:
7523                PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7524                              (Addr)op->data,
7525                              (op->width + 7) / 8 * 32 * op->charcount );
7526                break;
7527             case VKI_KD_FONT_OP_GET:
7528                if ( op->data )
7529                   PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7530                                  (Addr)op->data,
7531                                  (op->width + 7) / 8 * 32 * op->charcount );
7532                break;
7533             case VKI_KD_FONT_OP_SET_DEFAULT:
7534                if ( op->data )
7535                   PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7536                                    (Addr)op->data );
7537                break;
7538             case VKI_KD_FONT_OP_COPY:
7539                break;
7540          }
7541       }
7542       break;
7543 
7544    case VKI_VT_OPENQRY:
7545       PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7546       break;
7547    case VKI_VT_GETMODE:
7548       PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7549       break;
7550    case VKI_VT_SETMODE:
7551       PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7552       break;
7553    case VKI_VT_GETSTATE:
7554       PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7555                      (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
7556                      sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
7557       PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7558                      (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
7559                      sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
7560       break;
7561    case VKI_VT_RELDISP:
7562    case VKI_VT_ACTIVATE:
7563    case VKI_VT_WAITACTIVE:
7564    case VKI_VT_DISALLOCATE:
7565       break;
7566    case VKI_VT_RESIZE:
7567       PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7568       break;
7569    case VKI_VT_RESIZEX:
7570       PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7571       break;
7572    case VKI_VT_LOCKSWITCH:
7573    case VKI_VT_UNLOCKSWITCH:
7574       break;
7575 
7576    case VKI_USBDEVFS_CONTROL:
7577       if ( ARG3 ) {
7578          struct vki_usbdevfs_ctrltransfer *vkuc =
7579             (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
7580          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7581          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7582          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7583          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7584          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7585          PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7586          if (vkuc->bRequestType & 0x80)
7587             PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7588          else
7589             PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7590       }
7591       break;
7592    case VKI_USBDEVFS_BULK:
7593       if ( ARG3 ) {
7594          struct vki_usbdevfs_bulktransfer *vkub =
7595             (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
7596          PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7597          if (vkub->ep & 0x80)
7598             PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7599          else
7600             PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7601       }
7602       break;
7603    case VKI_USBDEVFS_GETDRIVER:
7604       if ( ARG3 ) {
7605          struct vki_usbdevfs_getdriver *vkugd =
7606             (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
7607          PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7608       }
7609       break;
7610    case VKI_USBDEVFS_SUBMITURB:
7611       if ( ARG3 ) {
7612          struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
7613 
7614          /* Not the whole struct needs to be initialized */
7615          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7616          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7617          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7618          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7619          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7620          PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7621          if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7622             struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7623             PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7624             PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7625             if (vkusp->bRequestType & 0x80)
7626                PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7627             else
7628                PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7629             PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7630          } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7631             int total_length = 0;
7632             int i;
7633             PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7634             for(i=0; i<vkuu->number_of_packets; i++) {
7635                PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7636                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));
7637                PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7638                total_length += vkuu->iso_frame_desc[i].length;
7639             }
7640             if (vkuu->endpoint & 0x80)
7641                PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7642             else
7643                PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7644             PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7645          } else {
7646             PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7647             if (vkuu->endpoint & 0x80)
7648                PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7649             else
7650                PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7651             PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7652          }
7653       }
7654       break;
7655    case VKI_USBDEVFS_DISCARDURB:
7656       break;
7657    case VKI_USBDEVFS_REAPURB:
7658       if ( ARG3 ) {
7659          PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7660       }
7661       break;
7662    case VKI_USBDEVFS_REAPURBNDELAY:
7663       if ( ARG3 ) {
7664          PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7665       }
7666       break;
7667    case VKI_USBDEVFS_CONNECTINFO:
7668       PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7669       break;
7670    case VKI_USBDEVFS_IOCTL:
7671       if ( ARG3 ) {
7672          struct vki_usbdevfs_ioctl *vkui =
7673             (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
7674          UInt dir2, size2;
7675          PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7676          dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
7677          size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7678          if (size2 > 0) {
7679             if (dir2 & _VKI_IOC_WRITE)
7680                PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7681             else if (dir2 & _VKI_IOC_READ)
7682                PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7683          }
7684       }
7685       break;
7686    case VKI_USBDEVFS_RESET:
7687       break;
7688 
7689       /* I2C (/dev/i2c-*) ioctls */
7690    case VKI_I2C_SLAVE:
7691    case VKI_I2C_SLAVE_FORCE:
7692    case VKI_I2C_TENBIT:
7693    case VKI_I2C_PEC:
7694       break;
7695    case VKI_I2C_FUNCS:
7696       PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7697       break;
7698    case VKI_I2C_RDWR:
7699       if ( ARG3 ) {
7700           struct vki_i2c_rdwr_ioctl_data *vkui =
7701              (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
7702           UInt i;
7703           PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7704           for (i=0; i < vkui->nmsgs; i++) {
7705               struct vki_i2c_msg *msg = vkui->msgs + i;
7706               PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7707               if (msg->flags & VKI_I2C_M_RD)
7708                   PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7709               else
7710                   PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7711           }
7712       }
7713       break;
7714    case VKI_I2C_SMBUS:
7715        if ( ARG3 ) {
7716             struct vki_i2c_smbus_ioctl_data *vkis
7717                = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
7718             PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7719                          (Addr)&vkis->read_write, sizeof(vkis->read_write));
7720             PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7721                          (Addr)&vkis->size, sizeof(vkis->size));
7722             PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7723                          (Addr)&vkis->command, sizeof(vkis->command));
7724             /* i2c_smbus_write_quick hides its value in read_write, so
7725                this variable can have a different meaning */
7726             /* to make matters worse i2c_smbus_write_byte stores its
7727                value in command */
7728             if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7729                  ((vkis->size == VKI_I2C_SMBUS_BYTE)
7730                   && (vkis->read_write == VKI_I2C_SMBUS_WRITE))))  {
7731                     /* the rest uses the byte array to store the data,
7732                        some the first byte for size */
7733                     UInt size;
7734                     switch(vkis->size) {
7735                         case VKI_I2C_SMBUS_BYTE_DATA:
7736                             size = 1;
7737                             break;
7738                         case VKI_I2C_SMBUS_WORD_DATA:
7739                         case VKI_I2C_SMBUS_PROC_CALL:
7740                             size = 2;
7741                             break;
7742                         case VKI_I2C_SMBUS_BLOCK_DATA:
7743                         case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7744                         case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7745                         case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7746                             size = 1 + vkis->data->block[0];
7747                             break;
7748                         default:
7749                             size = 0;
7750                     }
7751 
7752                     if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7753                         || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7754                         || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7755                         PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7756                                       ".i2c_smbus_ioctl_data.data",
7757                                       (Addr)&vkis->data->block[0], size);
7758                     else
7759                         PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7760                                      "i2c_smbus_ioctl_data.data",
7761                                      (Addr)&vkis->data->block[0], size);
7762             }
7763        }
7764        break;
7765 
7766       /* Wireless extensions ioctls */
7767    case VKI_SIOCSIWCOMMIT:
7768    case VKI_SIOCSIWNWID:
7769    case VKI_SIOCSIWFREQ:
7770    case VKI_SIOCSIWMODE:
7771    case VKI_SIOCSIWSENS:
7772    case VKI_SIOCSIWRANGE:
7773    case VKI_SIOCSIWPRIV:
7774    case VKI_SIOCSIWSTATS:
7775    case VKI_SIOCSIWSPY:
7776    case VKI_SIOCSIWTHRSPY:
7777    case VKI_SIOCSIWAP:
7778    case VKI_SIOCSIWSCAN:
7779    case VKI_SIOCSIWESSID:
7780    case VKI_SIOCSIWRATE:
7781    case VKI_SIOCSIWNICKN:
7782    case VKI_SIOCSIWRTS:
7783    case VKI_SIOCSIWFRAG:
7784    case VKI_SIOCSIWTXPOW:
7785    case VKI_SIOCSIWRETRY:
7786    case VKI_SIOCSIWENCODE:
7787    case VKI_SIOCSIWPOWER:
7788    case VKI_SIOCSIWGENIE:
7789    case VKI_SIOCSIWMLME:
7790    case VKI_SIOCSIWAUTH:
7791    case VKI_SIOCSIWENCODEEXT:
7792    case VKI_SIOCSIWPMKSA:
7793       break;
7794    case VKI_SIOCGIWNAME:
7795       if (ARG3) {
7796          PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7797                        (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
7798                        sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
7799       }
7800       break;
7801    case VKI_SIOCGIWNWID:
7802    case VKI_SIOCGIWSENS:
7803    case VKI_SIOCGIWRATE:
7804    case VKI_SIOCGIWRTS:
7805    case VKI_SIOCGIWFRAG:
7806    case VKI_SIOCGIWTXPOW:
7807    case VKI_SIOCGIWRETRY:
7808    case VKI_SIOCGIWPOWER:
7809    case VKI_SIOCGIWAUTH:
7810       if (ARG3) {
7811          PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7812                        "RETRY|PARAM|AUTH])",
7813                        (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
7814                        sizeof(struct vki_iw_param));
7815       }
7816       break;
7817    case VKI_SIOCGIWFREQ:
7818       if (ARG3) {
7819          PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7820                        (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
7821                        sizeof(struct vki_iw_freq));
7822       }
7823       break;
7824    case VKI_SIOCGIWMODE:
7825       if (ARG3) {
7826          PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
7827                        (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
7828                        sizeof(__vki_u32));
7829       }
7830       break;
7831    case VKI_SIOCGIWRANGE:
7832    case VKI_SIOCGIWPRIV:
7833    case VKI_SIOCGIWSTATS:
7834    case VKI_SIOCGIWSPY:
7835    case VKI_SIOCGIWTHRSPY:
7836    case VKI_SIOCGIWAPLIST:
7837    case VKI_SIOCGIWSCAN:
7838    case VKI_SIOCGIWESSID:
7839    case VKI_SIOCGIWNICKN:
7840    case VKI_SIOCGIWENCODE:
7841    case VKI_SIOCGIWGENIE:
7842    case VKI_SIOCGIWENCODEEXT:
7843       if (ARG3) {
7844          struct vki_iw_point* point;
7845          point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
7846          PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
7847                        "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
7848                        (Addr)point->pointer, point->length);
7849       }
7850       break;
7851    case VKI_SIOCGIWAP:
7852       if (ARG3) {
7853          PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
7854                        (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
7855                        sizeof(struct vki_sockaddr));
7856       }
7857       break;
7858 
7859   /* User input device creation */
7860   case VKI_UI_SET_EVBIT:
7861   case VKI_UI_SET_KEYBIT:
7862   case VKI_UI_SET_RELBIT:
7863   case VKI_UI_SET_ABSBIT:
7864   case VKI_UI_SET_MSCBIT:
7865   case VKI_UI_SET_LEDBIT:
7866   case VKI_UI_SET_SNDBIT:
7867   case VKI_UI_SET_FFBIT:
7868   case VKI_UI_SET_SWBIT:
7869   case VKI_UI_SET_PROPBIT:
7870       /* These just take an int by value */
7871       break;
7872 
7873 #  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7874       || defined(VGPV_mips32_linux_android) \
7875       || defined(VGPV_arm64_linux_android)
7876    /* ashmem */
7877    case VKI_ASHMEM_GET_SIZE:
7878    case VKI_ASHMEM_SET_SIZE:
7879    case VKI_ASHMEM_GET_PROT_MASK:
7880    case VKI_ASHMEM_SET_PROT_MASK:
7881    case VKI_ASHMEM_GET_PIN_STATUS:
7882    case VKI_ASHMEM_PURGE_ALL_CACHES:
7883        break;
7884    case VKI_ASHMEM_GET_NAME:
7885        PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
7886        break;
7887    case VKI_ASHMEM_SET_NAME:
7888        PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
7889        break;
7890    case VKI_ASHMEM_PIN:
7891    case VKI_ASHMEM_UNPIN:
7892        PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
7893                      ARG3, sizeof(struct vki_ashmem_pin) );
7894        break;
7895 
7896    /* binder */
7897    case VKI_BINDER_WRITE_READ:
7898        if (ARG3) {
7899            struct vki_binder_write_read* bwr
7900               = (struct vki_binder_write_read*)(Addr)ARG3;
7901 
7902            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7903                           bwr->write_buffer);
7904            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7905                           bwr->write_size);
7906            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7907                           bwr->write_consumed);
7908            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7909                           bwr->read_buffer);
7910            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7911                           bwr->read_size);
7912            PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7913                           bwr->read_consumed);
7914 
7915            PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7916                            bwr->write_consumed);
7917            PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7918                            bwr->read_consumed);
7919 
7920            if (bwr->read_size)
7921                PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7922                              (Addr)bwr->read_buffer, bwr->read_size);
7923            if (bwr->write_size)
7924                PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7925                             (Addr)bwr->write_buffer, bwr->write_size);
7926        }
7927        break;
7928 
7929    case VKI_BINDER_SET_IDLE_TIMEOUT:
7930    case VKI_BINDER_SET_MAX_THREADS:
7931    case VKI_BINDER_SET_IDLE_PRIORITY:
7932    case VKI_BINDER_SET_CONTEXT_MGR:
7933    case VKI_BINDER_THREAD_EXIT:
7934        break;
7935    case VKI_BINDER_VERSION:
7936        if (ARG3) {
7937            struct vki_binder_version* bv =
7938               (struct vki_binder_version*)(Addr)ARG3;
7939            PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7940        }
7941        break;
7942 #  endif /* defined(VGPV_*_linux_android) */
7943 
7944    case VKI_HCIGETDEVLIST:
7945       if (ARG3) {
7946          struct vki_hci_dev_list_req* dlr =
7947             (struct vki_hci_dev_list_req*)(Addr)ARG3;
7948          PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7949                       (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7950          PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7951                        (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7952                        dlr->dev_num * sizeof(struct vki_hci_dev_req));
7953       }
7954       break;
7955 
7956    case VKI_HCIINQUIRY:
7957       if (ARG3) {
7958          struct vki_hci_inquiry_req* ir =
7959             (struct vki_hci_inquiry_req*)(Addr)ARG3;
7960          PRE_MEM_READ("ioctl(HCIINQUIRY)",
7961                       (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7962          PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7963                        (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7964                        ir->num_rsp * sizeof(struct vki_inquiry_info));
7965       }
7966       break;
7967 
7968    case VKI_DRM_IOCTL_VERSION:
7969       if (ARG3) {
7970          struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
7971          struct vg_drm_version_info* info;
7972 	 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7973          PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7974          PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7975          PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7976          PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7977          PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7978          PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7979          PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7980          PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7981          PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7982          PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7983          PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7984          info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
7985          // To ensure we VG_(free) info even when syscall fails:
7986          *flags |= SfPostOnFail;
7987          info->data = *data;
7988          info->orig = data;
7989          ARG3 = (Addr)&info->data;
7990       }
7991       break;
7992    case VKI_DRM_IOCTL_GET_UNIQUE:
7993       if (ARG3) {
7994          struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
7995 	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7996 	 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7997 	 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7998       }
7999       break;
8000    case VKI_DRM_IOCTL_GET_MAGIC:
8001       if (ARG3) {
8002          struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8003          PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8004       }
8005       break;
8006    case VKI_DRM_IOCTL_WAIT_VBLANK:
8007       if (ARG3) {
8008          union vki_drm_wait_vblank *data =
8009             (union vki_drm_wait_vblank *)(Addr)ARG3;
8010 	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8011 	 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8012 	 /* XXX: It seems request.signal isn't used */
8013          PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8014       }
8015       break;
8016    case VKI_DRM_IOCTL_GEM_CLOSE:
8017       if (ARG3) {
8018          struct vki_drm_gem_close *data =
8019             (struct vki_drm_gem_close *)(Addr)ARG3;
8020 	 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8021       }
8022       break;
8023    case VKI_DRM_IOCTL_GEM_FLINK:
8024       if (ARG3) {
8025          struct vki_drm_gem_flink *data =
8026             (struct vki_drm_gem_flink *)(Addr)ARG3;
8027 	 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8028          PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8029       }
8030       break;
8031    case VKI_DRM_IOCTL_GEM_OPEN:
8032       if (ARG3) {
8033          struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8034 	 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8035 	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8036 	 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8037       }
8038       break;
8039    case VKI_DRM_IOCTL_I915_GETPARAM:
8040       if (ARG3) {
8041          vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8042 	 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8043 	 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8044       }
8045       break;
8046    case VKI_DRM_IOCTL_I915_GEM_BUSY:
8047       if (ARG3) {
8048          struct vki_drm_i915_gem_busy *data =
8049             (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8050 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8051          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8052       }
8053       break;
8054    case VKI_DRM_IOCTL_I915_GEM_CREATE:
8055       if (ARG3) {
8056          struct vki_drm_i915_gem_create *data =
8057             (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8058 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8059 	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8060       }
8061       break;
8062    case VKI_DRM_IOCTL_I915_GEM_PREAD:
8063       if (ARG3) {
8064          struct vki_drm_i915_gem_pread *data =
8065             (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8066 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8067 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8068 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8069 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8070 	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8071       }
8072       break;
8073    case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8074       if (ARG3) {
8075          struct vki_drm_i915_gem_pwrite *data =
8076             (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8077 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8078 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8079 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8080 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8081 	 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8082 	  * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8083 	  * interleaved vertex attributes may have a wide stride with uninitialized data between
8084 	  * consecutive vertices) */
8085       }
8086       break;
8087    case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8088       if (ARG3) {
8089          struct vki_drm_i915_gem_mmap_gtt *data =
8090             (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8091 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8092          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8093       }
8094       break;
8095    case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8096       if (ARG3) {
8097          struct vki_drm_i915_gem_set_domain *data =
8098             (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8099 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8100 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8101 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8102       }
8103       break;
8104    case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8105       if (ARG3) {
8106          struct vki_drm_i915_gem_set_tiling *data =
8107             (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8108 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8109          PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8110          PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8111          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8112       }
8113       break;
8114    case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8115       if (ARG3) {
8116          struct vki_drm_i915_gem_get_tiling *data =
8117             (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8118 	 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8119 	 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8120          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8121       }
8122       break;
8123    case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8124       if (ARG3) {
8125          struct vki_drm_i915_gem_get_aperture *data =
8126             (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8127          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8128          PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8129       }
8130       break;
8131 
8132    /* KVM ioctls that check for a numeric value as parameter */
8133    case VKI_KVM_GET_API_VERSION:
8134    case VKI_KVM_CREATE_VM:
8135    case VKI_KVM_GET_VCPU_MMAP_SIZE:
8136    case VKI_KVM_CHECK_EXTENSION:
8137    case VKI_KVM_SET_TSS_ADDR:
8138    case VKI_KVM_CREATE_VCPU:
8139    case VKI_KVM_RUN:
8140       break;
8141 
8142    case VKI_KVM_S390_MEM_OP: {
8143       struct vki_kvm_s390_mem_op *args =
8144          (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8145       PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8146                    sizeof(struct vki_kvm_s390_mem_op));
8147       if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8148          break;
8149       if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8150          PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8151       if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8152          PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8153       }
8154       break;
8155 
8156 
8157 #ifdef ENABLE_XEN
8158    case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8159       SyscallArgs harrghs;
8160       struct vki_xen_privcmd_hypercall *args =
8161          (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8162 
8163       if (!args)
8164          break;
8165 
8166       VG_(memset)(&harrghs, 0, sizeof(harrghs));
8167       harrghs.sysno = args->op;
8168       harrghs.arg1 = args->arg[0];
8169       harrghs.arg2 = args->arg[1];
8170       harrghs.arg3 = args->arg[2];
8171       harrghs.arg4 = args->arg[3];
8172       harrghs.arg5 = args->arg[4];
8173       harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8174 
8175       WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8176 
8177       /* HACK. arg8 is used to return the number of hypercall
8178        * arguments actually consumed! */
8179       PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8180                    ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8181 
8182       break;
8183    }
8184 
8185    case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8186        struct vki_xen_privcmd_mmap *args =
8187            (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8188        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8189                     (Addr)&args->num, sizeof(args->num));
8190        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8191                     (Addr)&args->dom, sizeof(args->dom));
8192        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8193                     (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8194       break;
8195    }
8196    case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8197        struct vki_xen_privcmd_mmapbatch *args =
8198            (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8199        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8200                     (Addr)&args->num, sizeof(args->num));
8201        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8202                     (Addr)&args->dom, sizeof(args->dom));
8203        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8204                     (Addr)&args->addr, sizeof(args->addr));
8205        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8206                     (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8207       break;
8208    }
8209    case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8210        struct vki_xen_privcmd_mmapbatch_v2 *args =
8211            (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8212        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8213                     (Addr)&args->num, sizeof(args->num));
8214        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8215                     (Addr)&args->dom, sizeof(args->dom));
8216        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8217                     (Addr)&args->addr, sizeof(args->addr));
8218        PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8219                     (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8220       break;
8221    }
8222 
8223    case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8224          struct vki_xen_ioctl_evtchn_bind_virq *args =
8225             (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8226          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8227                  (Addr)&args->virq, sizeof(args->virq));
8228       }
8229       break;
8230    case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8231          struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8232             (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8233          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8234                  (Addr)&args->remote_domain, sizeof(args->remote_domain));
8235          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8236                  (Addr)&args->remote_port, sizeof(args->remote_port));
8237       }
8238       break;
8239    case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8240          struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8241             (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8242          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8243                  (Addr)&args->remote_domain, sizeof(args->remote_domain));
8244       }
8245       break;
8246    case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8247          struct vki_xen_ioctl_evtchn_unbind *args =
8248             (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8249          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8250                  (Addr)&args->port, sizeof(args->port));
8251       }
8252       break;
8253    case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8254          struct vki_xen_ioctl_evtchn_notify *args =
8255             (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
8256          PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8257                  (Addr)&args->port, sizeof(args->port));
8258       }
8259       break;
8260    case VKI_XEN_IOCTL_EVTCHN_RESET:
8261       /* No input*/
8262       break;
8263 #endif
8264 
8265    /* Lustre */
8266    case VKI_OBD_IOC_FID2PATH: {
8267       struct vki_getinfo_fid2path *gf =
8268          (struct vki_getinfo_fid2path *)(Addr)ARG3;
8269       PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8270       PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8271       PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8272       PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8273       break;
8274    }
8275 
8276    case VKI_LL_IOC_PATH2FID:
8277       PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8278       break;
8279 
8280    case VKI_LL_IOC_GETPARENT: {
8281       struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
8282       PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8283       PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8284       PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8285       PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8286       break;
8287    }
8288 
8289    /* V4L2 */
8290    case VKI_V4L2_QUERYCAP: {
8291       struct vki_v4l2_capability *data =
8292          (struct vki_v4l2_capability *)(Addr)ARG3;
8293       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8294       break;
8295    }
8296    case VKI_V4L2_ENUM_FMT: {
8297       struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
8298       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8299       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8300       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8301       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8302       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8303       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8304       break;
8305    }
8306    case VKI_V4L2_G_FMT: {
8307       struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8308       PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8309       switch (data->type) {
8310       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8311       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8312          PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8313          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8314          PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8315                (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8316                sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8317          break;
8318       case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8319       case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8320          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8321          break;
8322       case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8323       case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8324          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8325          break;
8326       case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8327       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8328          PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8329          PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8330          PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8331          if (data->fmt.win.clipcount && data->fmt.win.clips)
8332             PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8333                   (Addr)data->fmt.win.clips,
8334                   data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8335          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8336          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8337          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8338          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8339          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8340          break;
8341       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8342       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8343          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8344          break;
8345       case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8346          PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8347          break;
8348       }
8349       break;
8350    }
8351    case VKI_V4L2_S_FMT: {
8352       struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8353       PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8354       switch (data->type) {
8355       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8356       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8357          PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8358                (Addr)&data->type + sizeof(data->type),
8359                sizeof(*data) - sizeof(data->type));
8360          break;
8361       case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8362       case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8363          PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8364          break;
8365       case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8366       case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8367          PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8368          break;
8369       case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8370       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8371          PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8372          if (data->fmt.win.clipcount && data->fmt.win.clips)
8373             PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8374                   (Addr)data->fmt.win.clips,
8375                   data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8376          if (data->fmt.win.bitmap)
8377             PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8378                   (Addr)data->fmt.win.bitmap,
8379                   data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8380          break;
8381       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8382       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8383          PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8384          break;
8385       case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8386          PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8387          break;
8388       }
8389       break;
8390    }
8391    case VKI_V4L2_TRY_FMT: {
8392       struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8393       PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8394       switch (data->type) {
8395       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8396       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8397          PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8398                (Addr)&data->type + sizeof(data->type),
8399                sizeof(*data) - sizeof(data->type));
8400          break;
8401       case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8402       case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8403          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8404          break;
8405       case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8406       case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8407          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8408          break;
8409       case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8410       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8411          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8412          if (data->fmt.win.clipcount && data->fmt.win.clips)
8413             PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8414                   (Addr)data->fmt.win.clips,
8415                   data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8416          if (data->fmt.win.bitmap)
8417             PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8418                   (Addr)data->fmt.win.bitmap,
8419                   data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8420          break;
8421       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8422       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8423          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8424          break;
8425       case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8426          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8427          break;
8428       }
8429       break;
8430    }
8431    case VKI_V4L2_REQBUFS: {
8432       struct vki_v4l2_requestbuffers *data =
8433          (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
8434       PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8435       break;
8436    }
8437    case VKI_V4L2_QUERYBUF: {
8438       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8439       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8440       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8441       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8442       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8443       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8444             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8445          unsigned i;
8446 
8447          PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8448          PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8449          for (i = 0; i < data->length; i++) {
8450             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8451             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8452             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8453             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8454             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8455          }
8456       } else {
8457          PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8458          PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8459       }
8460       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8461       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8462       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8463       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8464       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8465       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8466       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8467       PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8468       break;
8469    }
8470    case VKI_V4L2_G_FBUF: {
8471       struct vki_v4l2_framebuffer *data =
8472          (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8473       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8474       break;
8475    }
8476    case VKI_V4L2_S_FBUF: {
8477       struct vki_v4l2_framebuffer *data =
8478          (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8479       PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8480       PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8481       PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8482       PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8483       break;
8484    }
8485    case VKI_V4L2_OVERLAY: {
8486       int *data = (int *)(Addr)ARG3;
8487       PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8488       break;
8489    }
8490    case VKI_V4L2_QBUF: {
8491       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8492       int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8493          data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8494          data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8495          data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8496 
8497       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8498       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8499       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8500       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8501       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8502       PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8503       if (is_output) {
8504          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8505          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8506       }
8507       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8508             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8509          unsigned i;
8510 
8511          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8512          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8513          for (i = 0; i < data->length; i++) {
8514             if (is_output) {
8515                PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8516                PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8517             }
8518             if (data->memory == VKI_V4L2_MEMORY_MMAP)
8519                PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8520             else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8521                PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8522             else
8523                PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8524             PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8525          }
8526       } else {
8527          if (data->memory == VKI_V4L2_MEMORY_MMAP)
8528             PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8529          else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8530             PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8531          else
8532             PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8533          if (is_output) {
8534             PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8535             PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8536          }
8537       }
8538       if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8539          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8540          PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8541       }
8542       break;
8543    }
8544    case VKI_V4L2_EXPBUF: {
8545       struct vki_v4l2_exportbuffer *data =
8546          (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
8547       PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8548       PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8549       PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8550       PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8551       PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8552       PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8553       break;
8554    }
8555    case VKI_V4L2_DQBUF: {
8556       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8557       PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8558       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8559       PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8560       PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8561       PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8562       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8563       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8564       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8565             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8566          unsigned i;
8567 
8568          PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8569          PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8570          for (i = 0; i < data->length; i++) {
8571             PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8572             PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8573             PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8574             PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8575             PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8576          }
8577       } else {
8578          PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8579          PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8580          PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8581          PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8582       }
8583       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8584       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8585       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8586       break;
8587    }
8588    case VKI_V4L2_STREAMON: {
8589       int *data = (int *)(Addr)ARG3;
8590       PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8591       break;
8592    }
8593    case VKI_V4L2_STREAMOFF: {
8594       int *data = (int *)(Addr)ARG3;
8595       PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8596       break;
8597    }
8598    case VKI_V4L2_G_PARM: {
8599       struct vki_v4l2_streamparm *data =
8600          (struct vki_v4l2_streamparm *)(Addr)ARG3;
8601       int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8602          data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8603          data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8604          data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8605 
8606       PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8607       if (is_output) {
8608          PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8609             sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8610          PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8611       } else {
8612          PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8613             sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8614          PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8615       }
8616       break;
8617    }
8618    case VKI_V4L2_S_PARM: {
8619       struct vki_v4l2_streamparm *data =
8620          (struct vki_v4l2_streamparm *)(Addr)ARG3;
8621       int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8622          data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8623          data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8624          data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8625 
8626       PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8627       if (is_output)
8628          PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8629       else
8630          PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8631       break;
8632    }
8633    case VKI_V4L2_G_STD: {
8634       vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8635       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8636       break;
8637    }
8638    case VKI_V4L2_S_STD: {
8639       vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8640       PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8641       break;
8642    }
8643    case VKI_V4L2_ENUMSTD: {
8644       struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
8645       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8646       PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8647       break;
8648    }
8649    case VKI_V4L2_ENUMINPUT: {
8650       struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
8651       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8652       PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8653       break;
8654    }
8655    case VKI_V4L2_G_CTRL: {
8656       struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8657       PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8658       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8659       break;
8660    }
8661    case VKI_V4L2_S_CTRL: {
8662       struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8663       PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8664       break;
8665    }
8666    case VKI_V4L2_G_TUNER: {
8667       struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8668       PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8669       PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8670       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8671             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8672       break;
8673    }
8674    case VKI_V4L2_S_TUNER: {
8675       struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8676       PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8677       PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8678       PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8679       break;
8680    }
8681    case VKI_V4L2_G_AUDIO: {
8682       struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8683       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8684             sizeof(*data) - sizeof(data->reserved));
8685       PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8686       break;
8687    }
8688    case VKI_V4L2_S_AUDIO: {
8689       struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8690       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8691       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8692       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8693       break;
8694    }
8695    case VKI_V4L2_QUERYCTRL: {
8696       struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
8697       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8698       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8699             sizeof(*data) - sizeof(data->id));
8700       break;
8701    }
8702    case VKI_V4L2_QUERYMENU: {
8703       struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
8704       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8705       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8706       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8707             sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8708       break;
8709    }
8710    case VKI_V4L2_G_INPUT: {
8711       int *data = (int *)(Addr)ARG3;
8712       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8713       break;
8714    }
8715    case VKI_V4L2_S_INPUT: {
8716       int *data = (int *)(Addr)ARG3;
8717       PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8718       break;
8719    }
8720    case VKI_V4L2_G_EDID: {
8721       struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8722       PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8723       if (data->blocks && data->edid)
8724          PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8725       break;
8726    }
8727    case VKI_V4L2_S_EDID: {
8728       struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8729       PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8730       if (data->blocks && data->edid)
8731          PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8732       break;
8733    }
8734    case VKI_V4L2_G_OUTPUT: {
8735       int *data = (int *)(Addr)ARG3;
8736       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8737       break;
8738    }
8739    case VKI_V4L2_S_OUTPUT: {
8740       int *data = (int *)(Addr)ARG3;
8741       PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8742       break;
8743    }
8744    case VKI_V4L2_ENUMOUTPUT: {
8745       struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
8746       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8747       PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8748       break;
8749    }
8750    case VKI_V4L2_G_AUDOUT: {
8751       struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8752       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8753             sizeof(*data) - sizeof(data->reserved));
8754       PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8755       break;
8756    }
8757    case VKI_V4L2_S_AUDOUT: {
8758       struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8759       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8760       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8761       PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8762       break;
8763    }
8764    case VKI_V4L2_G_MODULATOR: {
8765       struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8766       PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8767       PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8768       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8769             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8770       break;
8771    }
8772    case VKI_V4L2_S_MODULATOR: {
8773       struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8774       PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8775       PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8776       PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8777       break;
8778    }
8779    case VKI_V4L2_G_FREQUENCY: {
8780       struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8781       PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8782       PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8783       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8784       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8785       break;
8786    }
8787    case VKI_V4L2_S_FREQUENCY: {
8788       struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8789       PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8790       break;
8791    }
8792    case VKI_V4L2_CROPCAP: {
8793       struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
8794       PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8795       PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8796       break;
8797    }
8798    case VKI_V4L2_G_CROP: {
8799       struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8800       PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8801       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8802       break;
8803    }
8804    case VKI_V4L2_S_CROP: {
8805       struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8806       PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
8807       break;
8808    }
8809    case VKI_V4L2_G_JPEGCOMP: {
8810       struct vki_v4l2_jpegcompression *data =
8811          (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8812       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
8813       break;
8814    }
8815    case VKI_V4L2_S_JPEGCOMP: {
8816       struct vki_v4l2_jpegcompression *data =
8817          (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8818       PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
8819       break;
8820    }
8821    case VKI_V4L2_QUERYSTD: {
8822       vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8823       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
8824       break;
8825    }
8826    case VKI_V4L2_ENUMAUDIO: {
8827       struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8828       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
8829       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
8830       PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
8831             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8832       break;
8833    }
8834    case VKI_V4L2_ENUMAUDOUT: {
8835       struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8836       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
8837       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
8838       PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
8839             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8840       break;
8841    }
8842    case VKI_V4L2_G_PRIORITY: {
8843       __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8844       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
8845       break;
8846    }
8847    case VKI_V4L2_S_PRIORITY: {
8848       __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8849       PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
8850       break;
8851    }
8852    case VKI_V4L2_G_SLICED_VBI_CAP: {
8853       struct vki_v4l2_sliced_vbi_cap *data =
8854          (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
8855       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
8856       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
8857       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
8858             sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
8859       break;
8860    }
8861    case VKI_V4L2_G_EXT_CTRLS: {
8862       struct vki_v4l2_ext_controls *data =
8863          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8864       PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
8865       PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
8866       if (data->count) {
8867          unsigned i;
8868 
8869          PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
8870          for (i = 0; i < data->count; i++) {
8871             PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
8872             PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
8873             PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
8874             if (data->controls[i].size) {
8875                PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
8876                PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
8877                      (Addr)data->controls[i].ptr, data->controls[i].size);
8878             } else {
8879                PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
8880                      data->controls[i].value64);
8881             }
8882          }
8883       }
8884       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
8885       PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
8886       break;
8887    }
8888    case VKI_V4L2_S_EXT_CTRLS: {
8889       struct vki_v4l2_ext_controls *data =
8890          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8891       PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
8892       PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
8893       if (data->count) {
8894          unsigned i;
8895 
8896          PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
8897          PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
8898                data->count * sizeof(data->controls[0]));
8899          for (i = 0; i < data->count; i++) {
8900             if (data->controls[i].size) {
8901                PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
8902                      (Addr)data->controls[i].ptr, data->controls[i].size);
8903             }
8904          }
8905       }
8906       PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
8907       PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
8908       break;
8909    }
8910    case VKI_V4L2_TRY_EXT_CTRLS: {
8911       struct vki_v4l2_ext_controls *data =
8912          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8913       PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
8914       PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
8915       if (data->count) {
8916          unsigned i;
8917 
8918          PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
8919          PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
8920                data->count * sizeof(data->controls[0]));
8921          for (i = 0; i < data->count; i++) {
8922             if (data->controls[i].size) {
8923                PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
8924                      (Addr)data->controls[i].ptr, data->controls[i].size);
8925             }
8926          }
8927       }
8928       PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
8929       PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
8930       break;
8931    }
8932    case VKI_V4L2_ENUM_FRAMESIZES: {
8933       struct vki_v4l2_frmsizeenum *data =
8934          (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
8935       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
8936       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
8937       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
8938       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
8939       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
8940       break;
8941    }
8942    case VKI_V4L2_ENUM_FRAMEINTERVALS: {
8943       struct vki_v4l2_frmivalenum *data =
8944          (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
8945       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
8946       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
8947       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
8948       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
8949       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8950       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8951       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8952       break;
8953    }
8954    case VKI_V4L2_G_ENC_INDEX: {
8955       struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
8956       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8957       break;
8958    }
8959    case VKI_V4L2_ENCODER_CMD: {
8960       struct vki_v4l2_encoder_cmd *data =
8961          (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8962       PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8963       break;
8964    }
8965    case VKI_V4L2_TRY_ENCODER_CMD: {
8966       struct vki_v4l2_encoder_cmd *data =
8967          (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8968       PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8969       break;
8970    }
8971    case VKI_V4L2_DBG_S_REGISTER: {
8972       struct vki_v4l2_dbg_register *data =
8973          (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8974       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8975       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8976       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8977       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8978       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8979       break;
8980    }
8981    case VKI_V4L2_DBG_G_REGISTER: {
8982       struct vki_v4l2_dbg_register *data =
8983          (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8984       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8985       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8986       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8987       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8988       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8989       break;
8990    }
8991    case VKI_V4L2_S_HW_FREQ_SEEK: {
8992       struct vki_v4l2_hw_freq_seek *data =
8993          (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
8994       PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8995       break;
8996    }
8997    case VKI_V4L2_S_DV_TIMINGS: {
8998       struct vki_v4l2_dv_timings *data =
8999          (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9000       PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9001       PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9002       break;
9003    }
9004    case VKI_V4L2_G_DV_TIMINGS: {
9005       struct vki_v4l2_dv_timings *data =
9006          (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9007       PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9008       break;
9009    }
9010    case VKI_V4L2_DQEVENT: {
9011       struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9012       PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9013       break;
9014    }
9015    case VKI_V4L2_SUBSCRIBE_EVENT: {
9016       struct vki_v4l2_event_subscription *data =
9017          (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9018       PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9019       break;
9020    }
9021    case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9022       struct vki_v4l2_event_subscription *data =
9023          (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9024       PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9025       break;
9026    }
9027    case VKI_V4L2_CREATE_BUFS: {
9028       struct vki_v4l2_create_buffers *data =
9029          (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9030       struct vki_v4l2_format *fmt = &data->format;
9031       PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9032       PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9033       PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9034       PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9035       PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9036       switch (fmt->type) {
9037       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9038       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9039          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9040          break;
9041       case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9042       case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9043          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9044          break;
9045       case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9046       case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9047          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9048          break;
9049       case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9050       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9051          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9052          break;
9053       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9054       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9055          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9056          break;
9057       case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9058          PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9059          break;
9060       }
9061       break;
9062    }
9063    case VKI_V4L2_PREPARE_BUF: {
9064       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9065       PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9066       PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9067       PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9068       PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9069       PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9070       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9071             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9072          unsigned i;
9073 
9074          PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9075          PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9076          for (i = 0; i < data->length; i++) {
9077             PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9078          }
9079       }
9080       break;
9081    }
9082    case VKI_V4L2_G_SELECTION: {
9083       struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9084       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9085       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9086       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9087       PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9088       PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9089       break;
9090    }
9091    case VKI_V4L2_S_SELECTION: {
9092       struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9093       PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9094       break;
9095    }
9096    case VKI_V4L2_DECODER_CMD: {
9097       struct vki_v4l2_decoder_cmd *data =
9098          (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9099       PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9100       break;
9101    }
9102    case VKI_V4L2_TRY_DECODER_CMD: {
9103       struct vki_v4l2_decoder_cmd *data =
9104          (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9105       PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9106       break;
9107    }
9108    case VKI_V4L2_ENUM_DV_TIMINGS: {
9109       struct vki_v4l2_enum_dv_timings *data =
9110          (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9111       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9112       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9113       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9114       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9115       break;
9116    }
9117    case VKI_V4L2_QUERY_DV_TIMINGS: {
9118       struct vki_v4l2_dv_timings *data =
9119          (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9120       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9121       break;
9122    }
9123    case VKI_V4L2_DV_TIMINGS_CAP: {
9124       struct vki_v4l2_dv_timings_cap *data =
9125          (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9126       PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9127       break;
9128    }
9129    case VKI_V4L2_ENUM_FREQ_BANDS: {
9130       struct vki_v4l2_frequency_band *data =
9131          (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9132       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9133       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9134       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9135       PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9136       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9137       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9138       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9139       PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9140       break;
9141    }
9142    case VKI_V4L2_DBG_G_CHIP_INFO: {
9143       struct vki_v4l2_dbg_chip_info *data =
9144          (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9145       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9146       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9147       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9148       PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9149       PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9150       break;
9151    }
9152    case VKI_V4L2_QUERY_EXT_CTRL: {
9153       struct vki_v4l2_query_ext_ctrl *data =
9154          (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9155       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9156       PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9157       PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9158             sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9159       break;
9160    }
9161    case VKI_V4L2_SUBDEV_G_FMT: {
9162       struct vki_v4l2_subdev_format *data =
9163          (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9164       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9165       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9166       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9167       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9168       break;
9169    }
9170    case VKI_V4L2_SUBDEV_S_FMT: {
9171       struct vki_v4l2_subdev_format *data =
9172          (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9173       PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9174       break;
9175    }
9176    case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9177       struct vki_v4l2_subdev_frame_interval *data =
9178          (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9179       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9180       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9181       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9182       break;
9183    }
9184    case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9185       struct vki_v4l2_subdev_frame_interval *data =
9186          (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9187       PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9188       break;
9189    }
9190    case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9191       struct vki_v4l2_subdev_mbus_code_enum *data =
9192          (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9193       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9194       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9195       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9196       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9197       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9198       break;
9199    }
9200    case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9201       struct vki_v4l2_subdev_frame_size_enum *data =
9202          (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9203       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9204       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9205       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9206       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9207       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9208       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9209       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9210       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9211       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9212       break;
9213    }
9214    case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9215       struct vki_v4l2_subdev_frame_interval_enum *data =
9216          (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9217       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9218       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9219       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9220       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9221       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9222       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9223       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9224       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9225       break;
9226    }
9227    case VKI_V4L2_SUBDEV_G_CROP: {
9228       struct vki_v4l2_subdev_crop *data =
9229          (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9230       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9231       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9232       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9233       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9234       break;
9235    }
9236    case VKI_V4L2_SUBDEV_S_CROP: {
9237       struct vki_v4l2_subdev_crop *data =
9238          (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9239       PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9240       break;
9241    }
9242    case VKI_V4L2_SUBDEV_G_SELECTION: {
9243       struct vki_v4l2_subdev_selection *data =
9244          (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9245       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9246       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9247       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9248       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9249       PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9250       PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9251       break;
9252    }
9253    case VKI_V4L2_SUBDEV_S_SELECTION: {
9254       struct vki_v4l2_subdev_selection *data =
9255          (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9256       PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
9257       break;
9258    }
9259    case VKI_MEDIA_IOC_DEVICE_INFO: {
9260       struct vki_media_device_info *data =
9261          (struct vki_media_device_info *)(Addr)ARG3;
9262       PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
9263       PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
9264             (Addr)data, sizeof(*data) - sizeof(data->reserved));
9265       break;
9266    }
9267    case VKI_MEDIA_IOC_ENUM_ENTITIES: {
9268       struct vki_media_entity_desc *data =
9269          (struct vki_media_entity_desc *)(Addr)ARG3;
9270       PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
9271       PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
9272             (Addr)data->name, sizeof(*data) - sizeof(data->id));
9273       break;
9274    }
9275    case VKI_MEDIA_IOC_ENUM_LINKS: {
9276       struct vki_media_links_enum *data =
9277          (struct vki_media_links_enum *)(Addr)ARG3;
9278       PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
9279       break;
9280    }
9281    case VKI_MEDIA_IOC_SETUP_LINK: {
9282       struct vki_media_link_desc *data =
9283          (struct vki_media_link_desc *)(Addr)ARG3;
9284       PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
9285       break;
9286    }
9287 
9288    /* Serial */
9289    case VKI_TIOCGSERIAL: {
9290       struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9291       PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9292       break;
9293    }
9294    case VKI_TIOCSSERIAL: {
9295       struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9296       PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9297       break;
9298    }
9299 
9300    case VKI_PERF_EVENT_IOC_RESET:
9301    case VKI_PERF_EVENT_IOC_REFRESH:
9302    case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9303    case VKI_PERF_EVENT_IOC_SET_BPF:
9304       /* These take scalar arguments, so already handled above */
9305       break;
9306 
9307    case VKI_PERF_EVENT_IOC_PERIOD:
9308       PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9309       break;
9310 
9311    case VKI_PERF_EVENT_IOC_SET_FILTER:
9312       PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9313       break;
9314 
9315    case VKI_PERF_EVENT_IOC_ID:
9316       PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9317       break;
9318 
9319    default:
9320       /* EVIOC* are variable length and return size written on success */
9321       switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9322       case VKI_EVIOCGNAME(0):
9323       case VKI_EVIOCGPHYS(0):
9324       case VKI_EVIOCGUNIQ(0):
9325       case VKI_EVIOCGKEY(0):
9326       case VKI_EVIOCGLED(0):
9327       case VKI_EVIOCGSND(0):
9328       case VKI_EVIOCGSW(0):
9329       case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9330       case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9331       case VKI_EVIOCGBIT(VKI_EV_REL,0):
9332       case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9333       case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9334       case VKI_EVIOCGBIT(VKI_EV_SW,0):
9335       case VKI_EVIOCGBIT(VKI_EV_LED,0):
9336       case VKI_EVIOCGBIT(VKI_EV_SND,0):
9337       case VKI_EVIOCGBIT(VKI_EV_REP,0):
9338       case VKI_EVIOCGBIT(VKI_EV_FF,0):
9339       case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9340       case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9341          PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9342          break;
9343       default:
9344          ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9345          break;
9346       }
9347       break;
9348    }
9349 }
9350 
POST(sys_ioctl)9351 POST(sys_ioctl)
9352 {
9353    ARG2 = (UInt)ARG2;
9354 
9355    vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9356 
9357    /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9358 
9359    /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9360    if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9361                        VG_(clo_kernel_variant))) {
9362 
9363       if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9364          /* What's going on here: there appear to be a bunch of ioctls
9365             of the form 0xC01C67xx which are undocumented, and if
9366             unhandled give rise to a vast number of false positives in
9367             Memcheck.
9368 
9369             The "normal" interpretation of an ioctl of this form would
9370             be that the 3rd arg is a pointer to an area of size 0x1C
9371             (28 bytes) which is filled in by the kernel.  Hence you
9372             might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9373             But it doesn't.
9374 
9375             It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9376             One interpretation of this is that ARG3 really does point
9377             to a 28 byte struct, but inside that are pointers to other
9378             areas also filled in by the kernel.  If these happen to be
9379             allocated just back up the stack then the 256 byte paint
9380             might cover them too, somewhat indiscriminately.
9381 
9382             By printing out ARG3 and also the 28 bytes that it points
9383             at, it's possible to guess that the 7 word structure has
9384             this form
9385 
9386               0            1    2    3        4    5        6
9387               ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9388 
9389             Unfortunately that doesn't seem to work for some reason,
9390             so stay with the blunt-instrument approach for the time
9391             being.
9392          */
9393          if (1) {
9394             /* blunt-instrument approach */
9395             POST_MEM_WRITE(ARG3, 256);
9396          } else {
9397             /* be a bit more sophisticated */
9398             POST_MEM_WRITE(ARG3, 28);
9399             UInt* word = (UInt*)(Addr)ARG3;
9400             if (word && word[2] && word[3] < 0x200/*stay sane*/)
9401                POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9402             if (word && word[4] && word[5] < 0x200/*stay sane*/)
9403                POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9404          }
9405          goto post_sys_ioctl__out;
9406       }
9407    }
9408    /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9409 
9410    /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9411    if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9412                        VG_(clo_kernel_variant))) {
9413      if (ARG2 == 0xC00C0902) {
9414          POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9415          goto post_sys_ioctl__out;
9416      }
9417    }
9418    /* END undocumented ioctls for Qualcomm Adreno 3xx */
9419 
9420    /* --- END special IOCTL handlers for specific Android hardware --- */
9421 
9422    /* --- normal handling --- */
9423    switch (ARG2 /* request */) {
9424 
9425    /* The Linux kernel "ion" memory allocator, used on Android.  Note:
9426       this is pretty poor given that there's no pre-handling to check
9427       that writable areas are addressable. */
9428    case VKI_ION_IOC_ALLOC: {
9429       struct vki_ion_allocation_data* data
9430          = (struct vki_ion_allocation_data*)(Addr)ARG3;
9431       POST_FIELD_WRITE(data->handle);
9432       break;
9433    }
9434    case VKI_ION_IOC_MAP: {
9435       struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9436       POST_FIELD_WRITE(data->fd);
9437       break;
9438    }
9439    case VKI_ION_IOC_FREE: // is this necessary?
9440       POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9441       break;
9442    case VKI_ION_IOC_SHARE:
9443       break;
9444    case VKI_ION_IOC_IMPORT: {
9445       struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9446       POST_FIELD_WRITE(data->handle);
9447       break;
9448    }
9449    case VKI_ION_IOC_SYNC:
9450       break;
9451    case VKI_ION_IOC_CUSTOM: // is this necessary?
9452       POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9453       break;
9454 
9455    case VKI_SYNC_IOC_MERGE: {
9456       struct vki_sync_merge_data* data =
9457          (struct vki_sync_merge_data*)(Addr)ARG3;
9458       POST_FIELD_WRITE(data->fence);
9459       break;
9460    }
9461 
9462    case VKI_TCSETS:
9463    case VKI_TCSETSW:
9464    case VKI_TCSETSF:
9465    case VKI_IB_USER_MAD_ENABLE_PKEY:
9466       break;
9467    case VKI_TCGETS:
9468       POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9469       break;
9470    case VKI_TCSETA:
9471    case VKI_TCSETAW:
9472    case VKI_TCSETAF:
9473       break;
9474    case VKI_TCGETA:
9475       POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9476       break;
9477    case VKI_TCSBRK:
9478    case VKI_TCXONC:
9479    case VKI_TCSBRKP:
9480    case VKI_TCFLSH:
9481    case VKI_TIOCSIG:
9482       break;
9483    case VKI_TIOCGWINSZ:
9484       POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9485       break;
9486    case VKI_TIOCSWINSZ:
9487    case VKI_TIOCMBIS:
9488    case VKI_TIOCMBIC:
9489    case VKI_TIOCMSET:
9490       break;
9491    case VKI_TIOCMGET:
9492       POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9493       break;
9494    case VKI_TIOCLINUX:
9495       POST_MEM_WRITE( ARG3, sizeof(char *) );
9496       break;
9497    case VKI_TIOCGPGRP:
9498       /* Get process group ID for foreground processing group. */
9499       POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9500       break;
9501    case VKI_TIOCSPGRP:
9502       /* Set a process group ID? */
9503       POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9504       break;
9505    case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9506       POST_MEM_WRITE( ARG3, sizeof(int));
9507       break;
9508    case VKI_TIOCSCTTY:
9509       break;
9510    case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9511       break;
9512    case VKI_FIONBIO:
9513       break;
9514    case VKI_FIONCLEX:
9515       break;
9516    case VKI_FIOCLEX:
9517       break;
9518    case VKI_TIOCNOTTY:
9519       break;
9520    case VKI_FIOASYNC:
9521       break;
9522    case VKI_FIONREAD:                /* identical to SIOCINQ */
9523       POST_MEM_WRITE( ARG3, sizeof(int) );
9524       break;
9525    case VKI_FIOQSIZE:
9526       POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9527       break;
9528 
9529    case VKI_TIOCSERGETLSR:
9530       POST_MEM_WRITE( ARG3, sizeof(int) );
9531       break;
9532    case VKI_TIOCGICOUNT:
9533       POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9534       break;
9535 
9536    case VKI_SG_SET_COMMAND_Q:
9537       break;
9538    case VKI_SG_IO:
9539       {
9540          vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
9541          if ( sgio->sbp ) {
9542             POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9543          }
9544          if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9545               sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9546             int transferred = sgio->dxfer_len - sgio->resid;
9547             POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9548          }
9549       }
9550       break;
9551    case VKI_SG_GET_SCSI_ID:
9552       POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9553       break;
9554    case VKI_SG_SET_RESERVED_SIZE:
9555       break;
9556    case VKI_SG_SET_TIMEOUT:
9557       break;
9558    case VKI_SG_GET_RESERVED_SIZE:
9559       POST_MEM_WRITE(ARG3, sizeof(int));
9560       break;
9561    case VKI_SG_GET_TIMEOUT:
9562       break;
9563    case VKI_SG_GET_VERSION_NUM:
9564       POST_MEM_WRITE(ARG3, sizeof(int));
9565       break;
9566    case VKI_SG_EMULATED_HOST:
9567       POST_MEM_WRITE(ARG3, sizeof(int));
9568       break;
9569    case VKI_SG_GET_SG_TABLESIZE:
9570       POST_MEM_WRITE(ARG3, sizeof(int));
9571       break;
9572 
9573    case VKI_IIOCGETCPS:
9574       POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9575       break;
9576    case VKI_IIOCNETGPN:
9577       POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9578       break;
9579 
9580       /* These all use struct ifreq AFAIK */
9581    case VKI_SIOCGIFINDEX:        /* get iface index              */
9582       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
9583                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
9584       break;
9585    case VKI_SIOCGIFFLAGS:        /* get flags                    */
9586       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9587                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
9588       break;
9589    case VKI_SIOCGIFHWADDR:       /* Get hardware address         */
9590       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
9591                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
9592       break;
9593    case VKI_SIOCGIFMTU:          /* get MTU size                 */
9594       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
9595                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
9596       break;
9597    case VKI_SIOCGIFADDR:         /* get PA address               */
9598    case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
9599    case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
9600    case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
9601       POST_MEM_WRITE(
9602                 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
9603                 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
9604       break;
9605    case VKI_SIOCGIFMETRIC:       /* get metric                   */
9606       POST_MEM_WRITE(
9607                 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
9608                 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
9609       break;
9610    case VKI_SIOCGIFMAP:          /* Get device parameters        */
9611       POST_MEM_WRITE(
9612                 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
9613                 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
9614       break;
9615      break;
9616    case VKI_SIOCGIFTXQLEN:       /* Get the tx queue length      */
9617       POST_MEM_WRITE(
9618                 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
9619                 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
9620       break;
9621    case VKI_SIOCGIFNAME:         /* get iface name               */
9622       POST_MEM_WRITE(
9623                 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9624                 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9625       break;
9626    case VKI_SIOCETHTOOL: {       /* ethtool(8) interface         */
9627       struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
9628       switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9629       case VKI_ETHTOOL_GSET:
9630          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9631          break;
9632       case VKI_ETHTOOL_SSET:
9633          break;
9634       case VKI_ETHTOOL_GDRVINFO:
9635          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9636          break;
9637       case VKI_ETHTOOL_GREGS:
9638          POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9639                          ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9640          break;
9641       case VKI_ETHTOOL_GWOL:
9642          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9643          break;
9644       case VKI_ETHTOOL_SWOL:
9645          break;
9646       case VKI_ETHTOOL_GMSGLVL:
9647       case VKI_ETHTOOL_GLINK:
9648       case VKI_ETHTOOL_GRXCSUM:
9649       case VKI_ETHTOOL_GSG:
9650       case VKI_ETHTOOL_GTSO:
9651       case VKI_ETHTOOL_GUFO:
9652       case VKI_ETHTOOL_GGSO:
9653       case VKI_ETHTOOL_GFLAGS:
9654       case VKI_ETHTOOL_GGRO:
9655          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9656          break;
9657       case VKI_ETHTOOL_SMSGLVL:
9658       case VKI_ETHTOOL_SRXCSUM:
9659       case VKI_ETHTOOL_SSG:
9660       case VKI_ETHTOOL_STSO:
9661       case VKI_ETHTOOL_SUFO:
9662       case VKI_ETHTOOL_SGSO:
9663       case VKI_ETHTOOL_SFLAGS:
9664       case VKI_ETHTOOL_SGRO:
9665          break;
9666       case VKI_ETHTOOL_NWAY_RST:
9667          break;
9668       case VKI_ETHTOOL_GRINGPARAM:
9669          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9670          break;
9671       case VKI_ETHTOOL_SRINGPARAM:
9672          break;
9673       case VKI_ETHTOOL_TEST:
9674          POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9675                          ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9676          break;
9677       case VKI_ETHTOOL_PHYS_ID:
9678          break;
9679       case VKI_ETHTOOL_GPERMADDR:
9680          POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9681                          ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9682          break;
9683       case VKI_ETHTOOL_RESET:
9684          break;
9685       case VKI_ETHTOOL_GSSET_INFO:
9686          POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9687                         __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9688          break;
9689       case VKI_ETHTOOL_GFEATURES:
9690          POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9691                          ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9692          break;
9693       case VKI_ETHTOOL_SFEATURES:
9694          break;
9695       case VKI_ETHTOOL_GCHANNELS:
9696          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9697          break;
9698       case VKI_ETHTOOL_SCHANNELS:
9699          break;
9700       case VKI_ETHTOOL_GET_TS_INFO:
9701          POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9702          break;
9703       }
9704       break;
9705    }
9706    case VKI_SIOCGMIIPHY:         /* get hardware entry           */
9707       POST_MEM_WRITE(
9708                 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
9709                 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
9710       break;
9711    case VKI_SIOCGMIIREG:         /* get hardware entry registers */
9712       POST_MEM_WRITE(
9713                 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
9714                 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
9715       break;
9716 
9717       /* tun/tap related ioctls */
9718    case VKI_TUNSETIFF:
9719       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9720                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9721       break;
9722    case VKI_TUNGETFEATURES:
9723       POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9724       break;
9725    case VKI_TUNGETIFF:
9726       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9727                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9728       POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9729                       sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
9730       break;
9731    case VKI_TUNGETSNDBUF:
9732       POST_MEM_WRITE( ARG3, sizeof(int) );
9733       break;
9734    case VKI_TUNGETVNETHDRSZ:
9735       POST_MEM_WRITE( ARG3, sizeof(int) );
9736       break;
9737 
9738    case VKI_SIOCGIFCONF:         /* get iface list               */
9739       /* WAS:
9740 	 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
9741 	 KERNEL_DO_SYSCALL(tid,RES);
9742 	 if (!VG_(is_kerror)(RES) && RES == 0)
9743 	 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
9744       */
9745       if (RES == 0 && ARG3 ) {
9746 	 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
9747 	 if (ifc->vki_ifc_buf != NULL)
9748 	    POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
9749       }
9750       break;
9751    case VKI_SIOCGSTAMP:
9752       POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9753       break;
9754    case VKI_SIOCGSTAMPNS:
9755       POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
9756       break;
9757       /* SIOCOUTQ is an ioctl that, when called on a socket, returns
9758 	 the number of bytes currently in that socket's send buffer.
9759 	 It writes this value as an int to the memory location
9760 	 indicated by the third argument of ioctl(2). */
9761    case VKI_SIOCOUTQ:
9762       POST_MEM_WRITE(ARG3, sizeof(int));
9763       break;
9764    case VKI_SIOCGRARP:           /* get RARP table entry         */
9765    case VKI_SIOCGARP:            /* get ARP table entry          */
9766       POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
9767       break;
9768 
9769    case VKI_SIOCSIFFLAGS:        /* set flags                    */
9770    case VKI_SIOCSIFMAP:          /* Set device parameters        */
9771    case VKI_SIOCSHWTSTAMP:       /* Set hardware time stamping   */
9772    case VKI_SIOCSIFTXQLEN:       /* Set the tx queue length      */
9773    case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
9774    case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
9775    case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
9776    case VKI_SIOCSIFMETRIC:       /* set metric                   */
9777    case VKI_SIOCSIFADDR:         /* set PA address               */
9778    case VKI_SIOCSIFMTU:          /* set MTU size                 */
9779    case VKI_SIOCSIFHWADDR:       /* set hardware address         */
9780    case VKI_SIOCSMIIREG:         /* set hardware entry registers */
9781       break;
9782       /* Routing table calls.  */
9783    case VKI_SIOCADDRT:           /* add routing table entry      */
9784    case VKI_SIOCDELRT:           /* delete routing table entry   */
9785       break;
9786 
9787       /* RARP cache control calls. */
9788    case VKI_SIOCDRARP:           /* delete RARP table entry      */
9789    case VKI_SIOCSRARP:           /* set RARP table entry         */
9790       /* ARP cache control calls. */
9791    case VKI_SIOCSARP:            /* set ARP table entry          */
9792    case VKI_SIOCDARP:            /* delete ARP table entry       */
9793       break;
9794 
9795    case VKI_SIOCGPGRP:
9796       POST_MEM_WRITE(ARG3, sizeof(int));
9797       break;
9798    case VKI_SIOCSPGRP:
9799       break;
9800 
9801    case VKI_SIOCATMARK:
9802       POST_MEM_WRITE(ARG3, sizeof(int));
9803       break;
9804 
9805       /* linux/soundcard interface (OSS) */
9806    case VKI_SNDCTL_SEQ_GETOUTCOUNT:
9807    case VKI_SNDCTL_SEQ_GETINCOUNT:
9808    case VKI_SNDCTL_SEQ_PERCMODE:
9809    case VKI_SNDCTL_SEQ_TESTMIDI:
9810    case VKI_SNDCTL_SEQ_RESETSAMPLES:
9811    case VKI_SNDCTL_SEQ_NRSYNTHS:
9812    case VKI_SNDCTL_SEQ_NRMIDIS:
9813    case VKI_SNDCTL_SEQ_GETTIME:
9814    case VKI_SNDCTL_DSP_GETBLKSIZE:
9815    case VKI_SNDCTL_DSP_GETFMTS:
9816    case VKI_SNDCTL_DSP_SETFMT:
9817    case VKI_SNDCTL_DSP_GETTRIGGER:
9818    case VKI_SNDCTL_DSP_GETODELAY:
9819    case VKI_SNDCTL_DSP_GETSPDIF:
9820    case VKI_SNDCTL_DSP_GETCAPS:
9821    case VKI_SOUND_PCM_READ_RATE:
9822    case VKI_SOUND_PCM_READ_CHANNELS:
9823    case VKI_SOUND_PCM_READ_BITS:
9824    case VKI_SOUND_PCM_READ_FILTER:
9825       POST_MEM_WRITE(ARG3, sizeof(int));
9826       break;
9827    case VKI_SNDCTL_SEQ_CTRLRATE:
9828    case VKI_SNDCTL_DSP_SPEED:
9829    case VKI_SNDCTL_DSP_STEREO:
9830    case VKI_SNDCTL_DSP_CHANNELS:
9831    case VKI_SOUND_PCM_WRITE_FILTER:
9832    case VKI_SNDCTL_DSP_SUBDIVIDE:
9833    case VKI_SNDCTL_DSP_SETFRAGMENT:
9834    case VKI_SNDCTL_DSP_GETCHANNELMASK:
9835    case VKI_SNDCTL_DSP_BIND_CHANNEL:
9836    case VKI_SNDCTL_TMR_TIMEBASE:
9837    case VKI_SNDCTL_TMR_TEMPO:
9838    case VKI_SNDCTL_TMR_SOURCE:
9839    case VKI_SNDCTL_MIDI_PRETIME:
9840    case VKI_SNDCTL_MIDI_MPUMODE:
9841       break;
9842    case VKI_SNDCTL_DSP_GETOSPACE:
9843    case VKI_SNDCTL_DSP_GETISPACE:
9844       POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
9845       break;
9846    case VKI_SNDCTL_DSP_NONBLOCK:
9847       break;
9848    case VKI_SNDCTL_DSP_SETTRIGGER:
9849       break;
9850 
9851    case VKI_SNDCTL_DSP_POST:
9852    case VKI_SNDCTL_DSP_RESET:
9853    case VKI_SNDCTL_DSP_SYNC:
9854    case VKI_SNDCTL_DSP_SETSYNCRO:
9855    case VKI_SNDCTL_DSP_SETDUPLEX:
9856       break;
9857 
9858       /* linux/soundcard interface (ALSA) */
9859    case VKI_SNDRV_PCM_IOCTL_HW_FREE:
9860    case VKI_SNDRV_PCM_IOCTL_HWSYNC:
9861    case VKI_SNDRV_PCM_IOCTL_PREPARE:
9862    case VKI_SNDRV_PCM_IOCTL_RESET:
9863    case VKI_SNDRV_PCM_IOCTL_START:
9864    case VKI_SNDRV_PCM_IOCTL_DROP:
9865    case VKI_SNDRV_PCM_IOCTL_DRAIN:
9866    case VKI_SNDRV_PCM_IOCTL_RESUME:
9867    case VKI_SNDRV_PCM_IOCTL_XRUN:
9868    case VKI_SNDRV_PCM_IOCTL_UNLINK:
9869    case VKI_SNDRV_TIMER_IOCTL_START:
9870    case VKI_SNDRV_TIMER_IOCTL_STOP:
9871    case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
9872    case VKI_SNDRV_TIMER_IOCTL_PAUSE:
9873       break;
9874 
9875    case VKI_SNDRV_CTL_IOCTL_PVERSION: {
9876       POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
9877       break;
9878    }
9879    case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
9880       POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
9881       break;
9882    case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
9883       struct vki_snd_ctl_elem_list *data =
9884          (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
9885       POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
9886       POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
9887       if (data->pids) {
9888          POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
9889       }
9890       break;
9891    }
9892    case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
9893       struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
9894       POST_MEM_WRITE( (Addr)data->tlv, data->length );
9895       break;
9896    }
9897    case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
9898    case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
9899       break;
9900 
9901       /* SCSI no operand */
9902    case VKI_SCSI_IOCTL_DOORLOCK:
9903    case VKI_SCSI_IOCTL_DOORUNLOCK:
9904       break;
9905 
9906       /* Real Time Clock (/dev/rtc) ioctls */
9907    case VKI_RTC_UIE_ON:
9908    case VKI_RTC_UIE_OFF:
9909    case VKI_RTC_AIE_ON:
9910    case VKI_RTC_AIE_OFF:
9911    case VKI_RTC_PIE_ON:
9912    case VKI_RTC_PIE_OFF:
9913    case VKI_RTC_IRQP_SET:
9914       break;
9915    case VKI_RTC_RD_TIME:
9916    case VKI_RTC_ALM_READ:
9917       POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
9918       break;
9919    case VKI_RTC_ALM_SET:
9920       break;
9921    case VKI_RTC_IRQP_READ:
9922       POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9923       break;
9924 
9925       /* Block devices */
9926    case VKI_BLKROSET:
9927       break;
9928    case VKI_BLKROGET:
9929       POST_MEM_WRITE(ARG3, sizeof(int));
9930       break;
9931    case VKI_BLKGETSIZE:
9932       POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9933       break;
9934    case VKI_BLKFLSBUF:
9935       break;
9936    case VKI_BLKRASET:
9937       break;
9938    case VKI_BLKRAGET:
9939       POST_MEM_WRITE(ARG3, sizeof(long));
9940       break;
9941    case VKI_BLKFRASET:
9942       break;
9943    case VKI_BLKFRAGET:
9944       POST_MEM_WRITE(ARG3, sizeof(long));
9945       break;
9946    case VKI_BLKSECTGET:
9947       POST_MEM_WRITE(ARG3, sizeof(unsigned short));
9948       break;
9949    case VKI_BLKSSZGET:
9950       POST_MEM_WRITE(ARG3, sizeof(int));
9951       break;
9952    case VKI_BLKBSZGET:
9953       POST_MEM_WRITE(ARG3, sizeof(int));
9954       break;
9955    case VKI_BLKBSZSET:
9956       break;
9957    case VKI_BLKGETSIZE64:
9958       POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
9959       break;
9960    case VKI_BLKPBSZGET:
9961       POST_MEM_WRITE(ARG3, sizeof(int));
9962       break;
9963    case VKI_BLKDISCARDZEROES:
9964       POST_MEM_WRITE(ARG3, sizeof(vki_uint));
9965       break;
9966    case VKI_BLKREPORTZONE: {
9967       const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
9968 
9969       POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
9970       break;
9971    }
9972    case VKI_BLKRESETZONE:
9973       break;
9974 
9975       /* Hard disks */
9976    case VKI_HDIO_GETGEO: /* 0x0301 */
9977       POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
9978       break;
9979    case VKI_HDIO_GET_DMA: /* 0x030b */
9980       POST_MEM_WRITE(ARG3, sizeof(long));
9981       break;
9982    case VKI_HDIO_GET_IDENTITY: /* 0x030d */
9983       POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
9984       break;
9985 
9986       /* SCSI */
9987    case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
9988       POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
9989       break;
9990    case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
9991       POST_MEM_WRITE(ARG3, sizeof(int));
9992       break;
9993 
9994       /* CD ROM stuff (??)  */
9995    case VKI_CDROM_DISC_STATUS:
9996    case VKI_CDROMSTOP:
9997       break;
9998    case VKI_CDROMSUBCHNL:
9999       POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10000       break;
10001    case VKI_CDROMREADTOCHDR:
10002       POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10003       break;
10004    case VKI_CDROMREADTOCENTRY:
10005       POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10006       break;
10007    case VKI_CDROMMULTISESSION:
10008       POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10009       break;
10010    case VKI_CDROMVOLREAD:
10011       POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10012       break;
10013    case VKI_CDROMREADMODE1:
10014       POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10015       break;
10016    case VKI_CDROMREADMODE2:
10017       POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10018       break;
10019    case VKI_CDROMREADRAW:
10020       POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10021       break;
10022    case VKI_CDROMREADAUDIO:
10023    {
10024       struct vki_cdrom_read_audio *cra =
10025          (struct vki_cdrom_read_audio *) (Addr)ARG3;
10026       POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10027       break;
10028    }
10029 
10030    case VKI_CDROMPLAYMSF:
10031       break;
10032       /* The following two are probably bogus (should check args
10033 	 for readability).  JRS 20021117 */
10034    case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10035    case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10036       break;
10037    case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10038       break;
10039 
10040       /* DVD stuff */
10041    case VKI_DVD_READ_STRUCT:
10042       break;
10043 
10044    case VKI_FIGETBSZ:
10045       POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10046       break;
10047    case VKI_FIBMAP:
10048       POST_MEM_WRITE(ARG3, sizeof(int));
10049       break;
10050 
10051    case VKI_FBIOGET_VSCREENINFO: //0x4600
10052       POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10053       break;
10054    case VKI_FBIOGET_FSCREENINFO: //0x4602
10055       POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10056       break;
10057 
10058    case VKI_PPCLAIM:
10059    case VKI_PPEXCL:
10060    case VKI_PPYIELD:
10061    case VKI_PPRELEASE:
10062    case VKI_PPSETMODE:
10063    case VKI_PPSETPHASE:
10064    case VKI_PPSETFLAGS:
10065    case VKI_PPWDATA:
10066    case VKI_PPWCONTROL:
10067    case VKI_PPFCONTROL:
10068    case VKI_PPDATADIR:
10069    case VKI_PPNEGOT:
10070    case VKI_PPWCTLONIRQ:
10071    case VKI_PPSETTIME:
10072       break;
10073    case VKI_PPGETMODE:
10074       POST_MEM_WRITE( ARG3, sizeof(int) );
10075       break;
10076    case VKI_PPGETPHASE:
10077       POST_MEM_WRITE( ARG3, sizeof(int) );
10078       break;
10079    case VKI_PPGETMODES:
10080       POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10081       break;
10082    case VKI_PPGETFLAGS:
10083       POST_MEM_WRITE( ARG3, sizeof(int) );
10084       break;
10085    case VKI_PPRSTATUS:
10086       POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10087       break;
10088    case VKI_PPRDATA:
10089       POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10090       break;
10091    case VKI_PPRCONTROL:
10092       POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10093       break;
10094    case VKI_PPCLRIRQ:
10095       POST_MEM_WRITE( ARG3, sizeof(int) );
10096       break;
10097    case VKI_PPGETTIME:
10098       POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10099       break;
10100 
10101    case VKI_GIO_FONT:
10102       POST_MEM_WRITE( ARG3, 32 * 256 );
10103       break;
10104    case VKI_PIO_FONT:
10105       break;
10106 
10107    case VKI_GIO_FONTX:
10108       POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10109                      32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10110       break;
10111    case VKI_PIO_FONTX:
10112       break;
10113 
10114    case VKI_PIO_FONTRESET:
10115       break;
10116 
10117    case VKI_GIO_CMAP:
10118       POST_MEM_WRITE( ARG3, 16 * 3 );
10119       break;
10120    case VKI_PIO_CMAP:
10121       break;
10122 
10123    case VKI_KIOCSOUND:
10124    case VKI_KDMKTONE:
10125       break;
10126 
10127    case VKI_KDGETLED:
10128       POST_MEM_WRITE( ARG3, sizeof(char) );
10129       break;
10130    case VKI_KDSETLED:
10131       break;
10132 
10133    case VKI_KDGKBTYPE:
10134       POST_MEM_WRITE( ARG3, sizeof(char) );
10135       break;
10136 
10137    case VKI_KDADDIO:
10138    case VKI_KDDELIO:
10139    case VKI_KDENABIO:
10140    case VKI_KDDISABIO:
10141       break;
10142 
10143    case VKI_KDSETMODE:
10144       break;
10145    case VKI_KDGETMODE:
10146       POST_MEM_WRITE( ARG3, sizeof(int) );
10147       break;
10148 
10149    case VKI_KDMAPDISP:
10150    case VKI_KDUNMAPDISP:
10151       break;
10152 
10153    case VKI_GIO_SCRNMAP:
10154       POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
10155       break;
10156    case VKI_PIO_SCRNMAP:
10157       break;
10158    case VKI_GIO_UNISCRNMAP:
10159       POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
10160       break;
10161    case VKI_PIO_UNISCRNMAP:
10162       break;
10163 
10164    case VKI_GIO_UNIMAP:
10165       if ( ARG3 ) {
10166          struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
10167          POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
10168          POST_MEM_WRITE( (Addr)desc->entries,
10169       	                 desc->entry_ct * sizeof(struct vki_unipair) );
10170       }
10171       break;
10172    case VKI_PIO_UNIMAP:
10173       break;
10174    case VKI_PIO_UNIMAPCLR:
10175       break;
10176 
10177    case VKI_KDGKBMODE:
10178       POST_MEM_WRITE( ARG3, sizeof(int) );
10179       break;
10180    case VKI_KDSKBMODE:
10181       break;
10182 
10183    case VKI_KDGKBMETA:
10184       POST_MEM_WRITE( ARG3, sizeof(int) );
10185       break;
10186    case VKI_KDSKBMETA:
10187       break;
10188 
10189    case VKI_KDGKBLED:
10190       POST_MEM_WRITE( ARG3, sizeof(char) );
10191       break;
10192    case VKI_KDSKBLED:
10193       break;
10194 
10195    case VKI_KDGKBENT:
10196       POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
10197                       sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
10198       break;
10199    case VKI_KDSKBENT:
10200       break;
10201 
10202    case VKI_KDGKBSENT:
10203       POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
10204                       sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
10205       break;
10206    case VKI_KDSKBSENT:
10207       break;
10208 
10209    case VKI_KDGKBDIACR:
10210       POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
10211       break;
10212    case VKI_KDSKBDIACR:
10213       break;
10214 
10215    case VKI_KDGETKEYCODE:
10216       POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
10217                       sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
10218       break;
10219    case VKI_KDSETKEYCODE:
10220       break;
10221 
10222    case VKI_KDSIGACCEPT:
10223       break;
10224 
10225    case VKI_KDKBDREP:
10226       break;
10227 
10228    case VKI_KDFONTOP:
10229       if ( ARG3 ) {
10230          struct vki_console_font_op *op =
10231             (struct vki_console_font_op *) (Addr)ARG3;
10232          switch ( op->op ) {
10233             case VKI_KD_FONT_OP_SET:
10234                break;
10235             case VKI_KD_FONT_OP_GET:
10236                if ( op->data )
10237                   POST_MEM_WRITE( (Addr) op->data,
10238                                   (op->width + 7) / 8 * 32 * op->charcount );
10239                break;
10240             case VKI_KD_FONT_OP_SET_DEFAULT:
10241                break;
10242             case VKI_KD_FONT_OP_COPY:
10243                break;
10244          }
10245          POST_MEM_WRITE( (Addr) op, sizeof(*op));
10246       }
10247       break;
10248 
10249    case VKI_VT_OPENQRY:
10250       POST_MEM_WRITE( ARG3, sizeof(int) );
10251       break;
10252    case VKI_VT_GETMODE:
10253       POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
10254       break;
10255    case VKI_VT_SETMODE:
10256       break;
10257    case VKI_VT_GETSTATE:
10258       POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
10259                       sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
10260       POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
10261                       sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
10262       break;
10263    case VKI_VT_RELDISP:
10264    case VKI_VT_ACTIVATE:
10265    case VKI_VT_WAITACTIVE:
10266    case VKI_VT_DISALLOCATE:
10267       break;
10268    case VKI_VT_RESIZE:
10269       break;
10270    case VKI_VT_RESIZEX:
10271       break;
10272    case VKI_VT_LOCKSWITCH:
10273    case VKI_VT_UNLOCKSWITCH:
10274       break;
10275 
10276    case VKI_USBDEVFS_CONTROL:
10277       if ( ARG3 ) {
10278          struct vki_usbdevfs_ctrltransfer *vkuc =
10279             (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
10280          if (vkuc->bRequestType & 0x80)
10281             POST_MEM_WRITE((Addr)vkuc->data, RES);
10282       }
10283       break;
10284    case VKI_USBDEVFS_BULK:
10285       if ( ARG3 ) {
10286          struct vki_usbdevfs_bulktransfer *vkub =
10287             (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
10288          if (vkub->ep & 0x80)
10289             POST_MEM_WRITE((Addr)vkub->data, RES);
10290       }
10291       break;
10292    case VKI_USBDEVFS_GETDRIVER:
10293       if ( ARG3 ) {
10294          struct vki_usbdevfs_getdriver *vkugd =
10295             (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
10296          POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
10297       }
10298       break;
10299    case VKI_USBDEVFS_REAPURB:
10300    case VKI_USBDEVFS_REAPURBNDELAY:
10301       if ( ARG3 ) {
10302          struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
10303          POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
10304          if (!*vkuu)
10305             break;
10306          POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
10307          if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10308             struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10309             if (vkusp->bRequestType & 0x80)
10310                POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10311             POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10312          } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10313             char *bp = (*vkuu)->buffer;
10314             int i;
10315             for(i=0; i<(*vkuu)->number_of_packets; i++) {
10316                POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10317                POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10318                if ((*vkuu)->endpoint & 0x80)
10319                   POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10320                bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10321             }
10322             POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10323          } else {
10324             if ((*vkuu)->endpoint & 0x80)
10325                POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10326             POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10327          }
10328       }
10329       break;
10330    case VKI_USBDEVFS_CONNECTINFO:
10331       POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10332       break;
10333    case VKI_USBDEVFS_IOCTL:
10334       if ( ARG3 ) {
10335          struct vki_usbdevfs_ioctl *vkui =
10336             (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
10337          UInt dir2, size2;
10338          dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
10339          size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10340          if (size2 > 0) {
10341             if (dir2 & _VKI_IOC_READ)
10342                POST_MEM_WRITE((Addr)vkui->data, size2);
10343          }
10344       }
10345       break;
10346 
10347       /* I2C (/dev/i2c-*) ioctls */
10348    case VKI_I2C_SLAVE:
10349    case VKI_I2C_SLAVE_FORCE:
10350    case VKI_I2C_TENBIT:
10351    case VKI_I2C_PEC:
10352       break;
10353    case VKI_I2C_FUNCS:
10354       POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10355       break;
10356    case VKI_I2C_RDWR:
10357       if ( ARG3 ) {
10358           struct vki_i2c_rdwr_ioctl_data *vkui =
10359              (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
10360           UInt i;
10361           for (i=0; i < vkui->nmsgs; i++) {
10362               struct vki_i2c_msg *msg = vkui->msgs + i;
10363               if (msg->flags & VKI_I2C_M_RD)
10364                   POST_MEM_WRITE((Addr)msg->buf, msg->len);
10365           }
10366       }
10367       break;
10368    case VKI_I2C_SMBUS:
10369        if ( ARG3 ) {
10370             struct vki_i2c_smbus_ioctl_data *vkis
10371                = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
10372             /* i2c_smbus_write_quick hides its value in read_write, so
10373                this variable can have a different meaning */
10374             if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10375                 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10376                 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10377                 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10378                     UInt size;
10379                     switch(vkis->size) {
10380                         case VKI_I2C_SMBUS_BYTE:
10381                         case VKI_I2C_SMBUS_BYTE_DATA:
10382                             size = 1;
10383                             break;
10384                         case VKI_I2C_SMBUS_WORD_DATA:
10385                         case VKI_I2C_SMBUS_PROC_CALL:
10386                             size = 2;
10387                             break;
10388                         case VKI_I2C_SMBUS_BLOCK_DATA:
10389                         case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10390                         case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10391                         case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10392                             size = 1 + vkis->data->block[0];
10393                             break;
10394                         default:
10395                             size = 0;
10396                     }
10397                     POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10398                 }
10399             }
10400        }
10401        break;
10402 
10403       /* Wireless extensions ioctls */
10404    case VKI_SIOCSIWCOMMIT:
10405    case VKI_SIOCSIWNWID:
10406    case VKI_SIOCSIWFREQ:
10407    case VKI_SIOCSIWMODE:
10408    case VKI_SIOCSIWSENS:
10409    case VKI_SIOCSIWRANGE:
10410    case VKI_SIOCSIWPRIV:
10411    case VKI_SIOCSIWSTATS:
10412    case VKI_SIOCSIWSPY:
10413    case VKI_SIOCSIWTHRSPY:
10414    case VKI_SIOCSIWAP:
10415    case VKI_SIOCSIWSCAN:
10416    case VKI_SIOCSIWESSID:
10417    case VKI_SIOCSIWRATE:
10418    case VKI_SIOCSIWNICKN:
10419    case VKI_SIOCSIWRTS:
10420    case VKI_SIOCSIWFRAG:
10421    case VKI_SIOCSIWTXPOW:
10422    case VKI_SIOCSIWRETRY:
10423    case VKI_SIOCSIWENCODE:
10424    case VKI_SIOCSIWPOWER:
10425    case VKI_SIOCSIWGENIE:
10426    case VKI_SIOCSIWMLME:
10427    case VKI_SIOCSIWAUTH:
10428    case VKI_SIOCSIWENCODEEXT:
10429    case VKI_SIOCSIWPMKSA:
10430       break;
10431    case VKI_SIOCGIWNAME:
10432       if (ARG3) {
10433          POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
10434                         sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
10435       }
10436       break;
10437    case VKI_SIOCGIWNWID:
10438    case VKI_SIOCGIWSENS:
10439    case VKI_SIOCGIWRATE:
10440    case VKI_SIOCGIWRTS:
10441    case VKI_SIOCGIWFRAG:
10442    case VKI_SIOCGIWTXPOW:
10443    case VKI_SIOCGIWRETRY:
10444    case VKI_SIOCGIWPOWER:
10445    case VKI_SIOCGIWAUTH:
10446       if (ARG3) {
10447          POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
10448                         sizeof(struct vki_iw_param));
10449       }
10450       break;
10451    case VKI_SIOCGIWFREQ:
10452       if (ARG3) {
10453          POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
10454                         sizeof(struct vki_iw_freq));
10455       }
10456       break;
10457    case VKI_SIOCGIWMODE:
10458       if (ARG3) {
10459          POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
10460                        sizeof(__vki_u32));
10461       }
10462       break;
10463    case VKI_SIOCGIWRANGE:
10464    case VKI_SIOCGIWPRIV:
10465    case VKI_SIOCGIWSTATS:
10466    case VKI_SIOCGIWSPY:
10467    case VKI_SIOCGIWTHRSPY:
10468    case VKI_SIOCGIWAPLIST:
10469    case VKI_SIOCGIWSCAN:
10470    case VKI_SIOCGIWESSID:
10471    case VKI_SIOCGIWNICKN:
10472    case VKI_SIOCGIWENCODE:
10473    case VKI_SIOCGIWGENIE:
10474    case VKI_SIOCGIWENCODEEXT:
10475       if (ARG3) {
10476          struct vki_iw_point* point;
10477          point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
10478          POST_MEM_WRITE((Addr)point->pointer, point->length);
10479       }
10480       break;
10481    case VKI_SIOCGIWAP:
10482       if (ARG3) {
10483          POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
10484                         sizeof(struct vki_sockaddr));
10485       }
10486       break;
10487 
10488 #  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10489       || defined(VGPV_mips32_linux_android) \
10490       || defined(VGPV_arm64_linux_android)
10491    /* ashmem */
10492    case VKI_ASHMEM_GET_SIZE:
10493    case VKI_ASHMEM_SET_SIZE:
10494    case VKI_ASHMEM_GET_PROT_MASK:
10495    case VKI_ASHMEM_SET_PROT_MASK:
10496    case VKI_ASHMEM_GET_PIN_STATUS:
10497    case VKI_ASHMEM_PURGE_ALL_CACHES:
10498    case VKI_ASHMEM_SET_NAME:
10499    case VKI_ASHMEM_PIN:
10500    case VKI_ASHMEM_UNPIN:
10501        break;
10502    case VKI_ASHMEM_GET_NAME:
10503        POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10504        break;
10505 
10506    /* binder */
10507    case VKI_BINDER_WRITE_READ:
10508        if (ARG3) {
10509            struct vki_binder_write_read* bwr
10510               = (struct vki_binder_write_read*)(Addr)ARG3;
10511            POST_FIELD_WRITE(bwr->write_consumed);
10512            POST_FIELD_WRITE(bwr->read_consumed);
10513 
10514            if (bwr->read_size)
10515                POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10516        }
10517        break;
10518 
10519    case VKI_BINDER_SET_IDLE_TIMEOUT:
10520    case VKI_BINDER_SET_MAX_THREADS:
10521    case VKI_BINDER_SET_IDLE_PRIORITY:
10522    case VKI_BINDER_SET_CONTEXT_MGR:
10523    case VKI_BINDER_THREAD_EXIT:
10524        break;
10525    case VKI_BINDER_VERSION:
10526        if (ARG3) {
10527            struct vki_binder_version* bv =
10528               (struct vki_binder_version*)(Addr)ARG3;
10529            POST_FIELD_WRITE(bv->protocol_version);
10530        }
10531        break;
10532 #  endif /* defined(VGPV_*_linux_android) */
10533 
10534    case VKI_HCIGETDEVLIST:
10535       if (ARG3) {
10536         struct vki_hci_dev_list_req* dlr =
10537            (struct vki_hci_dev_list_req*)(Addr)ARG3;
10538         POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10539                        dlr->dev_num * sizeof(struct vki_hci_dev_req));
10540       }
10541       break;
10542 
10543    case VKI_HCIINQUIRY:
10544       if (ARG3) {
10545         struct vki_hci_inquiry_req* ir =
10546            (struct vki_hci_inquiry_req*)(Addr)ARG3;
10547         POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10548                        ir->num_rsp * sizeof(struct vki_inquiry_info));
10549       }
10550       break;
10551 
10552    case VKI_DRM_IOCTL_VERSION:
10553       if (ARG3) {
10554          struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
10555          struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10556          const vki_size_t orig_name_len = info->orig->name_len;
10557          const vki_size_t orig_date_len = info->orig->date_len;
10558          const vki_size_t orig_desc_len = info->orig->desc_len;
10559          *info->orig = info->data;
10560          ARG3 = (Addr)info->orig;
10561          data = info->orig;
10562          VG_(free)(info);
10563          if (SUCCESS) {
10564             POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10565             POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10566             POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10567             POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10568             POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10569             POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10570             POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10571             POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10572             POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10573          }
10574       }
10575       break;
10576    case VKI_DRM_IOCTL_GET_UNIQUE:
10577       if (ARG3) {
10578          struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
10579 	 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10580       }
10581       break;
10582    case VKI_DRM_IOCTL_GET_MAGIC:
10583       if (ARG3) {
10584          struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
10585          POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10586       }
10587       break;
10588    case VKI_DRM_IOCTL_WAIT_VBLANK:
10589       if (ARG3) {
10590          union vki_drm_wait_vblank *data =
10591             (union vki_drm_wait_vblank *)(Addr)ARG3;
10592          POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10593       }
10594       break;
10595    case VKI_DRM_IOCTL_GEM_FLINK:
10596       if (ARG3) {
10597          struct vki_drm_gem_flink *data =
10598             (struct vki_drm_gem_flink *)(Addr)ARG3;
10599          POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10600       }
10601       break;
10602    case VKI_DRM_IOCTL_GEM_OPEN:
10603       if (ARG3) {
10604          struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
10605 	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10606 	 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10607       }
10608       break;
10609    case VKI_DRM_IOCTL_I915_GETPARAM:
10610       if (ARG3) {
10611          vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
10612 	 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10613       }
10614       break;
10615    case VKI_DRM_IOCTL_I915_GEM_BUSY:
10616       if (ARG3) {
10617          struct vki_drm_i915_gem_busy *data =
10618             (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
10619          POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10620       }
10621       break;
10622    case VKI_DRM_IOCTL_I915_GEM_CREATE:
10623       if (ARG3) {
10624          struct vki_drm_i915_gem_create *data =
10625             (struct vki_drm_i915_gem_create *)(Addr)ARG3;
10626 	 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10627       }
10628       break;
10629    case VKI_DRM_IOCTL_I915_GEM_PREAD:
10630       if (ARG3) {
10631          struct vki_drm_i915_gem_pread *data =
10632             (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
10633 	 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10634       }
10635       break;
10636    case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10637       if (ARG3) {
10638          struct vki_drm_i915_gem_mmap_gtt *data =
10639             (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
10640          POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10641       }
10642       break;
10643    case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10644       if (ARG3) {
10645          struct vki_drm_i915_gem_set_tiling *data =
10646             (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
10647          POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10648          POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10649          POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10650       }
10651       break;
10652    case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10653       if (ARG3) {
10654          struct vki_drm_i915_gem_get_tiling *data =
10655             (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
10656 	 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10657          POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10658       }
10659       break;
10660    case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10661       if (ARG3) {
10662          struct vki_drm_i915_gem_get_aperture *data =
10663             (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
10664          POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10665          POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10666       }
10667       break;
10668 
10669    /* KVM ioctls that only write the system call return value */
10670    case VKI_KVM_GET_API_VERSION:
10671    case VKI_KVM_CREATE_VM:
10672    case VKI_KVM_CHECK_EXTENSION:
10673    case VKI_KVM_GET_VCPU_MMAP_SIZE:
10674    case VKI_KVM_S390_ENABLE_SIE:
10675    case VKI_KVM_CREATE_VCPU:
10676    case VKI_KVM_SET_TSS_ADDR:
10677    case VKI_KVM_CREATE_IRQCHIP:
10678    case VKI_KVM_RUN:
10679    case VKI_KVM_S390_INITIAL_RESET:
10680    case VKI_KVM_KVMCLOCK_CTRL:
10681       break;
10682 
10683    case VKI_KVM_S390_MEM_OP: {
10684       struct vki_kvm_s390_mem_op *args =
10685          (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
10686       if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
10687          break;
10688       if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
10689          POST_MEM_WRITE((Addr)args->buf, args->size);
10690       }
10691       break;
10692 
10693 #ifdef ENABLE_XEN
10694    case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
10695        SyscallArgs harrghs;
10696        struct vki_xen_privcmd_hypercall *args =
10697           (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
10698 
10699        if (!args)
10700           break;
10701 
10702        VG_(memset)(&harrghs, 0, sizeof(harrghs));
10703        harrghs.sysno = args->op;
10704        harrghs.arg1 = args->arg[0];
10705        harrghs.arg2 = args->arg[1];
10706        harrghs.arg3 = args->arg[2];
10707        harrghs.arg4 = args->arg[3];
10708        harrghs.arg5 = args->arg[4];
10709        harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
10710 
10711        WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
10712       }
10713       break;
10714 
10715    case VKI_XEN_IOCTL_PRIVCMD_MMAP:
10716       break;
10717    case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
10718        struct vki_xen_privcmd_mmapbatch *args =
10719            (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
10720        POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
10721       }
10722       break;
10723    case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
10724        struct vki_xen_privcmd_mmapbatch_v2 *args =
10725            (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
10726        POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
10727       }
10728       break;
10729 
10730    case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
10731    case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
10732    case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
10733    case VKI_XEN_IOCTL_EVTCHN_UNBIND:
10734    case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
10735    case VKI_XEN_IOCTL_EVTCHN_RESET:
10736       /* No output */
10737       break;
10738 #endif
10739 
10740    /* Lustre */
10741    case VKI_OBD_IOC_FID2PATH: {
10742        struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
10743        POST_FIELD_WRITE(args->gf_recno);
10744        POST_FIELD_WRITE(args->gf_linkno);
10745        POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
10746        break;
10747       }
10748 
10749    case VKI_LL_IOC_PATH2FID:
10750        POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
10751       break;
10752 
10753    case VKI_LL_IOC_GETPARENT: {
10754        struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
10755        POST_FIELD_WRITE(gp->gp_fid);
10756        POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
10757        break;
10758    }
10759 
10760    /* V4L2 */
10761    case VKI_V4L2_S_FMT:
10762    case VKI_V4L2_TRY_FMT:
10763    case VKI_V4L2_REQBUFS:
10764    case VKI_V4L2_OVERLAY:
10765    case VKI_V4L2_STREAMON:
10766    case VKI_V4L2_STREAMOFF:
10767    case VKI_V4L2_S_PARM:
10768    case VKI_V4L2_S_STD:
10769    case VKI_V4L2_S_FREQUENCY:
10770    case VKI_V4L2_S_CTRL:
10771    case VKI_V4L2_S_TUNER:
10772    case VKI_V4L2_S_AUDIO:
10773    case VKI_V4L2_S_INPUT:
10774    case VKI_V4L2_S_EDID:
10775    case VKI_V4L2_S_OUTPUT:
10776    case VKI_V4L2_S_AUDOUT:
10777    case VKI_V4L2_S_MODULATOR:
10778    case VKI_V4L2_S_JPEGCOMP:
10779    case VKI_V4L2_S_CROP:
10780    case VKI_V4L2_S_PRIORITY:
10781    case VKI_V4L2_S_HW_FREQ_SEEK:
10782    case VKI_V4L2_S_DV_TIMINGS:
10783    case VKI_V4L2_SUBSCRIBE_EVENT:
10784    case VKI_V4L2_UNSUBSCRIBE_EVENT:
10785    case VKI_V4L2_PREPARE_BUF:
10786       break;
10787    case VKI_V4L2_QUERYCAP: {
10788       struct vki_v4l2_capability *data =
10789          (struct vki_v4l2_capability *)(Addr)ARG3;
10790       POST_MEM_WRITE((Addr)data, sizeof(*data));
10791       break;
10792    }
10793    case VKI_V4L2_ENUM_FMT: {
10794       struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
10795       POST_FIELD_WRITE(data->flags);
10796       POST_FIELD_WRITE(data->description);
10797       POST_FIELD_WRITE(data->pixelformat);
10798       POST_FIELD_WRITE(data->reserved);
10799       break;
10800    }
10801    case VKI_V4L2_G_FMT: {
10802       struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
10803       switch (data->type) {
10804       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10805       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10806          POST_FIELD_WRITE(data->fmt.pix);
10807          break;
10808       case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10809       case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10810          POST_FIELD_WRITE(data->fmt.vbi);
10811          break;
10812       case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10813       case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10814          POST_FIELD_WRITE(data->fmt.sliced);
10815          break;
10816       case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10817       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10818          POST_FIELD_WRITE(data->fmt.win);
10819          break;
10820       case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10821       case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10822          POST_FIELD_WRITE(data->fmt.pix_mp);
10823          break;
10824       case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10825          POST_FIELD_WRITE(data->fmt.sdr);
10826          break;
10827       }
10828       break;
10829    }
10830    case VKI_V4L2_QUERYBUF: {
10831       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10832       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10833             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10834          unsigned i;
10835 
10836          for (i = 0; i < data->length; i++) {
10837             POST_FIELD_WRITE(data->m.planes[i].bytesused);
10838             POST_FIELD_WRITE(data->m.planes[i].length);
10839             POST_FIELD_WRITE(data->m.planes[i].m);
10840             POST_FIELD_WRITE(data->m.planes[i].data_offset);
10841             POST_FIELD_WRITE(data->m.planes[i].reserved);
10842          }
10843       } else {
10844          POST_FIELD_WRITE(data->m);
10845          POST_FIELD_WRITE(data->length);
10846       }
10847       POST_FIELD_WRITE(data->bytesused);
10848       POST_FIELD_WRITE(data->flags);
10849       POST_FIELD_WRITE(data->field);
10850       POST_FIELD_WRITE(data->timestamp);
10851       POST_FIELD_WRITE(data->timecode);
10852       POST_FIELD_WRITE(data->sequence);
10853       POST_FIELD_WRITE(data->memory);
10854       POST_FIELD_WRITE(data->sequence);
10855       break;
10856    }
10857    case VKI_V4L2_G_FBUF: {
10858       struct vki_v4l2_framebuffer *data =
10859          (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10860       POST_MEM_WRITE((Addr)data, sizeof(*data));
10861       break;
10862    }
10863    case VKI_V4L2_S_FBUF: {
10864       struct vki_v4l2_framebuffer *data =
10865          (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10866       POST_FIELD_WRITE(data->capability);
10867       POST_FIELD_WRITE(data->flags);
10868       POST_FIELD_WRITE(data->fmt);
10869       break;
10870    }
10871    case VKI_V4L2_QBUF: {
10872       struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10873 
10874       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10875             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10876          unsigned i;
10877 
10878          for (i = 0; i < data->length; i++) {
10879             POST_FIELD_WRITE(data->m.planes[i].length);
10880             if (data->memory == VKI_V4L2_MEMORY_MMAP)
10881                POST_FIELD_WRITE(data->m.planes[i].m);
10882          }
10883       } else {
10884          if (data->memory == VKI_V4L2_MEMORY_MMAP)
10885             POST_FIELD_WRITE(data->m);
10886          POST_FIELD_WRITE(data->length);
10887       }
10888       break;
10889    }
10890    case VKI_V4L2_EXPBUF: {
10891       struct vki_v4l2_exportbuffer *data =
10892          (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
10893       POST_FIELD_WRITE(data->fd);
10894       break;
10895    }
10896    case VKI_V4L2_DQBUF: {
10897       struct vki_v4l2_buffer *data =
10898          (struct vki_v4l2_buffer *)(Addr)ARG3;
10899       POST_FIELD_WRITE(data->index);
10900       POST_FIELD_WRITE(data->bytesused);
10901       POST_FIELD_WRITE(data->field);
10902       if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10903             data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10904          unsigned i;
10905 
10906          for (i = 0; i < data->length; i++) {
10907             POST_FIELD_WRITE(data->m.planes[i].bytesused);
10908             POST_FIELD_WRITE(data->m.planes[i].data_offset);
10909             POST_FIELD_WRITE(data->m.planes[i].length);
10910             POST_FIELD_WRITE(data->m.planes[i].m);
10911          }
10912       } else {
10913          POST_FIELD_WRITE(data->m);
10914          POST_FIELD_WRITE(data->length);
10915          POST_FIELD_WRITE(data->bytesused);
10916          POST_FIELD_WRITE(data->field);
10917       }
10918       POST_FIELD_WRITE(data->timestamp);
10919       POST_FIELD_WRITE(data->timecode);
10920       POST_FIELD_WRITE(data->sequence);
10921       break;
10922    }
10923    case VKI_V4L2_G_PARM: {
10924       struct vki_v4l2_streamparm *data =
10925          (struct vki_v4l2_streamparm *)(Addr)ARG3;
10926       int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
10927          data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
10928          data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
10929          data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
10930 
10931       if (is_output)
10932         POST_MEM_WRITE((Addr)&data->parm.output,
10933             sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
10934       else
10935         POST_MEM_WRITE((Addr)&data->parm.capture,
10936             sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
10937       break;
10938    }
10939    case VKI_V4L2_G_STD: {
10940       vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
10941       POST_MEM_WRITE((Addr)data, sizeof(*data));
10942       break;
10943    }
10944    case VKI_V4L2_ENUMSTD: {
10945       struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
10946       POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
10947       break;
10948    }
10949    case VKI_V4L2_ENUMINPUT: {
10950       struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
10951       POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10952       break;
10953    }
10954    case VKI_V4L2_G_CTRL: {
10955       struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
10956       POST_FIELD_WRITE(data->value);
10957       break;
10958    }
10959    case VKI_V4L2_G_TUNER: {
10960       struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
10961       POST_MEM_WRITE((Addr)data->name,
10962             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10963       break;
10964    }
10965    case VKI_V4L2_G_AUDIO: {
10966       struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
10967       POST_MEM_WRITE((Addr)data,
10968             sizeof(*data) - sizeof(data->reserved));
10969       break;
10970    }
10971    case VKI_V4L2_QUERYCTRL: {
10972       struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
10973       POST_MEM_WRITE((Addr)&data->type,
10974             sizeof(*data) - sizeof(data->id));
10975       break;
10976    }
10977    case VKI_V4L2_QUERYMENU: {
10978       struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
10979       POST_MEM_WRITE((Addr)data->name,
10980             sizeof(*data) - sizeof(data->id) - sizeof(data->index));
10981       break;
10982    }
10983    case VKI_V4L2_G_INPUT: {
10984       int *data = (int *)(Addr)ARG3;
10985       POST_MEM_WRITE((Addr)data, sizeof(*data));
10986       break;
10987    }
10988    case VKI_V4L2_G_EDID: {
10989       struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
10990       if (data->blocks && data->edid)
10991          POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
10992       break;
10993    }
10994    case VKI_V4L2_G_OUTPUT: {
10995       int *data = (int *)(Addr)ARG3;
10996       POST_MEM_WRITE((Addr)data, sizeof(*data));
10997       break;
10998    }
10999    case VKI_V4L2_ENUMOUTPUT: {
11000       struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11001       POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11002       break;
11003    }
11004    case VKI_V4L2_G_AUDOUT: {
11005       struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11006       POST_MEM_WRITE((Addr)data,
11007             sizeof(*data) - sizeof(data->reserved));
11008       break;
11009    }
11010    case VKI_V4L2_G_MODULATOR: {
11011       struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11012       POST_MEM_WRITE((Addr)data->name,
11013             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11014       break;
11015    }
11016    case VKI_V4L2_G_FREQUENCY: {
11017       struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11018       POST_FIELD_WRITE(data->type);
11019       POST_FIELD_WRITE(data->frequency);
11020       break;
11021    }
11022    case VKI_V4L2_CROPCAP: {
11023       struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11024       POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11025       break;
11026    }
11027    case VKI_V4L2_G_CROP: {
11028       struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11029       POST_FIELD_WRITE(data->c);
11030       break;
11031    }
11032    case VKI_V4L2_G_JPEGCOMP: {
11033       struct vki_v4l2_jpegcompression *data =
11034          (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11035       POST_MEM_WRITE((Addr)data, sizeof(*data));
11036       break;
11037    }
11038    case VKI_V4L2_QUERYSTD: {
11039       vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11040       POST_MEM_WRITE((Addr)data, sizeof(*data));
11041       break;
11042    }
11043    case VKI_V4L2_ENUMAUDIO: {
11044       struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11045       POST_MEM_WRITE((Addr)data->name,
11046             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11047       break;
11048    }
11049    case VKI_V4L2_ENUMAUDOUT: {
11050       struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11051       POST_MEM_WRITE((Addr)data->name,
11052             sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11053       break;
11054    }
11055    case VKI_V4L2_G_PRIORITY: {
11056       __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11057       POST_MEM_WRITE((Addr)data, sizeof(*data));
11058       break;
11059    }
11060    case VKI_V4L2_G_SLICED_VBI_CAP: {
11061       struct vki_v4l2_sliced_vbi_cap *data =
11062          (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11063       POST_MEM_WRITE((Addr)data,
11064             sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11065       break;
11066    }
11067    case VKI_V4L2_G_EXT_CTRLS: {
11068       struct vki_v4l2_ext_controls *data =
11069          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11070       if (data->count) {
11071          unsigned i;
11072 
11073          for (i = 0; i < data->count; i++) {
11074             if (data->controls[i].size)
11075                POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11076             else
11077                POST_FIELD_WRITE(data->controls[i].value64);
11078          }
11079       }
11080       POST_FIELD_WRITE(data->error_idx);
11081       break;
11082    }
11083    case VKI_V4L2_S_EXT_CTRLS: {
11084       struct vki_v4l2_ext_controls *data =
11085          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11086       POST_FIELD_WRITE(data->error_idx);
11087       break;
11088    }
11089    case VKI_V4L2_TRY_EXT_CTRLS: {
11090       struct vki_v4l2_ext_controls *data =
11091          (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11092       POST_FIELD_WRITE(data->error_idx);
11093       break;
11094    }
11095    case VKI_V4L2_ENUM_FRAMESIZES: {
11096       struct vki_v4l2_frmsizeenum *data =
11097          (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11098       POST_FIELD_WRITE(data->type);
11099       POST_FIELD_WRITE(data->stepwise);
11100       break;
11101    }
11102    case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11103       struct vki_v4l2_frmivalenum *data =
11104          (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11105       POST_FIELD_WRITE(data->type);
11106       POST_FIELD_WRITE(data->stepwise);
11107       break;
11108    }
11109    case VKI_V4L2_G_ENC_INDEX: {
11110       struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11111       POST_MEM_WRITE((Addr)data, sizeof(*data));
11112       break;
11113    }
11114    case VKI_V4L2_ENCODER_CMD: {
11115       struct vki_v4l2_encoder_cmd *data =
11116          (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11117       POST_FIELD_WRITE(data->flags);
11118       break;
11119    }
11120    case VKI_V4L2_TRY_ENCODER_CMD: {
11121       struct vki_v4l2_encoder_cmd *data =
11122          (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11123       POST_FIELD_WRITE(data->flags);
11124       break;
11125    }
11126    case VKI_V4L2_DBG_S_REGISTER: {
11127       struct vki_v4l2_dbg_register *data =
11128          (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11129       POST_FIELD_WRITE(data->size);
11130       break;
11131    }
11132    case VKI_V4L2_DBG_G_REGISTER: {
11133       struct vki_v4l2_dbg_register *data =
11134          (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11135       POST_FIELD_WRITE(data->val);
11136       POST_FIELD_WRITE(data->size);
11137       break;
11138    }
11139    case VKI_V4L2_G_DV_TIMINGS: {
11140       struct vki_v4l2_dv_timings *data =
11141          (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11142       POST_MEM_WRITE((Addr)data, sizeof(*data));
11143       break;
11144    }
11145    case VKI_V4L2_DQEVENT: {
11146       struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
11147       POST_MEM_WRITE((Addr)data, sizeof(*data));
11148       break;
11149    }
11150    case VKI_V4L2_CREATE_BUFS: {
11151       struct vki_v4l2_create_buffers *data =
11152          (struct vki_v4l2_create_buffers *)(Addr)ARG3;
11153       POST_FIELD_WRITE(data->index);
11154       break;
11155    }
11156    case VKI_V4L2_G_SELECTION: {
11157       struct vki_v4l2_selection *data =
11158          (struct vki_v4l2_selection *)(Addr)ARG3;
11159       POST_FIELD_WRITE(data->r);
11160       break;
11161    }
11162    case VKI_V4L2_S_SELECTION: {
11163       struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
11164       POST_FIELD_WRITE(data->r);
11165       break;
11166    }
11167    case VKI_V4L2_DECODER_CMD: {
11168       struct vki_v4l2_decoder_cmd *data =
11169          (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11170       POST_FIELD_WRITE(data->flags);
11171       break;
11172    }
11173    case VKI_V4L2_TRY_DECODER_CMD: {
11174       struct vki_v4l2_decoder_cmd *data =
11175          (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11176       POST_FIELD_WRITE(data->flags);
11177       break;
11178    }
11179    case VKI_V4L2_ENUM_DV_TIMINGS: {
11180       struct vki_v4l2_enum_dv_timings *data =
11181          (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
11182       POST_FIELD_WRITE(data->timings);
11183       break;
11184    }
11185    case VKI_V4L2_QUERY_DV_TIMINGS: {
11186       struct vki_v4l2_dv_timings *data =
11187          (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11188       POST_MEM_WRITE((Addr)data, sizeof(*data));
11189       break;
11190    }
11191    case VKI_V4L2_DV_TIMINGS_CAP: {
11192       struct vki_v4l2_dv_timings_cap *data =
11193          (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
11194       POST_MEM_WRITE((Addr)data, sizeof(*data));
11195       break;
11196    }
11197    case VKI_V4L2_ENUM_FREQ_BANDS: {
11198       struct vki_v4l2_frequency_band *data =
11199          (struct vki_v4l2_frequency_band *)(Addr)ARG3;
11200       POST_FIELD_WRITE(data->capability);
11201       POST_FIELD_WRITE(data->rangelow);
11202       POST_FIELD_WRITE(data->rangehigh);
11203       POST_FIELD_WRITE(data->modulation);
11204       break;
11205    }
11206    case VKI_V4L2_DBG_G_CHIP_INFO: {
11207       struct vki_v4l2_dbg_chip_info *data =
11208          (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
11209       POST_FIELD_WRITE(data->name);
11210       POST_FIELD_WRITE(data->flags);
11211       break;
11212    }
11213    case VKI_V4L2_QUERY_EXT_CTRL: {
11214       struct vki_v4l2_query_ext_ctrl *data =
11215          (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
11216       POST_MEM_WRITE((Addr)&data->type,
11217             sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
11218       break;
11219    }
11220 
11221    case VKI_V4L2_SUBDEV_S_FMT:
11222    case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
11223    case VKI_V4L2_SUBDEV_S_CROP:
11224    case VKI_V4L2_SUBDEV_S_SELECTION:
11225       break;
11226 
11227    case VKI_V4L2_SUBDEV_G_FMT: {
11228       struct vki_v4l2_subdev_format *data =
11229          (struct vki_v4l2_subdev_format *)(Addr)ARG3;
11230       POST_FIELD_WRITE(data->format);
11231       break;
11232    }
11233    case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
11234       struct vki_v4l2_subdev_frame_interval *data =
11235          (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
11236       POST_FIELD_WRITE(data->interval);
11237       break;
11238    }
11239    case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
11240       struct vki_v4l2_subdev_mbus_code_enum *data =
11241          (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
11242       POST_FIELD_WRITE(data->code);
11243       break;
11244    }
11245    case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
11246       struct vki_v4l2_subdev_frame_size_enum *data =
11247          (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
11248       POST_FIELD_WRITE(data->min_width);
11249       POST_FIELD_WRITE(data->min_height);
11250       POST_FIELD_WRITE(data->max_width);
11251       POST_FIELD_WRITE(data->max_height);
11252       break;
11253    }
11254    case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
11255       struct vki_v4l2_subdev_frame_interval_enum *data =
11256          (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
11257       POST_FIELD_WRITE(data->interval);
11258       break;
11259    }
11260    case VKI_V4L2_SUBDEV_G_CROP: {
11261       struct vki_v4l2_subdev_crop *data =
11262          (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
11263       POST_FIELD_WRITE(data->rect);
11264       break;
11265    }
11266    case VKI_V4L2_SUBDEV_G_SELECTION: {
11267       struct vki_v4l2_subdev_selection *data =
11268          (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
11269       POST_FIELD_WRITE(data->r);
11270       break;
11271    }
11272    case VKI_MEDIA_IOC_DEVICE_INFO: {
11273       struct vki_media_device_info *data =
11274          (struct vki_media_device_info *)(Addr)ARG3;
11275       POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
11276       break;
11277    }
11278    case VKI_MEDIA_IOC_ENUM_ENTITIES: {
11279       struct vki_media_entity_desc *data =
11280          (struct vki_media_entity_desc *)(Addr)ARG3;
11281       POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
11282       break;
11283    }
11284    case VKI_MEDIA_IOC_ENUM_LINKS:
11285       /*
11286        * This ioctl does write to the provided pointers, but it's not
11287        * possible to deduce the size of the array those pointers point to.
11288        */
11289       break;
11290    case VKI_MEDIA_IOC_SETUP_LINK:
11291       break;
11292 
11293    /* Serial */
11294    case VKI_TIOCGSERIAL: {
11295       struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
11296       POST_MEM_WRITE((Addr)data, sizeof(*data));
11297       break;
11298    }
11299    case VKI_TIOCSSERIAL:
11300       break;
11301 
11302    case VKI_PERF_EVENT_IOC_ENABLE:
11303    case VKI_PERF_EVENT_IOC_DISABLE:
11304    case VKI_PERF_EVENT_IOC_REFRESH:
11305    case VKI_PERF_EVENT_IOC_RESET:
11306    case VKI_PERF_EVENT_IOC_PERIOD:
11307    case VKI_PERF_EVENT_IOC_SET_OUTPUT:
11308    case VKI_PERF_EVENT_IOC_SET_FILTER:
11309    case VKI_PERF_EVENT_IOC_SET_BPF:
11310       break;
11311 
11312    case VKI_PERF_EVENT_IOC_ID:
11313       POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
11314       break;
11315 
11316    default:
11317       /* EVIOC* are variable length and return size written on success */
11318       switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
11319       case VKI_EVIOCGNAME(0):
11320       case VKI_EVIOCGPHYS(0):
11321       case VKI_EVIOCGUNIQ(0):
11322       case VKI_EVIOCGKEY(0):
11323       case VKI_EVIOCGLED(0):
11324       case VKI_EVIOCGSND(0):
11325       case VKI_EVIOCGSW(0):
11326       case VKI_EVIOCGBIT(VKI_EV_SYN,0):
11327       case VKI_EVIOCGBIT(VKI_EV_KEY,0):
11328       case VKI_EVIOCGBIT(VKI_EV_REL,0):
11329       case VKI_EVIOCGBIT(VKI_EV_ABS,0):
11330       case VKI_EVIOCGBIT(VKI_EV_MSC,0):
11331       case VKI_EVIOCGBIT(VKI_EV_SW,0):
11332       case VKI_EVIOCGBIT(VKI_EV_LED,0):
11333       case VKI_EVIOCGBIT(VKI_EV_SND,0):
11334       case VKI_EVIOCGBIT(VKI_EV_REP,0):
11335       case VKI_EVIOCGBIT(VKI_EV_FF,0):
11336       case VKI_EVIOCGBIT(VKI_EV_PWR,0):
11337       case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
11338          if (RES > 0)
11339             POST_MEM_WRITE(ARG3, RES);
11340          break;
11341       default:
11342          ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
11343          break;
11344       }
11345       break;
11346    }
11347 
11348   post_sys_ioctl__out:
11349    {} /* keep C compilers happy */
11350 }
11351 
11352 /* ---------------------------------------------------------------------
11353    socketcall wrapper helpers
11354    ------------------------------------------------------------------ */
11355 
11356 void
ML_(linux_PRE_sys_getsockopt)11357 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
11358                                 UWord arg0, UWord arg1, UWord arg2,
11359                                 UWord arg3, UWord arg4 )
11360 {
11361    /* int getsockopt(int s, int level, int optname,
11362                      void *optval, socklen_t *optlen); */
11363    Addr optval_p = arg3;
11364    Addr optlen_p = arg4;
11365    /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11366    if (optval_p != (Addr)NULL) {
11367       ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11368                                    "socketcall.getsockopt(optval)",
11369                                    "socketcall.getsockopt(optlen)" );
11370       if (arg1 == VKI_SOL_SCTP &&
11371           (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11372            arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11373       {
11374          struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11375          int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11376          PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11377                         (Addr)ga->addrs, address_bytes );
11378       }
11379    }
11380 }
11381 
11382 void
ML_(linux_POST_sys_getsockopt)11383 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11384                                  SysRes res,
11385                                  UWord arg0, UWord arg1, UWord arg2,
11386                                  UWord arg3, UWord arg4 )
11387 {
11388    Addr optval_p = arg3;
11389    Addr optlen_p = arg4;
11390    vg_assert(!sr_isError(res)); /* guaranteed by caller */
11391    if (optval_p != (Addr)NULL) {
11392       ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11393                                     "socketcall.getsockopt(optlen_out)" );
11394       if (arg1 == VKI_SOL_SCTP &&
11395           (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11396            arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11397       {
11398          struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11399          struct vki_sockaddr *a = ga->addrs;
11400          int i;
11401          for (i = 0; i < ga->addr_num; i++) {
11402             int sl = 0;
11403             if (a->sa_family == VKI_AF_INET)
11404                sl = sizeof(struct vki_sockaddr_in);
11405             else if (a->sa_family == VKI_AF_INET6)
11406                sl = sizeof(struct vki_sockaddr_in6);
11407             else {
11408                VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11409                                         "address type %d\n", a->sa_family);
11410             }
11411             a = (struct vki_sockaddr*)((char*)a + sl);
11412          }
11413          POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11414       }
11415    }
11416 }
11417 
11418 void
ML_(linux_PRE_sys_setsockopt)11419 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11420                                 UWord arg0, UWord arg1, UWord arg2,
11421                                 UWord arg3, UWord arg4 )
11422 {
11423    /* int setsockopt(int s, int level, int optname,
11424                      const void *optval, socklen_t optlen); */
11425    Addr optval_p = arg3;
11426    if (optval_p != (Addr)NULL) {
11427       /*
11428        * OK, let's handle at least some setsockopt levels and options
11429        * ourselves, so we don't get false claims of references to
11430        * uninitialized memory (such as padding in structures) and *do*
11431        * check what pointers in the argument point to.
11432        */
11433       if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11434       {
11435          struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11436 
11437          /*
11438           * struct sock_fprog has a 16-bit count of instructions,
11439           * followed by a pointer to an array of those instructions.
11440           * There's padding between those two elements.
11441           *
11442           * So that we don't bogusly complain about the padding bytes,
11443           * we just report that we read len and and filter.
11444           *
11445           * We then make sure that what filter points to is valid.
11446           */
11447          PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11448                        (Addr)&fp->len, sizeof(fp->len) );
11449          PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11450                        (Addr)&fp->filter, sizeof(fp->filter) );
11451 
11452          /* len * sizeof (*filter) */
11453          if (fp->filter != NULL)
11454          {
11455             PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11456                           (Addr)(fp->filter),
11457                           fp->len * sizeof(*fp->filter) );
11458          }
11459       }
11460       else
11461       {
11462          PRE_MEM_READ( "socketcall.setsockopt(optval)",
11463                        arg3, /* optval */
11464                        arg4  /* optlen */ );
11465       }
11466    }
11467 }
11468 
11469 void
ML_(linux_PRE_sys_recvmmsg)11470 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11471                               UWord arg1, UWord arg2, UWord arg3,
11472                               UWord arg4, UWord arg5 )
11473 {
11474    struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11475    HChar name[40];     // large enough
11476    UInt i;
11477    for (i = 0; i < arg3; i++) {
11478       VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11479       ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11480       VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11481       PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11482    }
11483    if (arg5)
11484       PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11485 }
11486 
11487 void
ML_(linux_POST_sys_recvmmsg)11488 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11489                               UWord arg1, UWord arg2, UWord arg3,
11490                               UWord arg4, UWord arg5 )
11491 {
11492    if (res > 0) {
11493       struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11494       HChar name[32];    // large enough
11495       UInt i;
11496       for (i = 0; i < res; i++) {
11497          VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11498          ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11499          POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11500       }
11501    }
11502 }
11503 
11504 void
ML_(linux_PRE_sys_sendmmsg)11505 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11506                               UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11507 {
11508    struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11509    HChar name[40];     // large enough
11510    UInt i;
11511    for (i = 0; i < arg3; i++) {
11512       VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11513       ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11514       VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11515       PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11516    }
11517 }
11518 
11519 void
ML_(linux_POST_sys_sendmmsg)11520 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11521                               UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11522 {
11523    if (res > 0) {
11524       struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11525       UInt i;
11526       for (i = 0; i < res; i++) {
11527          POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11528       }
11529    }
11530 }
11531 
11532 /* ---------------------------------------------------------------------
11533    ptrace wrapper helpers
11534    ------------------------------------------------------------------ */
11535 
11536 void
ML_(linux_POST_traceme)11537 ML_(linux_POST_traceme) ( ThreadId tid )
11538 {
11539   ThreadState *tst = VG_(get_ThreadState)(tid);
11540   tst->ptrace = VKI_PT_PTRACED;
11541 }
11542 
11543 void
ML_(linux_PRE_getregset)11544 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11545 {
11546    struct vki_iovec *iov = (struct vki_iovec *) arg4;
11547 
11548    PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11549    PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11550    if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11551       PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11552                     (Addr) iov->iov_base, iov->iov_len);
11553    }
11554 }
11555 
11556 void
ML_(linux_PRE_setregset)11557 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11558 {
11559    struct vki_iovec *iov = (struct vki_iovec *) arg4;
11560 
11561    PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11562    PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11563    if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11564       PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11565                    (Addr) iov->iov_base, iov->iov_len);
11566    }
11567 }
11568 
11569 void
ML_(linux_POST_getregset)11570 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11571 {
11572    struct vki_iovec *iov = (struct vki_iovec *) arg4;
11573 
11574    /* XXX: The actual amount of data written by the kernel might be
11575       less than iov_len, depending on the regset (arg3). */
11576    POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11577 }
11578 
PRE(sys_kcmp)11579 PRE(sys_kcmp)
11580 {
11581    PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
11582          SARG1, SARG2, SARG3, ARG4, ARG5);
11583    switch (ARG3) {
11584       case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11585       case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11586          /* Most of the comparison types don't look at |idx1| or
11587             |idx2|. */
11588          PRE_REG_READ3(long, "kcmp",
11589                        vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11590          break;
11591       case VKI_KCMP_FILE:
11592       default:
11593          PRE_REG_READ5(long, "kcmp",
11594                        vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11595                        unsigned long, idx1, unsigned long, idx2);
11596          break;
11597    }
11598 }
11599 
11600 /* ---------------------------------------------------------------------
11601    bpf wrappers
11602    ------------------------------------------------------------------ */
11603 
bpf_map_get_sizes(Int fd,UInt * key_size,UInt * value_size)11604 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
11605 {
11606    HChar path[32], buf[1024];   /* large enough */
11607    SysRes sres;
11608    HChar *comp;
11609    Int proc_fd;
11610 
11611    *key_size = 0;
11612    *value_size = 0;
11613 
11614    VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
11615    sres = VG_(open)(path, VKI_O_RDONLY, 0);
11616    if (sr_isError(sres))
11617       return False;
11618    proc_fd = sr_Res(sres);
11619 
11620    if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
11621       return False;
11622    VG_(close)(proc_fd);
11623 
11624    comp = VG_(strstr)(buf, "key_size:");
11625    if (comp)
11626       *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
11627 
11628    comp = VG_(strstr)(buf, "value_size:");
11629    if (comp)
11630       *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
11631 
11632    return (*key_size && *value_size);
11633 }
11634 
11635 /*
11636  * From a file descriptor for an eBPF object, try to determine the size of the
11637  * struct that will be written, i.e. determine if object is a map or a program.
11638  * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
11639  * search for strings "prog_type" or "map_type".
11640  */
bpf_obj_get_info_size(Int fd)11641 static UInt bpf_obj_get_info_size(Int fd)
11642 {
11643    HChar path[32], buf[1024];   /* large enough */
11644    SysRes sres;
11645    Int proc_fd;
11646 
11647    VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
11648    sres = VG_(open)(path, VKI_O_RDONLY, 0);
11649    if (sr_isError(sres))
11650       return 0;
11651    proc_fd = sr_Res(sres);
11652 
11653    if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
11654       return 0;
11655    VG_(close)(proc_fd);
11656 
11657    if (VG_(strstr)(buf, "prog_type:"))
11658       return sizeof(struct vki_bpf_prog_info);
11659 
11660    if (VG_(strstr)(buf, "map_type:"))
11661       return sizeof(struct vki_bpf_map_info);
11662 
11663    return 0;
11664 }
11665 
PRE(sys_bpf)11666 PRE(sys_bpf)
11667 {
11668    union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
11669    UInt res, key_size, value_size;
11670 
11671    PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
11672          ARG1, ARG2, ARG3);
11673    PRE_REG_READ3(long, "bpf",
11674                  int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
11675    switch (ARG1) {
11676       case VKI_BPF_PROG_GET_NEXT_ID:
11677       case VKI_BPF_MAP_GET_NEXT_ID:
11678          PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
11679          break;
11680       case VKI_BPF_PROG_GET_FD_BY_ID:
11681          PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
11682          break;
11683       case VKI_BPF_MAP_GET_FD_BY_ID:
11684          PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
11685          break;
11686       case VKI_BPF_BTF_GET_FD_BY_ID:
11687          PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
11688          break;
11689       case VKI_BPF_MAP_CREATE:
11690          PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
11691          if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
11692             PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
11693          PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
11694          PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
11695          PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
11696          PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
11697          PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
11698          pre_asciiz_str(tid, (unsigned long int)attr->map_name,
11699                         VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
11700          switch (attr->map_type) {
11701             case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
11702             case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
11703                PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
11704                if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
11705                   SET_STATUS_Failure(VKI_EBADF);
11706                break;
11707             case VKI_BPF_MAP_TYPE_ARRAY:
11708                if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
11709                   PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
11710                   PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
11711                   if (attr->btf_key_type_id && attr->btf_value_type_id) {
11712                      PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
11713                      if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
11714                         SET_STATUS_Failure(VKI_EBADF);
11715                         break;
11716                      }
11717                   }
11718                }
11719                break;
11720             case VKI_BPF_MAP_TYPE_UNSPEC:
11721             case VKI_BPF_MAP_TYPE_HASH:
11722             case VKI_BPF_MAP_TYPE_PROG_ARRAY:
11723             case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
11724             case VKI_BPF_MAP_TYPE_PERCPU_HASH:
11725             case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
11726             case VKI_BPF_MAP_TYPE_STACK_TRACE:
11727             case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
11728             case VKI_BPF_MAP_TYPE_LRU_HASH:
11729             case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
11730             case VKI_BPF_MAP_TYPE_LPM_TRIE:
11731             case VKI_BPF_MAP_TYPE_DEVMAP:
11732             case VKI_BPF_MAP_TYPE_SOCKMAP:
11733             case VKI_BPF_MAP_TYPE_CPUMAP:
11734             case VKI_BPF_MAP_TYPE_XSKMAP:
11735             case VKI_BPF_MAP_TYPE_SOCKHASH:
11736             default:
11737                break;
11738          }
11739          break;
11740       case VKI_BPF_MAP_LOOKUP_ELEM:
11741          /* Perform a lookup on an eBPF map. Read key, write value. */
11742          PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11743          PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
11744          PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11745          if (ML_(safe_to_deref)(attr, ARG3)) {
11746             if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11747                SET_STATUS_Failure(VKI_EBADF);
11748                break;
11749             }
11750             /* Get size of key and value for this map. */
11751             if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11752                PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11753                PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
11754             }
11755          }
11756          break;
11757       case VKI_BPF_MAP_UPDATE_ELEM:
11758          /* Add or update a map element in kernel. Read key, read value. */
11759          PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11760          PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
11761          PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11762          PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
11763          if (ML_(safe_to_deref)(attr, ARG3)) {
11764             if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11765                SET_STATUS_Failure(VKI_EBADF);
11766                break;
11767             }
11768             /* Get size of key and value for this map. */
11769             if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11770                PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11771                PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
11772             }
11773          }
11774          break;
11775       case VKI_BPF_MAP_DELETE_ELEM:
11776          /* Delete a map element in kernel. Read key from user space. */
11777          PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11778          PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11779          if (ML_(safe_to_deref)(attr, ARG3)) {
11780             if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11781                SET_STATUS_Failure(VKI_EBADF);
11782                break;
11783             }
11784             /* Get size of key for this map. */
11785             if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
11786                PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11787          }
11788          break;
11789       case VKI_BPF_MAP_GET_NEXT_KEY:
11790          /* From a key, get next key for the map. Read key, write next key. */
11791          PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11792          PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
11793          PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11794          PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
11795          if (ML_(safe_to_deref)(attr, ARG3)) {
11796             if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11797                SET_STATUS_Failure(VKI_EBADF);
11798                break;
11799             }
11800             /* Get size of key for this map. */
11801             if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11802                PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11803                PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
11804             }
11805          }
11806          break;
11807       case VKI_BPF_PROG_LOAD:
11808          /* Load a program into the kernel from an array of instructions. */
11809          PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
11810          PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
11811          PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
11812          PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
11813          PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
11814          PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
11815          PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
11816          PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
11817          PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
11818          pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
11819          if (ML_(safe_to_deref)(attr, ARG3)) {
11820             if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
11821                PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
11822             /* Read instructions, license, program name. */
11823             PRE_MEM_READ("bpf(attr->insns)", attr->insns,
11824                          attr->insn_cnt * sizeof(struct vki_bpf_insn));
11825             /* License is limited to 128 characters in kernel/bpf/syscall.c. */
11826             pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
11827             /* Possibly write up to log_len into user space log buffer. */
11828             if (attr->log_level || attr->log_size || attr->log_buf)
11829                PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
11830          }
11831          break;
11832       case VKI_BPF_OBJ_PIN:
11833          /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
11834          /* fall through */
11835       case VKI_BPF_OBJ_GET:
11836          /* Get pinned eBPF program or map. Read path name. */
11837          PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
11838          PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
11839          PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
11840          if (ML_(safe_to_deref)(attr, ARG3)) {
11841             if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
11842                SET_STATUS_Failure(VKI_EBADF);
11843                break;
11844             }
11845             pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
11846          }
11847          break;
11848       case VKI_BPF_PROG_ATTACH:
11849       case VKI_BPF_PROG_DETACH:
11850          /* Detach eBPF program from kernel attach point. */
11851          PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
11852          PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
11853          if (ML_(safe_to_deref)(attr, ARG3)) {
11854             if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
11855                SET_STATUS_Failure(VKI_EBADF);
11856             if (ARG1 == VKI_BPF_PROG_ATTACH ||
11857                 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
11858                  attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
11859                  attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
11860                PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
11861                if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
11862                   SET_STATUS_Failure(VKI_EBADF);
11863             }
11864          }
11865          break;
11866       case VKI_BPF_PROG_TEST_RUN:
11867          /* Test prog. Read data_in, write up to data_size_out to data_out. */
11868          PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
11869          PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
11870          PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
11871          PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
11872          PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
11873          PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
11874          PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
11875          PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
11876          if (ML_(safe_to_deref)(attr, ARG3)) {
11877             if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
11878                SET_STATUS_Failure(VKI_EBADF);
11879                break;
11880             }
11881             PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
11882             /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
11883             PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
11884          }
11885          break;
11886       case VKI_BPF_OBJ_GET_INFO_BY_FD:
11887          /* Get info for eBPF map or program. Write info. */
11888          PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
11889          PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
11890          PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
11891          if (ML_(safe_to_deref)(attr, ARG3)) {
11892             if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
11893                SET_STATUS_Failure(VKI_EBADF);
11894                break;
11895             }
11896             /* Get size of struct to write: is object a program or a map? */
11897             res = bpf_obj_get_info_size(attr->info.bpf_fd);
11898             if (res)
11899                PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
11900                              VG_MIN(attr->info.info_len, res));
11901             else
11902                PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
11903                              VG_MIN(attr->info.info_len,
11904                                     VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
11905                                                   sizeof(struct vki_bpf_map_info)),
11906                                            sizeof(struct vki_bpf_btf_info))));
11907          }
11908          break;
11909       case VKI_BPF_PROG_QUERY:
11910          /*
11911           * Query list of eBPF program attached to cgroup.
11912           * Write array of ids (up to attr->query.prog_cnt u32-long ids).
11913           */
11914          PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
11915          PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
11916          PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
11917          PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
11918          PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
11919          if (ML_(safe_to_deref)(attr, ARG3)) {
11920             if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
11921                SET_STATUS_Failure(VKI_EBADF);
11922                break;
11923             }
11924             if (attr->query.prog_cnt > 0) {
11925                PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
11926                if (attr->query.prog_ids) {
11927                   PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
11928                                 attr->query.prog_cnt * sizeof(__vki_u32));
11929                }
11930             }
11931          }
11932          break;
11933       case VKI_BPF_RAW_TRACEPOINT_OPEN:
11934          /* Open raw tracepoint. Read tracepoint name. */
11935          PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
11936          PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
11937          if (ML_(safe_to_deref)(attr, ARG3)) {
11938             if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
11939                                  "bpf", tid, False)) {
11940                SET_STATUS_Failure(VKI_EBADF);
11941                break;
11942             }
11943             /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
11944             pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
11945                            "bpf(attr->raw_tracepoint.name)");
11946          }
11947          break;
11948       case VKI_BPF_BTF_LOAD:
11949          /* Load BTF information about a program into the kernel. */
11950          PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
11951          PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
11952          PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
11953          PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
11954          PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
11955          if (ML_(safe_to_deref)(attr, ARG3)) {
11956             /* Read BTF data. */
11957             PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
11958             /* Possibly write up to btf_log_len into user space log buffer. */
11959             if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
11960                PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
11961                              attr->btf_log_buf, attr->btf_log_size);
11962          }
11963       case VKI_BPF_TASK_FD_QUERY:
11964          /* Get info about the task. Write collected info. */
11965          PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
11966          PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
11967          PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
11968          PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
11969          PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
11970          PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
11971          PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
11972          PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
11973          PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
11974          if (ML_(safe_to_deref)(attr, ARG3)) {
11975             if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
11976                SET_STATUS_Failure(VKI_EBADF);
11977                break;
11978             }
11979             if (attr->task_fd_query.buf_len > 0) {
11980                 /* Write task or perf event name. */
11981                 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
11982                               attr->task_fd_query.buf,
11983                               attr->task_fd_query.buf_len);
11984             }
11985          }
11986          break;
11987       default:
11988          VG_(message)(Vg_DebugMsg,
11989                       "FATAL: unhandled eBPF command %lu\n", ARG1);
11990          VG_(core_panic)("... bye!\n");
11991          break;
11992    }
11993 }
11994 
POST(sys_bpf)11995 POST(sys_bpf)
11996 {
11997    union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
11998    UInt key_size, value_size;
11999 
12000    vg_assert(SUCCESS);
12001 
12002    switch (ARG1) {
12003       case VKI_BPF_PROG_GET_NEXT_ID:
12004       case VKI_BPF_MAP_GET_NEXT_ID:
12005          POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12006          break;
12007       case VKI_BPF_MAP_UPDATE_ELEM:
12008       case VKI_BPF_MAP_DELETE_ELEM:
12009       case VKI_BPF_OBJ_PIN:
12010       case VKI_BPF_PROG_ATTACH:
12011       case VKI_BPF_PROG_DETACH:
12012          break;
12013       /* Following commands have bpf() return a file descriptor. */
12014       case VKI_BPF_MAP_CREATE:
12015       case VKI_BPF_OBJ_GET:
12016       case VKI_BPF_PROG_GET_FD_BY_ID:
12017       case VKI_BPF_MAP_GET_FD_BY_ID:
12018       case VKI_BPF_BTF_GET_FD_BY_ID:
12019       case VKI_BPF_RAW_TRACEPOINT_OPEN:
12020          if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12021             VG_(close)(RES);
12022             SET_STATUS_Failure(VKI_EMFILE);
12023          } else {
12024             if (VG_(clo_track_fds))
12025                ML_(record_fd_open_nameless)(tid, RES);
12026          }
12027          break;
12028       /*
12029        * TODO: Is there a way to pass information between PRE and POST hooks?
12030        * To avoid querying again for the size of keys and values.
12031        */
12032       case VKI_BPF_MAP_LOOKUP_ELEM:
12033          if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12034             POST_MEM_WRITE(attr->value, value_size);
12035          break;
12036       case VKI_BPF_MAP_GET_NEXT_KEY:
12037          if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12038             POST_MEM_WRITE(attr->next_key, key_size);
12039          break;
12040       case VKI_BPF_PROG_LOAD:
12041          /* Return a file descriptor for loaded program, write into log_buf. */
12042          if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12043             VG_(close)(RES);
12044             SET_STATUS_Failure(VKI_EMFILE);
12045          } else {
12046             if (VG_(clo_track_fds))
12047                ML_(record_fd_open_nameless)(tid, RES);
12048          }
12049          if (attr->log_level || attr->log_size || attr->log_buf)
12050             POST_MEM_WRITE(attr->log_buf, attr->log_size);
12051          break;
12052       case VKI_BPF_PROG_TEST_RUN:
12053          POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
12054          POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12055          POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
12056          POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
12057          break;
12058       case VKI_BPF_OBJ_GET_INFO_BY_FD:
12059          POST_MEM_WRITE(attr->info.info, attr->info.info_len);
12060          break;
12061       case VKI_BPF_PROG_QUERY:
12062          POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12063          POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12064          if (attr->query.prog_ids)
12065             POST_MEM_WRITE(attr->query.prog_ids,
12066                            attr->query.prog_cnt * sizeof(__vki_u32));
12067          break;
12068       case VKI_BPF_BTF_LOAD:
12069          /* Return a file descriptor for BTF data, write into btf_log_buf. */
12070          if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12071             VG_(close)(RES);
12072             SET_STATUS_Failure(VKI_EMFILE);
12073          } else {
12074             if (VG_(clo_track_fds))
12075                ML_(record_fd_open_nameless)(tid, RES);
12076          }
12077          if (attr->btf_log_level)
12078             POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
12079          break;
12080       case VKI_BPF_TASK_FD_QUERY:
12081          POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
12082          POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12083          POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12084          POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12085          POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12086          break;
12087       default:
12088          VG_(message)(Vg_DebugMsg,
12089                       "FATAL: unhandled eBPF command %lu\n", ARG1);
12090          VG_(core_panic)("... bye!\n");
12091          break;
12092    }
12093 }
12094 
12095 #undef PRE
12096 #undef POST
12097 
12098 #endif // defined(VGO_linux)
12099 
12100 /*--------------------------------------------------------------------*/
12101 /*--- end                                                          ---*/
12102 /*--------------------------------------------------------------------*/
12103