Linux: Add support for the BLKFLSBUF ioctl
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blobbeb9dff6b1ab47c32b2ccbbe829cf85156582bc5
2 /*--------------------------------------------------------------------*/
3 /*--- Linux-specific syscalls, etc. syswrap-linux.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Nicholas Nethercote
11 njn@valgrind.org
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.
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.
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.
28 The GNU General Public License is contained in the file COPYING.
31 #if defined(VGO_linux)
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
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"
69 // Run a thread from beginning to end and return the thread's
70 // scheduler-return-code.
71 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
73 VgSchedReturnCode ret;
74 ThreadId tid = (ThreadId)tidW;
75 ThreadState* tst = VG_(get_ThreadState)(tid);
77 VG_(debugLog)(1, "syswrap-linux",
78 "thread_wrapper(tid=%u): entry\n",
79 tid);
81 vg_assert(tst->status == VgTs_Init);
83 /* make sure we get the CPU lock before doing anything significant */
84 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
86 if (0)
87 VG_(printf)("thread tid %u started: stack = %p\n",
88 tid, (void *)&tid);
90 /* Make sure error reporting is enabled in the new thread. */
91 tst->err_disablement_level = 0;
93 VG_TRACK(pre_thread_first_insn, tid);
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)();
100 /* Thread created with all signals blocked; scheduler will set the
101 appropriate mask */
103 ret = VG_(scheduler)(tid);
105 vg_assert(VG_(is_exiting)(tid));
107 vg_assert(tst->status == VgTs_Runnable);
108 vg_assert(VG_(is_running_thread)(tid));
110 VG_(debugLog)(1, "syswrap-linux",
111 "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
112 tid, VG_(name_of_VgSchedReturnCode)(ret));
114 /* Return to caller, still holding the lock. */
115 return ret;
119 /* ---------------------------------------------------------------------
120 clone-related stuff
121 ------------------------------------------------------------------ */
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). */
125 static void run_a_thread_NORETURN ( Word tidW )
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
135 VG_(debugLog)(1, "syswrap-linux",
136 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
137 tid);
139 tst = VG_(get_ThreadState)(tid);
140 vg_assert(tst);
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.
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));
155 /* Run the thread all the way through. */
156 src = thread_wrapper(tid);
158 VG_(debugLog)(1, "syswrap-linux",
159 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
160 tid);
162 c = VG_(count_living_threads)();
163 vg_assert(c >= 1); /* stay sane */
165 /* Deregister thread's stack. */
166 if (tst->os_state.stk_id != NULL_STK_ID)
167 VG_(deregister_stack)(tst->os_state.stk_id);
169 // Tell the tool this thread is exiting
170 VG_TRACK( pre_thread_ll_exit, tid );
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"
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
191 tst->err_disablement_level = 0;
193 if (c == 1) {
195 VG_(debugLog)(1, "syswrap-linux",
196 "run_a_thread_NORETURN(tid=%u): "
197 "last one standing\n",
198 tid);
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 {
206 VG_(debugLog)(1, "syswrap-linux",
207 "run_a_thread_NORETURN(tid=%u): "
208 "not last one standing\n",
209 tid);
211 /* OK, thread is dead, but others still exist. Just exit. */
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));
219 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
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"
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"
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"
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"
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"
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"
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"
304 #else
305 # error Unknown platform
306 #endif
308 VG_(core_panic)("Thread exit failed?\n");
311 /*NOTREACHED*/
312 vg_assert(0);
315 Word ML_(start_thread_NORETURN) ( void* arg )
317 ThreadState* tst = (ThreadState*)arg;
318 ThreadId tid = tst->tid;
320 run_a_thread_NORETURN ( (Word)tid );
321 /*NOTREACHED*/
322 vg_assert(0);
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. */
328 Addr ML_(allocstack)(ThreadId tid)
330 ThreadState* tst = VG_(get_ThreadState)(tid);
331 VgStack* stack;
332 Addr initial_SP;
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. */
338 if (tst->os_state.valgrind_stack_base == 0)
339 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
341 if (tst->os_state.valgrind_stack_base != 0)
342 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
344 /* If no stack is present, allocate one. */
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;
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 );
360 return tst->os_state.valgrind_stack_init_SP;
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.
368 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
370 Addr sp;
371 VG_(debugLog)(1, "syswrap-linux",
372 "entering VG_(main_thread_wrapper_NORETURN)\n");
374 sp = ML_(allocstack)(tid);
375 #if defined(ENABLE_INNER_CLIENT_REQUEST)
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));
386 #endif
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
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.");
409 /* shouldn't be any other threads around yet */
410 vg_assert( VG_(count_living_threads)() == 1 );
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 */
419 /*NOTREACHED*/
420 vg_assert(0);
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. */
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)
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;
527 static void setup_child ( /*OUT*/ ThreadArchState *child,
528 /*IN*/ ThreadArchState *parent )
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;
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
542 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
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);
549 if (debug)
550 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
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;
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
593 2. initialize the thread's new VCPU state
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.
599 static SysRes do_clone ( ThreadId ptid,
600 UWord flags, Addr sp,
601 Int* parent_tidptr,
602 Int* child_tidptr,
603 Addr tlsaddr)
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;
612 VG_(sigfillset)(&blockall);
614 vg_assert(VG_(is_running_thread)(ptid));
615 vg_assert(VG_(is_valid_tid)(ctid));
617 stack = (UWord*)ML_(allocstack)(ctid);
618 if (stack == NULL) {
619 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
620 goto out;
623 /* Copy register state
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.
629 The parent gets the child's new tid returned from clone, but the
630 child gets 0.
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.
635 setup_child( &ctst->arch, &ptst->arch );
637 if (sp != 0)
638 VG_(set_SP)(ctid, sp);
640 ctst->os_state.parent = ptid;
642 /* inherit signal mask */
643 ctst->sig_mask = ptst->sig_mask;
644 ctst->tmp_sig_mask = ptst->sig_mask;
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;
657 ML_(guess_and_register_stack) (sp, ctst);
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 );
669 if (flags & VKI_CLONE_SETTLS) {
670 res = setup_child_tls(ctid, tlsaddr);
671 if (sr_isError(res))
672 goto out;
674 flags &= ~VKI_CLONE_SETTLS;
676 /* start the thread with everything blocked */
677 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
679 /* Create the new thread */
680 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
681 child_tidptr, parent_tidptr);
683 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
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 );
694 return res;
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.
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.
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.
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. */
715 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
716 Int* parent_tidptr, Int* child_tidptr,
717 Addr child_sp)
719 vki_sigset_t fork_saved_mask;
720 vki_sigset_t mask;
721 SysRes res;
723 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
724 | VKI_CLONE_FILES))
725 return VG_(mk_SysRes_Error)( VKI_EINVAL );
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);
732 VG_(do_atfork_pre)(tid);
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
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);
764 /* restore signal mask */
765 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
767 else
768 if (!sr_isError(res) && sr_Res(res) > 0) {
769 /* parent */
770 VG_(do_atfork_parent)(tid);
772 if (VG_(clo_trace_syscalls))
773 VG_(printf)(" clone(fork): process %d created child %lu\n",
774 VG_(getpid)(), sr_Res(res));
776 /* restore signal mask */
777 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
780 return res;
783 /* ---------------------------------------------------------------------
784 PRE/POST wrappers for arch-generic, Linux-specific syscalls
785 ------------------------------------------------------------------ */
787 // Nb: See the comment above the generic PRE/POST wrappers in
788 // m_syswrap/syswrap-generic.c for notes about how they work.
790 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
791 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
793 PRE(sys_clone)
795 UInt cloneflags;
796 Bool badarg = False;
798 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
800 // Order of arguments differs between platforms.
801 #if defined(VGP_x86_linux) \
802 || defined(VGP_ppc32_linux) \
803 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
804 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
805 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
806 #define ARG_CHILD_TIDPTR ARG5
807 #define PRA_CHILD_TIDPTR PRA5
808 #define ARG_TLS ARG4
809 #define PRA_TLS PRA4
810 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
811 #define ARG_CHILD_TIDPTR ARG4
812 #define PRA_CHILD_TIDPTR PRA4
813 #define ARG_TLS ARG5
814 #define PRA_TLS PRA5
815 #else
816 # error Unknown platform
817 #endif
818 // And s390x is even more special, and inverts flags and child stack args
819 #if defined(VGP_s390x_linux)
820 #define ARG_FLAGS ARG2
821 #define PRA_FLAGS PRA2
822 #define ARG_CHILD_STACK ARG1
823 #define PRA_CHILD_STACK PRA1
824 #else
825 #define ARG_FLAGS ARG1
826 #define PRA_FLAGS PRA1
827 #define ARG_CHILD_STACK ARG2
828 #define PRA_CHILD_STACK PRA2
829 #endif
831 if (VG_(tdict).track_pre_reg_read) {
832 PRA_FLAGS("clone", unsigned long, flags);
833 PRA_CHILD_STACK("clone", void *, child_stack);
836 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID) {
837 if (VG_(tdict).track_pre_reg_read) {
838 PRA3("clone", int *, parent_tidptr);
840 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
841 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
842 VKI_PROT_WRITE)) {
843 badarg = True;
846 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
847 if (VG_(tdict).track_pre_reg_read) {
848 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
850 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
851 dummy type (that we define as a char). We only dereference/check the
852 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
853 if (sizeof(vki_modify_ldt_t) > 1) {
854 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
855 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
856 VKI_PROT_READ)) {
857 badarg = True;
861 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
862 if (VG_(tdict).track_pre_reg_read) {
863 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
865 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
866 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
867 VKI_PROT_WRITE)) {
868 badarg = True;
872 if (badarg) {
873 SET_STATUS_Failure( VKI_EFAULT );
874 return;
877 cloneflags = ARG_FLAGS;
879 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
880 SET_STATUS_Failure( VKI_EINVAL );
881 return;
884 /* Only look at the flags we really care about */
885 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
886 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
887 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
888 /* thread creation */
889 SET_STATUS_from_SysRes(
890 do_clone(tid,
891 ARG_FLAGS, /* flags */
892 (Addr)ARG_CHILD_STACK, /* child ESP */
893 (Int*)ARG3, /* parent_tidptr */
894 (Int*)ARG_CHILD_TIDPTR, /* child_tidptr */
895 (Addr)ARG_TLS)); /* set_tls */
896 break;
898 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
899 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
900 cloneflags &= ~VKI_CLONE_VM;
902 case 0: /* plain fork */
903 SET_STATUS_from_SysRes(
904 ML_(do_fork_clone)(tid,
905 cloneflags, /* flags */
906 (Int*)ARG3, /* parent_tidptr */
907 (Int*)ARG_CHILD_TIDPTR, /* child_tidptr */
908 (Addr)ARG_CHILD_STACK));
909 break;
911 default:
912 /* should we just ENOSYS? */
913 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG_FLAGS);
914 VG_(message)(Vg_UserMsg, "\n");
915 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
916 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
917 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
918 VG_(unimplemented)
919 ("Valgrind does not support general clone().");
922 if (SUCCESS) {
923 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
924 POST_MEM_WRITE(ARG3, sizeof(Int));
925 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
926 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
928 /* Thread creation was successful; let the child have the chance
929 to run */
930 *flags |= SfYieldAfter;
933 #undef ARG_CHILD_TIDPTR
934 #undef PRA_CHILD_TIDPTR
935 #undef ARG_TLS
936 #undef PRA_TLS
937 #undef ARG_FLAGS
938 #undef PRA_FLAGS
939 #undef ARG_CHILD_STACK
940 #undef PRA_CHILD_STACK
943 /* ---------------------------------------------------------------------
944 *mount wrappers
945 ------------------------------------------------------------------ */
947 PRE(sys_mount)
949 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
950 // We are conservative and check everything, except the memory pointed to
951 // by 'data'.
952 *flags |= SfMayBlock;
953 PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx(%s), %#lx, %#lx )",
954 ARG1,(HChar*)ARG1, ARG2,(HChar*)ARG2, ARG3,(HChar*)ARG3, ARG4, ARG5);
955 PRE_REG_READ5(long, "mount",
956 char *, source, char *, target, char *, type,
957 unsigned long, flags, void *, data);
958 if (ARG1)
959 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
960 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
961 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
964 PRE(sys_oldumount)
966 PRINT("sys_oldumount( %#lx )", ARG1);
967 PRE_REG_READ1(long, "umount", char *, path);
968 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
971 PRE(sys_umount)
973 PRINT("sys_umount( %#lx, %ld )", ARG1, SARG2);
974 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
975 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
978 /* Not actually wrapped by GLibc but does things with the system
979 * mounts so it is put here.
981 PRE(sys_pivot_root)
983 PRINT("sys_pivot_root ( %s %s )", (HChar*)ARG1, (HChar*)ARG2);
984 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
985 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
986 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
990 /* ---------------------------------------------------------------------
991 16- and 32-bit uid/gid wrappers
992 ------------------------------------------------------------------ */
994 PRE(sys_setfsuid16)
996 PRINT("sys_setfsuid16 ( %lu )", ARG1);
997 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1000 PRE(sys_setfsuid)
1002 PRINT("sys_setfsuid ( %lu )", ARG1);
1003 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1006 PRE(sys_setfsgid16)
1008 PRINT("sys_setfsgid16 ( %lu )", ARG1);
1009 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1012 PRE(sys_setfsgid)
1014 PRINT("sys_setfsgid ( %lu )", ARG1);
1015 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1018 PRE(sys_setresuid16)
1020 PRINT("sys_setresuid16 ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1021 PRE_REG_READ3(long, "setresuid16",
1022 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1025 PRE(sys_setresuid)
1027 PRINT("sys_setresuid ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1028 PRE_REG_READ3(long, "setresuid",
1029 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1032 PRE(sys_getresuid16)
1034 PRINT("sys_getresuid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1035 PRE_REG_READ3(long, "getresuid16",
1036 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1037 vki_old_uid_t *, suid);
1038 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1039 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1040 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1042 POST(sys_getresuid16)
1044 vg_assert(SUCCESS);
1045 if (RES == 0) {
1046 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1047 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1048 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1052 PRE(sys_getresuid)
1054 PRINT("sys_getresuid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1055 PRE_REG_READ3(long, "getresuid",
1056 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1057 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1058 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1059 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1061 POST(sys_getresuid)
1063 vg_assert(SUCCESS);
1064 if (RES == 0) {
1065 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1066 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1067 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1071 PRE(sys_setresgid16)
1073 PRINT("sys_setresgid16 ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1074 PRE_REG_READ3(long, "setresgid16",
1075 vki_old_gid_t, rgid,
1076 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1079 PRE(sys_setresgid)
1081 PRINT("sys_setresgid ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
1082 PRE_REG_READ3(long, "setresgid",
1083 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1086 PRE(sys_getresgid16)
1088 PRINT("sys_getresgid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1089 PRE_REG_READ3(long, "getresgid16",
1090 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1091 vki_old_gid_t *, sgid);
1092 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1093 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1094 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1096 POST(sys_getresgid16)
1098 vg_assert(SUCCESS);
1099 if (RES == 0) {
1100 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1101 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1102 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1106 PRE(sys_getresgid)
1108 PRINT("sys_getresgid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
1109 PRE_REG_READ3(long, "getresgid",
1110 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1111 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1112 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1113 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1115 POST(sys_getresgid)
1117 vg_assert(SUCCESS);
1118 if (RES == 0) {
1119 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1120 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1121 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1125 /* ---------------------------------------------------------------------
1126 miscellaneous wrappers
1127 ------------------------------------------------------------------ */
1129 PRE(sys_exit_group)
1131 ThreadId t;
1132 ThreadState* tst;
1134 PRINT("exit_group( %ld )", SARG1);
1135 PRE_REG_READ1(void, "exit_group", int, status);
1137 tst = VG_(get_ThreadState)(tid);
1138 /* A little complex; find all the threads with the same threadgroup
1139 as this one (including this one), and mark them to exit */
1140 /* It is unclear how one can get a threadgroup in this process which
1141 is not the threadgroup of the calling thread:
1142 The assignments to threadgroups are:
1143 = 0; /// scheduler.c os_state_clear
1144 = getpid(); /// scheduler.c in child after fork
1145 = getpid(); /// this file, in thread_wrapper
1146 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1147 copying the thread group of the thread doing clone
1148 So, the only case where the threadgroup might be different to the getpid
1149 value is in the child, just after fork. But then the fork syscall is
1150 still going on, the forked thread has had no chance yet to make this
1151 syscall. */
1152 for (t = 1; t < VG_N_THREADS; t++) {
1153 if ( /* not alive */
1154 VG_(threads)[t].status == VgTs_Empty
1156 /* not our group */
1157 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1159 continue;
1160 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1161 the exitreason. */
1162 VG_(threads)[t].os_state.exitcode = ARG1;
1165 /* Indicate in all other threads that the process is exiting.
1166 Then wait using VG_(reap_threads) for these threads to disappear.
1168 Can this give a deadlock if another thread is calling exit in parallel
1169 and would then wait for this thread to disappear ?
1170 The answer is no:
1171 Other threads are either blocked in a syscall or have yielded the CPU.
1173 A thread that has yielded the CPU is trying to get the big lock in
1174 VG_(scheduler). This thread will get the CPU thanks to the call
1175 to VG_(reap_threads). The scheduler will then check for signals,
1176 kill the process if this is a fatal signal, and otherwise prepare
1177 the thread for handling this signal. After this preparation, if
1178 the thread status is VG_(is_exiting), the scheduler exits the thread.
1179 So, a thread that has yielded the CPU does not have a chance to
1180 call exit => no deadlock for this thread.
1182 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1183 to all threads blocked in a syscall.
1184 The syscall will be interrupted, and the control will go to the
1185 scheduler. The scheduler will then return, as the thread is in
1186 exiting state. */
1188 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1189 VG_(reap_threads)(tid);
1190 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1191 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1192 is the thread calling exit_group and so its registers must be considered
1193 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1195 /* We have to claim the syscall already succeeded. */
1196 SET_STATUS_Success(0);
1199 PRE(sys_llseek)
1201 PRINT("sys_llseek ( %lu, 0x%lx, 0x%lx, %#lx, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5);
1202 PRE_REG_READ5(long, "llseek",
1203 unsigned int, fd, unsigned long, offset_high,
1204 unsigned long, offset_low, vki_loff_t *, result,
1205 unsigned int, whence);
1206 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1207 SET_STATUS_Failure( VKI_EBADF );
1208 else
1209 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1211 POST(sys_llseek)
1213 vg_assert(SUCCESS);
1214 if (RES == 0)
1215 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1218 PRE(sys_adjtimex)
1220 struct vki_timex *tx = (struct vki_timex *)ARG1;
1221 PRINT("sys_adjtimex ( %#lx )", ARG1);
1222 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1224 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1225 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1227 #define ADJX(bits,field) \
1228 if (tx->modes & (bits)) \
1229 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1230 (Addr)&tx->field, sizeof(tx->field))
1232 if (tx->modes & VKI_ADJ_ADJTIME) {
1233 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1234 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1235 } else {
1236 ADJX(VKI_ADJ_OFFSET, offset);
1237 ADJX(VKI_ADJ_FREQUENCY, freq);
1238 ADJX(VKI_ADJ_MAXERROR, maxerror);
1239 ADJX(VKI_ADJ_ESTERROR, esterror);
1240 ADJX(VKI_ADJ_STATUS, status);
1241 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1242 ADJX(VKI_ADJ_TICK, tick);
1244 #undef ADJX
1247 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1250 POST(sys_adjtimex)
1252 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1255 PRE(sys_clock_adjtime)
1257 struct vki_timex *tx = (struct vki_timex *)ARG2;
1258 PRINT("sys_clock_adjtime ( %ld, %#lx )", SARG1,ARG2);
1259 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1260 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1262 #define ADJX(bits,field) \
1263 if (tx->modes & (bits)) \
1264 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1265 (Addr)&tx->field, sizeof(tx->field))
1267 if (tx->modes & VKI_ADJ_ADJTIME) {
1268 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1269 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1270 } else {
1271 ADJX(VKI_ADJ_OFFSET, offset);
1272 ADJX(VKI_ADJ_FREQUENCY, freq);
1273 ADJX(VKI_ADJ_MAXERROR, maxerror);
1274 ADJX(VKI_ADJ_ESTERROR, esterror);
1275 ADJX(VKI_ADJ_STATUS, status);
1276 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1277 ADJX(VKI_ADJ_TICK, tick);
1279 #undef ADJX
1281 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1284 POST(sys_clock_adjtime)
1286 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1289 PRE(sys_ioperm)
1291 PRINT("sys_ioperm ( %lu, %lu, %ld )", ARG1, ARG2, SARG3 );
1292 PRE_REG_READ3(long, "ioperm",
1293 unsigned long, from, unsigned long, num, int, turn_on);
1296 PRE(sys_syslog)
1298 *flags |= SfMayBlock;
1299 PRINT("sys_syslog (%ld, %#lx, %ld)", SARG1, ARG2, SARG3);
1300 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1301 switch (ARG1) {
1302 // The kernel uses magic numbers here, rather than named constants,
1303 // therefore so do we.
1304 case 2: case 3: case 4:
1305 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1306 break;
1307 default:
1308 break;
1311 POST(sys_syslog)
1313 switch (ARG1) {
1314 case 2: case 3: case 4:
1315 POST_MEM_WRITE( ARG2, ARG3 );
1316 break;
1317 default:
1318 break;
1322 PRE(sys_vhangup)
1324 PRINT("sys_vhangup ( )");
1325 PRE_REG_READ0(long, "vhangup");
1328 PRE(sys_sysinfo)
1330 PRINT("sys_sysinfo ( %#lx )",ARG1);
1331 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1332 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1334 POST(sys_sysinfo)
1336 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1339 PRE(sys_personality)
1341 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1342 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1345 PRE(sys_sysctl)
1347 struct __vki_sysctl_args *args;
1348 PRINT("sys_sysctl ( %#lx )", ARG1 );
1349 args = (struct __vki_sysctl_args *)ARG1;
1350 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1351 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1352 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1353 VKI_PROT_READ)) {
1354 SET_STATUS_Failure( VKI_EFAULT );
1355 return;
1358 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1359 if (args->newval != NULL)
1360 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1361 if (args->oldlenp != NULL) {
1362 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1363 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1366 POST(sys_sysctl)
1368 struct __vki_sysctl_args *args;
1369 args = (struct __vki_sysctl_args *)ARG1;
1370 if (args->oldlenp != NULL) {
1371 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1372 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1376 PRE(sys_prctl)
1378 *flags |= SfMayBlock;
1379 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1380 switch (ARG1) {
1381 case VKI_PR_SET_PDEATHSIG:
1382 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1383 break;
1384 case VKI_PR_GET_PDEATHSIG:
1385 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1386 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1387 break;
1388 case VKI_PR_GET_DUMPABLE:
1389 PRE_REG_READ1(int, "prctl", int, option);
1390 break;
1391 case VKI_PR_SET_DUMPABLE:
1392 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1393 break;
1394 case VKI_PR_GET_UNALIGN:
1395 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1396 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1397 break;
1398 case VKI_PR_SET_UNALIGN:
1399 PRE_REG_READ2(int, "prctl", int, option, int, value);
1400 break;
1401 case VKI_PR_GET_KEEPCAPS:
1402 PRE_REG_READ1(int, "prctl", int, option);
1403 break;
1404 case VKI_PR_SET_KEEPCAPS:
1405 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1406 break;
1407 case VKI_PR_GET_FPEMU:
1408 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1409 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1410 break;
1411 case VKI_PR_SET_FPEMU:
1412 PRE_REG_READ2(int, "prctl", int, option, int, value);
1413 break;
1414 case VKI_PR_GET_FPEXC:
1415 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1416 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1417 break;
1418 case VKI_PR_SET_FPEXC:
1419 PRE_REG_READ2(int, "prctl", int, option, int, value);
1420 break;
1421 case VKI_PR_GET_TIMING:
1422 PRE_REG_READ1(int, "prctl", int, option);
1423 break;
1424 case VKI_PR_SET_TIMING:
1425 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1426 break;
1427 case VKI_PR_SET_NAME:
1428 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1429 /* The name can be up to TASK_COMM_LEN(16) bytes long, including
1430 the terminating null byte. So do not check more than 16 bytes. */
1431 if (ML_(safe_to_deref)((const HChar *) ARG2, VKI_TASK_COMM_LEN)) {
1432 SizeT len = VG_(strnlen)((const HChar *) ARG2, VKI_TASK_COMM_LEN);
1433 if (len < VKI_TASK_COMM_LEN) {
1434 PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
1435 } else {
1436 PRE_MEM_READ("prctl(set-name)", ARG2, VKI_TASK_COMM_LEN);
1438 } else {
1439 /* Do it the slow way, one byte at a time, while checking for
1440 terminating '\0'. */
1441 const HChar *name = (const HChar *) ARG2;
1442 for (UInt i = 0; i < VKI_TASK_COMM_LEN; i++) {
1443 PRE_MEM_READ("prctl(set-name)", (Addr) &name[i], 1);
1444 if (!ML_(safe_to_deref)(&name[i], 1) || name[i] == '\0') {
1445 break;
1449 break;
1450 case VKI_PR_GET_NAME:
1451 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1452 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1453 break;
1454 case VKI_PR_GET_ENDIAN:
1455 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1456 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1457 break;
1458 case VKI_PR_SET_ENDIAN:
1459 PRE_REG_READ2(int, "prctl", int, option, int, value);
1460 break;
1461 case VKI_PR_SET_PTRACER:
1462 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1463 break;
1464 case VKI_PR_SET_SECCOMP:
1465 /* This is a bit feeble in that it uses |option| before checking
1466 it, but at least both sides of the conditional check it. */
1467 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1468 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1469 if (ARG3) {
1470 /* Should check that ARG3 points at a valid struct sock_fprog.
1471 Sounds complex; hence be lame. */
1472 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1473 ARG3, 1 );
1475 } else {
1476 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1478 break;
1479 default:
1480 PRE_REG_READ5(long, "prctl",
1481 int, option, unsigned long, arg2, unsigned long, arg3,
1482 unsigned long, arg4, unsigned long, arg5);
1483 break;
1486 POST(sys_prctl)
1488 switch (ARG1) {
1489 case VKI_PR_GET_PDEATHSIG:
1490 POST_MEM_WRITE(ARG2, sizeof(Int));
1491 break;
1492 case VKI_PR_GET_UNALIGN:
1493 POST_MEM_WRITE(ARG2, sizeof(Int));
1494 break;
1495 case VKI_PR_GET_FPEMU:
1496 POST_MEM_WRITE(ARG2, sizeof(Int));
1497 break;
1498 case VKI_PR_GET_FPEXC:
1499 POST_MEM_WRITE(ARG2, sizeof(Int));
1500 break;
1501 case VKI_PR_GET_NAME:
1502 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1503 break;
1504 case VKI_PR_GET_ENDIAN:
1505 POST_MEM_WRITE(ARG2, sizeof(Int));
1506 break;
1507 case VKI_PR_SET_NAME:
1509 const HChar* new_name = (const HChar*) ARG2;
1510 if (new_name) { // Paranoia
1511 ThreadState* tst = VG_(get_ThreadState)(tid);
1512 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1514 /* Don't bother reusing the memory. This is a rare event. */
1515 tst->thread_name =
1516 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1517 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1520 break;
1524 PRE(sys_sendfile)
1526 *flags |= SfMayBlock;
1527 PRINT("sys_sendfile ( %ld, %ld, %#lx, %lu )", SARG1,SARG2,ARG3,ARG4);
1528 PRE_REG_READ4(ssize_t, "sendfile",
1529 int, out_fd, int, in_fd, vki_off_t *, offset,
1530 vki_size_t, count);
1531 if (ARG3 != 0)
1532 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1534 POST(sys_sendfile)
1536 if (ARG3 != 0 ) {
1537 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1541 PRE(sys_sendfile64)
1543 *flags |= SfMayBlock;
1544 PRINT("sendfile64 ( %ld, %ld, %#lx, %lu )",SARG1,SARG2,ARG3,ARG4);
1545 PRE_REG_READ4(ssize_t, "sendfile64",
1546 int, out_fd, int, in_fd, vki_loff_t *, offset,
1547 vki_size_t, count);
1548 if (ARG3 != 0)
1549 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1551 POST(sys_sendfile64)
1553 if (ARG3 != 0 ) {
1554 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1558 PRE(sys_futex)
1561 arg param used by ops
1563 ARG1 - u32 *futex all
1564 ARG2 - int op
1565 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1566 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1567 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1568 ARG6 - int val3 CMP_REQUEUE
1570 PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,SARG2,SARG3,ARG4,ARG5);
1571 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1572 case VKI_FUTEX_CMP_REQUEUE:
1573 case VKI_FUTEX_WAKE_OP:
1574 case VKI_FUTEX_CMP_REQUEUE_PI:
1575 PRE_REG_READ6(long, "futex",
1576 vki_u32 *, futex, int, op, int, val,
1577 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1578 break;
1579 case VKI_FUTEX_REQUEUE:
1580 case VKI_FUTEX_WAIT_REQUEUE_PI:
1581 PRE_REG_READ5(long, "futex",
1582 vki_u32 *, futex, int, op, int, val,
1583 struct timespec *, utime, vki_u32 *, uaddr2);
1584 break;
1585 case VKI_FUTEX_WAIT_BITSET:
1586 /* Check that the address at least begins in client-accessible area. */
1587 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1588 SET_STATUS_Failure( VKI_EFAULT );
1589 return;
1591 if (*(vki_u32 *)ARG1 != ARG3) {
1592 PRE_REG_READ4(long, "futex",
1593 vki_u32 *, futex, int, op, int, val,
1594 struct timespec *, utime);
1595 } else {
1596 /* Note argument 5 is unused, but argument 6 is used.
1597 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1598 PRE_REG_READ4(long, "futex",
1599 vki_u32 *, futex, int, op, int, val,
1600 struct timespec *, utime);
1601 if (VG_(tdict).track_pre_reg_read)
1602 PRA6("futex",int,val3);
1604 break;
1605 case VKI_FUTEX_WAKE_BITSET:
1606 PRE_REG_READ3(long, "futex",
1607 vki_u32 *, futex, int, op, int, val);
1608 if (VG_(tdict).track_pre_reg_read) {
1609 PRA6("futex", int, val3);
1611 break;
1612 case VKI_FUTEX_WAIT:
1613 case VKI_FUTEX_LOCK_PI:
1614 PRE_REG_READ4(long, "futex",
1615 vki_u32 *, futex, int, op, int, val,
1616 struct timespec *, utime);
1617 break;
1618 case VKI_FUTEX_WAKE:
1619 case VKI_FUTEX_FD:
1620 PRE_REG_READ3(long, "futex",
1621 vki_u32 *, futex, int, op, int, val);
1622 break;
1623 case VKI_FUTEX_TRYLOCK_PI:
1624 case VKI_FUTEX_UNLOCK_PI:
1625 default:
1626 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1627 break;
1630 *flags |= SfMayBlock;
1632 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1633 case VKI_FUTEX_WAIT:
1634 case VKI_FUTEX_LOCK_PI:
1635 case VKI_FUTEX_WAIT_BITSET:
1636 case VKI_FUTEX_WAIT_REQUEUE_PI:
1637 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1638 if (ARG4 != 0)
1639 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1640 break;
1642 case VKI_FUTEX_REQUEUE:
1643 case VKI_FUTEX_CMP_REQUEUE:
1644 case VKI_FUTEX_CMP_REQUEUE_PI:
1645 case VKI_FUTEX_WAKE_OP:
1646 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1647 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1648 break;
1650 case VKI_FUTEX_FD:
1651 case VKI_FUTEX_TRYLOCK_PI:
1652 case VKI_FUTEX_UNLOCK_PI:
1653 case VKI_FUTEX_WAKE:
1654 case VKI_FUTEX_WAKE_BITSET:
1655 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1656 break;
1658 default:
1659 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1660 break;
1663 POST(sys_futex)
1665 vg_assert(SUCCESS);
1666 POST_MEM_WRITE( ARG1, sizeof(int) );
1667 if (ARG2 == VKI_FUTEX_FD) {
1668 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1669 VG_(close)(RES);
1670 SET_STATUS_Failure( VKI_EMFILE );
1671 } else {
1672 if (VG_(clo_track_fds))
1673 ML_(record_fd_open_nameless)(tid, RES);
1678 PRE(sys_set_robust_list)
1680 PRINT("sys_set_robust_list ( %#lx, %lu )", ARG1,ARG2);
1681 PRE_REG_READ2(long, "set_robust_list",
1682 struct vki_robust_list_head *, head, vki_size_t, len);
1684 /* Just check the robust_list_head structure is readable - don't
1685 try and chase the list as the kernel will only read it when
1686 the thread exits so the current contents is irrelevant. */
1687 if (ARG1 != 0)
1688 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1691 PRE(sys_get_robust_list)
1693 PRINT("sys_get_robust_list ( %ld, %#lx, %#lx )", SARG1,ARG2,ARG3);
1694 PRE_REG_READ3(long, "get_robust_list",
1695 int, pid,
1696 struct vki_robust_list_head **, head_ptr,
1697 vki_size_t *, len_ptr);
1698 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1699 ARG2, sizeof(struct vki_robust_list_head *));
1700 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1701 ARG3, sizeof(struct vki_size_t *));
1703 POST(sys_get_robust_list)
1705 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1706 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1709 struct pselect_sized_sigset {
1710 const vki_sigset_t *ss;
1711 vki_size_t ss_len;
1713 struct pselect_adjusted_sigset {
1714 struct pselect_sized_sigset ss; /* The actual syscall arg */
1715 vki_sigset_t adjusted_ss;
1718 PRE(sys_pselect6)
1720 *flags |= SfMayBlock | SfPostOnFail;
1721 PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )",
1722 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1723 PRE_REG_READ6(long, "pselect6",
1724 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1725 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1726 void *, sig);
1727 // XXX: this possibly understates how much memory is read.
1728 if (ARG2 != 0)
1729 PRE_MEM_READ( "pselect6(readfds)",
1730 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1731 if (ARG3 != 0)
1732 PRE_MEM_READ( "pselect6(writefds)",
1733 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1734 if (ARG4 != 0)
1735 PRE_MEM_READ( "pselect6(exceptfds)",
1736 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1737 if (ARG5 != 0)
1738 PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1739 if (ARG6 != 0) {
1740 const struct pselect_sized_sigset *pss =
1741 (struct pselect_sized_sigset *)ARG6;
1742 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1743 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1744 ARG6 = 1; /* Something recognisable to POST() hook. */
1745 } else {
1746 struct pselect_adjusted_sigset *pas;
1747 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1748 ARG6 = (Addr)pas;
1749 pas->ss.ss = (void *)1;
1750 pas->ss.ss_len = pss->ss_len;
1751 if (pss->ss_len == sizeof(*pss->ss)) {
1752 if (pss->ss == NULL) {
1753 pas->ss.ss = NULL;
1754 } else {
1755 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1756 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1757 pas->adjusted_ss = *pss->ss;
1758 pas->ss.ss = &pas->adjusted_ss;
1759 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1766 POST(sys_pselect6)
1768 if (ARG6 != 0 && ARG6 != 1) {
1769 VG_(free)((struct pselect_adjusted_sigset *)ARG6);
1773 PRE(sys_ppoll)
1775 UInt i;
1776 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1777 *flags |= SfMayBlock | SfPostOnFail;
1778 PRINT("sys_ppoll ( %#lx, %lu, %#lx, %#lx, %lu )\n", ARG1,ARG2,ARG3,ARG4,ARG5);
1779 PRE_REG_READ5(long, "ppoll",
1780 struct vki_pollfd *, ufds, unsigned int, nfds,
1781 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1782 vki_size_t, sigsetsize);
1784 for (i = 0; i < ARG2; i++) {
1785 PRE_MEM_READ( "ppoll(ufds.fd)",
1786 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1787 PRE_MEM_READ( "ppoll(ufds.events)",
1788 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1789 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1790 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1793 if (ARG3)
1794 PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1795 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1796 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)ARG4;
1797 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1798 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1799 ARG4 = 1; /* Something recognisable to POST() hook. */
1800 } else {
1801 vki_sigset_t *vg_sigmask =
1802 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1803 ARG4 = (Addr)vg_sigmask;
1804 *vg_sigmask = *guest_sigmask;
1805 VG_(sanitize_client_sigmask)(vg_sigmask);
1810 POST(sys_ppoll)
1812 vg_assert(SUCCESS || FAILURE);
1813 if (SUCCESS && (RES >= 0)) {
1814 UInt i;
1815 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1816 for (i = 0; i < ARG2; i++)
1817 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1819 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1820 VG_(free)((vki_sigset_t *) ARG4);
1825 /* ---------------------------------------------------------------------
1826 epoll_* wrappers
1827 ------------------------------------------------------------------ */
1829 PRE(sys_epoll_create)
1831 PRINT("sys_epoll_create ( %ld )", SARG1);
1832 PRE_REG_READ1(long, "epoll_create", int, size);
1834 POST(sys_epoll_create)
1836 vg_assert(SUCCESS);
1837 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1838 VG_(close)(RES);
1839 SET_STATUS_Failure( VKI_EMFILE );
1840 } else {
1841 if (VG_(clo_track_fds))
1842 ML_(record_fd_open_nameless) (tid, RES);
1846 PRE(sys_epoll_create1)
1848 PRINT("sys_epoll_create1 ( %ld )", SARG1);
1849 PRE_REG_READ1(long, "epoll_create1", int, flags);
1851 POST(sys_epoll_create1)
1853 vg_assert(SUCCESS);
1854 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1855 VG_(close)(RES);
1856 SET_STATUS_Failure( VKI_EMFILE );
1857 } else {
1858 if (VG_(clo_track_fds))
1859 ML_(record_fd_open_nameless) (tid, RES);
1863 PRE(sys_epoll_ctl)
1865 static const HChar* epoll_ctl_s[3] = {
1866 "EPOLL_CTL_ADD",
1867 "EPOLL_CTL_DEL",
1868 "EPOLL_CTL_MOD"
1870 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#lx )",
1871 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1872 PRE_REG_READ4(long, "epoll_ctl",
1873 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1874 if (ARG2 != VKI_EPOLL_CTL_DEL)
1875 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1878 PRE(sys_epoll_wait)
1880 *flags |= SfMayBlock;
1881 PRINT("sys_epoll_wait ( %ld, %#lx, %ld, %ld )", SARG1, ARG2, SARG3, SARG4);
1882 PRE_REG_READ4(long, "epoll_wait",
1883 int, epfd, struct vki_epoll_event *, events,
1884 int, maxevents, int, timeout);
1885 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1887 POST(sys_epoll_wait)
1889 vg_assert(SUCCESS);
1890 if (RES > 0)
1891 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1894 PRE(sys_epoll_pwait)
1896 *flags |= SfMayBlock;
1897 PRINT("sys_epoll_pwait ( %ld, %#lx, %ld, %ld, %#lx, %lu )",
1898 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1899 PRE_REG_READ6(long, "epoll_pwait",
1900 int, epfd, struct vki_epoll_event *, events,
1901 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1902 vki_size_t, sigsetsize);
1903 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1904 if (ARG5)
1905 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1907 POST(sys_epoll_pwait)
1909 vg_assert(SUCCESS);
1910 if (RES > 0)
1911 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1914 PRE(sys_eventfd)
1916 PRINT("sys_eventfd ( %lu )", ARG1);
1917 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1919 POST(sys_eventfd)
1921 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1922 VG_(close)(RES);
1923 SET_STATUS_Failure( VKI_EMFILE );
1924 } else {
1925 if (VG_(clo_track_fds))
1926 ML_(record_fd_open_nameless) (tid, RES);
1930 PRE(sys_eventfd2)
1932 PRINT("sys_eventfd2 ( %lu, %ld )", ARG1, SARG2);
1933 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1935 POST(sys_eventfd2)
1937 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1938 VG_(close)(RES);
1939 SET_STATUS_Failure( VKI_EMFILE );
1940 } else {
1941 if (VG_(clo_track_fds))
1942 ML_(record_fd_open_nameless) (tid, RES);
1946 PRE(sys_fallocate)
1948 *flags |= SfMayBlock;
1949 #if VG_WORDSIZE == 4
1950 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1951 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
1952 PRE_REG_READ6(long, "fallocate",
1953 int, fd, int, mode,
1954 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1955 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1956 #elif VG_WORDSIZE == 8
1957 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
1958 SARG1, SARG2, SARG3, SARG4);
1959 PRE_REG_READ4(long, "fallocate",
1960 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1961 #else
1962 # error Unexpected word size
1963 #endif
1964 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1965 SET_STATUS_Failure( VKI_EBADF );
1968 PRE(sys_prlimit64)
1970 PRINT("sys_prlimit64 ( %ld, %lu, %#lx, %#lx )", SARG1,ARG2,ARG3,ARG4);
1971 PRE_REG_READ4(long, "prlimit64",
1972 vki_pid_t, pid, unsigned int, resource,
1973 const struct rlimit64 *, new_rlim,
1974 struct rlimit64 *, old_rlim);
1975 if (ARG3)
1976 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
1977 if (ARG4)
1978 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
1980 if (ARG3 &&
1981 ((struct vki_rlimit64 *)ARG3)->rlim_cur > ((struct vki_rlimit64 *)ARG3)->rlim_max) {
1982 SET_STATUS_Failure( VKI_EINVAL );
1984 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
1985 switch (ARG2) {
1986 case VKI_RLIMIT_NOFILE:
1987 SET_STATUS_Success( 0 );
1988 if (ARG4) {
1989 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(fd_soft_limit);
1990 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(fd_hard_limit);
1992 if (ARG3) {
1993 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(fd_hard_limit) ||
1994 ((struct vki_rlimit64 *)ARG3)->rlim_max != VG_(fd_hard_limit)) {
1995 SET_STATUS_Failure( VKI_EPERM );
1997 else {
1998 VG_(fd_soft_limit) = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2001 break;
2003 case VKI_RLIMIT_DATA:
2004 SET_STATUS_Success( 0 );
2005 if (ARG4) {
2006 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_data).rlim_cur;
2007 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_data).rlim_max;
2009 if (ARG3) {
2010 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
2011 ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_data).rlim_max) {
2012 SET_STATUS_Failure( VKI_EPERM );
2014 else {
2015 VG_(client_rlimit_data).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2016 VG_(client_rlimit_data).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
2019 break;
2021 case VKI_RLIMIT_STACK:
2022 SET_STATUS_Success( 0 );
2023 if (ARG4) {
2024 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_stack).rlim_cur;
2025 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_stack).rlim_max;
2027 if (ARG3) {
2028 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
2029 ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
2030 SET_STATUS_Failure( VKI_EPERM );
2032 else {
2033 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2034 VG_(client_rlimit_stack).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
2035 VG_(client_rlimit_stack).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
2038 break;
2043 POST(sys_prlimit64)
2045 if (ARG4)
2046 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2049 /* ---------------------------------------------------------------------
2050 tid-related wrappers
2051 ------------------------------------------------------------------ */
2053 PRE(sys_gettid)
2055 PRINT("sys_gettid ()");
2056 PRE_REG_READ0(long, "gettid");
2059 PRE(sys_set_tid_address)
2061 PRINT("sys_set_tid_address ( %#lx )", ARG1);
2062 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2065 PRE(sys_tkill)
2067 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2068 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2069 if (!ML_(client_signal_OK)(ARG2)) {
2070 SET_STATUS_Failure( VKI_EINVAL );
2071 return;
2074 /* Check to see if this kill gave us a pending signal */
2075 *flags |= SfPollAfter;
2077 if (VG_(clo_trace_signals))
2078 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2079 SARG2, SARG1);
2081 /* If we're sending SIGKILL, check to see if the target is one of
2082 our threads and handle it specially. */
2083 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2084 SET_STATUS_Success(0);
2085 return;
2088 /* Ask to handle this syscall via the slow route, since that's the
2089 only one that sets tst->status to VgTs_WaitSys. If the result
2090 of doing the syscall is an immediate run of
2091 async_signalhandler() in m_signals, then we need the thread to
2092 be properly tidied away. I have the impression the previous
2093 version of this wrapper worked on x86/amd64 only because the
2094 kernel did not immediately deliver the async signal to this
2095 thread (on ppc it did, which broke the assertion re tst->status
2096 at the top of async_signalhandler()). */
2097 *flags |= SfMayBlock;
2099 POST(sys_tkill)
2101 if (VG_(clo_trace_signals))
2102 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2103 SARG2, SARG1);
2106 PRE(sys_tgkill)
2108 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2109 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2110 if (!ML_(client_signal_OK)(ARG3)) {
2111 SET_STATUS_Failure( VKI_EINVAL );
2112 return;
2115 /* Check to see if this kill gave us a pending signal */
2116 *flags |= SfPollAfter;
2118 if (VG_(clo_trace_signals))
2119 VG_(message)(Vg_DebugMsg,
2120 "tgkill: sending signal %ld to pid %ld/%ld\n",
2121 SARG3, SARG1, SARG2);
2123 /* If we're sending SIGKILL, check to see if the target is one of
2124 our threads and handle it specially. */
2125 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2126 SET_STATUS_Success(0);
2127 return;
2130 /* Ask to handle this syscall via the slow route, since that's the
2131 only one that sets tst->status to VgTs_WaitSys. If the result
2132 of doing the syscall is an immediate run of
2133 async_signalhandler() in m_signals, then we need the thread to
2134 be properly tidied away. I have the impression the previous
2135 version of this wrapper worked on x86/amd64 only because the
2136 kernel did not immediately deliver the async signal to this
2137 thread (on ppc it did, which broke the assertion re tst->status
2138 at the top of async_signalhandler()). */
2139 *flags |= SfMayBlock;
2141 POST(sys_tgkill)
2143 if (VG_(clo_trace_signals))
2144 VG_(message)(Vg_DebugMsg,
2145 "tgkill: sent signal %ld to pid %ld/%ld\n",
2146 SARG3, SARG1, SARG2);
2149 /* ---------------------------------------------------------------------
2150 fadvise64* wrappers
2151 ------------------------------------------------------------------ */
2153 PRE(sys_fadvise64)
2155 PRINT("sys_fadvise64 ( %ld, %llu, %lu, %ld )",
2156 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2157 PRE_REG_READ5(long, "fadvise64",
2158 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2159 vki_size_t, len, int, advice);
2162 PRE(sys_fadvise64_64)
2164 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2165 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2166 PRE_REG_READ6(long, "fadvise64_64",
2167 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2168 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2171 /* ---------------------------------------------------------------------
2172 io_* wrappers
2173 ------------------------------------------------------------------ */
2175 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2176 // and this allows us to control exactly the code that gets run while
2177 // the padding is in place.
2179 PRE(sys_io_setup)
2181 PRINT("sys_io_setup ( %lu, %#lx )", ARG1,ARG2);
2182 PRE_REG_READ2(long, "io_setup",
2183 unsigned, nr_events, vki_aio_context_t *, ctxp);
2184 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2187 POST(sys_io_setup)
2189 SizeT size;
2190 struct vki_aio_ring *r;
2192 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2193 ARG1*sizeof(struct vki_io_event));
2194 r = *(struct vki_aio_ring **)ARG2;
2195 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2197 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2198 VKI_PROT_READ | VKI_PROT_WRITE,
2199 VKI_MAP_ANONYMOUS, -1, 0 );
2201 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2204 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2205 // after the syscall. We must get 'size' from the aio_ring structure,
2206 // before the syscall, while the aio_ring structure still exists. (And we
2207 // know that we must look at the aio_ring structure because Tom inspected the
2208 // kernel and glibc sources to see what they do, yuk.)
2210 // XXX This segment can be implicitly unmapped when aio
2211 // file-descriptors are closed...
2212 PRE(sys_io_destroy)
2214 SizeT size = 0;
2216 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2217 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2219 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2220 // possible...
2221 if (ML_(safe_to_deref)( (void*)ARG1, sizeof(struct vki_aio_ring))) {
2222 struct vki_aio_ring *r = (struct vki_aio_ring *)ARG1;
2223 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2224 r->nr*sizeof(struct vki_io_event));
2227 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2229 if (SUCCESS && RES == 0) {
2230 Bool d = VG_(am_notify_munmap)( ARG1, size );
2231 VG_TRACK( die_mem_munmap, ARG1, size );
2232 if (d)
2233 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2234 "PRE(sys_io_destroy)" );
2238 PRE(sys_io_getevents)
2240 *flags |= SfMayBlock;
2241 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#lx, %#lx )",
2242 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2243 PRE_REG_READ5(long, "io_getevents",
2244 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2245 struct io_event *, events,
2246 struct timespec *, timeout);
2247 if (ARG3 > 0)
2248 PRE_MEM_WRITE( "io_getevents(events)",
2249 ARG4, sizeof(struct vki_io_event)*ARG3 );
2250 if (ARG5 != 0)
2251 PRE_MEM_READ( "io_getevents(timeout)",
2252 ARG5, sizeof(struct vki_timespec));
2254 POST(sys_io_getevents)
2256 Int i;
2257 vg_assert(SUCCESS);
2258 if (RES > 0) {
2259 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2260 for (i = 0; i < RES; i++) {
2261 const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
2262 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2264 switch (cb->aio_lio_opcode) {
2265 case VKI_IOCB_CMD_PREAD:
2266 if (vev->result > 0)
2267 POST_MEM_WRITE( cb->aio_buf, vev->result );
2268 break;
2270 case VKI_IOCB_CMD_PWRITE:
2271 break;
2273 case VKI_IOCB_CMD_FSYNC:
2274 break;
2276 case VKI_IOCB_CMD_FDSYNC:
2277 break;
2279 case VKI_IOCB_CMD_PREADV:
2280 if (vev->result > 0) {
2281 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2282 Int remains = vev->result;
2283 Int j;
2285 for (j = 0; j < cb->aio_nbytes; j++) {
2286 Int nReadThisBuf = vec[j].iov_len;
2287 if (nReadThisBuf > remains) nReadThisBuf = remains;
2288 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2289 remains -= nReadThisBuf;
2290 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2293 break;
2295 case VKI_IOCB_CMD_PWRITEV:
2296 break;
2298 default:
2299 VG_(message)(Vg_DebugMsg,
2300 "Warning: unhandled io_getevents opcode: %u\n",
2301 cb->aio_lio_opcode);
2302 break;
2308 PRE(sys_io_submit)
2310 Int i, j;
2312 PRINT("sys_io_submit ( %lu, %ld, %#lx )", ARG1, SARG2, ARG3);
2313 PRE_REG_READ3(long, "io_submit",
2314 vki_aio_context_t, ctx_id, long, nr,
2315 struct iocb **, iocbpp);
2316 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2317 if (ARG3 != 0) {
2318 for (i = 0; i < ARG2; i++) {
2319 struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
2320 struct vki_iovec *iov;
2322 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2323 switch (cb->aio_lio_opcode) {
2324 case VKI_IOCB_CMD_PREAD:
2325 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2326 break;
2328 case VKI_IOCB_CMD_PWRITE:
2329 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2330 break;
2332 case VKI_IOCB_CMD_FSYNC:
2333 break;
2335 case VKI_IOCB_CMD_FDSYNC:
2336 break;
2338 case VKI_IOCB_CMD_PREADV:
2339 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2340 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2341 for (j = 0; j < cb->aio_nbytes; j++)
2342 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2343 break;
2345 case VKI_IOCB_CMD_PWRITEV:
2346 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2347 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2348 for (j = 0; j < cb->aio_nbytes; j++)
2349 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2350 break;
2352 default:
2353 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2354 cb->aio_lio_opcode);
2355 break;
2361 PRE(sys_io_cancel)
2363 PRINT("sys_io_cancel ( %llu, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3);
2364 PRE_REG_READ3(long, "io_cancel",
2365 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2366 struct io_event *, result);
2367 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2368 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2370 POST(sys_io_cancel)
2372 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2375 /* ---------------------------------------------------------------------
2376 *_mempolicy wrappers
2377 ------------------------------------------------------------------ */
2379 PRE(sys_mbind)
2381 PRINT("sys_mbind ( %#lx, %lu, %lu, %#lx, %lu, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
2382 PRE_REG_READ6(long, "mbind",
2383 unsigned long, start, unsigned long, len,
2384 unsigned long, policy, unsigned long *, nodemask,
2385 unsigned long, maxnode, unsigned, flags);
2386 if (ARG1 != 0)
2387 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2388 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2391 PRE(sys_set_mempolicy)
2393 PRINT("sys_set_mempolicy ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
2394 PRE_REG_READ3(long, "set_mempolicy",
2395 int, policy, unsigned long *, nodemask,
2396 unsigned long, maxnode);
2397 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2398 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2401 PRE(sys_get_mempolicy)
2403 PRINT("sys_get_mempolicy ( %#lx, %#lx, %lu, %#lx, %lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
2404 PRE_REG_READ5(long, "get_mempolicy",
2405 int *, policy, unsigned long *, nodemask,
2406 unsigned long, maxnode, unsigned long, addr,
2407 unsigned long, flags);
2408 if (ARG1 != 0)
2409 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2410 if (ARG2 != 0)
2411 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2412 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2414 POST(sys_get_mempolicy)
2416 if (ARG1 != 0)
2417 POST_MEM_WRITE( ARG1, sizeof(Int) );
2418 if (ARG2 != 0)
2419 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2422 /* ---------------------------------------------------------------------
2423 fanotify_* wrappers
2424 ------------------------------------------------------------------ */
2426 PRE(sys_fanotify_init)
2428 PRINT("sys_fanotify_init ( %lu, %lu )", ARG1,ARG2);
2429 PRE_REG_READ2(long, "fanotify_init",
2430 unsigned int, flags, unsigned int, event_f_flags);
2433 POST(sys_fanotify_init)
2435 vg_assert(SUCCESS);
2436 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2437 VG_(close)(RES);
2438 SET_STATUS_Failure( VKI_EMFILE );
2439 } else {
2440 if (VG_(clo_track_fds))
2441 ML_(record_fd_open_nameless) (tid, RES);
2445 PRE(sys_fanotify_mark)
2447 #if VG_WORDSIZE == 4
2448 PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
2449 SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6, (HChar *)ARG6);
2450 PRE_REG_READ6(long, "sys_fanotify_mark",
2451 int, fanotify_fd, unsigned int, flags,
2452 __vki_u32, mask0, __vki_u32, mask1,
2453 int, dfd, const char *, pathname);
2454 if (ARG6)
2455 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2456 #elif VG_WORDSIZE == 8
2457 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2458 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)ARG5);
2459 PRE_REG_READ5(long, "sys_fanotify_mark",
2460 int, fanotify_fd, unsigned int, flags,
2461 __vki_u64, mask,
2462 int, dfd, const char *, pathname);
2463 if (ARG5)
2464 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2465 #else
2466 # error Unexpected word size
2467 #endif
2470 /* ---------------------------------------------------------------------
2471 inotify_* wrappers
2472 ------------------------------------------------------------------ */
2474 PRE(sys_inotify_init)
2476 PRINT("sys_inotify_init ( )");
2477 PRE_REG_READ0(long, "inotify_init");
2479 POST(sys_inotify_init)
2481 vg_assert(SUCCESS);
2482 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2483 VG_(close)(RES);
2484 SET_STATUS_Failure( VKI_EMFILE );
2485 } else {
2486 if (VG_(clo_track_fds))
2487 ML_(record_fd_open_nameless) (tid, RES);
2491 PRE(sys_inotify_init1)
2493 PRINT("sys_inotify_init ( %ld )", SARG1);
2494 PRE_REG_READ1(long, "inotify_init", int, flag);
2497 POST(sys_inotify_init1)
2499 vg_assert(SUCCESS);
2500 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2501 VG_(close)(RES);
2502 SET_STATUS_Failure( VKI_EMFILE );
2503 } else {
2504 if (VG_(clo_track_fds))
2505 ML_(record_fd_open_nameless) (tid, RES);
2509 PRE(sys_inotify_add_watch)
2511 PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", SARG1, ARG2, ARG3);
2512 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2513 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2516 PRE(sys_inotify_rm_watch)
2518 PRINT( "sys_inotify_rm_watch ( %ld, %lx )", SARG1, ARG2);
2519 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2522 /* ---------------------------------------------------------------------
2523 mq_* wrappers
2524 ------------------------------------------------------------------ */
2526 PRE(sys_mq_open)
2528 PRINT("sys_mq_open( %#lx(%s), %ld, %lu, %#lx )",
2529 ARG1, (HChar*)ARG1, SARG2, ARG3, ARG4);
2530 PRE_REG_READ4(long, "mq_open",
2531 const char *, name, int, oflag, vki_mode_t, mode,
2532 struct mq_attr *, attr);
2533 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2534 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2535 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
2536 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2537 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2538 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2539 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2542 POST(sys_mq_open)
2544 vg_assert(SUCCESS);
2545 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2546 VG_(close)(RES);
2547 SET_STATUS_Failure( VKI_EMFILE );
2548 } else {
2549 if (VG_(clo_track_fds))
2550 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
2554 PRE(sys_mq_unlink)
2556 PRINT("sys_mq_unlink ( %#lx(%s) )", ARG1,(char*)ARG1);
2557 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2558 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2561 PRE(sys_mq_timedsend)
2563 *flags |= SfMayBlock;
2564 PRINT("sys_mq_timedsend ( %ld, %#lx, %lu, %lu, %#lx )",
2565 SARG1,ARG2,ARG3,ARG4,ARG5);
2566 PRE_REG_READ5(long, "mq_timedsend",
2567 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2568 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2569 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2570 SET_STATUS_Failure( VKI_EBADF );
2571 } else {
2572 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2573 if (ARG5 != 0)
2574 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2575 sizeof(struct vki_timespec) );
2579 PRE(sys_mq_timedreceive)
2581 *flags |= SfMayBlock;
2582 PRINT("sys_mq_timedreceive( %ld, %#lx, %lu, %#lx, %#lx )",
2583 SARG1,ARG2,ARG3,ARG4,ARG5);
2584 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2585 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2586 unsigned int *, msg_prio,
2587 const struct timespec *, abs_timeout);
2588 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2589 SET_STATUS_Failure( VKI_EBADF );
2590 } else {
2591 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2592 if (ARG4 != 0)
2593 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2594 ARG4, sizeof(unsigned int) );
2595 if (ARG5 != 0)
2596 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2597 ARG5, sizeof(struct vki_timespec) );
2600 POST(sys_mq_timedreceive)
2602 POST_MEM_WRITE( ARG2, RES );
2603 if (ARG4 != 0)
2604 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2607 PRE(sys_mq_notify)
2609 PRINT("sys_mq_notify( %ld, %#lx )", SARG1, ARG2 );
2610 PRE_REG_READ2(long, "mq_notify",
2611 vki_mqd_t, mqdes, const struct sigevent *, notification);
2612 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2613 SET_STATUS_Failure( VKI_EBADF );
2614 else if (ARG2 != 0)
2615 PRE_MEM_READ( "mq_notify(notification)",
2616 ARG2, sizeof(struct vki_sigevent) );
2619 PRE(sys_mq_getsetattr)
2621 PRINT("sys_mq_getsetattr( %ld, %#lx, %#lx )", SARG1,ARG2,ARG3 );
2622 PRE_REG_READ3(long, "mq_getsetattr",
2623 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2624 struct mq_attr *, omqstat);
2625 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2626 SET_STATUS_Failure( VKI_EBADF );
2627 } else {
2628 if (ARG2 != 0) {
2629 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
2630 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2631 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2633 if (ARG3 != 0)
2634 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2635 sizeof(struct vki_mq_attr) );
2638 POST(sys_mq_getsetattr)
2640 if (ARG3 != 0)
2641 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2644 /* ---------------------------------------------------------------------
2645 clock_* wrappers
2646 ------------------------------------------------------------------ */
2648 PRE(sys_clock_settime)
2650 PRINT("sys_clock_settime( %ld, %#lx )", SARG1, ARG2);
2651 PRE_REG_READ2(long, "clock_settime",
2652 vki_clockid_t, clk_id, const struct timespec *, tp);
2653 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2656 PRE(sys_clock_gettime)
2658 PRINT("sys_clock_gettime( %ld, %#lx )" , SARG1, ARG2);
2659 PRE_REG_READ2(long, "clock_gettime",
2660 vki_clockid_t, clk_id, struct timespec *, tp);
2661 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2663 POST(sys_clock_gettime)
2665 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2668 PRE(sys_clock_getres)
2670 PRINT("sys_clock_getres( %ld, %#lx )" , SARG1, ARG2);
2671 // Nb: we can't use "RES" as the param name because that's a macro
2672 // defined above!
2673 PRE_REG_READ2(long, "clock_getres",
2674 vki_clockid_t, clk_id, struct timespec *, res);
2675 if (ARG2 != 0)
2676 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2678 POST(sys_clock_getres)
2680 if (ARG2 != 0)
2681 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2684 PRE(sys_clock_nanosleep)
2686 *flags |= SfMayBlock|SfPostOnFail;
2687 PRINT("sys_clock_nanosleep( %ld, %ld, %#lx, %#lx )",
2688 SARG1, SARG2, ARG3, ARG4);
2689 PRE_REG_READ4(int32_t, "clock_nanosleep",
2690 vki_clockid_t, clkid, int, flags,
2691 const struct timespec *, rqtp, struct timespec *, rmtp);
2692 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2693 if (ARG4 != 0)
2694 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2696 POST(sys_clock_nanosleep)
2698 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2699 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2702 /* ---------------------------------------------------------------------
2703 timer_* wrappers
2704 ------------------------------------------------------------------ */
2706 PRE(sys_timer_create)
2708 PRINT("sys_timer_create( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
2709 PRE_REG_READ3(long, "timer_create",
2710 vki_clockid_t, clockid, struct sigevent *, evp,
2711 vki_timer_t *, timerid);
2712 if (ARG2 != 0) {
2713 struct vki_sigevent *evp = (struct vki_sigevent *) ARG2;
2714 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2715 sizeof(vki_sigval_t) );
2716 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2717 sizeof(int) );
2718 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2719 sizeof(int) );
2720 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2721 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2722 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2723 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2725 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2727 POST(sys_timer_create)
2729 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2732 PRE(sys_timer_settime)
2734 PRINT("sys_timer_settime( %ld, %ld, %#lx, %#lx )", SARG1,SARG2,ARG3,ARG4);
2735 PRE_REG_READ4(long, "timer_settime",
2736 vki_timer_t, timerid, int, flags,
2737 const struct itimerspec *, value,
2738 struct itimerspec *, ovalue);
2739 PRE_MEM_READ( "timer_settime(value)", ARG3,
2740 sizeof(struct vki_itimerspec) );
2741 if (ARG4 != 0)
2742 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2743 sizeof(struct vki_itimerspec) );
2745 POST(sys_timer_settime)
2747 if (ARG4 != 0)
2748 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2751 PRE(sys_timer_gettime)
2753 PRINT("sys_timer_gettime( %ld, %#lx )", SARG1, ARG2);
2754 PRE_REG_READ2(long, "timer_gettime",
2755 vki_timer_t, timerid, struct itimerspec *, value);
2756 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2757 sizeof(struct vki_itimerspec));
2759 POST(sys_timer_gettime)
2761 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2764 PRE(sys_timer_getoverrun)
2766 PRINT("sys_timer_getoverrun( %#lx )", ARG1);
2767 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2770 PRE(sys_timer_delete)
2772 PRINT("sys_timer_delete( %#lx )", ARG1);
2773 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2776 /* ---------------------------------------------------------------------
2777 timerfd* wrappers
2778 See also http://lwn.net/Articles/260172/ for an overview.
2779 See also /usr/src/linux/fs/timerfd.c for the implementation.
2780 ------------------------------------------------------------------ */
2782 /* Returns True if running on 2.6.22, else False (or False if
2783 cannot be determined). */
2784 static Bool linux_kernel_2_6_22(void)
2786 static Int result = -1;
2787 Int fd, read;
2788 HChar release[64]; // large enough
2789 SysRes res;
2791 if (result == -1) {
2792 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2793 if (sr_isError(res))
2794 return False;
2795 fd = sr_Res(res);
2796 read = VG_(read)(fd, release, sizeof(release) - 1);
2797 if (read < 0)
2798 return False;
2799 release[read] = 0;
2800 VG_(close)(fd);
2801 //VG_(printf)("kernel release = %s\n", release);
2802 result = VG_(strncmp)(release, "2.6.22", 6) == 0
2803 && ! VG_(isdigit)(release[6]);
2805 vg_assert(result == 0 || result == 1);
2806 return result == 1;
2809 PRE(sys_timerfd_create)
2811 if (linux_kernel_2_6_22()) {
2812 /* 2.6.22 kernel: timerfd system call. */
2813 PRINT("sys_timerfd ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
2814 PRE_REG_READ3(long, "sys_timerfd",
2815 int, fd, int, clockid, const struct itimerspec *, tmr);
2816 PRE_MEM_READ("timerfd(tmr)", ARG3,
2817 sizeof(struct vki_itimerspec) );
2818 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2819 SET_STATUS_Failure( VKI_EBADF );
2820 } else {
2821 /* 2.6.24 and later kernels: timerfd_create system call. */
2822 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2823 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2826 POST(sys_timerfd_create)
2828 if (linux_kernel_2_6_22())
2830 /* 2.6.22 kernel: timerfd system call. */
2831 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2832 VG_(close)(RES);
2833 SET_STATUS_Failure( VKI_EMFILE );
2834 } else {
2835 if (VG_(clo_track_fds))
2836 ML_(record_fd_open_nameless) (tid, RES);
2839 else
2841 /* 2.6.24 and later kernels: timerfd_create system call. */
2842 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2843 VG_(close)(RES);
2844 SET_STATUS_Failure( VKI_EMFILE );
2845 } else {
2846 if (VG_(clo_track_fds))
2847 ML_(record_fd_open_nameless) (tid, RES);
2852 PRE(sys_timerfd_gettime)
2854 PRINT("sys_timerfd_gettime ( %ld, %#lx )", SARG1, ARG2);
2855 PRE_REG_READ2(long, "timerfd_gettime",
2856 int, ufd,
2857 struct vki_itimerspec*, otmr);
2858 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2859 SET_STATUS_Failure(VKI_EBADF);
2860 else
2861 PRE_MEM_WRITE("timerfd_gettime(result)",
2862 ARG2, sizeof(struct vki_itimerspec));
2864 POST(sys_timerfd_gettime)
2866 if (RES == 0)
2867 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2870 PRE(sys_timerfd_settime)
2872 PRINT("sys_timerfd_settime ( %ld, %ld, %#lx, %#lx )",
2873 SARG1, SARG2, ARG3, ARG4);
2874 PRE_REG_READ4(long, "timerfd_settime",
2875 int, ufd,
2876 int, flags,
2877 const struct vki_itimerspec*, utmr,
2878 struct vki_itimerspec*, otmr);
2879 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2880 SET_STATUS_Failure(VKI_EBADF);
2881 else
2883 PRE_MEM_READ("timerfd_settime(result)",
2884 ARG3, sizeof(struct vki_itimerspec));
2885 if (ARG4)
2887 PRE_MEM_WRITE("timerfd_settime(result)",
2888 ARG4, sizeof(struct vki_itimerspec));
2892 POST(sys_timerfd_settime)
2894 if (RES == 0 && ARG4 != 0)
2895 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2898 /* ---------------------------------------------------------------------
2899 capabilities wrappers
2900 ------------------------------------------------------------------ */
2902 PRE(sys_capget)
2904 PRINT("sys_capget ( %#lx, %#lx )", ARG1, ARG2 );
2905 PRE_REG_READ2(long, "capget",
2906 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2907 PRE_MEM_READ( "capget(header)", ARG1,
2908 sizeof(struct __vki_user_cap_header_struct) );
2909 if (ARG2 != (Addr)NULL)
2910 PRE_MEM_WRITE( "capget(data)", ARG2,
2911 sizeof(struct __vki_user_cap_data_struct) );
2913 POST(sys_capget)
2915 if (ARG2 != (Addr)NULL)
2916 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2919 PRE(sys_capset)
2921 PRINT("sys_capset ( %#lx, %#lx )", ARG1, ARG2 );
2922 PRE_REG_READ2(long, "capset",
2923 vki_cap_user_header_t, header,
2924 const vki_cap_user_data_t, data);
2925 PRE_MEM_READ( "capset(header)",
2926 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2927 PRE_MEM_READ( "capset(data)",
2928 ARG2, sizeof(struct __vki_user_cap_data_struct) );
2931 /* ---------------------------------------------------------------------
2932 16-bit uid/gid/groups wrappers
2933 ------------------------------------------------------------------ */
2935 PRE(sys_getuid16)
2937 PRINT("sys_getuid16 ( )");
2938 PRE_REG_READ0(long, "getuid16");
2941 PRE(sys_setuid16)
2943 PRINT("sys_setuid16 ( %lu )", ARG1);
2944 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
2947 PRE(sys_getgid16)
2949 PRINT("sys_getgid16 ( )");
2950 PRE_REG_READ0(long, "getgid16");
2953 PRE(sys_setgid16)
2955 PRINT("sys_setgid16 ( %lu )", ARG1);
2956 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
2959 PRE(sys_geteuid16)
2961 PRINT("sys_geteuid16 ( )");
2962 PRE_REG_READ0(long, "geteuid16");
2965 PRE(sys_getegid16)
2967 PRINT("sys_getegid16 ( )");
2968 PRE_REG_READ0(long, "getegid16");
2971 PRE(sys_setreuid16)
2973 PRINT("setreuid16 ( 0x%lx, 0x%lx )", ARG1, ARG2);
2974 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
2977 PRE(sys_setregid16)
2979 PRINT("sys_setregid16 ( %lu, %lu )", ARG1, ARG2);
2980 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2983 PRE(sys_getgroups16)
2985 PRINT("sys_getgroups16 ( %ld, %#lx )", SARG1, ARG2);
2986 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2987 if (ARG1 > 0)
2988 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2990 POST(sys_getgroups16)
2992 vg_assert(SUCCESS);
2993 if (ARG1 > 0 && RES > 0)
2994 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2997 PRE(sys_setgroups16)
2999 PRINT("sys_setgroups16 ( %llu, %#lx )", (ULong)ARG1, ARG2);
3000 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3001 if (ARG1 > 0)
3002 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3005 /* ---------------------------------------------------------------------
3006 *chown16 wrappers
3007 ------------------------------------------------------------------ */
3009 PRE(sys_chown16)
3011 PRINT("sys_chown16 ( %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3);
3012 PRE_REG_READ3(long, "chown16",
3013 const char *, path,
3014 vki_old_uid_t, owner, vki_old_gid_t, group);
3015 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3018 PRE(sys_fchown16)
3020 PRINT("sys_fchown16 ( %lu, %lu, %lu )", ARG1,ARG2,ARG3);
3021 PRE_REG_READ3(long, "fchown16",
3022 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3025 /* ---------------------------------------------------------------------
3026 *xattr wrappers
3027 ------------------------------------------------------------------ */
3029 PRE(sys_setxattr)
3031 *flags |= SfMayBlock;
3032 PRINT("sys_setxattr ( %#lx, %#lx, %#lx, %lu, %ld )",
3033 ARG1, ARG2, ARG3, ARG4, SARG5);
3034 PRE_REG_READ5(long, "setxattr",
3035 char *, path, char *, name,
3036 void *, value, vki_size_t, size, int, flags);
3037 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3038 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3039 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3042 PRE(sys_lsetxattr)
3044 *flags |= SfMayBlock;
3045 PRINT("sys_lsetxattr ( %#lx, %#lx, %#lx, %lu, %ld )",
3046 ARG1, ARG2, ARG3, ARG4, SARG5);
3047 PRE_REG_READ5(long, "lsetxattr",
3048 char *, path, char *, name,
3049 void *, value, vki_size_t, size, int, flags);
3050 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3051 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3052 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3055 PRE(sys_fsetxattr)
3057 *flags |= SfMayBlock;
3058 PRINT("sys_fsetxattr ( %ld, %#lx, %#lx, %lu, %ld )",
3059 SARG1, ARG2, ARG3, ARG4, SARG5);
3060 PRE_REG_READ5(long, "fsetxattr",
3061 int, fd, char *, name, void *, value,
3062 vki_size_t, size, int, flags);
3063 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3064 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3067 PRE(sys_getxattr)
3069 *flags |= SfMayBlock;
3070 PRINT("sys_getxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
3071 PRE_REG_READ4(ssize_t, "getxattr",
3072 char *, path, char *, name, void *, value, vki_size_t, size);
3073 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3074 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3075 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3077 POST(sys_getxattr)
3079 vg_assert(SUCCESS);
3080 if (RES > 0 && ARG3 != (Addr)NULL) {
3081 POST_MEM_WRITE( ARG3, RES );
3085 PRE(sys_lgetxattr)
3087 *flags |= SfMayBlock;
3088 PRINT("sys_lgetxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
3089 PRE_REG_READ4(ssize_t, "lgetxattr",
3090 char *, path, char *, name, void *, value, vki_size_t, size);
3091 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3092 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3093 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3095 POST(sys_lgetxattr)
3097 vg_assert(SUCCESS);
3098 if (RES > 0 && ARG3 != (Addr)NULL) {
3099 POST_MEM_WRITE( ARG3, RES );
3103 PRE(sys_fgetxattr)
3105 *flags |= SfMayBlock;
3106 PRINT("sys_fgetxattr ( %ld, %#lx, %#lx, %lu )", SARG1, ARG2, ARG3, ARG4);
3107 PRE_REG_READ4(ssize_t, "fgetxattr",
3108 int, fd, char *, name, void *, value, vki_size_t, size);
3109 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3110 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3112 POST(sys_fgetxattr)
3114 if (RES > 0 && ARG3 != (Addr)NULL)
3115 POST_MEM_WRITE( ARG3, RES );
3118 PRE(sys_listxattr)
3120 *flags |= SfMayBlock;
3121 PRINT("sys_listxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
3122 PRE_REG_READ3(ssize_t, "listxattr",
3123 char *, path, char *, list, vki_size_t, size);
3124 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3125 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3127 POST(sys_listxattr)
3129 if (RES > 0 && ARG2 != (Addr)NULL)
3130 POST_MEM_WRITE( ARG2, RES );
3133 PRE(sys_llistxattr)
3135 *flags |= SfMayBlock;
3136 PRINT("sys_llistxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
3137 PRE_REG_READ3(ssize_t, "llistxattr",
3138 char *, path, char *, list, vki_size_t, size);
3139 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3140 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3142 POST(sys_llistxattr)
3144 if (RES > 0 && ARG2 != (Addr)NULL)
3145 POST_MEM_WRITE( ARG2, RES );
3148 PRE(sys_flistxattr)
3150 *flags |= SfMayBlock;
3151 PRINT("sys_flistxattr ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
3152 PRE_REG_READ3(ssize_t, "flistxattr",
3153 int, fd, char *, list, vki_size_t, size);
3154 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3156 POST(sys_flistxattr)
3158 if (RES > 0 && ARG2 != (Addr)NULL)
3159 POST_MEM_WRITE( ARG2, RES );
3162 PRE(sys_removexattr)
3164 *flags |= SfMayBlock;
3165 PRINT("sys_removexattr ( %#lx, %#lx )", ARG1, ARG2);
3166 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3167 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3168 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3171 PRE(sys_lremovexattr)
3173 *flags |= SfMayBlock;
3174 PRINT("sys_lremovexattr ( %#lx, %#lx )", ARG1, ARG2);
3175 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3176 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3177 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3180 PRE(sys_fremovexattr)
3182 *flags |= SfMayBlock;
3183 PRINT("sys_fremovexattr ( %ld, %#lx )", SARG1, ARG2);
3184 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3185 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3188 /* ---------------------------------------------------------------------
3189 sched_* wrappers
3190 ------------------------------------------------------------------ */
3192 PRE(sys_sched_setparam)
3194 PRINT("sched_setparam ( %ld, %#lx )", SARG1, ARG2 );
3195 PRE_REG_READ2(long, "sched_setparam",
3196 vki_pid_t, pid, struct sched_param *, p);
3197 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3199 POST(sys_sched_setparam)
3201 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3204 PRE(sys_sched_getparam)
3206 PRINT("sched_getparam ( %ld, %#lx )", SARG1, ARG2 );
3207 PRE_REG_READ2(long, "sched_getparam",
3208 vki_pid_t, pid, struct sched_param *, p);
3209 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3211 POST(sys_sched_getparam)
3213 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3216 PRE(sys_sched_getscheduler)
3218 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3219 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3222 PRE(sys_sched_setscheduler)
3224 PRINT("sys_sched_setscheduler ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
3225 PRE_REG_READ3(long, "sched_setscheduler",
3226 vki_pid_t, pid, int, policy, struct sched_param *, p);
3227 if (ARG3 != 0)
3228 PRE_MEM_READ( "sched_setscheduler(p)",
3229 ARG3, sizeof(struct vki_sched_param));
3232 PRE(sys_sched_yield)
3234 *flags |= SfMayBlock;
3235 PRINT("sched_yield()");
3236 PRE_REG_READ0(long, "sys_sched_yield");
3239 PRE(sys_sched_get_priority_max)
3241 PRINT("sched_get_priority_max ( %ld )", SARG1);
3242 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3245 PRE(sys_sched_get_priority_min)
3247 PRINT("sched_get_priority_min ( %ld )", SARG1);
3248 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3251 PRE(sys_sched_rr_get_interval)
3253 PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", SARG1, ARG2);
3254 PRE_REG_READ2(int, "sched_rr_get_interval",
3255 vki_pid_t, pid,
3256 struct vki_timespec *, tp);
3257 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3258 ARG2, sizeof(struct vki_timespec));
3261 POST(sys_sched_rr_get_interval)
3263 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3266 PRE(sys_sched_setaffinity)
3268 PRINT("sched_setaffinity ( %ld, %lu, %#lx )", SARG1, ARG2, ARG3);
3269 PRE_REG_READ3(long, "sched_setaffinity",
3270 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3271 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3274 PRE(sys_sched_getaffinity)
3276 PRINT("sched_getaffinity ( %ld, %lu, %#lx )", SARG1, ARG2, ARG3);
3277 PRE_REG_READ3(long, "sched_getaffinity",
3278 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3279 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3281 POST(sys_sched_getaffinity)
3283 POST_MEM_WRITE(ARG3, ARG2);
3286 PRE(sys_unshare)
3288 PRINT("sys_unshare ( %#lx )", ARG1);
3289 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3292 /* ---------------------------------------------------------------------
3293 miscellaneous wrappers
3294 ------------------------------------------------------------------ */
3296 PRE(sys_munlockall)
3298 *flags |= SfMayBlock;
3299 PRINT("sys_munlockall ( )");
3300 PRE_REG_READ0(long, "munlockall");
3303 // This has different signatures for different platforms.
3305 // x86: int sys_pipe(unsigned long __user *fildes);
3306 // AMD64: long sys_pipe(int *fildes);
3307 // ppc32: int sys_pipe(int __user *fildes);
3308 // ppc64: int sys_pipe(int __user *fildes);
3310 // The type of the argument is most important, and it is an array of 32 bit
3311 // values in all cases. (The return type differs across platforms, but it
3312 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3313 // was caused by using an array of 'unsigned long's, which didn't work on
3314 // AMD64.
3315 PRE(sys_pipe)
3317 PRINT("sys_pipe ( %#lx )", ARG1);
3318 PRE_REG_READ1(int, "pipe", int *, filedes);
3319 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3321 POST(sys_pipe)
3323 Int *p = (Int *)ARG1;
3324 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3325 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3326 VG_(close)(p[0]);
3327 VG_(close)(p[1]);
3328 SET_STATUS_Failure( VKI_EMFILE );
3329 } else {
3330 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3331 if (VG_(clo_track_fds)) {
3332 ML_(record_fd_open_nameless)(tid, p[0]);
3333 ML_(record_fd_open_nameless)(tid, p[1]);
3338 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3339 there's a second arg containing flags to be applied to the new file
3340 descriptors. It hardly seems worth the effort to factor out the
3341 duplicated code, hence: */
3342 PRE(sys_pipe2)
3344 PRINT("sys_pipe2 ( %#lx, %#lx )", ARG1, ARG2);
3345 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3346 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3348 POST(sys_pipe2)
3350 Int *p = (Int *)ARG1;
3351 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3352 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3353 VG_(close)(p[0]);
3354 VG_(close)(p[1]);
3355 SET_STATUS_Failure( VKI_EMFILE );
3356 } else {
3357 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3358 if (VG_(clo_track_fds)) {
3359 ML_(record_fd_open_nameless)(tid, p[0]);
3360 ML_(record_fd_open_nameless)(tid, p[1]);
3365 PRE(sys_dup3)
3367 PRINT("sys_dup3 ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
3368 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3369 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3370 SET_STATUS_Failure( VKI_EBADF );
3373 POST(sys_dup3)
3375 vg_assert(SUCCESS);
3376 if (VG_(clo_track_fds))
3377 ML_(record_fd_open_named)(tid, RES);
3380 PRE(sys_quotactl)
3382 PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
3383 PRE_REG_READ4(long, "quotactl",
3384 unsigned int, cmd, const char *, special, vki_qid_t, id,
3385 void *, addr);
3386 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3389 PRE(sys_waitid)
3391 *flags |= SfMayBlock;
3392 PRINT("sys_waitid( %ld, %ld, %#lx, %ld, %#lx )",
3393 SARG1, SARG2, ARG3, SARG4, ARG5);
3394 PRE_REG_READ5(int32_t, "sys_waitid",
3395 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3396 int, options, struct vki_rusage *, ru);
3397 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3398 if (ARG5 != 0)
3399 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3401 POST(sys_waitid)
3403 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3404 if (ARG5 != 0)
3405 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3408 PRE(sys_sync_file_range)
3410 *flags |= SfMayBlock;
3411 #if VG_WORDSIZE == 4
3412 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#lx )",
3413 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3414 PRE_REG_READ6(long, "sync_file_range",
3415 int, fd,
3416 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3417 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3418 unsigned int, flags);
3419 #elif VG_WORDSIZE == 8
3420 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3421 SARG1, SARG2, SARG3, ARG4);
3422 PRE_REG_READ4(long, "sync_file_range",
3423 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3424 unsigned int, flags);
3425 #else
3426 # error Unexpected word size
3427 #endif
3428 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3429 SET_STATUS_Failure( VKI_EBADF );
3432 PRE(sys_sync_file_range2)
3434 *flags |= SfMayBlock;
3435 #if VG_WORDSIZE == 4
3436 PRINT("sys_sync_file_range2 ( %ld, %lu, %lld, %lld )",
3437 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3438 PRE_REG_READ6(long, "sync_file_range2",
3439 int, fd, unsigned int, flags,
3440 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3441 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3442 #elif VG_WORDSIZE == 8
3443 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3444 SARG1, ARG2, SARG3, SARG4);
3445 PRE_REG_READ4(long, "sync_file_range2",
3446 int, fd, unsigned int, flags,
3447 vki_loff_t, offset, vki_loff_t, nbytes);
3448 #else
3449 # error Unexpected word size
3450 #endif
3451 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3452 SET_STATUS_Failure( VKI_EBADF );
3455 PRE(sys_stime)
3457 PRINT("sys_stime ( %#lx )", ARG1);
3458 PRE_REG_READ1(int, "stime", vki_time_t*, t);
3459 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3462 PRE(sys_perf_event_open)
3464 struct vki_perf_event_attr *attr;
3465 PRINT("sys_perf_event_open ( %#lx, %ld, %ld, %ld, %#lx )",
3466 ARG1, SARG2, SARG3, SARG4, ARG5);
3467 PRE_REG_READ5(long, "perf_event_open",
3468 struct vki_perf_event_attr *, attr,
3469 vki_pid_t, pid, int, cpu, int, group_fd,
3470 unsigned long, flags);
3471 attr = (struct vki_perf_event_attr *)ARG1;
3472 PRE_MEM_READ( "perf_event_open(attr->size)",
3473 (Addr)&attr->size, sizeof(attr->size) );
3474 PRE_MEM_READ( "perf_event_open(attr)",
3475 (Addr)attr, attr->size );
3478 POST(sys_perf_event_open)
3480 vg_assert(SUCCESS);
3481 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3482 VG_(close)(RES);
3483 SET_STATUS_Failure( VKI_EMFILE );
3484 } else {
3485 if (VG_(clo_track_fds))
3486 ML_(record_fd_open_nameless)(tid, RES);
3490 PRE(sys_getcpu)
3492 PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
3493 PRE_REG_READ3(int, "getcpu",
3494 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3495 if (ARG1 != 0)
3496 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3497 if (ARG2 != 0)
3498 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3499 if (ARG3 != 0)
3500 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3503 POST(sys_getcpu)
3505 if (ARG1 != 0)
3506 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3507 if (ARG2 != 0)
3508 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3509 if (ARG3 != 0)
3510 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3513 PRE(sys_move_pages)
3515 PRINT("sys_move_pages ( %ld, %lu, %#lx, %#lx, %#lx, %#lx )",
3516 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3517 PRE_REG_READ6(int, "move_pages",
3518 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3519 const int *, nodes, int *, status, int, flags);
3520 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3521 if (ARG4)
3522 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3523 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3526 POST(sys_move_pages)
3528 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3531 PRE(sys_getrandom)
3533 PRINT("sys_getrandom ( %#lx, %lu, %lu )" , ARG1, ARG2, ARG3);
3534 PRE_REG_READ3(int, "getrandom",
3535 char *, buf, vki_size_t, count, unsigned int, flags);
3536 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3539 POST(sys_getrandom)
3541 POST_MEM_WRITE( ARG1, ARG2 );
3544 PRE(sys_memfd_create)
3546 PRINT("sys_memfd_create ( %#lx, %lu )" , ARG1, ARG2);
3547 PRE_REG_READ2(int, "memfd_create",
3548 char *, uname, unsigned int, flags);
3549 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3552 POST(sys_memfd_create)
3554 vg_assert(SUCCESS);
3555 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3556 VG_(close)(RES);
3557 SET_STATUS_Failure( VKI_EMFILE );
3558 } else {
3559 if (VG_(clo_track_fds))
3560 ML_(record_fd_open_nameless)(tid, RES);
3564 PRE(sys_syncfs)
3566 *flags |= SfMayBlock;
3567 PRINT("sys_syncfs ( %lu )", ARG1);
3568 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3571 /* ---------------------------------------------------------------------
3572 utime wrapper
3573 ------------------------------------------------------------------ */
3575 PRE(sys_utime)
3577 *flags |= SfMayBlock;
3578 PRINT("sys_utime ( %#lx, %#lx )", ARG1,ARG2);
3579 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3580 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3581 if (ARG2 != 0)
3582 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3585 /* ---------------------------------------------------------------------
3586 lseek wrapper
3587 ------------------------------------------------------------------ */
3589 PRE(sys_lseek)
3591 PRINT("sys_lseek ( %lu, %ld, %lu )", ARG1, SARG2, ARG3);
3592 PRE_REG_READ3(vki_off_t, "lseek",
3593 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3596 /* ---------------------------------------------------------------------
3597 readahead wrapper
3598 ------------------------------------------------------------------ */
3600 PRE(sys_readahead)
3602 *flags |= SfMayBlock;
3603 #if VG_WORDSIZE == 4
3604 PRINT("sys_readahead ( %ld, %lld, %lu )",
3605 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3606 PRE_REG_READ4(vki_off_t, "readahead",
3607 int, fd, unsigned, MERGE64_FIRST(offset),
3608 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3609 #elif VG_WORDSIZE == 8
3610 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3611 PRE_REG_READ3(vki_off_t, "readahead",
3612 int, fd, vki_loff_t, offset, vki_size_t, count);
3613 #else
3614 # error Unexpected word size
3615 #endif
3616 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3617 SET_STATUS_Failure( VKI_EBADF );
3620 /* ---------------------------------------------------------------------
3621 sig* wrappers
3622 ------------------------------------------------------------------ */
3624 PRE(sys_sigpending)
3626 PRINT( "sys_sigpending ( %#lx )", ARG1 );
3627 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3628 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3630 POST(sys_sigpending)
3632 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3635 // This syscall is not used on amd64/Linux -- it only provides
3636 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3637 // This wrapper is only suitable for 32-bit architectures.
3638 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3639 // conditional compilation like this?)
3640 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3641 || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
3642 PRE(sys_sigprocmask)
3644 vki_old_sigset_t* set;
3645 vki_old_sigset_t* oldset;
3646 vki_sigset_t bigger_set;
3647 vki_sigset_t bigger_oldset;
3649 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3650 PRE_REG_READ3(long, "sigprocmask",
3651 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3652 if (ARG2 != 0)
3653 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3654 if (ARG3 != 0)
3655 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3657 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3658 // vki_sigset_t params.
3659 set = (vki_old_sigset_t*)ARG2;
3660 oldset = (vki_old_sigset_t*)ARG3;
3662 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
3663 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3664 if (set)
3665 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3667 SET_STATUS_from_SysRes(
3668 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3669 set ? &bigger_set : NULL,
3670 oldset ? &bigger_oldset : NULL)
3673 if (oldset)
3674 *oldset = bigger_oldset.sig[0];
3676 if (SUCCESS)
3677 *flags |= SfPollAfter;
3679 POST(sys_sigprocmask)
3681 vg_assert(SUCCESS);
3682 if (RES == 0 && ARG3 != 0)
3683 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3686 /* Convert from non-RT to RT sigset_t's */
3687 static
3688 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3690 VG_(sigemptyset)(set);
3691 set->sig[0] = *oldset;
3693 PRE(sys_sigaction)
3695 vki_sigaction_toK_t new, *newp;
3696 vki_sigaction_fromK_t old, *oldp;
3698 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3699 PRE_REG_READ3(int, "sigaction",
3700 int, signum, const struct old_sigaction *, act,
3701 struct old_sigaction *, oldact);
3703 newp = oldp = NULL;
3705 if (ARG2 != 0) {
3706 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
3707 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3708 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3709 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3710 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3711 && (sa->sa_flags & VKI_SA_RESTORER))
3712 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3715 if (ARG3 != 0) {
3716 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3717 oldp = &old;
3720 /* If the new or old sigaction is not NULL, but the structs
3721 aren't accessible then sigaction returns EFAULT and we cannot
3722 use either struct for our own bookkeeping. Just fail early. */
3723 if (ARG2 != 0
3724 && ! ML_(safe_to_deref)((void *)ARG2,
3725 sizeof(struct vki_old_sigaction))) {
3726 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3727 (void *)ARG2);
3728 SET_STATUS_Failure ( VKI_EFAULT );
3729 } else if ((ARG3 != 0
3730 && ! ML_(safe_to_deref)((void *)ARG3,
3731 sizeof(struct vki_old_sigaction)))) {
3732 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3733 (void *)ARG3);
3734 SET_STATUS_Failure ( VKI_EFAULT );
3735 } else {
3736 if (ARG2 != 0) {
3737 struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
3739 new.ksa_handler = oldnew->ksa_handler;
3740 new.sa_flags = oldnew->sa_flags;
3741 new.sa_restorer = oldnew->sa_restorer;
3742 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3743 newp = &new;
3746 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3748 if (ARG3 != 0 && SUCCESS && RES == 0) {
3749 struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
3751 oldold->ksa_handler = oldp->ksa_handler;
3752 oldold->sa_flags = oldp->sa_flags;
3753 oldold->sa_restorer = oldp->sa_restorer;
3754 oldold->sa_mask = oldp->sa_mask.sig[0];
3758 POST(sys_sigaction)
3760 vg_assert(SUCCESS);
3761 if (RES == 0 && ARG3 != 0)
3762 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3764 #endif
3766 PRE(sys_signalfd)
3768 PRINT("sys_signalfd ( %d, %#lx, %llu )", (Int)ARG1,ARG2,(ULong)ARG3);
3769 PRE_REG_READ3(long, "sys_signalfd",
3770 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3771 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3772 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3773 SET_STATUS_Failure( VKI_EBADF );
3775 POST(sys_signalfd)
3777 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3778 VG_(close)(RES);
3779 SET_STATUS_Failure( VKI_EMFILE );
3780 } else {
3781 if (VG_(clo_track_fds))
3782 ML_(record_fd_open_nameless) (tid, RES);
3786 PRE(sys_signalfd4)
3788 PRINT("sys_signalfd4 ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
3789 PRE_REG_READ4(long, "sys_signalfd4",
3790 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3791 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3792 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3793 SET_STATUS_Failure( VKI_EBADF );
3795 POST(sys_signalfd4)
3797 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3798 VG_(close)(RES);
3799 SET_STATUS_Failure( VKI_EMFILE );
3800 } else {
3801 if (VG_(clo_track_fds))
3802 ML_(record_fd_open_nameless) (tid, RES);
3807 /* ---------------------------------------------------------------------
3808 rt_sig* wrappers
3809 ------------------------------------------------------------------ */
3811 PRE(sys_rt_sigaction)
3813 PRINT("sys_rt_sigaction ( %ld, %#lx, %#lx, %lu )", SARG1, ARG2, ARG3, ARG4);
3814 PRE_REG_READ4(long, "rt_sigaction",
3815 int, signum, const struct sigaction *, act,
3816 struct sigaction *, oldact, vki_size_t, sigsetsize);
3818 if (ARG2 != 0) {
3819 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
3820 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3821 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3822 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3823 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3824 && (sa->sa_flags & VKI_SA_RESTORER))
3825 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3827 if (ARG3 != 0)
3828 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3830 /* If the new or old sigaction is not NULL, but the structs
3831 aren't accessible then sigaction returns EFAULT and we cannot
3832 use either struct for our own bookkeeping. Just fail early. */
3833 if (ARG2 != 0
3834 && ! ML_(safe_to_deref)((void *)ARG2,
3835 sizeof(vki_sigaction_toK_t))) {
3836 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3837 (void *)ARG2);
3838 SET_STATUS_Failure ( VKI_EFAULT );
3839 } else if ((ARG3 != 0
3840 && ! ML_(safe_to_deref)((void *)ARG3,
3841 sizeof(vki_sigaction_fromK_t)))) {
3842 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3843 (void *)ARG3);
3844 SET_STATUS_Failure ( VKI_EFAULT );
3845 } else {
3847 // XXX: doesn't seem right to be calling do_sys_sigaction for
3848 // sys_rt_sigaction... perhaps this function should be renamed
3849 // VG_(do_sys_rt_sigaction)() --njn
3851 SET_STATUS_from_SysRes(
3852 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
3853 (vki_sigaction_fromK_t *)ARG3)
3857 POST(sys_rt_sigaction)
3859 vg_assert(SUCCESS);
3860 if (RES == 0 && ARG3 != 0)
3861 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3864 PRE(sys_rt_sigprocmask)
3866 PRINT("sys_rt_sigprocmask ( %ld, %#lx, %#lx, %lu )",
3867 SARG1, ARG2, ARG3, ARG4);
3868 PRE_REG_READ4(long, "rt_sigprocmask",
3869 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3870 vki_size_t, sigsetsize);
3871 if (ARG2 != 0)
3872 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3873 if (ARG3 != 0)
3874 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3876 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3877 // Since we want to use the set and oldset for bookkeeping we also want
3878 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
3879 if (sizeof(vki_sigset_t) != ARG4)
3880 SET_STATUS_Failure( VKI_EINVAL );
3881 else if (ARG2 != 0
3882 && ! ML_(safe_to_deref)((void *)ARG2, sizeof(vki_sigset_t))) {
3883 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
3884 (void *)ARG2);
3885 SET_STATUS_Failure ( VKI_EFAULT );
3887 else if (ARG3 != 0
3888 && ! ML_(safe_to_deref)((void *)ARG3, sizeof(vki_sigset_t))) {
3889 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
3890 (void *)ARG3);
3891 SET_STATUS_Failure ( VKI_EFAULT );
3894 else {
3895 SET_STATUS_from_SysRes(
3896 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3897 (vki_sigset_t*) ARG2,
3898 (vki_sigset_t*) ARG3 )
3902 if (SUCCESS)
3903 *flags |= SfPollAfter;
3905 POST(sys_rt_sigprocmask)
3907 vg_assert(SUCCESS);
3908 if (RES == 0 && ARG3 != 0)
3909 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3912 PRE(sys_rt_sigpending)
3914 PRINT( "sys_rt_sigpending ( %#lx )", ARG1 );
3915 PRE_REG_READ2(long, "rt_sigpending",
3916 vki_sigset_t *, set, vki_size_t, sigsetsize);
3917 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
3919 POST(sys_rt_sigpending)
3921 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3924 PRE(sys_rt_sigtimedwait)
3926 *flags |= SfMayBlock;
3927 PRINT("sys_rt_sigtimedwait ( %#lx, %#lx, %#lx, %lu )",
3928 ARG1, ARG2, ARG3, ARG4);
3929 PRE_REG_READ4(long, "rt_sigtimedwait",
3930 const vki_sigset_t *, set, vki_siginfo_t *, info,
3931 const struct timespec *, timeout, vki_size_t, sigsetsize);
3932 if (ARG1 != 0)
3933 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
3934 if (ARG2 != 0)
3935 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3936 if (ARG3 != 0)
3937 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
3938 ARG3, sizeof(struct vki_timespec) );
3940 POST(sys_rt_sigtimedwait)
3942 if (ARG2 != 0)
3943 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3946 PRE(sys_rt_sigqueueinfo)
3948 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#lx)", SARG1, SARG2, ARG3);
3949 PRE_REG_READ3(long, "rt_sigqueueinfo",
3950 int, pid, int, sig, vki_siginfo_t *, uinfo);
3951 if (ARG2 != 0)
3952 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
3954 POST(sys_rt_sigqueueinfo)
3956 if (!ML_(client_signal_OK)(ARG2))
3957 SET_STATUS_Failure( VKI_EINVAL );
3960 PRE(sys_rt_tgsigqueueinfo)
3962 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)",
3963 SARG1, SARG2, SARG3, ARG4);
3964 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
3965 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
3966 if (ARG3 != 0)
3967 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
3970 POST(sys_rt_tgsigqueueinfo)
3972 if (!ML_(client_signal_OK)(ARG3))
3973 SET_STATUS_Failure( VKI_EINVAL );
3976 // XXX: x86-specific? The kernel prototypes for the different archs are
3977 // hard to decipher.
3978 PRE(sys_rt_sigsuspend)
3980 /* The C library interface to sigsuspend just takes a pointer to
3981 a signal mask but this system call has two arguments - a pointer
3982 to the mask and the number of bytes used by it. The kernel insists
3983 on the size being equal to sizeof(sigset_t) however and will just
3984 return EINVAL if it isn't.
3986 *flags |= SfMayBlock;
3987 PRINT("sys_rt_sigsuspend ( %#lx, %lu )", ARG1, ARG2 );
3988 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
3989 if (ARG1 != (Addr)NULL) {
3990 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
3991 if (ML_(safe_to_deref)((vki_sigset_t *) ARG1, sizeof(vki_sigset_t))) {
3992 VG_(sigdelset)((vki_sigset_t *) ARG1, VG_SIGVGKILL);
3993 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
3994 be killable by VG_(nuke_all_threads_except).
3995 We thus silently ignore the user request to mask this signal.
3996 Note that this is similar to what is done for e.g.
3997 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
3998 } else {
3999 SET_STATUS_Failure(VKI_EFAULT);
4004 /* ---------------------------------------------------------------------
4005 linux msg* wrapper helpers
4006 ------------------------------------------------------------------ */
4008 void
4009 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4010 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4012 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4013 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4014 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4015 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4018 void
4019 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4020 UWord arg0, UWord arg1, UWord arg2,
4021 UWord arg3, UWord arg4 )
4023 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4024 long msgtyp, int msgflg); */
4025 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4026 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4027 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4029 void
4030 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4031 UWord res,
4032 UWord arg0, UWord arg1, UWord arg2,
4033 UWord arg3, UWord arg4 )
4035 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4036 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4037 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4040 void
4041 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4042 UWord arg0, UWord arg1, UWord arg2 )
4044 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4045 switch (arg1 /* cmd */) {
4046 case VKI_IPC_INFO:
4047 case VKI_MSG_INFO:
4048 case VKI_IPC_INFO|VKI_IPC_64:
4049 case VKI_MSG_INFO|VKI_IPC_64:
4050 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4051 arg2, sizeof(struct vki_msginfo) );
4052 break;
4053 case VKI_IPC_STAT:
4054 case VKI_MSG_STAT:
4055 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4056 arg2, sizeof(struct vki_msqid_ds) );
4057 break;
4058 case VKI_IPC_STAT|VKI_IPC_64:
4059 case VKI_MSG_STAT|VKI_IPC_64:
4060 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4061 arg2, sizeof(struct vki_msqid64_ds) );
4062 break;
4063 case VKI_IPC_SET:
4064 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4065 arg2, sizeof(struct vki_msqid_ds) );
4066 break;
4067 case VKI_IPC_SET|VKI_IPC_64:
4068 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4069 arg2, sizeof(struct vki_msqid64_ds) );
4070 break;
4073 void
4074 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4075 UWord res,
4076 UWord arg0, UWord arg1, UWord arg2 )
4078 switch (arg1 /* cmd */) {
4079 case VKI_IPC_INFO:
4080 case VKI_MSG_INFO:
4081 case VKI_IPC_INFO|VKI_IPC_64:
4082 case VKI_MSG_INFO|VKI_IPC_64:
4083 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4084 break;
4085 case VKI_IPC_STAT:
4086 case VKI_MSG_STAT:
4087 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4088 break;
4089 case VKI_IPC_STAT|VKI_IPC_64:
4090 case VKI_MSG_STAT|VKI_IPC_64:
4091 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4092 break;
4096 /* ---------------------------------------------------------------------
4097 Generic handler for sys_ipc
4098 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4099 are either direct system calls, or are all implemented via sys_ipc.
4100 ------------------------------------------------------------------ */
4101 #ifdef __NR_ipc
4102 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4104 Addr* a_p = (Addr*)a;
4105 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4106 return *a_p;
4109 static Bool semctl_cmd_has_4args (UWord cmd)
4111 switch (cmd & ~VKI_IPC_64)
4113 case VKI_IPC_INFO:
4114 case VKI_SEM_INFO:
4115 case VKI_IPC_STAT:
4116 case VKI_SEM_STAT:
4117 case VKI_IPC_SET:
4118 case VKI_GETALL:
4119 case VKI_SETALL:
4120 return True;
4121 default:
4122 return False;
4126 PRE(sys_ipc)
4128 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4129 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4131 switch (ARG1 /* call */) {
4132 case VKI_SEMOP:
4133 PRE_REG_READ5(int, "ipc",
4134 vki_uint, call, int, first, int, second, int, third,
4135 void *, ptr);
4136 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4137 *flags |= SfMayBlock;
4138 break;
4139 case VKI_SEMGET:
4140 PRE_REG_READ4(int, "ipc",
4141 vki_uint, call, int, first, int, second, int, third);
4142 break;
4143 case VKI_SEMCTL:
4145 PRE_REG_READ5(int, "ipc",
4146 vki_uint, call, int, first, int, second, int, third,
4147 void *, ptr);
4148 UWord arg;
4149 if (semctl_cmd_has_4args(ARG4))
4150 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4151 else
4152 arg = 0;
4153 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4154 break;
4156 case VKI_SEMTIMEDOP:
4157 PRE_REG_READ6(int, "ipc",
4158 vki_uint, call, int, first, int, second, int, third,
4159 void *, ptr, long, fifth);
4160 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4161 *flags |= SfMayBlock;
4162 break;
4163 case VKI_MSGSND:
4164 PRE_REG_READ5(int, "ipc",
4165 vki_uint, call, int, first, int, second, int, third,
4166 void *, ptr);
4167 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4168 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4169 *flags |= SfMayBlock;
4170 break;
4171 case VKI_MSGRCV:
4173 PRE_REG_READ5(int, "ipc",
4174 vki_uint, call, int, first, int, second, int, third,
4175 void *, ptr);
4176 Addr msgp;
4177 Word msgtyp;
4179 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
4180 "msgrcv(msgp)" );
4181 msgtyp = deref_Addr( tid,
4182 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
4183 "msgrcv(msgp)" );
4185 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4187 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4188 *flags |= SfMayBlock;
4189 break;
4191 case VKI_MSGGET:
4192 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4193 break;
4194 case VKI_MSGCTL:
4195 PRE_REG_READ5(int, "ipc",
4196 vki_uint, call, int, first, int, second, int, third,
4197 void *, ptr);
4198 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4199 break;
4200 case VKI_SHMAT:
4202 PRE_REG_READ5(int, "ipc",
4203 vki_uint, call, int, first, int, second, int, third,
4204 void *, ptr);
4205 UWord w;
4206 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4207 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4208 if (w == 0)
4209 SET_STATUS_Failure( VKI_EINVAL );
4210 else
4211 ARG5 = w;
4212 break;
4214 case VKI_SHMDT:
4215 PRE_REG_READ5(int, "ipc",
4216 vki_uint, call, int, first, int, second, int, third,
4217 void *, ptr);
4218 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4219 SET_STATUS_Failure( VKI_EINVAL );
4220 break;
4221 case VKI_SHMGET:
4222 PRE_REG_READ4(int, "ipc",
4223 vki_uint, call, int, first, int, second, int, third);
4224 if (ARG4 & VKI_SHM_HUGETLB) {
4225 static Bool warning_given = False;
4226 ARG4 &= ~VKI_SHM_HUGETLB;
4227 if (!warning_given) {
4228 warning_given = True;
4229 VG_(umsg)(
4230 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4233 break;
4234 case VKI_SHMCTL: /* IPCOP_shmctl */
4235 PRE_REG_READ5(int, "ipc",
4236 vki_uint, call, int, first, int, second, int, third,
4237 void *, ptr);
4238 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4239 break;
4240 default:
4241 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4242 VG_(core_panic)("... bye!\n");
4243 break; /*NOTREACHED*/
4247 POST(sys_ipc)
4249 vg_assert(SUCCESS);
4250 switch (ARG1 /* call */) {
4251 case VKI_SEMOP:
4252 case VKI_SEMGET:
4253 break;
4254 case VKI_SEMCTL:
4256 UWord arg;
4257 if (semctl_cmd_has_4args(ARG4))
4258 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4259 else
4260 arg = 0;
4261 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4262 break;
4264 case VKI_SEMTIMEDOP:
4265 case VKI_MSGSND:
4266 break;
4267 case VKI_MSGRCV:
4269 Addr msgp;
4270 Word msgtyp;
4272 msgp = deref_Addr( tid,
4273 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
4274 "msgrcv(msgp)" );
4275 msgtyp = deref_Addr( tid,
4276 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
4277 "msgrcv(msgp)" );
4279 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4280 break;
4282 case VKI_MSGGET:
4283 break;
4284 case VKI_MSGCTL:
4285 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4286 break;
4287 case VKI_SHMAT:
4289 Addr addr;
4291 /* force readability. before the syscall it is
4292 * indeed uninitialized, as can be seen in
4293 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4294 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4296 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4297 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4298 break;
4300 case VKI_SHMDT:
4301 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4302 break;
4303 case VKI_SHMGET:
4304 break;
4305 case VKI_SHMCTL:
4306 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4307 break;
4308 default:
4309 VG_(message)(Vg_DebugMsg,
4310 "FATAL: unhandled syscall(ipc) %lu\n",
4311 ARG1 );
4312 VG_(core_panic)("... bye!\n");
4313 break; /*NOTREACHED*/
4316 #endif
4318 PRE(sys_semget)
4320 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4321 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4324 PRE(sys_semop)
4326 *flags |= SfMayBlock;
4327 PRINT("sys_semop ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4328 PRE_REG_READ3(long, "semop",
4329 int, semid, struct sembuf *, sops, unsigned, nsoops);
4330 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4333 PRE(sys_semctl)
4335 switch (ARG3 & ~VKI_IPC_64) {
4336 case VKI_IPC_INFO:
4337 case VKI_SEM_INFO:
4338 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4339 PRE_REG_READ4(long, "semctl",
4340 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4341 break;
4342 case VKI_IPC_STAT:
4343 case VKI_SEM_STAT:
4344 case VKI_IPC_SET:
4345 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4346 PRE_REG_READ4(long, "semctl",
4347 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4348 break;
4349 case VKI_GETALL:
4350 case VKI_SETALL:
4351 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
4352 PRE_REG_READ4(long, "semctl",
4353 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4354 break;
4355 default:
4356 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4357 PRE_REG_READ3(long, "semctl",
4358 int, semid, int, semnum, int, cmd);
4359 break;
4361 #ifdef VGP_amd64_linux
4362 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4363 #else
4364 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4365 #endif
4368 POST(sys_semctl)
4370 #ifdef VGP_amd64_linux
4371 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4372 #else
4373 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4374 #endif
4377 PRE(sys_semtimedop)
4379 *flags |= SfMayBlock;
4380 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
4381 PRE_REG_READ4(long, "semtimedop",
4382 int, semid, struct sembuf *, sops, unsigned, nsoops,
4383 struct timespec *, timeout);
4384 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4387 PRE(sys_msgget)
4389 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4390 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4393 PRE(sys_msgsnd)
4395 PRINT("sys_msgsnd ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
4396 PRE_REG_READ4(long, "msgsnd",
4397 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4398 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4399 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4400 *flags |= SfMayBlock;
4403 PRE(sys_msgrcv)
4405 PRINT("sys_msgrcv ( %ld, %#lx, %lu, %ld, %ld )",
4406 SARG1, ARG2, ARG3, SARG4, SARG5);
4407 PRE_REG_READ5(long, "msgrcv",
4408 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4409 long, msgytp, int, msgflg);
4410 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4411 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4412 *flags |= SfMayBlock;
4414 POST(sys_msgrcv)
4416 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4419 PRE(sys_msgctl)
4421 PRINT("sys_msgctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
4422 PRE_REG_READ3(long, "msgctl",
4423 int, msqid, int, cmd, struct msqid_ds *, buf);
4424 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4427 POST(sys_msgctl)
4429 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4432 PRE(sys_shmget)
4434 PRINT("sys_shmget ( %ld, %lu, %ld )", SARG1, ARG2, SARG3);
4435 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4436 if (ARG3 & VKI_SHM_HUGETLB) {
4437 static Bool warning_given = False;
4438 ARG3 &= ~VKI_SHM_HUGETLB;
4439 if (!warning_given) {
4440 warning_given = True;
4441 VG_(umsg)(
4442 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4447 PRE(sys_shmat)
4449 UWord arg2tmp;
4450 PRINT("sys_shmat ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4451 PRE_REG_READ3(long, "shmat",
4452 int, shmid, const void *, shmaddr, int, shmflg);
4453 #if defined(VGP_arm_linux)
4454 /* Round the attach address down to an VKI_SHMLBA boundary if the
4455 client requested rounding. See #222545. This is necessary only
4456 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4457 other linux targets it is the same as the page size. */
4458 if (ARG3 & VKI_SHM_RND)
4459 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4460 #endif
4461 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4462 if (arg2tmp == 0)
4463 SET_STATUS_Failure( VKI_EINVAL );
4464 else
4465 ARG2 = arg2tmp; // used in POST
4468 POST(sys_shmat)
4470 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4473 PRE(sys_shmdt)
4475 PRINT("sys_shmdt ( %#lx )",ARG1);
4476 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4477 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4478 SET_STATUS_Failure( VKI_EINVAL );
4481 POST(sys_shmdt)
4483 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4486 PRE(sys_shmctl)
4488 PRINT("sys_shmctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
4489 PRE_REG_READ3(long, "shmctl",
4490 int, shmid, int, cmd, struct shmid_ds *, buf);
4491 #ifdef VGP_amd64_linux
4492 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4493 #else
4494 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4495 #endif
4498 POST(sys_shmctl)
4500 #ifdef VGP_amd64_linux
4501 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4502 #else
4503 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4504 #endif
4508 /* ---------------------------------------------------------------------
4509 Generic handler for sys_socketcall
4510 Depending on the platform, some socket related syscalls (e.g. socketpair,
4511 socket, bind, ...)
4512 are either direct system calls, or are all implemented via sys_socketcall.
4513 ------------------------------------------------------------------ */
4514 #ifdef __NR_socketcall
4515 PRE(sys_socketcall)
4517 # define ARG2_0 (((UWord*)ARG2)[0])
4518 # define ARG2_1 (((UWord*)ARG2)[1])
4519 # define ARG2_2 (((UWord*)ARG2)[2])
4520 # define ARG2_3 (((UWord*)ARG2)[3])
4521 # define ARG2_4 (((UWord*)ARG2)[4])
4522 # define ARG2_5 (((UWord*)ARG2)[5])
4524 // call PRE_MEM_READ and check for EFAULT result.
4525 #define PRE_MEM_READ_ef(msg, arg, size) \
4527 PRE_MEM_READ( msg, arg, size); \
4528 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
4529 SET_STATUS_Failure( VKI_EFAULT ); \
4530 break; \
4534 *flags |= SfMayBlock;
4535 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4536 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4538 switch (ARG1 /* request */) {
4540 case VKI_SYS_SOCKETPAIR:
4541 /* int socketpair(int d, int type, int protocol, int sv[2]); */
4542 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4543 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4544 break;
4546 case VKI_SYS_SOCKET:
4547 /* int socket(int domain, int type, int protocol); */
4548 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4549 break;
4551 case VKI_SYS_BIND:
4552 /* int bind(int sockfd, struct sockaddr *my_addr,
4553 int addrlen); */
4554 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4555 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4556 break;
4558 case VKI_SYS_LISTEN:
4559 /* int listen(int s, int backlog); */
4560 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4561 break;
4563 case VKI_SYS_ACCEPT:
4564 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4565 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4566 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4567 break;
4569 case VKI_SYS_ACCEPT4:
4570 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4571 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4572 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4573 break;
4575 case VKI_SYS_SENDTO:
4576 /* int sendto(int s, const void *msg, int len,
4577 unsigned int flags,
4578 const struct sockaddr *to, int tolen); */
4579 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4580 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4581 ARG2_3, ARG2_4, ARG2_5 );
4582 break;
4584 case VKI_SYS_SEND:
4585 /* int send(int s, const void *msg, size_t len, int flags); */
4586 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4587 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4588 break;
4590 case VKI_SYS_RECVFROM:
4591 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4592 struct sockaddr *from, int *fromlen); */
4593 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4594 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4595 ARG2_3, ARG2_4, ARG2_5 );
4596 break;
4598 case VKI_SYS_RECV:
4599 /* int recv(int s, void *buf, int len, unsigned int flags); */
4600 /* man 2 recv says:
4601 The recv call is normally used only on a connected socket
4602 (see connect(2)) and is identical to recvfrom with a NULL
4603 from parameter.
4605 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4606 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4607 break;
4609 case VKI_SYS_CONNECT:
4610 /* int connect(int sockfd,
4611 struct sockaddr *serv_addr, int addrlen ); */
4612 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4613 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4614 break;
4616 case VKI_SYS_SETSOCKOPT:
4617 /* int setsockopt(int s, int level, int optname,
4618 const void *optval, int optlen); */
4619 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4620 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4621 ARG2_3, ARG2_4 );
4622 break;
4624 case VKI_SYS_GETSOCKOPT:
4625 /* int getsockopt(int s, int level, int optname,
4626 void *optval, socklen_t *optlen); */
4627 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4628 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4629 ARG2_3, ARG2_4 );
4630 break;
4632 case VKI_SYS_GETSOCKNAME:
4633 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4634 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4635 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4636 break;
4638 case VKI_SYS_GETPEERNAME:
4639 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4640 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4641 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4642 break;
4644 case VKI_SYS_SHUTDOWN:
4645 /* int shutdown(int s, int how); */
4646 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4647 break;
4649 case VKI_SYS_SENDMSG:
4650 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4651 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4652 ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4653 break;
4655 case VKI_SYS_RECVMSG:
4656 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4657 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4658 ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
4659 break;
4661 case VKI_SYS_RECVMMSG:
4662 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4663 struct timespec *timeout); */
4664 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4665 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4666 ARG2_4 );
4667 break;
4669 case VKI_SYS_SENDMMSG:
4670 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4671 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4672 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4673 break;
4675 default:
4676 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4677 SET_STATUS_Failure( VKI_EINVAL );
4678 break;
4680 # undef ARG2_0
4681 # undef ARG2_1
4682 # undef ARG2_2
4683 # undef ARG2_3
4684 # undef ARG2_4
4685 # undef ARG2_5
4688 POST(sys_socketcall)
4690 # define ARG2_0 (((UWord*)ARG2)[0])
4691 # define ARG2_1 (((UWord*)ARG2)[1])
4692 # define ARG2_2 (((UWord*)ARG2)[2])
4693 # define ARG2_3 (((UWord*)ARG2)[3])
4694 # define ARG2_4 (((UWord*)ARG2)[4])
4695 # define ARG2_5 (((UWord*)ARG2)[5])
4697 SysRes r;
4698 vg_assert(SUCCESS);
4699 switch (ARG1 /* request */) {
4701 case VKI_SYS_SOCKETPAIR:
4702 r = ML_(generic_POST_sys_socketpair)(
4703 tid, VG_(mk_SysRes_Success)(RES),
4704 ARG2_0, ARG2_1, ARG2_2, ARG2_3
4706 SET_STATUS_from_SysRes(r);
4707 break;
4709 case VKI_SYS_SOCKET:
4710 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4711 SET_STATUS_from_SysRes(r);
4712 break;
4714 case VKI_SYS_BIND:
4715 /* int bind(int sockfd, struct sockaddr *my_addr,
4716 int addrlen); */
4717 break;
4719 case VKI_SYS_LISTEN:
4720 /* int listen(int s, int backlog); */
4721 break;
4723 case VKI_SYS_ACCEPT:
4724 case VKI_SYS_ACCEPT4:
4725 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4726 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4727 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4728 ARG2_0, ARG2_1, ARG2_2 );
4729 SET_STATUS_from_SysRes(r);
4730 break;
4732 case VKI_SYS_SENDTO:
4733 break;
4735 case VKI_SYS_SEND:
4736 break;
4738 case VKI_SYS_RECVFROM:
4739 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4740 ARG2_0, ARG2_1, ARG2_2,
4741 ARG2_3, ARG2_4, ARG2_5 );
4742 break;
4744 case VKI_SYS_RECV:
4745 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4746 break;
4748 case VKI_SYS_CONNECT:
4749 break;
4751 case VKI_SYS_SETSOCKOPT:
4752 break;
4754 case VKI_SYS_GETSOCKOPT:
4755 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4756 ARG2_0, ARG2_1,
4757 ARG2_2, ARG2_3, ARG2_4 );
4758 break;
4760 case VKI_SYS_GETSOCKNAME:
4761 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4762 ARG2_0, ARG2_1, ARG2_2 );
4763 break;
4765 case VKI_SYS_GETPEERNAME:
4766 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4767 ARG2_0, ARG2_1, ARG2_2 );
4768 break;
4770 case VKI_SYS_SHUTDOWN:
4771 break;
4773 case VKI_SYS_SENDMSG:
4774 break;
4776 case VKI_SYS_RECVMSG:
4777 ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
4778 break;
4780 case VKI_SYS_RECVMMSG:
4781 ML_(linux_POST_sys_recvmmsg)( tid, RES,
4782 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4783 break;
4785 case VKI_SYS_SENDMMSG:
4786 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4787 break;
4789 default:
4790 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4791 VG_(core_panic)("... bye!\n");
4792 break; /*NOTREACHED*/
4794 # undef ARG2_0
4795 # undef ARG2_1
4796 # undef ARG2_2
4797 # undef ARG2_3
4798 # undef ARG2_4
4799 # undef ARG2_5
4801 #endif
4803 PRE(sys_socket)
4805 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4806 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4808 POST(sys_socket)
4810 SysRes r;
4811 vg_assert(SUCCESS);
4812 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4813 SET_STATUS_from_SysRes(r);
4816 PRE(sys_setsockopt)
4818 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %lu )",
4819 SARG1, SARG2, SARG3, ARG4, ARG5);
4820 PRE_REG_READ5(long, "setsockopt",
4821 int, s, int, level, int, optname,
4822 const void *, optval, unsigned, optlen); // socklen_t
4823 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4826 PRE(sys_getsockopt)
4828 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %ld )",
4829 SARG1, SARG2, SARG3, ARG4, SARG5);
4830 PRE_REG_READ5(long, "getsockopt",
4831 int, s, int, level, int, optname,
4832 void *, optval, int, *optlen);
4833 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4835 POST(sys_getsockopt)
4837 vg_assert(SUCCESS);
4838 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4839 ARG1,ARG2,ARG3,ARG4,ARG5);
4842 PRE(sys_connect)
4844 *flags |= SfMayBlock;
4845 PRINT("sys_connect ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4846 PRE_REG_READ3(long, "connect",
4847 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4848 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4851 PRE(sys_accept)
4853 *flags |= SfMayBlock;
4854 PRINT("sys_accept ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4855 PRE_REG_READ3(long, "accept",
4856 int, s, struct sockaddr *, addr, int *, addrlen);
4857 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4859 POST(sys_accept)
4861 SysRes r;
4862 vg_assert(SUCCESS);
4863 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4864 ARG1,ARG2,ARG3);
4865 SET_STATUS_from_SysRes(r);
4868 PRE(sys_accept4)
4870 *flags |= SfMayBlock;
4871 PRINT("sys_accept4 ( %ld, %#lx, %#lx, %ld )", SARG1, ARG2, ARG3, SARG4);
4872 PRE_REG_READ4(long, "accept4",
4873 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
4874 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4876 POST(sys_accept4)
4878 SysRes r;
4879 vg_assert(SUCCESS);
4880 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4881 ARG1,ARG2,ARG3);
4882 SET_STATUS_from_SysRes(r);
4885 PRE(sys_send)
4887 *flags |= SfMayBlock;
4888 PRINT("sys_send ( %ld, %#lx, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
4889 PRE_REG_READ4(long, "send",
4890 int, s, const void *, msg, vki_size_t, len,
4891 int, flags);
4893 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
4896 PRE(sys_sendto)
4898 *flags |= SfMayBlock;
4899 PRINT("sys_sendto ( %ld, %#lx, %lu, %lu, %#lx, %ld )",
4900 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
4901 PRE_REG_READ6(long, "sendto",
4902 int, s, const void *, msg, vki_size_t, len,
4903 unsigned int, flags,
4904 const struct sockaddr *, to, int, tolen);
4905 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4908 PRE (sys_recv)
4910 *flags |= SfMayBlock;
4911 PRINT ("sys_recv ( %ld, %#lx, %lu, %lu )", SARG1, ARG2, ARG3, ARG4);
4912 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
4913 unsigned int, flags);
4914 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
4917 POST (sys_recv)
4919 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
4922 PRE(sys_recvfrom)
4924 *flags |= SfMayBlock;
4925 PRINT("sys_recvfrom ( %ld, %#lx, %lu, %lu, %#lx, %#lx )",
4926 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4927 PRE_REG_READ6(long, "recvfrom",
4928 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
4929 struct sockaddr *, from, int *, fromlen);
4930 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4932 POST(sys_recvfrom)
4934 vg_assert(SUCCESS);
4935 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
4936 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4939 PRE(sys_sendmsg)
4941 *flags |= SfMayBlock;
4942 PRINT("sys_sendmsg ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4943 PRE_REG_READ3(long, "sendmsg",
4944 int, s, const struct msghdr *, msg, unsigned int, flags);
4945 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4948 PRE(sys_recvmsg)
4950 *flags |= SfMayBlock;
4951 PRINT("sys_recvmsg ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
4952 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
4953 unsigned int, flags);
4954 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4956 POST(sys_recvmsg)
4958 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
4961 PRE(sys_shutdown)
4963 *flags |= SfMayBlock;
4964 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
4965 PRE_REG_READ2(int, "shutdown", int, s, int, how);
4968 PRE(sys_bind)
4970 PRINT("sys_bind ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
4971 PRE_REG_READ3(long, "bind",
4972 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
4973 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
4976 PRE(sys_listen)
4978 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
4979 PRE_REG_READ2(long, "listen", int, s, int, backlog);
4982 PRE(sys_getsockname)
4984 PRINT("sys_getsockname ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4985 PRE_REG_READ3(long, "getsockname",
4986 int, s, struct sockaddr *, name, int *, namelen);
4987 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
4989 POST(sys_getsockname)
4991 vg_assert(SUCCESS);
4992 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
4993 ARG1,ARG2,ARG3);
4996 PRE(sys_getpeername)
4998 PRINT("sys_getpeername ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4999 PRE_REG_READ3(long, "getpeername",
5000 int, s, struct sockaddr *, name, int *, namelen);
5001 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5003 POST(sys_getpeername)
5005 vg_assert(SUCCESS);
5006 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5007 ARG1,ARG2,ARG3);
5010 PRE(sys_socketpair)
5012 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
5013 PRE_REG_READ4(long, "socketpair",
5014 int, d, int, type, int, protocol, int*, sv);
5015 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5017 POST(sys_socketpair)
5019 vg_assert(SUCCESS);
5020 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5021 ARG1,ARG2,ARG3,ARG4);
5025 /* ---------------------------------------------------------------------
5026 *at wrappers
5027 ------------------------------------------------------------------ */
5029 PRE(sys_openat)
5031 HChar name[30]; // large enough
5032 SysRes sres;
5034 if (ARG3 & VKI_O_CREAT) {
5035 // 4-arg version
5036 PRINT("sys_openat ( %ld, %#lx(%s), %ld, %ld )",
5037 SARG1, ARG2, (HChar*)ARG2, SARG3, SARG4);
5038 PRE_REG_READ4(long, "openat",
5039 int, dfd, const char *, filename, int, flags, int, mode);
5040 } else {
5041 // 3-arg version
5042 PRINT("sys_openat ( %ld, %#lx(%s), %ld )",
5043 SARG1, ARG2, (HChar*)ARG2, SARG3);
5044 PRE_REG_READ3(long, "openat",
5045 int, dfd, const char *, filename, int, flags);
5048 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5050 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5051 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5052 be sure only to compare the bottom 32 bits. */
5053 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5054 && *(Char *)ARG2 != '/'
5055 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5056 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5057 SET_STATUS_Failure( VKI_EBADF );
5059 /* Handle the case where the open is of /proc/self/cmdline or
5060 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5061 fake file we cooked up at startup (in m_main). Also, seek the
5062 cloned fd back to the start. */
5064 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5065 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5066 && (VG_(strcmp)((HChar *)ARG2, name) == 0
5067 || VG_(strcmp)((HChar *)ARG2, "/proc/self/cmdline") == 0)) {
5068 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5069 SET_STATUS_from_SysRes( sres );
5070 if (!sr_isError(sres)) {
5071 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5072 if (off < 0)
5073 SET_STATUS_Failure( VKI_EMFILE );
5075 return;
5078 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5080 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5081 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
5082 && (VG_(strcmp)((HChar *)ARG2, name) == 0
5083 || VG_(strcmp)((HChar *)ARG2, "/proc/self/auxv") == 0)) {
5084 sres = VG_(dup)( VG_(cl_auxv_fd) );
5085 SET_STATUS_from_SysRes( sres );
5086 if (!sr_isError(sres)) {
5087 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5088 if (off < 0)
5089 SET_STATUS_Failure( VKI_EMFILE );
5091 return;
5094 /* Otherwise handle normally */
5095 *flags |= SfMayBlock;
5098 POST(sys_openat)
5100 vg_assert(SUCCESS);
5101 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5102 VG_(close)(RES);
5103 SET_STATUS_Failure( VKI_EMFILE );
5104 } else {
5105 if (VG_(clo_track_fds))
5106 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
5110 PRE(sys_mkdirat)
5112 *flags |= SfMayBlock;
5113 PRINT("sys_mkdirat ( %ld, %#lx(%s), %ld )",
5114 SARG1, ARG2, (HChar*)ARG2, SARG3);
5115 PRE_REG_READ3(long, "mkdirat",
5116 int, dfd, const char *, pathname, int, mode);
5117 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5120 PRE(sys_mknodat)
5122 PRINT("sys_mknodat ( %ld, %#lx(%s), 0x%lx, 0x%lx )",
5123 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4 );
5124 PRE_REG_READ4(long, "mknodat",
5125 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5126 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5129 PRE(sys_fchownat)
5131 PRINT("sys_fchownat ( %ld, %#lx(%s), 0x%lx, 0x%lx )",
5132 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5133 PRE_REG_READ4(long, "fchownat",
5134 int, dfd, const char *, path,
5135 vki_uid_t, owner, vki_gid_t, group);
5136 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5139 PRE(sys_futimesat)
5141 PRINT("sys_futimesat ( %ld, %#lx(%s), %#lx )",
5142 SARG1, ARG2, (HChar*)ARG2, ARG3);
5143 PRE_REG_READ3(long, "futimesat",
5144 int, dfd, char *, filename, struct timeval *, tvp);
5145 if (ARG2 != 0)
5146 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5147 if (ARG3 != 0)
5148 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5151 PRE(sys_utimensat)
5153 PRINT("sys_utimensat ( %ld, %#lx(%s), %#lx, 0x%lx )",
5154 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5155 PRE_REG_READ4(long, "utimensat",
5156 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5157 if (ARG2 != 0)
5158 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5159 if (ARG3 != 0)
5160 PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
5163 PRE(sys_newfstatat)
5165 FUSE_COMPATIBLE_MAY_BLOCK();
5166 PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )",
5167 SARG1, ARG2, (HChar*)ARG2, ARG3);
5168 PRE_REG_READ3(long, "fstatat",
5169 int, dfd, char *, file_name, struct stat *, buf);
5170 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5171 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5174 POST(sys_newfstatat)
5176 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5179 PRE(sys_unlinkat)
5181 *flags |= SfMayBlock;
5182 PRINT("sys_unlinkat ( %ld, %#lx(%s) )", SARG1, ARG2, (HChar*)ARG2);
5183 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5184 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5187 PRE(sys_renameat)
5189 PRINT("sys_renameat ( %ld, %#lx(%s), %ld, %#lx(%s) )",
5190 SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4);
5191 PRE_REG_READ4(long, "renameat",
5192 int, olddfd, const char *, oldpath,
5193 int, newdfd, const char *, newpath);
5194 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5195 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5198 PRE(sys_renameat2)
5200 PRINT("sys_renameat2 ( %ld, %#lx(%s), %ld, %#lx(%s), %lu )",
5201 SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4, ARG5);
5202 PRE_REG_READ5(long, "renameat2",
5203 int, olddfd, const char *, oldpath,
5204 int, newdfd, const char *, newpath,
5205 unsigned int, flags);
5206 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5207 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5210 PRE(sys_linkat)
5212 *flags |= SfMayBlock;
5213 PRINT("sys_linkat ( %ld, %#lx(%s), %ld, %#lx(%s), %ld )",
5214 SARG1, ARG2, (HChar*)ARG2, SARG3, ARG4, (HChar*)ARG4, SARG5);
5215 PRE_REG_READ5(long, "linkat",
5216 int, olddfd, const char *, oldpath,
5217 int, newdfd, const char *, newpath,
5218 int, flags);
5219 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5220 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5223 PRE(sys_symlinkat)
5225 *flags |= SfMayBlock;
5226 PRINT("sys_symlinkat ( %#lx(%s), %ld, %#lx(%s) )",
5227 ARG1, (HChar*)ARG1, SARG2, ARG3, (HChar*)ARG3);
5228 PRE_REG_READ3(long, "symlinkat",
5229 const char *, oldpath, int, newdfd, const char *, newpath);
5230 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5231 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5234 PRE(sys_readlinkat)
5236 HChar name[30]; // large enough
5237 Word saved = SYSNO;
5239 PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %lu )",
5240 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
5241 PRE_REG_READ4(long, "readlinkat",
5242 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5243 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5244 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5247 * Handle the case where readlinkat is looking at /proc/self/exe or
5248 * /proc/<pid>/exe.
5250 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5251 if (ML_(safe_to_deref)((void*)ARG2, 1)
5252 && (VG_(strcmp)((HChar *)ARG2, name) == 0
5253 || VG_(strcmp)((HChar *)ARG2, "/proc/self/exe") == 0)) {
5254 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5255 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5256 ARG3, ARG4));
5257 } else {
5258 /* Normal case */
5259 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5262 if (SUCCESS && RES > 0)
5263 POST_MEM_WRITE( ARG3, RES );
5266 PRE(sys_fchmodat)
5268 PRINT("sys_fchmodat ( %ld, %#lx(%s), %lu )",
5269 SARG1, ARG2, (HChar*)ARG2, ARG3);
5270 PRE_REG_READ3(long, "fchmodat",
5271 int, dfd, const char *, path, vki_mode_t, mode);
5272 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5275 PRE(sys_faccessat)
5277 PRINT("sys_faccessat ( %ld, %#lx(%s), %ld )",
5278 SARG1, ARG2, (HChar*)ARG2, SARG3);
5279 PRE_REG_READ3(long, "faccessat",
5280 int, dfd, const char *, pathname, int, mode);
5281 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5284 PRE(sys_name_to_handle_at)
5286 PRINT("sys_name_to_handle_at ( %ld, %#lx(%s), %#lx, %#lx, %ld )",
5287 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, SARG5);
5288 PRE_REG_READ5(int, "name_to_handle_at",
5289 int, dfd, const char *, name,
5290 struct vki_file_handle *, handle,
5291 int *, mnt_id, int, flag);
5292 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5293 if (ML_(safe_to_deref)( (void*)ARG3, sizeof(struct vki_file_handle))) {
5294 struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
5295 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5296 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5298 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5301 POST(sys_name_to_handle_at)
5303 struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
5304 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5305 POST_MEM_WRITE( ARG4, sizeof(int) );
5308 PRE(sys_open_by_handle_at)
5310 *flags |= SfMayBlock;
5311 PRINT("sys_open_by_handle_at ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
5312 PRE_REG_READ3(int, "open_by_handle_at",
5313 int, mountdirfd,
5314 struct vki_file_handle *, handle,
5315 int, flags);
5316 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2, sizeof(struct vki_file_handle) + ((struct vki_file_handle*)ARG2)->handle_bytes );
5319 POST(sys_open_by_handle_at)
5321 vg_assert(SUCCESS);
5322 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5323 VG_(close)(RES);
5324 SET_STATUS_Failure( VKI_EMFILE );
5325 } else {
5326 if (VG_(clo_track_fds))
5327 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
5331 /* ---------------------------------------------------------------------
5332 p{read,write}v wrappers
5333 ------------------------------------------------------------------ */
5335 PRE(sys_preadv)
5337 Int i;
5338 struct vki_iovec * vec;
5339 *flags |= SfMayBlock;
5340 #if VG_WORDSIZE == 4
5341 /* Note that the offset argument here is in lo+hi order on both
5342 big and little endian platforms... */
5343 PRINT("sys_preadv ( %lu, %#lx, %lu, %lld )",
5344 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5345 PRE_REG_READ5(ssize_t, "preadv",
5346 unsigned long, fd, const struct iovec *, vector,
5347 unsigned long, count, vki_u32, offset_low,
5348 vki_u32, offset_high);
5349 #elif VG_WORDSIZE == 8
5350 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5351 PRE_REG_READ4(ssize_t, "preadv",
5352 unsigned long, fd, const struct iovec *, vector,
5353 unsigned long, count, Word, offset);
5354 #else
5355 # error Unexpected word size
5356 #endif
5357 if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
5358 SET_STATUS_Failure( VKI_EBADF );
5359 } else {
5360 PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5362 if (ARG2 != 0) {
5363 /* ToDo: don't do any of the following if the vector is invalid */
5364 vec = (struct vki_iovec *)ARG2;
5365 for (i = 0; i < (Int)ARG3; i++)
5366 PRE_MEM_WRITE( "preadv(vector[...])",
5367 (Addr)vec[i].iov_base, vec[i].iov_len );
5372 POST(sys_preadv)
5374 vg_assert(SUCCESS);
5375 if (RES > 0) {
5376 Int i;
5377 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
5378 Int remains = RES;
5380 /* RES holds the number of bytes read. */
5381 for (i = 0; i < (Int)ARG3; i++) {
5382 Int nReadThisBuf = vec[i].iov_len;
5383 if (nReadThisBuf > remains) nReadThisBuf = remains;
5384 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5385 remains -= nReadThisBuf;
5386 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5391 PRE(sys_pwritev)
5393 Int i;
5394 struct vki_iovec * vec;
5395 *flags |= SfMayBlock;
5396 #if VG_WORDSIZE == 4
5397 /* Note that the offset argument here is in lo+hi order on both
5398 big and little endian platforms... */
5399 PRINT("sys_pwritev ( %lu, %#lx, %lu, %lld )",
5400 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5401 PRE_REG_READ5(ssize_t, "pwritev",
5402 unsigned long, fd, const struct iovec *, vector,
5403 unsigned long, count, vki_u32, offset_low,
5404 vki_u32, offset_high);
5405 #elif VG_WORDSIZE == 8
5406 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5407 PRE_REG_READ4(ssize_t, "pwritev",
5408 unsigned long, fd, const struct iovec *, vector,
5409 unsigned long, count, Word, offset);
5410 #else
5411 # error Unexpected word size
5412 #endif
5413 if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
5414 SET_STATUS_Failure( VKI_EBADF );
5415 } else {
5416 PRE_MEM_READ( "pwritev(vector)",
5417 ARG2, ARG3 * sizeof(struct vki_iovec) );
5418 if (ARG2 != 0) {
5419 /* ToDo: don't do any of the following if the vector is invalid */
5420 vec = (struct vki_iovec *)ARG2;
5421 for (i = 0; i < (Int)ARG3; i++)
5422 PRE_MEM_READ( "pwritev(vector[...])",
5423 (Addr)vec[i].iov_base, vec[i].iov_len );
5428 /* ---------------------------------------------------------------------
5429 process_vm_{read,write}v wrappers
5430 ------------------------------------------------------------------ */
5432 PRE(sys_process_vm_readv)
5434 PRINT("sys_process_vm_readv ( %ld, %#lx, %lu, %#lx, %lu, %lu )",
5435 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5436 PRE_REG_READ6(ssize_t, "process_vm_readv",
5437 vki_pid_t, pid,
5438 const struct iovec *, lvec,
5439 unsigned long, liovcnt,
5440 const struct iovec *, rvec,
5441 unsigned long, riovcnt,
5442 unsigned long, flags);
5443 PRE_MEM_READ( "process_vm_readv(lvec)",
5444 ARG2, ARG3 * sizeof(struct vki_iovec) );
5445 PRE_MEM_READ( "process_vm_readv(rvec)",
5446 ARG4, ARG5 * sizeof(struct vki_iovec) );
5447 if (ARG2 != 0
5448 && ML_(safe_to_deref) ((void *)ARG2, sizeof(struct vki_iovec) * ARG3)) {
5449 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5450 UInt i;
5451 for (i = 0; i < ARG3; i++)
5452 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5453 (Addr)vec[i].iov_base, vec[i].iov_len );
5457 POST(sys_process_vm_readv)
5459 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5460 UInt remains = RES;
5461 UInt i;
5462 for (i = 0; i < ARG3; i++) {
5463 UInt nReadThisBuf = vec[i].iov_len <= remains ?
5464 vec[i].iov_len : remains;
5465 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5466 remains -= nReadThisBuf;
5470 PRE(sys_process_vm_writev)
5472 PRINT("sys_process_vm_writev ( %ld, %#lx, %lu, %#lx, %lu, %lu )",
5473 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5474 PRE_REG_READ6(ssize_t, "process_vm_writev",
5475 vki_pid_t, pid,
5476 const struct iovec *, lvec,
5477 unsigned long, liovcnt,
5478 const struct iovec *, rvec,
5479 unsigned long, riovcnt,
5480 unsigned long, flags);
5481 PRE_MEM_READ( "process_vm_writev(lvec)",
5482 ARG2, ARG3 * sizeof(struct vki_iovec) );
5483 PRE_MEM_READ( "process_vm_writev(rvec)",
5484 ARG4, ARG5 * sizeof(struct vki_iovec) );
5485 if (ARG2 != 0
5486 && ML_(safe_to_deref) ((void *)ARG2, sizeof(struct vki_iovec) * ARG3)) {
5487 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
5488 UInt i;
5489 for (i = 0; i < ARG3; i++)
5490 PRE_MEM_READ( "process_vm_writev(lvec[...])",
5491 (Addr)vec[i].iov_base, vec[i].iov_len );
5495 /* ---------------------------------------------------------------------
5496 {send,recv}mmsg wrappers
5497 ------------------------------------------------------------------ */
5499 PRE(sys_sendmmsg)
5501 *flags |= SfMayBlock;
5502 PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )", SARG1, ARG2, SARG3, SARG4);
5503 PRE_REG_READ4(long, "sendmmsg",
5504 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5505 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5508 POST(sys_sendmmsg)
5510 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5513 PRE(sys_recvmmsg)
5515 *flags |= SfMayBlock;
5516 PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",
5517 SARG1, ARG2, SARG3, SARG4, ARG5);
5518 PRE_REG_READ5(long, "recvmmsg",
5519 int, s, struct mmsghdr *, mmsg, int, vlen,
5520 int, flags, struct timespec *, timeout);
5521 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5524 POST(sys_recvmmsg)
5526 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5529 /* ---------------------------------------------------------------------
5530 key retention service wrappers
5531 ------------------------------------------------------------------ */
5533 PRE(sys_request_key)
5535 PRINT("sys_request_key ( %#lx(%s), %#lx(%s), %#lx(%s), %ld )",
5536 ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3, (HChar*)ARG3, SARG4);
5537 PRE_REG_READ4(long, "request_key",
5538 const char *, type, const char *, description,
5539 const char *, callout_info, vki_key_serial_t, keyring);
5540 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5541 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5542 if (ARG3 != (UWord)NULL)
5543 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5546 PRE(sys_add_key)
5548 PRINT("sys_add_key ( %#lx(%s), %#lx(%s), %#lx, %lu, %ld )",
5549 ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, SARG5);
5550 PRE_REG_READ5(long, "add_key",
5551 const char *, type, const char *, description,
5552 const void *, payload, vki_size_t, plen,
5553 vki_key_serial_t, keyring);
5554 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5555 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5556 if (ARG3 != (UWord)NULL)
5557 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5560 PRE(sys_keyctl)
5562 switch (ARG1 /* option */) {
5563 case VKI_KEYCTL_GET_KEYRING_ID:
5564 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5565 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5566 int, option, vki_key_serial_t, id, int, create);
5567 break;
5568 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5569 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#lx(%s) )", ARG2,(char*)ARG2);
5570 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5571 int, option, const char *, name);
5572 if (ARG2 != (UWord)NULL)
5573 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5574 break;
5575 case VKI_KEYCTL_UPDATE:
5576 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5577 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5578 int, option, vki_key_serial_t, key,
5579 const void *, payload, vki_size_t, plen);
5580 if (ARG3 != (UWord)NULL)
5581 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5582 break;
5583 case VKI_KEYCTL_REVOKE:
5584 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5585 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5586 int, option, vki_key_serial_t, id);
5587 break;
5588 case VKI_KEYCTL_CHOWN:
5589 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %lu, %lu )", SARG2, ARG3, ARG4);
5590 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5591 int, option, vki_key_serial_t, id,
5592 vki_uid_t, uid, vki_gid_t, gid);
5593 break;
5594 case VKI_KEYCTL_SETPERM:
5595 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %lu )", SARG2, ARG3);
5596 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5597 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5598 break;
5599 case VKI_KEYCTL_DESCRIBE:
5600 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5601 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5602 int, option, vki_key_serial_t, id,
5603 char *, buffer, vki_size_t, buflen);
5604 if (ARG3 != (UWord)NULL)
5605 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5606 break;
5607 case VKI_KEYCTL_CLEAR:
5608 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5609 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5610 int, option, vki_key_serial_t, keyring);
5611 break;
5612 case VKI_KEYCTL_LINK:
5613 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5614 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5615 vki_key_serial_t, keyring, vki_key_serial_t, key);
5616 break;
5617 case VKI_KEYCTL_UNLINK:
5618 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5619 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5620 vki_key_serial_t, keyring, vki_key_serial_t, key);
5621 break;
5622 case VKI_KEYCTL_SEARCH:
5623 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#lx(%s), %#lx(%s), %ld )",
5624 SARG2, ARG3, (HChar*)ARG3, ARG4, (HChar*)ARG4, SARG5);
5625 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5626 int, option, vki_key_serial_t, keyring,
5627 const char *, type, const char *, description,
5628 vki_key_serial_t, destring);
5629 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5630 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5631 break;
5632 case VKI_KEYCTL_READ:
5633 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#lx, %lu )", SARG2, ARG3, ARG4);
5634 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5635 int, option, vki_key_serial_t, keyring,
5636 char *, buffer, vki_size_t, buflen);
5637 if (ARG3 != (UWord)NULL)
5638 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5639 break;
5640 case VKI_KEYCTL_INSTANTIATE:
5641 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#lx, %lu, %ld )",
5642 SARG2, ARG3, ARG4, SARG5);
5643 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5644 int, option, vki_key_serial_t, key,
5645 char *, payload, vki_size_t, plen,
5646 vki_key_serial_t, keyring);
5647 if (ARG3 != (UWord)NULL)
5648 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5649 break;
5650 case VKI_KEYCTL_NEGATE:
5651 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %lu, %ld )", SARG2, ARG3, SARG4);
5652 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5653 int, option, vki_key_serial_t, key,
5654 unsigned, timeout, vki_key_serial_t, keyring);
5655 break;
5656 case VKI_KEYCTL_SET_REQKEY_KEYRING:
5657 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5658 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5659 int, option, int, reqkey_defl);
5660 break;
5661 case VKI_KEYCTL_SET_TIMEOUT:
5662 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %lu )", SARG2, ARG3);
5663 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5664 int, option, vki_key_serial_t, key, unsigned, timeout);
5665 break;
5666 case VKI_KEYCTL_ASSUME_AUTHORITY:
5667 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5668 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5669 int, option, vki_key_serial_t, key);
5670 break;
5671 default:
5672 PRINT("sys_keyctl ( %ld ) ", SARG1);
5673 PRE_REG_READ1(long, "keyctl", int, option);
5674 break;
5678 POST(sys_keyctl)
5680 vg_assert(SUCCESS);
5681 switch (ARG1 /* option */) {
5682 case VKI_KEYCTL_DESCRIBE:
5683 case VKI_KEYCTL_READ:
5684 if (RES > ARG4)
5685 POST_MEM_WRITE(ARG3, ARG4);
5686 else
5687 POST_MEM_WRITE(ARG3, RES);
5688 break;
5689 default:
5690 break;
5694 /* ---------------------------------------------------------------------
5695 ioprio_ wrappers
5696 ------------------------------------------------------------------ */
5698 PRE(sys_ioprio_set)
5700 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5701 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5704 PRE(sys_ioprio_get)
5706 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
5707 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5710 /* ---------------------------------------------------------------------
5711 _module wrappers
5712 ------------------------------------------------------------------ */
5714 PRE(sys_init_module)
5716 *flags |= SfMayBlock;
5717 PRINT("sys_init_module ( %#lx, %lu, %#lx(\"%s\") )",
5718 ARG1, ARG2, ARG3, (HChar*)ARG3);
5719 PRE_REG_READ3(long, "init_module",
5720 void *, umod, unsigned long, len, const char *, uargs);
5721 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5722 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5725 PRE(sys_finit_module)
5727 *flags |= SfMayBlock;
5729 PRINT("sys_finit_module ( %lx, %#lx(\"%s\"), %lx )",
5730 ARG1, ARG2, (HChar*)ARG2, ARG3);
5731 PRE_REG_READ3(long, "finit_module",
5732 int, fd, const char *, params, int, flags);
5733 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
5736 PRE(sys_delete_module)
5738 *flags |= SfMayBlock;
5739 PRINT("sys_delete_module ( %#lx(\"%s\"), 0x%lx )", ARG1, (HChar*)ARG1, ARG2);
5740 PRE_REG_READ2(long, "delete_module",
5741 const char *, name_user, unsigned int, flags);
5742 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5745 /* ---------------------------------------------------------------------
5746 splice wrappers
5747 ------------------------------------------------------------------ */
5749 PRE(sys_splice)
5751 *flags |= SfMayBlock;
5752 PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %lu, %#lx )",
5753 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
5754 PRE_REG_READ6(vki_ssize_t, "splice",
5755 int, fd_in, vki_loff_t *, off_in,
5756 int, fd_out, vki_loff_t *, off_out,
5757 vki_size_t, len, unsigned int, flags);
5758 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5759 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5760 SET_STATUS_Failure( VKI_EBADF );
5761 } else {
5762 if (ARG2 != 0)
5763 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5764 if (ARG4 != 0)
5765 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5769 PRE(sys_tee)
5771 *flags |= SfMayBlock;
5772 PRINT("sys_tree ( %ld, %ld, %lu, %#lx )", SARG1, SARG2, ARG3, ARG4);
5773 PRE_REG_READ4(vki_ssize_t, "tee",
5774 int, fd_in, int, fd_out,
5775 vki_size_t, len, unsigned int, flags);
5776 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5777 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5778 SET_STATUS_Failure( VKI_EBADF );
5782 PRE(sys_vmsplice)
5784 Int fdfl;
5785 *flags |= SfMayBlock;
5786 PRINT("sys_vmsplice ( %ld, %#lx, %lu, %lu )", SARG1, ARG2, ARG3, ARG4);
5787 PRE_REG_READ4(vki_ssize_t, "splice",
5788 int, fd, struct vki_iovec *, iov,
5789 unsigned long, nr_segs, unsigned int, flags);
5790 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5791 SET_STATUS_Failure( VKI_EBADF );
5792 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5793 SET_STATUS_Failure( VKI_EBADF );
5794 } else {
5795 const struct vki_iovec *iov;
5796 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5797 for (iov = (struct vki_iovec *)ARG2;
5798 iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5800 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
5801 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5802 PRE_MEM_WRITE( "vmsplice(iov[...])",
5803 (Addr)iov->iov_base, iov->iov_len );
5804 else
5805 PRE_MEM_READ( "vmsplice(iov[...])",
5806 (Addr)iov->iov_base, iov->iov_len );
5812 POST(sys_vmsplice)
5814 vg_assert(SUCCESS);
5815 if (RES > 0) {
5816 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
5817 vg_assert(fdfl >= 0);
5818 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5820 const struct vki_iovec *iov;
5821 for (iov = (struct vki_iovec *)ARG2;
5822 iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5824 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
5830 /* ---------------------------------------------------------------------
5831 oprofile-related wrappers
5832 ------------------------------------------------------------------ */
5834 #if defined(VGP_x86_linux)
5835 PRE(sys_lookup_dcookie)
5837 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
5838 MERGE64(ARG1,ARG2), ARG3, ARG4);
5839 PRE_REG_READ4(long, "lookup_dcookie",
5840 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
5841 char *, buf, vki_size_t, len);
5842 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
5844 POST(sys_lookup_dcookie)
5846 vg_assert(SUCCESS);
5847 if (ARG3 != (Addr)NULL)
5848 POST_MEM_WRITE( ARG3, RES);
5850 #endif
5852 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
5853 || defined(VGP_arm64_linux)
5854 PRE(sys_lookup_dcookie)
5856 *flags |= SfMayBlock;
5857 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
5858 PRE_REG_READ3(int, "lookup_dcookie",
5859 unsigned long long, cookie, char *, buf, vki_size_t, len);
5861 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
5864 POST(sys_lookup_dcookie)
5866 vg_assert(SUCCESS);
5867 if (ARG2 != (Addr)NULL)
5868 POST_MEM_WRITE( ARG2, RES );
5870 #endif
5872 /* ---------------------------------------------------------------------
5873 fcntl wrappers
5874 ------------------------------------------------------------------ */
5876 PRE(sys_fcntl)
5878 switch (ARG2) {
5879 // These ones ignore ARG3.
5880 case VKI_F_GETFD:
5881 case VKI_F_GETFL:
5882 case VKI_F_GETOWN:
5883 case VKI_F_GETSIG:
5884 case VKI_F_GETLEASE:
5885 case VKI_F_GETPIPE_SZ:
5886 PRINT("sys_fcntl ( %lu, %lu )", ARG1, ARG2);
5887 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
5888 break;
5890 // These ones use ARG3 as "arg".
5891 case VKI_F_DUPFD:
5892 case VKI_F_DUPFD_CLOEXEC:
5893 case VKI_F_SETFD:
5894 case VKI_F_SETFL:
5895 case VKI_F_SETLEASE:
5896 case VKI_F_NOTIFY:
5897 case VKI_F_SETOWN:
5898 case VKI_F_SETSIG:
5899 case VKI_F_SETPIPE_SZ:
5900 PRINT("sys_fcntl[ARG3=='arg'] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5901 PRE_REG_READ3(long, "fcntl",
5902 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5903 break;
5905 // These ones use ARG3 as "lock".
5906 case VKI_F_GETLK:
5907 case VKI_F_SETLK:
5908 case VKI_F_SETLKW:
5909 case VKI_F_OFD_GETLK:
5910 case VKI_F_OFD_SETLK:
5911 case VKI_F_OFD_SETLKW:
5912 PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
5913 PRE_REG_READ3(long, "fcntl",
5914 unsigned int, fd, unsigned int, cmd,
5915 struct vki_flock *, lock);
5917 struct vki_flock *lock = (struct vki_flock *) ARG3;
5918 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
5919 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
5920 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
5921 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
5922 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
5923 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
5926 break;
5928 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
5929 case VKI_F_GETLK64:
5930 case VKI_F_SETLK64:
5931 case VKI_F_SETLKW64:
5932 PRINT("sys_fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
5933 PRE_REG_READ3(long, "fcntl",
5934 unsigned int, fd, unsigned int, cmd,
5935 struct flock64 *, lock);
5937 struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
5938 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
5939 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
5940 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
5941 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
5942 if (ARG2 == VKI_F_GETLK64) {
5943 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
5946 break;
5947 # endif
5949 case VKI_F_SETOWN_EX:
5950 PRINT("sys_fcntl[F_SETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5951 PRE_REG_READ3(long, "fcntl",
5952 unsigned int, fd, unsigned int, cmd,
5953 struct vki_f_owner_ex *, arg);
5954 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5955 break;
5957 case VKI_F_GETOWN_EX:
5958 PRINT("sys_fcntl[F_GETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5959 PRE_REG_READ3(long, "fcntl",
5960 unsigned int, fd, unsigned int, cmd,
5961 struct vki_f_owner_ex *, arg);
5962 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5963 break;
5965 default:
5966 PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
5967 VG_(umsg)("Warning: unimplemented fcntl command: %lu\n", ARG2);
5968 SET_STATUS_Failure( VKI_EINVAL );
5969 break;
5972 # if defined(VGP_x86_linux)
5973 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5974 # else
5975 if (ARG2 == VKI_F_SETLKW)
5976 # endif
5977 *flags |= SfMayBlock;
5980 POST(sys_fcntl)
5982 vg_assert(SUCCESS);
5983 if (ARG2 == VKI_F_DUPFD) {
5984 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
5985 VG_(close)(RES);
5986 SET_STATUS_Failure( VKI_EMFILE );
5987 } else {
5988 if (VG_(clo_track_fds))
5989 ML_(record_fd_open_named)(tid, RES);
5992 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5993 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
5994 VG_(close)(RES);
5995 SET_STATUS_Failure( VKI_EMFILE );
5996 } else {
5997 if (VG_(clo_track_fds))
5998 ML_(record_fd_open_named)(tid, RES);
6000 } else if (ARG2 == VKI_F_GETOWN_EX) {
6001 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6002 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6003 struct vki_flock *lock = (struct vki_flock *) ARG3;
6004 POST_FIELD_WRITE(lock->l_pid);
6005 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6006 } else if (ARG2 == VKI_F_GETLK64) {
6007 struct vki_flock64 *lock = (struct vki_flock64 *) ARG3;
6008 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6009 # endif
6013 // XXX: wrapper only suitable for 32-bit systems
6014 PRE(sys_fcntl64)
6016 switch (ARG2) {
6017 // These ones ignore ARG3.
6018 case VKI_F_GETFD:
6019 case VKI_F_GETFL:
6020 case VKI_F_GETOWN:
6021 case VKI_F_SETOWN:
6022 case VKI_F_GETSIG:
6023 case VKI_F_SETSIG:
6024 case VKI_F_GETLEASE:
6025 PRINT("sys_fcntl64 ( %lu, %lu )", ARG1, ARG2);
6026 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6027 break;
6029 // These ones use ARG3 as "arg".
6030 case VKI_F_DUPFD:
6031 case VKI_F_DUPFD_CLOEXEC:
6032 case VKI_F_SETFD:
6033 case VKI_F_SETFL:
6034 case VKI_F_SETLEASE:
6035 case VKI_F_NOTIFY:
6036 PRINT("sys_fcntl64[ARG3=='arg'] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6037 PRE_REG_READ3(long, "fcntl64",
6038 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6039 break;
6041 // These ones use ARG3 as "lock".
6042 case VKI_F_GETLK:
6043 case VKI_F_SETLK:
6044 case VKI_F_SETLKW:
6045 # if defined(VGP_x86_linux)
6046 case VKI_F_GETLK64:
6047 case VKI_F_SETLK64:
6048 case VKI_F_SETLKW64:
6049 # endif
6050 case VKI_F_OFD_GETLK:
6051 case VKI_F_OFD_SETLK:
6052 case VKI_F_OFD_SETLKW:
6053 PRINT("sys_fcntl64[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1, ARG2, ARG3);
6054 PRE_REG_READ3(long, "fcntl64",
6055 unsigned int, fd, unsigned int, cmd,
6056 struct flock64 *, lock);
6057 break;
6059 case VKI_F_SETOWN_EX:
6060 PRINT("sys_fcntl[F_SETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6061 PRE_REG_READ3(long, "fcntl",
6062 unsigned int, fd, unsigned int, cmd,
6063 struct vki_f_owner_ex *, arg);
6064 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6065 break;
6067 case VKI_F_GETOWN_EX:
6068 PRINT("sys_fcntl[F_GETOWN_EX] ( %lu, %lu, %lu )", ARG1, ARG2, ARG3);
6069 PRE_REG_READ3(long, "fcntl",
6070 unsigned int, fd, unsigned int, cmd,
6071 struct vki_f_owner_ex *, arg);
6072 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6073 break;
6076 # if defined(VGP_x86_linux)
6077 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6078 # else
6079 if (ARG2 == VKI_F_SETLKW)
6080 # endif
6081 *flags |= SfMayBlock;
6084 POST(sys_fcntl64)
6086 vg_assert(SUCCESS);
6087 if (ARG2 == VKI_F_DUPFD) {
6088 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6089 VG_(close)(RES);
6090 SET_STATUS_Failure( VKI_EMFILE );
6091 } else {
6092 if (VG_(clo_track_fds))
6093 ML_(record_fd_open_named)(tid, RES);
6096 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6097 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6098 VG_(close)(RES);
6099 SET_STATUS_Failure( VKI_EMFILE );
6100 } else {
6101 if (VG_(clo_track_fds))
6102 ML_(record_fd_open_named)(tid, RES);
6104 } else if (ARG2 == VKI_F_GETOWN_EX) {
6105 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6109 /* ---------------------------------------------------------------------
6110 ioctl wrappers
6111 ------------------------------------------------------------------ */
6113 struct vg_drm_version_info {
6114 struct vki_drm_version data;
6115 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6118 PRE(sys_ioctl)
6120 *flags |= SfMayBlock;
6122 ARG2 = (UInt)ARG2;
6124 // We first handle the ones that don't use ARG3 (even as a
6125 // scalar/non-pointer argument).
6126 switch (ARG2 /* request */) {
6128 /* asm-generic/ioctls.h */
6129 case VKI_FIOCLEX:
6130 case VKI_FIONCLEX:
6131 case VKI_TIOCNOTTY:
6133 /* linux perf_event ioctls */
6134 case VKI_PERF_EVENT_IOC_ENABLE:
6135 case VKI_PERF_EVENT_IOC_DISABLE:
6137 /* linux/soundcard interface (ALSA) */
6138 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6139 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6140 case VKI_SNDRV_PCM_IOCTL_PREPARE:
6141 case VKI_SNDRV_PCM_IOCTL_RESET:
6142 case VKI_SNDRV_PCM_IOCTL_START:
6143 case VKI_SNDRV_PCM_IOCTL_DROP:
6144 case VKI_SNDRV_PCM_IOCTL_DRAIN:
6145 case VKI_SNDRV_PCM_IOCTL_RESUME:
6146 case VKI_SNDRV_PCM_IOCTL_XRUN:
6147 case VKI_SNDRV_PCM_IOCTL_UNLINK:
6148 case VKI_SNDRV_TIMER_IOCTL_START:
6149 case VKI_SNDRV_TIMER_IOCTL_STOP:
6150 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6151 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6153 /* SCSI no operand */
6154 case VKI_SCSI_IOCTL_DOORLOCK:
6155 case VKI_SCSI_IOCTL_DOORUNLOCK:
6157 /* CDROM stuff. */
6158 case VKI_CDROM_DISC_STATUS:
6159 case VKI_CDROMSTOP:
6161 /* DVD stuff */
6162 case VKI_DVD_READ_STRUCT:
6164 /* KVM ioctls that don't check for a numeric value as parameter */
6165 case VKI_KVM_S390_ENABLE_SIE:
6166 case VKI_KVM_CREATE_IRQCHIP:
6167 case VKI_KVM_S390_INITIAL_RESET:
6168 case VKI_KVM_KVMCLOCK_CTRL:
6170 /* vhost without parameter */
6171 case VKI_VHOST_SET_OWNER:
6172 case VKI_VHOST_RESET_OWNER:
6174 /* User input device creation */
6175 case VKI_UI_DEV_CREATE:
6176 case VKI_UI_DEV_DESTROY:
6178 /* InfiniBand */
6179 case VKI_IB_USER_MAD_ENABLE_PKEY:
6181 /* Lustre */
6182 case VKI_LL_IOC_GROUP_LOCK:
6183 case VKI_LL_IOC_GROUP_UNLOCK:
6185 /* V4L2 */
6186 case VKI_V4L2_LOG_STATUS:
6188 /* DVB */
6189 case VKI_DMX_STOP:
6190 PRINT("sys_ioctl ( %lu, 0x%lx )", ARG1, ARG2);
6191 PRE_REG_READ2(long, "ioctl",
6192 unsigned int, fd, unsigned int, request);
6193 return;
6195 default:
6196 PRINT("sys_ioctl ( %lu, 0x%lx, 0x%lx )", ARG1, ARG2, ARG3);
6197 PRE_REG_READ3(long, "ioctl",
6198 unsigned int, fd, unsigned int, request, unsigned long, arg);
6199 break;
6202 // We now handle those that do look at ARG3 (and unknown ones fall into
6203 // this category). Nb: some of these may well belong in the
6204 // doesn't-use-ARG3 switch above.
6205 switch (ARG2 /* request */) {
6207 case VKI_ION_IOC_ALLOC: {
6208 struct vki_ion_allocation_data* data
6209 = (struct vki_ion_allocation_data*)ARG3;
6210 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
6211 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
6212 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6213 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
6214 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
6215 break;
6217 case VKI_ION_IOC_MAP: {
6218 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
6219 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6220 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
6221 break;
6223 case VKI_ION_IOC_IMPORT: {
6224 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
6225 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
6226 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6227 break;
6230 case VKI_SYNC_IOC_MERGE: {
6231 struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
6232 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
6233 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
6234 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6235 break;
6238 case VKI_TCSETS:
6239 case VKI_TCSETSW:
6240 case VKI_TCSETSF:
6241 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6242 break;
6243 case VKI_TCGETS:
6244 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6245 break;
6246 case VKI_TCSETA:
6247 case VKI_TCSETAW:
6248 case VKI_TCSETAF:
6249 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6250 break;
6251 case VKI_TCGETA:
6252 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6253 break;
6254 case VKI_TCSBRK:
6255 case VKI_TCXONC:
6256 case VKI_TCSBRKP:
6257 case VKI_TCFLSH:
6258 case VKI_TIOCSIG:
6259 /* These just take an int by value */
6260 break;
6261 case VKI_TIOCGWINSZ:
6262 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6263 break;
6264 case VKI_TIOCSWINSZ:
6265 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
6266 break;
6267 case VKI_TIOCMBIS:
6268 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
6269 break;
6270 case VKI_TIOCMBIC:
6271 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
6272 break;
6273 case VKI_TIOCMSET:
6274 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
6275 break;
6276 case VKI_TIOCMGET:
6277 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
6278 break;
6279 case VKI_TIOCLINUX:
6280 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
6281 if (*(char *)ARG3 == 11) {
6282 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6284 break;
6285 case VKI_TIOCGPGRP:
6286 /* Get process group ID for foreground processing group. */
6287 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6288 break;
6289 case VKI_TIOCSPGRP:
6290 /* Set a process group ID? */
6291 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6292 break;
6293 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6294 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6295 break;
6296 case VKI_TIOCSCTTY:
6297 /* Just takes an int value. */
6298 break;
6299 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6300 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6301 break;
6302 case VKI_FIONBIO:
6303 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
6304 break;
6305 case VKI_FIOASYNC:
6306 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
6307 break;
6308 case VKI_FIONREAD: /* identical to SIOCINQ */
6309 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
6310 break;
6311 case VKI_FIOQSIZE:
6312 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
6313 break;
6315 case VKI_TIOCSERGETLSR:
6316 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6317 break;
6318 case VKI_TIOCGICOUNT:
6319 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6320 sizeof(struct vki_serial_icounter_struct) );
6321 break;
6323 case VKI_SG_SET_COMMAND_Q:
6324 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6325 break;
6326 case VKI_SG_IO:
6327 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6329 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
6330 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6331 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6332 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6333 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6336 break;
6337 case VKI_SG_GET_SCSI_ID:
6338 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6339 break;
6340 case VKI_SG_SET_RESERVED_SIZE:
6341 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6342 break;
6343 case VKI_SG_SET_TIMEOUT:
6344 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6345 break;
6346 case VKI_SG_GET_RESERVED_SIZE:
6347 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6348 break;
6349 case VKI_SG_GET_TIMEOUT:
6350 break;
6351 case VKI_SG_GET_VERSION_NUM:
6352 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
6353 break;
6354 case VKI_SG_EMULATED_HOST: /* 0x2203 */
6355 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
6356 break;
6357 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6358 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6359 break;
6361 case VKI_IIOCGETCPS:
6362 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6363 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6364 break;
6365 case VKI_IIOCNETGPN:
6366 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6367 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
6368 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
6369 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6370 sizeof(vki_isdn_net_ioctl_phone) );
6371 break;
6373 /* These all use struct ifreq AFAIK */
6374 case VKI_SIOCGIFINDEX: /* get iface index */
6375 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6376 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6377 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6378 break;
6379 case VKI_SIOCGIFFLAGS: /* get flags */
6380 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6381 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6382 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6383 break;
6384 case VKI_SIOCGIFHWADDR: /* Get hardware address */
6385 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6386 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6387 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6388 break;
6389 case VKI_SIOCGIFMTU: /* get MTU size */
6390 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6391 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6392 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6393 break;
6394 case VKI_SIOCGIFADDR: /* get PA address */
6395 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6396 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6397 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6398 break;
6399 case VKI_SIOCGIFNETMASK: /* get network PA mask */
6400 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6401 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6402 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6403 break;
6404 case VKI_SIOCGIFMETRIC: /* get metric */
6405 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6406 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6407 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6408 break;
6409 case VKI_SIOCGIFMAP: /* Get device parameters */
6410 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6411 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6412 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6413 break;
6414 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
6415 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6416 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6417 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6418 break;
6419 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
6420 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6421 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6422 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6423 break;
6424 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
6425 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6426 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6427 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6428 break;
6429 case VKI_SIOCGIFNAME: /* get iface name */
6430 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6431 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
6432 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
6433 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6434 break;
6435 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
6436 struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
6437 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
6438 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
6439 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6440 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6441 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6442 case VKI_ETHTOOL_GSET:
6443 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6444 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6445 break;
6446 case VKI_ETHTOOL_SSET:
6447 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6448 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6449 break;
6450 case VKI_ETHTOOL_GDRVINFO:
6451 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6452 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6453 break;
6454 case VKI_ETHTOOL_GREGS:
6455 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6456 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6457 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6458 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6459 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6460 break;
6461 case VKI_ETHTOOL_GWOL:
6462 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6463 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6464 break;
6465 case VKI_ETHTOOL_SWOL:
6466 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6467 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6468 break;
6469 case VKI_ETHTOOL_GMSGLVL:
6470 case VKI_ETHTOOL_GLINK:
6471 case VKI_ETHTOOL_GRXCSUM:
6472 case VKI_ETHTOOL_GSG:
6473 case VKI_ETHTOOL_GTSO:
6474 case VKI_ETHTOOL_GUFO:
6475 case VKI_ETHTOOL_GGSO:
6476 case VKI_ETHTOOL_GFLAGS:
6477 case VKI_ETHTOOL_GGRO:
6478 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6479 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6480 break;
6481 case VKI_ETHTOOL_SMSGLVL:
6482 case VKI_ETHTOOL_SRXCSUM:
6483 case VKI_ETHTOOL_SSG:
6484 case VKI_ETHTOOL_STSO:
6485 case VKI_ETHTOOL_SUFO:
6486 case VKI_ETHTOOL_SGSO:
6487 case VKI_ETHTOOL_SFLAGS:
6488 case VKI_ETHTOOL_SGRO:
6489 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6490 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6491 break;
6492 case VKI_ETHTOOL_NWAY_RST:
6493 break;
6494 case VKI_ETHTOOL_GRINGPARAM:
6495 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6496 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6497 break;
6498 case VKI_ETHTOOL_SRINGPARAM:
6499 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6500 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6501 break;
6502 case VKI_ETHTOOL_TEST:
6503 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6504 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6505 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6506 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6507 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6508 break;
6509 case VKI_ETHTOOL_PHYS_ID:
6510 break;
6511 case VKI_ETHTOOL_GPERMADDR:
6512 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6513 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6514 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6515 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6516 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6517 break;
6518 case VKI_ETHTOOL_RESET:
6519 break;
6520 case VKI_ETHTOOL_GSSET_INFO:
6521 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6522 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6523 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6524 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6525 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6526 break;
6527 case VKI_ETHTOOL_GFEATURES:
6528 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6529 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6530 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6531 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6532 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6533 break;
6534 case VKI_ETHTOOL_SFEATURES:
6535 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6536 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6537 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6538 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6539 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6540 break;
6541 case VKI_ETHTOOL_GCHANNELS:
6542 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6543 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6544 break;
6545 case VKI_ETHTOOL_SCHANNELS:
6546 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6547 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6548 break;
6549 case VKI_ETHTOOL_GET_TS_INFO:
6550 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6551 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6552 break;
6554 break;
6556 case VKI_SIOCGMIIPHY: /* get hardware entry */
6557 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6558 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6559 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6560 break;
6561 case VKI_SIOCGMIIREG: /* get hardware entry registers */
6562 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6563 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6564 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6565 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
6566 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
6567 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6568 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
6569 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
6570 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6571 sizeof(struct vki_ifreq));
6572 break;
6573 case VKI_SIOCGIFCONF: /* get iface list */
6574 /* WAS:
6575 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6576 KERNEL_DO_SYSCALL(tid,RES);
6577 if (!VG_(is_kerror)(RES) && RES == 0)
6578 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6580 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6581 (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
6582 sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
6583 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6584 (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
6585 sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
6586 if ( ARG3 ) {
6587 // TODO len must be readable and writable
6588 // buf pointer only needs to be readable
6589 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
6590 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6591 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6593 break;
6594 case VKI_SIOCGSTAMP:
6595 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6596 break;
6597 case VKI_SIOCGSTAMPNS:
6598 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6599 break;
6600 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6601 the number of bytes currently in that socket's send buffer.
6602 It writes this value as an int to the memory location
6603 indicated by the third argument of ioctl(2). */
6604 case VKI_SIOCOUTQ:
6605 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6606 break;
6607 case VKI_SIOCGRARP: /* get RARP table entry */
6608 case VKI_SIOCGARP: /* get ARP table entry */
6609 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6610 break;
6612 case VKI_SIOCSIFFLAGS: /* set flags */
6613 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6614 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6615 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6616 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6617 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6618 break;
6619 case VKI_SIOCSIFMAP: /* Set device parameters */
6620 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6621 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6622 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6623 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_map,
6624 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_map) );
6625 break;
6626 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
6627 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
6628 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6629 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
6630 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
6631 sizeof(struct vki_hwtstamp_config) );
6632 break;
6633 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
6634 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
6635 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6636 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
6637 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_qlen,
6638 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_qlen) );
6639 break;
6640 case VKI_SIOCSIFADDR: /* set PA address */
6641 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
6642 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
6643 case VKI_SIOCSIFNETMASK: /* set network PA mask */
6644 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
6645 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6646 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
6647 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_addr,
6648 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_addr) );
6649 break;
6650 case VKI_SIOCSIFMETRIC: /* set metric */
6651 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
6652 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6653 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
6654 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
6655 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
6656 break;
6657 case VKI_SIOCSIFMTU: /* set MTU size */
6658 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
6659 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6660 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
6661 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
6662 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
6663 break;
6664 case VKI_SIOCSIFHWADDR: /* set hardware address */
6665 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6666 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6667 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6668 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr,
6669 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr) );
6670 break;
6671 case VKI_SIOCSMIIREG: /* set hardware entry registers */
6672 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6673 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6674 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6675 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
6676 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
6677 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6678 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
6679 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
6680 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6681 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
6682 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
6683 break;
6684 /* Routing table calls. */
6685 case VKI_SIOCADDRT: /* add routing table entry */
6686 case VKI_SIOCDELRT: /* delete routing table entry */
6687 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6688 sizeof(struct vki_rtentry));
6689 break;
6691 /* tun/tap related ioctls */
6692 case VKI_TUNSETNOCSUM:
6693 case VKI_TUNSETDEBUG:
6694 break;
6695 case VKI_TUNSETIFF:
6696 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6697 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
6698 PRE_MEM_READ( "ioctl(TUNSETIFF)",
6699 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6700 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6701 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6702 break;
6703 case VKI_TUNSETPERSIST:
6704 case VKI_TUNSETOWNER:
6705 case VKI_TUNSETLINK:
6706 case VKI_TUNSETGROUP:
6707 break;
6708 case VKI_TUNGETFEATURES:
6709 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6710 break;
6711 case VKI_TUNSETOFFLOAD:
6712 break;
6713 case VKI_TUNGETIFF:
6714 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6715 break;
6716 case VKI_TUNGETSNDBUF:
6717 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6718 break;
6719 case VKI_TUNSETSNDBUF:
6720 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6721 break;
6722 case VKI_TUNGETVNETHDRSZ:
6723 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6724 break;
6725 case VKI_TUNSETVNETHDRSZ:
6726 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6727 break;
6728 case VKI_TUNSETQUEUE:
6729 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6730 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6731 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6732 break;
6733 case VKI_TUNSETIFINDEX:
6734 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6735 break;
6737 /* RARP cache control calls. */
6738 case VKI_SIOCDRARP: /* delete RARP table entry */
6739 case VKI_SIOCSRARP: /* set RARP table entry */
6740 /* ARP cache control calls. */
6741 case VKI_SIOCSARP: /* set ARP table entry */
6742 case VKI_SIOCDARP: /* delete ARP table entry */
6743 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6744 break;
6746 case VKI_SIOCGPGRP:
6747 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6748 break;
6749 case VKI_SIOCSPGRP:
6750 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6751 //tst->sys_flags &= ~SfMayBlock;
6752 break;
6754 case VKI_SIOCATMARK:
6755 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6756 break;
6758 /* linux/soundcard interface (OSS) */
6759 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6760 case VKI_SNDCTL_SEQ_GETINCOUNT:
6761 case VKI_SNDCTL_SEQ_PERCMODE:
6762 case VKI_SNDCTL_SEQ_TESTMIDI:
6763 case VKI_SNDCTL_SEQ_RESETSAMPLES:
6764 case VKI_SNDCTL_SEQ_NRSYNTHS:
6765 case VKI_SNDCTL_SEQ_NRMIDIS:
6766 case VKI_SNDCTL_SEQ_GETTIME:
6767 case VKI_SNDCTL_DSP_GETBLKSIZE:
6768 case VKI_SNDCTL_DSP_GETFMTS:
6769 case VKI_SNDCTL_DSP_GETTRIGGER:
6770 case VKI_SNDCTL_DSP_GETODELAY:
6771 case VKI_SNDCTL_DSP_GETSPDIF:
6772 case VKI_SNDCTL_DSP_GETCAPS:
6773 case VKI_SOUND_PCM_READ_RATE:
6774 case VKI_SOUND_PCM_READ_CHANNELS:
6775 case VKI_SOUND_PCM_READ_BITS:
6776 case VKI_SOUND_PCM_READ_FILTER:
6777 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6778 ARG3, sizeof(int));
6779 break;
6780 case VKI_SNDCTL_SEQ_CTRLRATE:
6781 case VKI_SNDCTL_DSP_SPEED:
6782 case VKI_SNDCTL_DSP_STEREO:
6783 case VKI_SNDCTL_DSP_CHANNELS:
6784 case VKI_SOUND_PCM_WRITE_FILTER:
6785 case VKI_SNDCTL_DSP_SUBDIVIDE:
6786 case VKI_SNDCTL_DSP_SETFRAGMENT:
6787 case VKI_SNDCTL_DSP_SETFMT:
6788 case VKI_SNDCTL_DSP_GETCHANNELMASK:
6789 case VKI_SNDCTL_DSP_BIND_CHANNEL:
6790 case VKI_SNDCTL_TMR_TIMEBASE:
6791 case VKI_SNDCTL_TMR_TEMPO:
6792 case VKI_SNDCTL_TMR_SOURCE:
6793 case VKI_SNDCTL_MIDI_PRETIME:
6794 case VKI_SNDCTL_MIDI_MPUMODE:
6795 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6796 ARG3, sizeof(int));
6797 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6798 ARG3, sizeof(int));
6799 break;
6800 case VKI_SNDCTL_DSP_GETOSPACE:
6801 case VKI_SNDCTL_DSP_GETISPACE:
6802 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
6803 ARG3, sizeof(vki_audio_buf_info));
6804 break;
6805 case VKI_SNDCTL_DSP_NONBLOCK:
6806 break;
6807 case VKI_SNDCTL_DSP_SETTRIGGER:
6808 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
6809 ARG3, sizeof(int));
6810 break;
6812 case VKI_SNDCTL_DSP_POST:
6813 case VKI_SNDCTL_DSP_RESET:
6814 case VKI_SNDCTL_DSP_SYNC:
6815 case VKI_SNDCTL_DSP_SETSYNCRO:
6816 case VKI_SNDCTL_DSP_SETDUPLEX:
6817 break;
6819 /* linux/soundcard interface (ALSA) */
6820 case VKI_SNDRV_PCM_IOCTL_PAUSE:
6821 case VKI_SNDRV_PCM_IOCTL_LINK:
6822 /* these just take an int by value */
6823 break;
6824 case VKI_SNDRV_CTL_IOCTL_PVERSION:
6825 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
6826 break;
6827 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
6828 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
6829 break;
6830 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
6831 struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
6832 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
6833 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
6834 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
6835 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
6836 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
6837 if (data->pids) {
6838 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
6840 break;
6842 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
6843 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6844 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
6845 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
6846 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
6847 break;
6849 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
6850 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
6851 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
6852 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
6853 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
6854 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
6855 break;
6858 /* Real Time Clock (/dev/rtc) ioctls */
6859 case VKI_RTC_UIE_ON:
6860 case VKI_RTC_UIE_OFF:
6861 case VKI_RTC_AIE_ON:
6862 case VKI_RTC_AIE_OFF:
6863 case VKI_RTC_PIE_ON:
6864 case VKI_RTC_PIE_OFF:
6865 case VKI_RTC_IRQP_SET:
6866 break;
6867 case VKI_RTC_RD_TIME:
6868 case VKI_RTC_ALM_READ:
6869 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
6870 ARG3, sizeof(struct vki_rtc_time));
6871 break;
6872 case VKI_RTC_ALM_SET:
6873 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
6874 break;
6875 case VKI_RTC_IRQP_READ:
6876 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
6877 break;
6879 /* Block devices */
6880 case VKI_BLKROSET:
6881 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
6882 break;
6883 case VKI_BLKROGET:
6884 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
6885 break;
6886 case VKI_BLKGETSIZE:
6887 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
6888 break;
6889 case VKI_BLKFLSBUF:
6890 break;
6891 case VKI_BLKRASET:
6892 break;
6893 case VKI_BLKRAGET:
6894 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
6895 break;
6896 case VKI_BLKFRASET:
6897 break;
6898 case VKI_BLKFRAGET:
6899 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
6900 break;
6901 case VKI_BLKSECTGET:
6902 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
6903 break;
6904 case VKI_BLKSSZGET:
6905 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
6906 break;
6907 case VKI_BLKBSZGET:
6908 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
6909 break;
6910 case VKI_BLKBSZSET:
6911 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
6912 break;
6913 case VKI_BLKGETSIZE64:
6914 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
6915 break;
6916 case VKI_BLKPBSZGET:
6917 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
6918 break;
6919 case VKI_BLKDISCARDZEROES:
6920 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
6921 break;
6923 /* Hard disks */
6924 case VKI_HDIO_GETGEO: /* 0x0301 */
6925 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
6926 break;
6927 case VKI_HDIO_GET_DMA: /* 0x030b */
6928 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
6929 break;
6930 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6931 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
6932 VKI_SIZEOF_STRUCT_HD_DRIVEID );
6933 break;
6935 /* SCSI */
6936 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6937 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
6938 break;
6939 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6940 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
6941 break;
6943 /* CD ROM stuff (??) */
6944 case VKI_CDROM_GET_MCN:
6945 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
6946 sizeof(struct vki_cdrom_mcn) );
6947 break;
6948 case VKI_CDROM_SEND_PACKET:
6949 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
6950 sizeof(struct vki_cdrom_generic_command));
6951 break;
6952 case VKI_CDROMSUBCHNL:
6953 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
6954 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
6955 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
6956 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
6957 sizeof(struct vki_cdrom_subchnl));
6958 break;
6959 case VKI_CDROMREADMODE1: /*0x530d*/
6960 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
6961 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
6962 break;
6963 case VKI_CDROMREADMODE2: /*0x530c*/
6964 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
6965 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
6966 break;
6967 case VKI_CDROMREADTOCHDR:
6968 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
6969 sizeof(struct vki_cdrom_tochdr));
6970 break;
6971 case VKI_CDROMREADTOCENTRY:
6972 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
6973 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
6974 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
6975 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
6976 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
6977 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
6978 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
6979 sizeof(struct vki_cdrom_tocentry));
6980 break;
6981 case VKI_CDROMMULTISESSION: /* 0x5310 */
6982 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
6983 sizeof(struct vki_cdrom_multisession));
6984 break;
6985 case VKI_CDROMVOLREAD: /* 0x5313 */
6986 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
6987 sizeof(struct vki_cdrom_volctrl));
6988 break;
6989 case VKI_CDROMREADRAW: /* 0x5314 */
6990 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
6991 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
6992 break;
6993 case VKI_CDROMREADAUDIO: /* 0x530e */
6994 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
6995 sizeof (struct vki_cdrom_read_audio));
6996 if ( ARG3 ) {
6997 /* ToDo: don't do any of the following if the structure is invalid */
6998 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6999 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7000 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7002 break;
7003 case VKI_CDROMPLAYMSF:
7004 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7005 break;
7006 /* The following two are probably bogus (should check args
7007 for readability). JRS 20021117 */
7008 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7009 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7010 break;
7011 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7012 break;
7014 case VKI_FIGETBSZ:
7015 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7016 break;
7017 case VKI_FIBMAP:
7018 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7019 break;
7021 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7022 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7023 sizeof(struct vki_fb_var_screeninfo));
7024 break;
7025 case VKI_FBIOPUT_VSCREENINFO:
7026 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7027 sizeof(struct vki_fb_var_screeninfo));
7028 break;
7029 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7030 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7031 sizeof(struct vki_fb_fix_screeninfo));
7032 break;
7033 case VKI_FBIOPAN_DISPLAY:
7034 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7035 sizeof(struct vki_fb_var_screeninfo));
7037 break;
7038 case VKI_PPCLAIM:
7039 case VKI_PPEXCL:
7040 case VKI_PPYIELD:
7041 case VKI_PPRELEASE:
7042 break;
7043 case VKI_PPSETMODE:
7044 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7045 break;
7046 case VKI_PPGETMODE:
7047 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7048 break;
7049 case VKI_PPSETPHASE:
7050 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7051 break;
7052 case VKI_PPGETPHASE:
7053 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7054 break;
7055 case VKI_PPGETMODES:
7056 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7057 break;
7058 case VKI_PPSETFLAGS:
7059 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7060 break;
7061 case VKI_PPGETFLAGS:
7062 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7063 break;
7064 case VKI_PPRSTATUS:
7065 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
7066 break;
7067 case VKI_PPRDATA:
7068 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
7069 break;
7070 case VKI_PPRCONTROL:
7071 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7072 break;
7073 case VKI_PPWDATA:
7074 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
7075 break;
7076 case VKI_PPWCONTROL:
7077 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7078 break;
7079 case VKI_PPFCONTROL:
7080 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7081 break;
7082 case VKI_PPDATADIR:
7083 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
7084 break;
7085 case VKI_PPNEGOT:
7086 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
7087 break;
7088 case VKI_PPWCTLONIRQ:
7089 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7090 break;
7091 case VKI_PPCLRIRQ:
7092 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
7093 break;
7094 case VKI_PPSETTIME:
7095 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
7096 break;
7097 case VKI_PPGETTIME:
7098 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
7099 break;
7101 case VKI_GIO_FONT:
7102 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7103 break;
7104 case VKI_PIO_FONT:
7105 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7106 break;
7108 case VKI_GIO_FONTX:
7109 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7110 if ( ARG3 ) {
7111 /* ToDo: don't do any of the following if the structure is invalid */
7112 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
7113 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7114 32 * cfd->charcount );
7116 break;
7117 case VKI_PIO_FONTX:
7118 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7119 if ( ARG3 ) {
7120 /* ToDo: don't do any of the following if the structure is invalid */
7121 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
7122 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7123 32 * cfd->charcount );
7125 break;
7127 case VKI_PIO_FONTRESET:
7128 break;
7130 case VKI_GIO_CMAP:
7131 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7132 break;
7133 case VKI_PIO_CMAP:
7134 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7135 break;
7137 case VKI_KIOCSOUND:
7138 case VKI_KDMKTONE:
7139 break;
7141 case VKI_KDGETLED:
7142 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7143 break;
7144 case VKI_KDSETLED:
7145 break;
7147 case VKI_KDGKBTYPE:
7148 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7149 break;
7151 case VKI_KDADDIO:
7152 case VKI_KDDELIO:
7153 case VKI_KDENABIO:
7154 case VKI_KDDISABIO:
7155 break;
7157 case VKI_KDSETMODE:
7158 break;
7159 case VKI_KDGETMODE:
7160 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7161 break;
7163 case VKI_KDMAPDISP:
7164 case VKI_KDUNMAPDISP:
7165 break;
7167 case VKI_GIO_SCRNMAP:
7168 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7169 break;
7170 case VKI_PIO_SCRNMAP:
7171 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7172 break;
7173 case VKI_GIO_UNISCRNMAP:
7174 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7175 VKI_E_TABSZ * sizeof(unsigned short) );
7176 break;
7177 case VKI_PIO_UNISCRNMAP:
7178 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7179 VKI_E_TABSZ * sizeof(unsigned short) );
7180 break;
7182 case VKI_GIO_UNIMAP:
7183 if ( ARG3 ) {
7184 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
7185 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7186 sizeof(unsigned short));
7187 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7188 sizeof(struct vki_unipair *));
7189 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7190 desc->entry_ct * sizeof(struct vki_unipair));
7192 break;
7193 case VKI_PIO_UNIMAP:
7194 if ( ARG3 ) {
7195 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
7196 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7197 sizeof(unsigned short) );
7198 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7199 sizeof(struct vki_unipair *) );
7200 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7201 desc->entry_ct * sizeof(struct vki_unipair) );
7203 break;
7204 case VKI_PIO_UNIMAPCLR:
7205 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7206 break;
7208 case VKI_KDGKBMODE:
7209 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7210 break;
7211 case VKI_KDSKBMODE:
7212 break;
7214 case VKI_KDGKBMETA:
7215 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7216 break;
7217 case VKI_KDSKBMETA:
7218 break;
7220 case VKI_KDGKBLED:
7221 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7222 break;
7223 case VKI_KDSKBLED:
7224 break;
7226 case VKI_KDGKBENT:
7227 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7228 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
7229 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
7230 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7231 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
7232 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
7233 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7234 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
7235 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
7236 break;
7237 case VKI_KDSKBENT:
7238 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7239 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
7240 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
7241 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7242 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
7243 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
7244 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7245 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
7246 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
7247 break;
7249 case VKI_KDGKBSENT:
7250 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7251 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
7252 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
7253 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7254 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
7255 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
7256 break;
7257 case VKI_KDSKBSENT:
7258 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7259 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
7260 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
7261 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7262 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
7263 break;
7265 case VKI_KDGKBDIACR:
7266 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7267 break;
7268 case VKI_KDSKBDIACR:
7269 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7270 break;
7272 case VKI_KDGETKEYCODE:
7273 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7274 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
7275 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
7276 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7277 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
7278 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
7279 break;
7280 case VKI_KDSETKEYCODE:
7281 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7282 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
7283 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
7284 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7285 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
7286 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
7287 break;
7289 case VKI_KDSIGACCEPT:
7290 break;
7292 case VKI_KDKBDREP:
7293 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7294 break;
7296 case VKI_KDFONTOP:
7297 if ( ARG3 ) {
7298 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
7299 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7300 sizeof(struct vki_console_font_op) );
7301 switch ( op->op ) {
7302 case VKI_KD_FONT_OP_SET:
7303 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7304 (Addr)op->data,
7305 (op->width + 7) / 8 * 32 * op->charcount );
7306 break;
7307 case VKI_KD_FONT_OP_GET:
7308 if ( op->data )
7309 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7310 (Addr)op->data,
7311 (op->width + 7) / 8 * 32 * op->charcount );
7312 break;
7313 case VKI_KD_FONT_OP_SET_DEFAULT:
7314 if ( op->data )
7315 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7316 (Addr)op->data );
7317 break;
7318 case VKI_KD_FONT_OP_COPY:
7319 break;
7322 break;
7324 case VKI_VT_OPENQRY:
7325 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7326 break;
7327 case VKI_VT_GETMODE:
7328 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7329 break;
7330 case VKI_VT_SETMODE:
7331 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7332 break;
7333 case VKI_VT_GETSTATE:
7334 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7335 (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
7336 sizeof(((struct vki_vt_stat*) ARG3)->v_active));
7337 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7338 (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
7339 sizeof(((struct vki_vt_stat*) ARG3)->v_state));
7340 break;
7341 case VKI_VT_RELDISP:
7342 case VKI_VT_ACTIVATE:
7343 case VKI_VT_WAITACTIVE:
7344 case VKI_VT_DISALLOCATE:
7345 break;
7346 case VKI_VT_RESIZE:
7347 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7348 break;
7349 case VKI_VT_RESIZEX:
7350 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7351 break;
7352 case VKI_VT_LOCKSWITCH:
7353 case VKI_VT_UNLOCKSWITCH:
7354 break;
7356 case VKI_USBDEVFS_CONTROL:
7357 if ( ARG3 ) {
7358 struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
7359 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7360 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7361 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7362 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7363 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7364 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7365 if (vkuc->bRequestType & 0x80)
7366 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7367 else
7368 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7370 break;
7371 case VKI_USBDEVFS_BULK:
7372 if ( ARG3 ) {
7373 struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
7374 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7375 if (vkub->ep & 0x80)
7376 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7377 else
7378 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7380 break;
7381 case VKI_USBDEVFS_GETDRIVER:
7382 if ( ARG3 ) {
7383 struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
7384 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7386 break;
7387 case VKI_USBDEVFS_SUBMITURB:
7388 if ( ARG3 ) {
7389 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
7391 /* Not the whole struct needs to be initialized */
7392 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7393 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7394 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7395 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7396 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7397 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7398 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7399 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7400 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7401 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7402 if (vkusp->bRequestType & 0x80)
7403 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7404 else
7405 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7406 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7407 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7408 int total_length = 0;
7409 int i;
7410 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7411 for(i=0; i<vkuu->number_of_packets; i++) {
7412 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7413 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));
7414 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7415 total_length += vkuu->iso_frame_desc[i].length;
7417 if (vkuu->endpoint & 0x80)
7418 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7419 else
7420 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7421 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7422 } else {
7423 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7424 if (vkuu->endpoint & 0x80)
7425 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7426 else
7427 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7428 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7431 break;
7432 case VKI_USBDEVFS_DISCARDURB:
7433 break;
7434 case VKI_USBDEVFS_REAPURB:
7435 if ( ARG3 ) {
7436 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7438 break;
7439 case VKI_USBDEVFS_REAPURBNDELAY:
7440 if ( ARG3 ) {
7441 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7443 break;
7444 case VKI_USBDEVFS_CONNECTINFO:
7445 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7446 break;
7447 case VKI_USBDEVFS_IOCTL:
7448 if ( ARG3 ) {
7449 struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
7450 UInt dir2, size2;
7451 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7452 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
7453 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7454 if (size2 > 0) {
7455 if (dir2 & _VKI_IOC_WRITE)
7456 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7457 else if (dir2 & _VKI_IOC_READ)
7458 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7461 break;
7462 case VKI_USBDEVFS_RESET:
7463 break;
7465 /* I2C (/dev/i2c-*) ioctls */
7466 case VKI_I2C_SLAVE:
7467 case VKI_I2C_SLAVE_FORCE:
7468 case VKI_I2C_TENBIT:
7469 case VKI_I2C_PEC:
7470 break;
7471 case VKI_I2C_FUNCS:
7472 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7473 break;
7474 case VKI_I2C_RDWR:
7475 if ( ARG3 ) {
7476 struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
7477 UInt i;
7478 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7479 for (i=0; i < vkui->nmsgs; i++) {
7480 struct vki_i2c_msg *msg = vkui->msgs + i;
7481 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7482 if (msg->flags & VKI_I2C_M_RD)
7483 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7484 else
7485 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7488 break;
7489 case VKI_I2C_SMBUS:
7490 if ( ARG3 ) {
7491 struct vki_i2c_smbus_ioctl_data *vkis
7492 = (struct vki_i2c_smbus_ioctl_data *) ARG3;
7493 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7494 (Addr)&vkis->read_write, sizeof(vkis->read_write));
7495 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7496 (Addr)&vkis->size, sizeof(vkis->size));
7497 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7498 (Addr)&vkis->command, sizeof(vkis->command));
7499 /* i2c_smbus_write_quick hides its value in read_write, so
7500 this variable can have a different meaning */
7501 /* to make matters worse i2c_smbus_write_byte stores its
7502 value in command */
7503 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7504 ((vkis->size == VKI_I2C_SMBUS_BYTE)
7505 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
7506 /* the rest uses the byte array to store the data,
7507 some the first byte for size */
7508 UInt size;
7509 switch(vkis->size) {
7510 case VKI_I2C_SMBUS_BYTE_DATA:
7511 size = 1;
7512 break;
7513 case VKI_I2C_SMBUS_WORD_DATA:
7514 case VKI_I2C_SMBUS_PROC_CALL:
7515 size = 2;
7516 break;
7517 case VKI_I2C_SMBUS_BLOCK_DATA:
7518 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7519 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7520 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7521 size = 1 + vkis->data->block[0];
7522 break;
7523 default:
7524 size = 0;
7527 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7528 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7529 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7530 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7531 ".i2c_smbus_ioctl_data.data",
7532 (Addr)&vkis->data->block[0], size);
7533 else
7534 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7535 "i2c_smbus_ioctl_data.data",
7536 (Addr)&vkis->data->block[0], size);
7539 break;
7541 /* Wireless extensions ioctls */
7542 case VKI_SIOCSIWCOMMIT:
7543 case VKI_SIOCSIWNWID:
7544 case VKI_SIOCSIWFREQ:
7545 case VKI_SIOCSIWMODE:
7546 case VKI_SIOCSIWSENS:
7547 case VKI_SIOCSIWRANGE:
7548 case VKI_SIOCSIWPRIV:
7549 case VKI_SIOCSIWSTATS:
7550 case VKI_SIOCSIWSPY:
7551 case VKI_SIOCSIWTHRSPY:
7552 case VKI_SIOCSIWAP:
7553 case VKI_SIOCSIWSCAN:
7554 case VKI_SIOCSIWESSID:
7555 case VKI_SIOCSIWRATE:
7556 case VKI_SIOCSIWNICKN:
7557 case VKI_SIOCSIWRTS:
7558 case VKI_SIOCSIWFRAG:
7559 case VKI_SIOCSIWTXPOW:
7560 case VKI_SIOCSIWRETRY:
7561 case VKI_SIOCSIWENCODE:
7562 case VKI_SIOCSIWPOWER:
7563 case VKI_SIOCSIWGENIE:
7564 case VKI_SIOCSIWMLME:
7565 case VKI_SIOCSIWAUTH:
7566 case VKI_SIOCSIWENCODEEXT:
7567 case VKI_SIOCSIWPMKSA:
7568 break;
7569 case VKI_SIOCGIWNAME:
7570 if (ARG3) {
7571 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7572 (Addr)((struct vki_iwreq *)ARG3)->u.name,
7573 sizeof(((struct vki_iwreq *)ARG3)->u.name));
7575 break;
7576 case VKI_SIOCGIWNWID:
7577 case VKI_SIOCGIWSENS:
7578 case VKI_SIOCGIWRATE:
7579 case VKI_SIOCGIWRTS:
7580 case VKI_SIOCGIWFRAG:
7581 case VKI_SIOCGIWTXPOW:
7582 case VKI_SIOCGIWRETRY:
7583 case VKI_SIOCGIWPOWER:
7584 case VKI_SIOCGIWAUTH:
7585 if (ARG3) {
7586 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7587 "RETRY|PARAM|AUTH])",
7588 (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
7589 sizeof(struct vki_iw_param));
7591 break;
7592 case VKI_SIOCGIWFREQ:
7593 if (ARG3) {
7594 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7595 (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
7596 sizeof(struct vki_iw_freq));
7598 break;
7599 case VKI_SIOCGIWMODE:
7600 if (ARG3) {
7601 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
7602 (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
7603 sizeof(__vki_u32));
7605 break;
7606 case VKI_SIOCGIWRANGE:
7607 case VKI_SIOCGIWPRIV:
7608 case VKI_SIOCGIWSTATS:
7609 case VKI_SIOCGIWSPY:
7610 case VKI_SIOCGIWTHRSPY:
7611 case VKI_SIOCGIWAPLIST:
7612 case VKI_SIOCGIWSCAN:
7613 case VKI_SIOCGIWESSID:
7614 case VKI_SIOCGIWNICKN:
7615 case VKI_SIOCGIWENCODE:
7616 case VKI_SIOCGIWGENIE:
7617 case VKI_SIOCGIWENCODEEXT:
7618 if (ARG3) {
7619 struct vki_iw_point* point;
7620 point = &((struct vki_iwreq *)ARG3)->u.data;
7621 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
7622 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
7623 (Addr)point->pointer, point->length);
7625 break;
7626 case VKI_SIOCGIWAP:
7627 if (ARG3) {
7628 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
7629 (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
7630 sizeof(struct vki_sockaddr));
7632 break;
7634 /* User input device creation */
7635 case VKI_UI_SET_EVBIT:
7636 case VKI_UI_SET_KEYBIT:
7637 case VKI_UI_SET_RELBIT:
7638 case VKI_UI_SET_ABSBIT:
7639 case VKI_UI_SET_MSCBIT:
7640 case VKI_UI_SET_LEDBIT:
7641 case VKI_UI_SET_SNDBIT:
7642 case VKI_UI_SET_FFBIT:
7643 case VKI_UI_SET_SWBIT:
7644 case VKI_UI_SET_PROPBIT:
7645 /* These just take an int by value */
7646 break;
7648 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7649 || defined(VGPV_mips32_linux_android) \
7650 || defined(VGPV_arm64_linux_android)
7651 /* ashmem */
7652 case VKI_ASHMEM_GET_SIZE:
7653 case VKI_ASHMEM_SET_SIZE:
7654 case VKI_ASHMEM_GET_PROT_MASK:
7655 case VKI_ASHMEM_SET_PROT_MASK:
7656 case VKI_ASHMEM_GET_PIN_STATUS:
7657 case VKI_ASHMEM_PURGE_ALL_CACHES:
7658 break;
7659 case VKI_ASHMEM_GET_NAME:
7660 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
7661 break;
7662 case VKI_ASHMEM_SET_NAME:
7663 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
7664 break;
7665 case VKI_ASHMEM_PIN:
7666 case VKI_ASHMEM_UNPIN:
7667 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
7668 ARG3, sizeof(struct vki_ashmem_pin) );
7669 break;
7671 /* binder */
7672 case VKI_BINDER_WRITE_READ:
7673 if (ARG3) {
7674 struct vki_binder_write_read* bwr
7675 = (struct vki_binder_write_read*)ARG3;
7677 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7678 bwr->write_buffer);
7679 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7680 bwr->write_size);
7681 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7682 bwr->write_consumed);
7683 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7684 bwr->read_buffer);
7685 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7686 bwr->read_size);
7687 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7688 bwr->read_consumed);
7690 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7691 bwr->write_consumed);
7692 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7693 bwr->read_consumed);
7695 if (bwr->read_size)
7696 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7697 (Addr)bwr->read_buffer, bwr->read_size);
7698 if (bwr->write_size)
7699 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7700 (Addr)bwr->write_buffer, bwr->write_size);
7702 break;
7704 case VKI_BINDER_SET_IDLE_TIMEOUT:
7705 case VKI_BINDER_SET_MAX_THREADS:
7706 case VKI_BINDER_SET_IDLE_PRIORITY:
7707 case VKI_BINDER_SET_CONTEXT_MGR:
7708 case VKI_BINDER_THREAD_EXIT:
7709 break;
7710 case VKI_BINDER_VERSION:
7711 if (ARG3) {
7712 struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
7713 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7715 break;
7716 # endif /* defined(VGPV_*_linux_android) */
7718 case VKI_HCIGETDEVLIST:
7719 if (ARG3) {
7720 struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
7721 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7722 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7723 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7724 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7725 dlr->dev_num * sizeof(struct vki_hci_dev_req));
7727 break;
7729 case VKI_HCIINQUIRY:
7730 if (ARG3) {
7731 struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
7732 PRE_MEM_READ("ioctl(HCIINQUIRY)",
7733 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7734 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7735 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7736 ir->num_rsp * sizeof(struct vki_inquiry_info));
7738 break;
7740 case VKI_DRM_IOCTL_VERSION:
7741 if (ARG3) {
7742 struct vki_drm_version* data = (struct vki_drm_version *)ARG3;
7743 struct vg_drm_version_info* info;
7744 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7745 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7746 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7747 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7748 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7749 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7750 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7751 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7752 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7753 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7754 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7755 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7756 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
7757 // To ensure we VG_(free) info even when syscall fails:
7758 *flags |= SfPostOnFail;
7759 info->data = *data;
7760 info->orig = data;
7761 ARG3 = (Addr)&info->data;
7763 break;
7764 case VKI_DRM_IOCTL_GET_UNIQUE:
7765 if (ARG3) {
7766 struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
7767 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7768 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7769 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7771 break;
7772 case VKI_DRM_IOCTL_GET_MAGIC:
7773 if (ARG3) {
7774 struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
7775 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
7777 break;
7778 case VKI_DRM_IOCTL_WAIT_VBLANK:
7779 if (ARG3) {
7780 union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
7781 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
7782 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
7783 /* XXX: It seems request.signal isn't used */
7784 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
7786 break;
7787 case VKI_DRM_IOCTL_GEM_CLOSE:
7788 if (ARG3) {
7789 struct vki_drm_gem_close *data = (struct vki_drm_gem_close *)ARG3;
7790 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
7792 break;
7793 case VKI_DRM_IOCTL_GEM_FLINK:
7794 if (ARG3) {
7795 struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
7796 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
7797 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
7799 break;
7800 case VKI_DRM_IOCTL_GEM_OPEN:
7801 if (ARG3) {
7802 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
7803 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
7804 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
7805 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
7807 break;
7808 case VKI_DRM_IOCTL_I915_GETPARAM:
7809 if (ARG3) {
7810 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
7811 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
7812 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
7814 break;
7815 case VKI_DRM_IOCTL_I915_GEM_BUSY:
7816 if (ARG3) {
7817 struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
7818 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
7819 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
7821 break;
7822 case VKI_DRM_IOCTL_I915_GEM_CREATE:
7823 if (ARG3) {
7824 struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
7825 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
7826 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
7828 break;
7829 case VKI_DRM_IOCTL_I915_GEM_PREAD:
7830 if (ARG3) {
7831 struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
7832 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
7833 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
7834 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
7835 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7836 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
7838 break;
7839 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
7840 if (ARG3) {
7841 struct vki_drm_i915_gem_pwrite *data = (struct vki_drm_i915_gem_pwrite *)ARG3;
7842 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
7843 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
7844 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
7845 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
7846 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
7847 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
7848 * interleaved vertex attributes may have a wide stride with uninitialized data between
7849 * consecutive vertices) */
7851 break;
7852 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
7853 if (ARG3) {
7854 struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
7855 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
7856 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
7858 break;
7859 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
7860 if (ARG3) {
7861 struct vki_drm_i915_gem_set_domain *data = (struct vki_drm_i915_gem_set_domain *)ARG3;
7862 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
7863 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
7864 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
7866 break;
7867 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
7868 if (ARG3) {
7869 struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
7870 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7871 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7872 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
7873 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7875 break;
7876 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
7877 if (ARG3) {
7878 struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
7879 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
7880 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
7881 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
7883 break;
7884 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
7885 if (ARG3) {
7886 struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
7887 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
7888 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
7890 break;
7892 /* KVM ioctls that check for a numeric value as parameter */
7893 case VKI_KVM_GET_API_VERSION:
7894 case VKI_KVM_CREATE_VM:
7895 case VKI_KVM_GET_VCPU_MMAP_SIZE:
7896 case VKI_KVM_CHECK_EXTENSION:
7897 case VKI_KVM_SET_TSS_ADDR:
7898 case VKI_KVM_CREATE_VCPU:
7899 case VKI_KVM_RUN:
7900 break;
7902 case VKI_KVM_S390_MEM_OP: {
7903 struct vki_kvm_s390_mem_op *args =
7904 (struct vki_kvm_s390_mem_op *)(ARG3);
7905 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
7906 sizeof(struct vki_kvm_s390_mem_op));
7907 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
7908 break;
7909 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
7910 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
7911 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
7912 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
7914 break;
7917 #ifdef ENABLE_XEN
7918 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
7919 SyscallArgs harrghs;
7920 struct vki_xen_privcmd_hypercall *args =
7921 (struct vki_xen_privcmd_hypercall *)(ARG3);
7923 if (!args)
7924 break;
7926 VG_(memset)(&harrghs, 0, sizeof(harrghs));
7927 harrghs.sysno = args->op;
7928 harrghs.arg1 = args->arg[0];
7929 harrghs.arg2 = args->arg[1];
7930 harrghs.arg3 = args->arg[2];
7931 harrghs.arg4 = args->arg[3];
7932 harrghs.arg5 = args->arg[4];
7933 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
7935 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
7937 /* HACK. arg8 is used to return the number of hypercall
7938 * arguments actually consumed! */
7939 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
7940 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
7942 break;
7945 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
7946 struct vki_xen_privcmd_mmap *args =
7947 (struct vki_xen_privcmd_mmap *)(ARG3);
7948 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
7949 (Addr)&args->num, sizeof(args->num));
7950 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
7951 (Addr)&args->dom, sizeof(args->dom));
7952 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
7953 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
7954 break;
7956 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
7957 struct vki_xen_privcmd_mmapbatch *args =
7958 (struct vki_xen_privcmd_mmapbatch *)(ARG3);
7959 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
7960 (Addr)&args->num, sizeof(args->num));
7961 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
7962 (Addr)&args->dom, sizeof(args->dom));
7963 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
7964 (Addr)&args->addr, sizeof(args->addr));
7965 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
7966 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7967 break;
7969 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
7970 struct vki_xen_privcmd_mmapbatch_v2 *args =
7971 (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
7972 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
7973 (Addr)&args->num, sizeof(args->num));
7974 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
7975 (Addr)&args->dom, sizeof(args->dom));
7976 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
7977 (Addr)&args->addr, sizeof(args->addr));
7978 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
7979 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
7980 break;
7983 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
7984 struct vki_xen_ioctl_evtchn_bind_virq *args =
7985 (struct vki_xen_ioctl_evtchn_bind_virq *)(ARG3);
7986 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
7987 (Addr)&args->virq, sizeof(args->virq));
7989 break;
7990 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
7991 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
7992 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(ARG3);
7993 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
7994 (Addr)&args->remote_domain, sizeof(args->remote_domain));
7995 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
7996 (Addr)&args->remote_port, sizeof(args->remote_port));
7998 break;
7999 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8000 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8001 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(ARG3);
8002 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8003 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8005 break;
8006 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8007 struct vki_xen_ioctl_evtchn_unbind *args =
8008 (struct vki_xen_ioctl_evtchn_unbind *)(ARG3);
8009 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8010 (Addr)&args->port, sizeof(args->port));
8012 break;
8013 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8014 struct vki_xen_ioctl_evtchn_notify *args =
8015 (struct vki_xen_ioctl_evtchn_notify*)(ARG3);
8016 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8017 (Addr)&args->port, sizeof(args->port));
8019 break;
8020 case VKI_XEN_IOCTL_EVTCHN_RESET:
8021 /* No input*/
8022 break;
8023 #endif
8025 /* Lustre */
8026 case VKI_OBD_IOC_FID2PATH: {
8027 struct vki_getinfo_fid2path *gf = (struct vki_getinfo_fid2path *)ARG3;
8028 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8029 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8030 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8031 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8032 break;
8035 case VKI_LL_IOC_PATH2FID:
8036 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8037 break;
8039 case VKI_LL_IOC_GETPARENT: {
8040 struct vki_getparent *gp = (struct vki_getparent *)ARG3;
8041 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8042 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8043 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8044 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8045 break;
8048 /* V4L2 */
8049 case VKI_V4L2_QUERYCAP: {
8050 struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
8051 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8052 break;
8054 case VKI_V4L2_ENUM_FMT: {
8055 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
8056 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8057 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8058 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8059 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8060 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8061 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8062 break;
8064 case VKI_V4L2_G_FMT: {
8065 struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8066 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8067 switch (data->type) {
8068 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8069 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8070 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8071 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8072 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8073 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8074 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8075 break;
8076 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8077 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8078 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8079 break;
8080 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8081 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8082 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8083 break;
8084 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8085 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8086 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8087 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8088 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8089 if (data->fmt.win.clipcount && data->fmt.win.clips)
8090 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8091 (Addr)data->fmt.win.clips,
8092 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8093 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8094 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8095 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8096 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8097 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8098 break;
8099 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8100 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8101 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8102 break;
8103 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8104 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8105 break;
8107 break;
8109 case VKI_V4L2_S_FMT: {
8110 struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8111 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8112 switch (data->type) {
8113 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8114 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8115 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8116 (Addr)&data->type + sizeof(data->type),
8117 sizeof(*data) - sizeof(data->type));
8118 break;
8119 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8120 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8121 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8122 break;
8123 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8124 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8125 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8126 break;
8127 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8128 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8129 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8130 if (data->fmt.win.clipcount && data->fmt.win.clips)
8131 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8132 (Addr)data->fmt.win.clips,
8133 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8134 if (data->fmt.win.bitmap)
8135 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8136 (Addr)data->fmt.win.bitmap,
8137 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8138 break;
8139 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8140 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8141 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8142 break;
8143 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8144 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8145 break;
8147 break;
8149 case VKI_V4L2_TRY_FMT: {
8150 struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
8151 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8152 switch (data->type) {
8153 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8154 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8155 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8156 (Addr)&data->type + sizeof(data->type),
8157 sizeof(*data) - sizeof(data->type));
8158 break;
8159 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8160 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8161 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8162 break;
8163 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8164 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8165 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8166 break;
8167 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8168 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8169 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8170 if (data->fmt.win.clipcount && data->fmt.win.clips)
8171 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8172 (Addr)data->fmt.win.clips,
8173 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8174 if (data->fmt.win.bitmap)
8175 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8176 (Addr)data->fmt.win.bitmap,
8177 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8178 break;
8179 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8180 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8181 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8182 break;
8183 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8184 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8185 break;
8187 break;
8189 case VKI_V4L2_REQBUFS: {
8190 struct vki_v4l2_requestbuffers *data = (struct vki_v4l2_requestbuffers *)ARG3;
8191 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8192 break;
8194 case VKI_V4L2_QUERYBUF: {
8195 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8196 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8197 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8198 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8199 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8200 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8201 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8202 unsigned i;
8204 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8205 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8206 for (i = 0; i < data->length; i++) {
8207 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8208 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8209 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8210 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8211 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8213 } else {
8214 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8215 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8217 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8218 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8219 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8220 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8221 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8222 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8223 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8224 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8225 break;
8227 case VKI_V4L2_G_FBUF: {
8228 struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
8229 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8230 break;
8232 case VKI_V4L2_S_FBUF: {
8233 struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
8234 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8235 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8236 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8237 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8238 break;
8240 case VKI_V4L2_OVERLAY: {
8241 int *data = (int *)ARG3;
8242 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8243 break;
8245 case VKI_V4L2_QBUF: {
8246 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8247 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8248 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8249 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8250 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8252 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8253 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8254 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8255 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8256 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8257 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8258 if (is_output) {
8259 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8260 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8262 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8263 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8264 unsigned i;
8266 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8267 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8268 for (i = 0; i < data->length; i++) {
8269 if (is_output) {
8270 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8271 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8273 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8274 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8275 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8276 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8277 else
8278 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8279 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8281 } else {
8282 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8283 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8284 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8285 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8286 else
8287 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8288 if (is_output) {
8289 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8290 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8293 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8294 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8295 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8297 break;
8299 case VKI_V4L2_EXPBUF: {
8300 struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
8301 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8302 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8303 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8304 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8305 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8306 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8307 break;
8309 case VKI_V4L2_DQBUF: {
8310 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8311 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8312 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8313 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8314 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8315 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8316 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8317 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8318 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8319 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8320 unsigned i;
8322 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8323 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8324 for (i = 0; i < data->length; i++) {
8325 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8326 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8327 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8328 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8329 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8331 } else {
8332 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8333 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8334 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8335 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8337 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8338 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8339 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8340 break;
8342 case VKI_V4L2_STREAMON: {
8343 int *data = (int *)ARG3;
8344 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8345 break;
8347 case VKI_V4L2_STREAMOFF: {
8348 int *data = (int *)ARG3;
8349 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8350 break;
8352 case VKI_V4L2_G_PARM: {
8353 struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
8354 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8355 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8356 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8357 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8359 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8360 if (is_output) {
8361 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8362 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8363 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8364 } else {
8365 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8366 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8367 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8369 break;
8371 case VKI_V4L2_S_PARM: {
8372 struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
8373 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8374 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8375 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8376 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8378 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8379 if (is_output)
8380 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8381 else
8382 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8383 break;
8385 case VKI_V4L2_G_STD: {
8386 vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8387 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8388 break;
8390 case VKI_V4L2_S_STD: {
8391 vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8392 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8393 break;
8395 case VKI_V4L2_ENUMSTD: {
8396 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
8397 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8398 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8399 break;
8401 case VKI_V4L2_ENUMINPUT: {
8402 struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
8403 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8404 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8405 break;
8407 case VKI_V4L2_G_CTRL: {
8408 struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
8409 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8410 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8411 break;
8413 case VKI_V4L2_S_CTRL: {
8414 struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
8415 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8416 break;
8418 case VKI_V4L2_G_TUNER: {
8419 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
8420 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8421 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8422 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8423 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8424 break;
8426 case VKI_V4L2_S_TUNER: {
8427 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
8428 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8429 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8430 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8431 break;
8433 case VKI_V4L2_G_AUDIO: {
8434 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8435 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8436 sizeof(*data) - sizeof(data->reserved));
8437 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8438 break;
8440 case VKI_V4L2_S_AUDIO: {
8441 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8442 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8443 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8444 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8445 break;
8447 case VKI_V4L2_QUERYCTRL: {
8448 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
8449 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8450 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8451 sizeof(*data) - sizeof(data->id));
8452 break;
8454 case VKI_V4L2_QUERYMENU: {
8455 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
8456 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8457 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8458 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8459 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8460 break;
8462 case VKI_V4L2_G_INPUT: {
8463 int *data = (int *)ARG3;
8464 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8465 break;
8467 case VKI_V4L2_S_INPUT: {
8468 int *data = (int *)ARG3;
8469 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8470 break;
8472 case VKI_V4L2_G_EDID: {
8473 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
8474 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8475 if (data->blocks && data->edid)
8476 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8477 break;
8479 case VKI_V4L2_S_EDID: {
8480 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
8481 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8482 if (data->blocks && data->edid)
8483 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8484 break;
8486 case VKI_V4L2_G_OUTPUT: {
8487 int *data = (int *)ARG3;
8488 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8489 break;
8491 case VKI_V4L2_S_OUTPUT: {
8492 int *data = (int *)ARG3;
8493 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8494 break;
8496 case VKI_V4L2_ENUMOUTPUT: {
8497 struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
8498 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8499 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8500 break;
8502 case VKI_V4L2_G_AUDOUT: {
8503 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8504 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8505 sizeof(*data) - sizeof(data->reserved));
8506 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8507 break;
8509 case VKI_V4L2_S_AUDOUT: {
8510 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8511 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8512 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8513 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8514 break;
8516 case VKI_V4L2_G_MODULATOR: {
8517 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
8518 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8519 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8520 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8521 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8522 break;
8524 case VKI_V4L2_S_MODULATOR: {
8525 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
8526 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8527 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8528 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8529 break;
8531 case VKI_V4L2_G_FREQUENCY: {
8532 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
8533 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8534 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8535 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8536 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8537 break;
8539 case VKI_V4L2_S_FREQUENCY: {
8540 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
8541 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8542 break;
8544 case VKI_V4L2_CROPCAP: {
8545 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
8546 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8547 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8548 break;
8550 case VKI_V4L2_G_CROP: {
8551 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
8552 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8553 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8554 break;
8556 case VKI_V4L2_S_CROP: {
8557 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
8558 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
8559 break;
8561 case VKI_V4L2_G_JPEGCOMP: {
8562 struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
8563 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
8564 break;
8566 case VKI_V4L2_S_JPEGCOMP: {
8567 struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
8568 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
8569 break;
8571 case VKI_V4L2_QUERYSTD: {
8572 vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
8573 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
8574 break;
8576 case VKI_V4L2_ENUMAUDIO: {
8577 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
8578 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
8579 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
8580 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
8581 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8582 break;
8584 case VKI_V4L2_ENUMAUDOUT: {
8585 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
8586 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
8587 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
8588 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
8589 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8590 break;
8592 case VKI_V4L2_G_PRIORITY: {
8593 __vki_u32 *data = (__vki_u32 *)ARG3;
8594 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
8595 break;
8597 case VKI_V4L2_S_PRIORITY: {
8598 __vki_u32 *data = (__vki_u32 *)ARG3;
8599 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
8600 break;
8602 case VKI_V4L2_G_SLICED_VBI_CAP: {
8603 struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
8604 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
8605 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
8606 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
8607 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
8608 break;
8610 case VKI_V4L2_G_EXT_CTRLS: {
8611 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8612 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
8613 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
8614 if (data->count) {
8615 unsigned i;
8617 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
8618 for (i = 0; i < data->count; i++) {
8619 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
8620 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
8621 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
8622 if (data->controls[i].size) {
8623 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
8624 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
8625 (Addr)data->controls[i].ptr, data->controls[i].size);
8626 } else {
8627 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
8628 data->controls[i].value64);
8632 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
8633 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
8634 break;
8636 case VKI_V4L2_S_EXT_CTRLS: {
8637 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8638 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
8639 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
8640 if (data->count) {
8641 unsigned i;
8643 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
8644 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
8645 data->count * sizeof(data->controls[0]));
8646 for (i = 0; i < data->count; i++) {
8647 if (data->controls[i].size) {
8648 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
8649 (Addr)data->controls[i].ptr, data->controls[i].size);
8653 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
8654 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
8655 break;
8657 case VKI_V4L2_TRY_EXT_CTRLS: {
8658 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
8659 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
8660 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
8661 if (data->count) {
8662 unsigned i;
8664 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
8665 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
8666 data->count * sizeof(data->controls[0]));
8667 for (i = 0; i < data->count; i++) {
8668 if (data->controls[i].size) {
8669 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
8670 (Addr)data->controls[i].ptr, data->controls[i].size);
8674 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
8675 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
8676 break;
8678 case VKI_V4L2_ENUM_FRAMESIZES: {
8679 struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
8680 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
8681 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
8682 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
8683 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
8684 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
8685 break;
8687 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
8688 struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
8689 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
8690 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
8691 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
8692 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
8693 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8694 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8695 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8696 break;
8698 case VKI_V4L2_G_ENC_INDEX: {
8699 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)ARG3;
8700 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8701 break;
8703 case VKI_V4L2_ENCODER_CMD: {
8704 struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8705 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8706 break;
8708 case VKI_V4L2_TRY_ENCODER_CMD: {
8709 struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
8710 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8711 break;
8713 case VKI_V4L2_DBG_S_REGISTER: {
8714 struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8715 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8716 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8717 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8718 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8719 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8720 break;
8722 case VKI_V4L2_DBG_G_REGISTER: {
8723 struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
8724 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8725 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8726 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8727 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8728 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8729 break;
8731 case VKI_V4L2_S_HW_FREQ_SEEK: {
8732 struct vki_v4l2_hw_freq_seek *data = (struct vki_v4l2_hw_freq_seek *)ARG3;
8733 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8734 break;
8736 case VKI_V4L2_S_DV_TIMINGS: {
8737 struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8738 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
8739 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
8740 break;
8742 case VKI_V4L2_G_DV_TIMINGS: {
8743 struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8744 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
8745 break;
8747 case VKI_V4L2_DQEVENT: {
8748 struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
8749 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
8750 break;
8752 case VKI_V4L2_SUBSCRIBE_EVENT: {
8753 struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8754 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8755 break;
8757 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
8758 struct vki_v4l2_event_subscription *data = (struct vki_v4l2_event_subscription *)ARG3;
8759 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8760 break;
8762 case VKI_V4L2_CREATE_BUFS: {
8763 struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
8764 struct vki_v4l2_format *fmt = &data->format;
8765 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
8766 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
8767 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
8768 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
8769 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
8770 switch (fmt->type) {
8771 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8772 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8773 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
8774 break;
8775 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8776 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8777 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
8778 break;
8779 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8780 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8781 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
8782 break;
8783 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8784 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8785 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
8786 break;
8787 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8788 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8789 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
8790 break;
8791 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8792 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
8793 break;
8795 break;
8797 case VKI_V4L2_PREPARE_BUF: {
8798 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
8799 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
8800 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
8801 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
8802 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
8803 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
8804 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8805 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8806 unsigned i;
8808 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
8809 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
8810 for (i = 0; i < data->length; i++) {
8811 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
8814 break;
8816 case VKI_V4L2_G_SELECTION: {
8817 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8818 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
8819 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
8820 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
8821 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
8822 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
8823 break;
8825 case VKI_V4L2_S_SELECTION: {
8826 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
8827 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
8828 break;
8830 case VKI_V4L2_DECODER_CMD: {
8831 struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8832 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
8833 break;
8835 case VKI_V4L2_TRY_DECODER_CMD: {
8836 struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
8837 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
8838 break;
8840 case VKI_V4L2_ENUM_DV_TIMINGS: {
8841 struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
8842 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
8843 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
8844 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
8845 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
8846 break;
8848 case VKI_V4L2_QUERY_DV_TIMINGS: {
8849 struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
8850 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
8851 break;
8853 case VKI_V4L2_DV_TIMINGS_CAP: {
8854 struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
8855 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
8856 break;
8858 case VKI_V4L2_ENUM_FREQ_BANDS: {
8859 struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
8860 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
8861 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
8862 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
8863 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
8864 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
8865 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
8866 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
8867 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
8868 break;
8870 case VKI_V4L2_DBG_G_CHIP_INFO: {
8871 struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
8872 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
8873 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
8874 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
8875 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
8876 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
8877 break;
8879 case VKI_V4L2_QUERY_EXT_CTRL: {
8880 struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
8881 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
8882 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
8883 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
8884 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
8885 break;
8887 case VKI_V4L2_SUBDEV_G_FMT: {
8888 struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8889 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
8890 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
8891 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
8892 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
8893 break;
8895 case VKI_V4L2_SUBDEV_S_FMT: {
8896 struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
8897 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
8898 break;
8900 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
8901 struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8902 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
8903 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
8904 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
8905 break;
8907 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
8908 struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
8909 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
8910 break;
8912 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
8913 struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
8914 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
8915 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
8916 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
8917 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
8918 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
8919 break;
8921 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
8922 struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
8923 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
8924 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
8925 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
8926 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
8927 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
8928 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
8929 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
8930 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
8931 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
8932 break;
8934 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
8935 struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
8936 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
8937 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
8938 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
8939 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
8940 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
8941 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
8942 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
8943 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
8944 break;
8946 case VKI_V4L2_SUBDEV_G_CROP: {
8947 struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8948 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
8949 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
8950 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
8951 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
8952 break;
8954 case VKI_V4L2_SUBDEV_S_CROP: {
8955 struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
8956 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
8957 break;
8959 case VKI_V4L2_SUBDEV_G_SELECTION: {
8960 struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8961 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
8962 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
8963 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
8964 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
8965 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
8966 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
8967 break;
8969 case VKI_V4L2_SUBDEV_S_SELECTION: {
8970 struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
8971 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
8972 break;
8974 case VKI_MEDIA_IOC_DEVICE_INFO: {
8975 struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
8976 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
8977 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
8978 (Addr)data, sizeof(*data) - sizeof(data->reserved));
8979 break;
8981 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
8982 struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
8983 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
8984 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
8985 (Addr)data->name, sizeof(*data) - sizeof(data->id));
8986 break;
8988 case VKI_MEDIA_IOC_ENUM_LINKS: {
8989 struct vki_media_links_enum *data = (struct vki_media_links_enum *)ARG3;
8990 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
8991 break;
8993 case VKI_MEDIA_IOC_SETUP_LINK: {
8994 struct vki_media_link_desc *data = (struct vki_media_link_desc *)ARG3;
8995 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
8996 break;
8999 /* Serial */
9000 case VKI_TIOCGSERIAL: {
9001 struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
9002 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9003 break;
9005 case VKI_TIOCSSERIAL: {
9006 struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
9007 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9008 break;
9011 case VKI_PERF_EVENT_IOC_RESET:
9012 case VKI_PERF_EVENT_IOC_REFRESH:
9013 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9014 case VKI_PERF_EVENT_IOC_SET_BPF:
9015 /* These take scalar arguments, so already handled above */
9016 break;
9018 case VKI_PERF_EVENT_IOC_PERIOD:
9019 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9020 break;
9022 case VKI_PERF_EVENT_IOC_SET_FILTER:
9023 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9024 break;
9026 case VKI_PERF_EVENT_IOC_ID:
9027 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9028 break;
9030 default:
9031 /* EVIOC* are variable length and return size written on success */
9032 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9033 case VKI_EVIOCGNAME(0):
9034 case VKI_EVIOCGPHYS(0):
9035 case VKI_EVIOCGUNIQ(0):
9036 case VKI_EVIOCGKEY(0):
9037 case VKI_EVIOCGLED(0):
9038 case VKI_EVIOCGSND(0):
9039 case VKI_EVIOCGSW(0):
9040 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9041 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9042 case VKI_EVIOCGBIT(VKI_EV_REL,0):
9043 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9044 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9045 case VKI_EVIOCGBIT(VKI_EV_SW,0):
9046 case VKI_EVIOCGBIT(VKI_EV_LED,0):
9047 case VKI_EVIOCGBIT(VKI_EV_SND,0):
9048 case VKI_EVIOCGBIT(VKI_EV_REP,0):
9049 case VKI_EVIOCGBIT(VKI_EV_FF,0):
9050 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9051 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9052 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9053 break;
9054 default:
9055 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9056 break;
9058 break;
9062 POST(sys_ioctl)
9064 ARG2 = (UInt)ARG2;
9066 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9068 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9070 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9071 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9072 VG_(clo_kernel_variant))) {
9074 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9075 /* What's going on here: there appear to be a bunch of ioctls
9076 of the form 0xC01C67xx which are undocumented, and if
9077 unhandled give rise to a vast number of false positives in
9078 Memcheck.
9080 The "normal" interpretation of an ioctl of this form would
9081 be that the 3rd arg is a pointer to an area of size 0x1C
9082 (28 bytes) which is filled in by the kernel. Hence you
9083 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9084 But it doesn't.
9086 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9087 One interpretation of this is that ARG3 really does point
9088 to a 28 byte struct, but inside that are pointers to other
9089 areas also filled in by the kernel. If these happen to be
9090 allocated just back up the stack then the 256 byte paint
9091 might cover them too, somewhat indiscriminately.
9093 By printing out ARG3 and also the 28 bytes that it points
9094 at, it's possible to guess that the 7 word structure has
9095 this form
9097 0 1 2 3 4 5 6
9098 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9100 Unfortunately that doesn't seem to work for some reason,
9101 so stay with the blunt-instrument approach for the time
9102 being.
9104 if (1) {
9105 /* blunt-instrument approach */
9106 POST_MEM_WRITE(ARG3, 256);
9107 } else {
9108 /* be a bit more sophisticated */
9109 POST_MEM_WRITE(ARG3, 28);
9110 UInt* word = (UInt*)ARG3;
9111 if (word && word[2] && word[3] < 0x200/*stay sane*/)
9112 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9113 if (word && word[4] && word[5] < 0x200/*stay sane*/)
9114 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9116 goto post_sys_ioctl__out;
9119 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9121 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9122 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9123 VG_(clo_kernel_variant))) {
9124 if (ARG2 == 0xC00C0902) {
9125 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9126 goto post_sys_ioctl__out;
9129 /* END undocumented ioctls for Qualcomm Adreno 3xx */
9131 /* --- END special IOCTL handlers for specific Android hardware --- */
9133 /* --- normal handling --- */
9134 switch (ARG2 /* request */) {
9136 /* The Linux kernel "ion" memory allocator, used on Android. Note:
9137 this is pretty poor given that there's no pre-handling to check
9138 that writable areas are addressable. */
9139 case VKI_ION_IOC_ALLOC: {
9140 struct vki_ion_allocation_data* data
9141 = (struct vki_ion_allocation_data*)ARG3;
9142 POST_FIELD_WRITE(data->handle);
9143 break;
9145 case VKI_ION_IOC_MAP: {
9146 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
9147 POST_FIELD_WRITE(data->fd);
9148 break;
9150 case VKI_ION_IOC_FREE: // is this necessary?
9151 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9152 break;
9153 case VKI_ION_IOC_SHARE:
9154 break;
9155 case VKI_ION_IOC_IMPORT: {
9156 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)ARG3;
9157 POST_FIELD_WRITE(data->handle);
9158 break;
9160 case VKI_ION_IOC_SYNC:
9161 break;
9162 case VKI_ION_IOC_CUSTOM: // is this necessary?
9163 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9164 break;
9166 case VKI_SYNC_IOC_MERGE: {
9167 struct vki_sync_merge_data* data = (struct vki_sync_merge_data*)ARG3;
9168 POST_FIELD_WRITE(data->fence);
9169 break;
9172 case VKI_TCSETS:
9173 case VKI_TCSETSW:
9174 case VKI_TCSETSF:
9175 case VKI_IB_USER_MAD_ENABLE_PKEY:
9176 break;
9177 case VKI_TCGETS:
9178 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9179 break;
9180 case VKI_TCSETA:
9181 case VKI_TCSETAW:
9182 case VKI_TCSETAF:
9183 break;
9184 case VKI_TCGETA:
9185 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9186 break;
9187 case VKI_TCSBRK:
9188 case VKI_TCXONC:
9189 case VKI_TCSBRKP:
9190 case VKI_TCFLSH:
9191 case VKI_TIOCSIG:
9192 break;
9193 case VKI_TIOCGWINSZ:
9194 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9195 break;
9196 case VKI_TIOCSWINSZ:
9197 case VKI_TIOCMBIS:
9198 case VKI_TIOCMBIC:
9199 case VKI_TIOCMSET:
9200 break;
9201 case VKI_TIOCMGET:
9202 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9203 break;
9204 case VKI_TIOCLINUX:
9205 POST_MEM_WRITE( ARG3, sizeof(char *) );
9206 break;
9207 case VKI_TIOCGPGRP:
9208 /* Get process group ID for foreground processing group. */
9209 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9210 break;
9211 case VKI_TIOCSPGRP:
9212 /* Set a process group ID? */
9213 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9214 break;
9215 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9216 POST_MEM_WRITE( ARG3, sizeof(int));
9217 break;
9218 case VKI_TIOCSCTTY:
9219 break;
9220 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9221 break;
9222 case VKI_FIONBIO:
9223 break;
9224 case VKI_FIONCLEX:
9225 break;
9226 case VKI_FIOCLEX:
9227 break;
9228 case VKI_TIOCNOTTY:
9229 break;
9230 case VKI_FIOASYNC:
9231 break;
9232 case VKI_FIONREAD: /* identical to SIOCINQ */
9233 POST_MEM_WRITE( ARG3, sizeof(int) );
9234 break;
9235 case VKI_FIOQSIZE:
9236 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9237 break;
9239 case VKI_TIOCSERGETLSR:
9240 POST_MEM_WRITE( ARG3, sizeof(int) );
9241 break;
9242 case VKI_TIOCGICOUNT:
9243 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9244 break;
9246 case VKI_SG_SET_COMMAND_Q:
9247 break;
9248 case VKI_SG_IO:
9250 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)ARG3;
9251 if ( sgio->sbp ) {
9252 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9254 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9255 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9256 int transferred = sgio->dxfer_len - sgio->resid;
9257 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9260 break;
9261 case VKI_SG_GET_SCSI_ID:
9262 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9263 break;
9264 case VKI_SG_SET_RESERVED_SIZE:
9265 break;
9266 case VKI_SG_SET_TIMEOUT:
9267 break;
9268 case VKI_SG_GET_RESERVED_SIZE:
9269 POST_MEM_WRITE(ARG3, sizeof(int));
9270 break;
9271 case VKI_SG_GET_TIMEOUT:
9272 break;
9273 case VKI_SG_GET_VERSION_NUM:
9274 POST_MEM_WRITE(ARG3, sizeof(int));
9275 break;
9276 case VKI_SG_EMULATED_HOST:
9277 POST_MEM_WRITE(ARG3, sizeof(int));
9278 break;
9279 case VKI_SG_GET_SG_TABLESIZE:
9280 POST_MEM_WRITE(ARG3, sizeof(int));
9281 break;
9283 case VKI_IIOCGETCPS:
9284 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9285 break;
9286 case VKI_IIOCNETGPN:
9287 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9288 break;
9290 /* These all use struct ifreq AFAIK */
9291 case VKI_SIOCGIFINDEX: /* get iface index */
9292 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
9293 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
9294 break;
9295 case VKI_SIOCGIFFLAGS: /* get flags */
9296 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
9297 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
9298 break;
9299 case VKI_SIOCGIFHWADDR: /* Get hardware address */
9300 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr,
9301 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_hwaddr) );
9302 break;
9303 case VKI_SIOCGIFMTU: /* get MTU size */
9304 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
9305 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
9306 break;
9307 case VKI_SIOCGIFADDR: /* get PA address */
9308 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
9309 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
9310 case VKI_SIOCGIFNETMASK: /* get network PA mask */
9311 POST_MEM_WRITE(
9312 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_addr,
9313 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_addr) );
9314 break;
9315 case VKI_SIOCGIFMETRIC: /* get metric */
9316 POST_MEM_WRITE(
9317 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
9318 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
9319 break;
9320 case VKI_SIOCGIFMAP: /* Get device parameters */
9321 POST_MEM_WRITE(
9322 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_map,
9323 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_map) );
9324 break;
9325 break;
9326 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
9327 POST_MEM_WRITE(
9328 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_qlen,
9329 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_qlen) );
9330 break;
9331 case VKI_SIOCGIFNAME: /* get iface name */
9332 POST_MEM_WRITE(
9333 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9334 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9335 break;
9336 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
9337 struct vki_ifreq *ir = (struct vki_ifreq *)ARG3;
9338 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9339 case VKI_ETHTOOL_GSET:
9340 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9341 break;
9342 case VKI_ETHTOOL_SSET:
9343 break;
9344 case VKI_ETHTOOL_GDRVINFO:
9345 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9346 break;
9347 case VKI_ETHTOOL_GREGS:
9348 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9349 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9350 break;
9351 case VKI_ETHTOOL_GWOL:
9352 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9353 break;
9354 case VKI_ETHTOOL_SWOL:
9355 break;
9356 case VKI_ETHTOOL_GMSGLVL:
9357 case VKI_ETHTOOL_GLINK:
9358 case VKI_ETHTOOL_GRXCSUM:
9359 case VKI_ETHTOOL_GSG:
9360 case VKI_ETHTOOL_GTSO:
9361 case VKI_ETHTOOL_GUFO:
9362 case VKI_ETHTOOL_GGSO:
9363 case VKI_ETHTOOL_GFLAGS:
9364 case VKI_ETHTOOL_GGRO:
9365 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9366 break;
9367 case VKI_ETHTOOL_SMSGLVL:
9368 case VKI_ETHTOOL_SRXCSUM:
9369 case VKI_ETHTOOL_SSG:
9370 case VKI_ETHTOOL_STSO:
9371 case VKI_ETHTOOL_SUFO:
9372 case VKI_ETHTOOL_SGSO:
9373 case VKI_ETHTOOL_SFLAGS:
9374 case VKI_ETHTOOL_SGRO:
9375 break;
9376 case VKI_ETHTOOL_NWAY_RST:
9377 break;
9378 case VKI_ETHTOOL_GRINGPARAM:
9379 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9380 break;
9381 case VKI_ETHTOOL_SRINGPARAM:
9382 break;
9383 case VKI_ETHTOOL_TEST:
9384 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9385 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9386 break;
9387 case VKI_ETHTOOL_PHYS_ID:
9388 break;
9389 case VKI_ETHTOOL_GPERMADDR:
9390 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9391 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9392 break;
9393 case VKI_ETHTOOL_RESET:
9394 break;
9395 case VKI_ETHTOOL_GSSET_INFO:
9396 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9397 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9398 break;
9399 case VKI_ETHTOOL_GFEATURES:
9400 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9401 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9402 break;
9403 case VKI_ETHTOOL_SFEATURES:
9404 break;
9405 case VKI_ETHTOOL_GCHANNELS:
9406 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9407 break;
9408 case VKI_ETHTOOL_SCHANNELS:
9409 break;
9410 case VKI_ETHTOOL_GET_TS_INFO:
9411 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9412 break;
9414 break;
9416 case VKI_SIOCGMIIPHY: /* get hardware entry */
9417 POST_MEM_WRITE(
9418 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
9419 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
9420 break;
9421 case VKI_SIOCGMIIREG: /* get hardware entry registers */
9422 POST_MEM_WRITE(
9423 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
9424 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
9425 break;
9427 /* tun/tap related ioctls */
9428 case VKI_TUNSETIFF:
9429 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9430 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9431 break;
9432 case VKI_TUNGETFEATURES:
9433 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9434 break;
9435 case VKI_TUNGETIFF:
9436 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
9437 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
9438 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
9439 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
9440 break;
9441 case VKI_TUNGETSNDBUF:
9442 POST_MEM_WRITE( ARG3, sizeof(int) );
9443 break;
9444 case VKI_TUNGETVNETHDRSZ:
9445 POST_MEM_WRITE( ARG3, sizeof(int) );
9446 break;
9448 case VKI_SIOCGIFCONF: /* get iface list */
9449 /* WAS:
9450 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
9451 KERNEL_DO_SYSCALL(tid,RES);
9452 if (!VG_(is_kerror)(RES) && RES == 0)
9453 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
9455 if (RES == 0 && ARG3 ) {
9456 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
9457 if (ifc->vki_ifc_buf != NULL)
9458 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
9460 break;
9461 case VKI_SIOCGSTAMP:
9462 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9463 break;
9464 case VKI_SIOCGSTAMPNS:
9465 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
9466 break;
9467 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
9468 the number of bytes currently in that socket's send buffer.
9469 It writes this value as an int to the memory location
9470 indicated by the third argument of ioctl(2). */
9471 case VKI_SIOCOUTQ:
9472 POST_MEM_WRITE(ARG3, sizeof(int));
9473 break;
9474 case VKI_SIOCGRARP: /* get RARP table entry */
9475 case VKI_SIOCGARP: /* get ARP table entry */
9476 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
9477 break;
9479 case VKI_SIOCSIFFLAGS: /* set flags */
9480 case VKI_SIOCSIFMAP: /* Set device parameters */
9481 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
9482 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
9483 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
9484 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
9485 case VKI_SIOCSIFNETMASK: /* set network PA mask */
9486 case VKI_SIOCSIFMETRIC: /* set metric */
9487 case VKI_SIOCSIFADDR: /* set PA address */
9488 case VKI_SIOCSIFMTU: /* set MTU size */
9489 case VKI_SIOCSIFHWADDR: /* set hardware address */
9490 case VKI_SIOCSMIIREG: /* set hardware entry registers */
9491 break;
9492 /* Routing table calls. */
9493 case VKI_SIOCADDRT: /* add routing table entry */
9494 case VKI_SIOCDELRT: /* delete routing table entry */
9495 break;
9497 /* RARP cache control calls. */
9498 case VKI_SIOCDRARP: /* delete RARP table entry */
9499 case VKI_SIOCSRARP: /* set RARP table entry */
9500 /* ARP cache control calls. */
9501 case VKI_SIOCSARP: /* set ARP table entry */
9502 case VKI_SIOCDARP: /* delete ARP table entry */
9503 break;
9505 case VKI_SIOCGPGRP:
9506 POST_MEM_WRITE(ARG3, sizeof(int));
9507 break;
9508 case VKI_SIOCSPGRP:
9509 break;
9511 case VKI_SIOCATMARK:
9512 POST_MEM_WRITE(ARG3, sizeof(int));
9513 break;
9515 /* linux/soundcard interface (OSS) */
9516 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
9517 case VKI_SNDCTL_SEQ_GETINCOUNT:
9518 case VKI_SNDCTL_SEQ_PERCMODE:
9519 case VKI_SNDCTL_SEQ_TESTMIDI:
9520 case VKI_SNDCTL_SEQ_RESETSAMPLES:
9521 case VKI_SNDCTL_SEQ_NRSYNTHS:
9522 case VKI_SNDCTL_SEQ_NRMIDIS:
9523 case VKI_SNDCTL_SEQ_GETTIME:
9524 case VKI_SNDCTL_DSP_GETBLKSIZE:
9525 case VKI_SNDCTL_DSP_GETFMTS:
9526 case VKI_SNDCTL_DSP_SETFMT:
9527 case VKI_SNDCTL_DSP_GETTRIGGER:
9528 case VKI_SNDCTL_DSP_GETODELAY:
9529 case VKI_SNDCTL_DSP_GETSPDIF:
9530 case VKI_SNDCTL_DSP_GETCAPS:
9531 case VKI_SOUND_PCM_READ_RATE:
9532 case VKI_SOUND_PCM_READ_CHANNELS:
9533 case VKI_SOUND_PCM_READ_BITS:
9534 case VKI_SOUND_PCM_READ_FILTER:
9535 POST_MEM_WRITE(ARG3, sizeof(int));
9536 break;
9537 case VKI_SNDCTL_SEQ_CTRLRATE:
9538 case VKI_SNDCTL_DSP_SPEED:
9539 case VKI_SNDCTL_DSP_STEREO:
9540 case VKI_SNDCTL_DSP_CHANNELS:
9541 case VKI_SOUND_PCM_WRITE_FILTER:
9542 case VKI_SNDCTL_DSP_SUBDIVIDE:
9543 case VKI_SNDCTL_DSP_SETFRAGMENT:
9544 case VKI_SNDCTL_DSP_GETCHANNELMASK:
9545 case VKI_SNDCTL_DSP_BIND_CHANNEL:
9546 case VKI_SNDCTL_TMR_TIMEBASE:
9547 case VKI_SNDCTL_TMR_TEMPO:
9548 case VKI_SNDCTL_TMR_SOURCE:
9549 case VKI_SNDCTL_MIDI_PRETIME:
9550 case VKI_SNDCTL_MIDI_MPUMODE:
9551 break;
9552 case VKI_SNDCTL_DSP_GETOSPACE:
9553 case VKI_SNDCTL_DSP_GETISPACE:
9554 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
9555 break;
9556 case VKI_SNDCTL_DSP_NONBLOCK:
9557 break;
9558 case VKI_SNDCTL_DSP_SETTRIGGER:
9559 break;
9561 case VKI_SNDCTL_DSP_POST:
9562 case VKI_SNDCTL_DSP_RESET:
9563 case VKI_SNDCTL_DSP_SYNC:
9564 case VKI_SNDCTL_DSP_SETSYNCRO:
9565 case VKI_SNDCTL_DSP_SETDUPLEX:
9566 break;
9568 /* linux/soundcard interface (ALSA) */
9569 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
9570 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
9571 case VKI_SNDRV_PCM_IOCTL_PREPARE:
9572 case VKI_SNDRV_PCM_IOCTL_RESET:
9573 case VKI_SNDRV_PCM_IOCTL_START:
9574 case VKI_SNDRV_PCM_IOCTL_DROP:
9575 case VKI_SNDRV_PCM_IOCTL_DRAIN:
9576 case VKI_SNDRV_PCM_IOCTL_RESUME:
9577 case VKI_SNDRV_PCM_IOCTL_XRUN:
9578 case VKI_SNDRV_PCM_IOCTL_UNLINK:
9579 case VKI_SNDRV_TIMER_IOCTL_START:
9580 case VKI_SNDRV_TIMER_IOCTL_STOP:
9581 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
9582 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
9583 break;
9585 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
9586 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
9587 break;
9589 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
9590 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
9591 break;
9592 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
9593 struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
9594 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
9595 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
9596 if (data->pids) {
9597 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
9599 break;
9601 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
9602 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
9603 POST_MEM_WRITE( (Addr)data->tlv, data->length );
9604 break;
9606 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
9607 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
9608 break;
9610 /* SCSI no operand */
9611 case VKI_SCSI_IOCTL_DOORLOCK:
9612 case VKI_SCSI_IOCTL_DOORUNLOCK:
9613 break;
9615 /* Real Time Clock (/dev/rtc) ioctls */
9616 case VKI_RTC_UIE_ON:
9617 case VKI_RTC_UIE_OFF:
9618 case VKI_RTC_AIE_ON:
9619 case VKI_RTC_AIE_OFF:
9620 case VKI_RTC_PIE_ON:
9621 case VKI_RTC_PIE_OFF:
9622 case VKI_RTC_IRQP_SET:
9623 break;
9624 case VKI_RTC_RD_TIME:
9625 case VKI_RTC_ALM_READ:
9626 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
9627 break;
9628 case VKI_RTC_ALM_SET:
9629 break;
9630 case VKI_RTC_IRQP_READ:
9631 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9632 break;
9634 /* Block devices */
9635 case VKI_BLKROSET:
9636 break;
9637 case VKI_BLKROGET:
9638 POST_MEM_WRITE(ARG3, sizeof(int));
9639 break;
9640 case VKI_BLKGETSIZE:
9641 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9642 break;
9643 case VKI_BLKFLSBUF:
9644 break;
9645 case VKI_BLKRASET:
9646 break;
9647 case VKI_BLKRAGET:
9648 POST_MEM_WRITE(ARG3, sizeof(long));
9649 break;
9650 case VKI_BLKFRASET:
9651 break;
9652 case VKI_BLKFRAGET:
9653 POST_MEM_WRITE(ARG3, sizeof(long));
9654 break;
9655 case VKI_BLKSECTGET:
9656 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
9657 break;
9658 case VKI_BLKSSZGET:
9659 POST_MEM_WRITE(ARG3, sizeof(int));
9660 break;
9661 case VKI_BLKBSZGET:
9662 POST_MEM_WRITE(ARG3, sizeof(int));
9663 break;
9664 case VKI_BLKBSZSET:
9665 break;
9666 case VKI_BLKGETSIZE64:
9667 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
9668 break;
9669 case VKI_BLKPBSZGET:
9670 POST_MEM_WRITE(ARG3, sizeof(int));
9671 break;
9672 case VKI_BLKDISCARDZEROES:
9673 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
9674 break;
9676 /* Hard disks */
9677 case VKI_HDIO_GETGEO: /* 0x0301 */
9678 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
9679 break;
9680 case VKI_HDIO_GET_DMA: /* 0x030b */
9681 POST_MEM_WRITE(ARG3, sizeof(long));
9682 break;
9683 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
9684 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
9685 break;
9687 /* SCSI */
9688 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
9689 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
9690 break;
9691 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
9692 POST_MEM_WRITE(ARG3, sizeof(int));
9693 break;
9695 /* CD ROM stuff (??) */
9696 case VKI_CDROM_DISC_STATUS:
9697 case VKI_CDROMSTOP:
9698 break;
9699 case VKI_CDROMSUBCHNL:
9700 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
9701 break;
9702 case VKI_CDROMREADTOCHDR:
9703 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
9704 break;
9705 case VKI_CDROMREADTOCENTRY:
9706 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
9707 break;
9708 case VKI_CDROMMULTISESSION:
9709 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
9710 break;
9711 case VKI_CDROMVOLREAD:
9712 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
9713 break;
9714 case VKI_CDROMREADMODE1:
9715 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
9716 break;
9717 case VKI_CDROMREADMODE2:
9718 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
9719 break;
9720 case VKI_CDROMREADRAW:
9721 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
9722 break;
9723 case VKI_CDROMREADAUDIO:
9725 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
9726 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
9727 break;
9730 case VKI_CDROMPLAYMSF:
9731 break;
9732 /* The following two are probably bogus (should check args
9733 for readability). JRS 20021117 */
9734 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
9735 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
9736 break;
9737 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
9738 break;
9740 /* DVD stuff */
9741 case VKI_DVD_READ_STRUCT:
9742 break;
9744 case VKI_FIGETBSZ:
9745 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9746 break;
9747 case VKI_FIBMAP:
9748 POST_MEM_WRITE(ARG3, sizeof(int));
9749 break;
9751 case VKI_FBIOGET_VSCREENINFO: //0x4600
9752 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
9753 break;
9754 case VKI_FBIOGET_FSCREENINFO: //0x4602
9755 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
9756 break;
9758 case VKI_PPCLAIM:
9759 case VKI_PPEXCL:
9760 case VKI_PPYIELD:
9761 case VKI_PPRELEASE:
9762 case VKI_PPSETMODE:
9763 case VKI_PPSETPHASE:
9764 case VKI_PPSETFLAGS:
9765 case VKI_PPWDATA:
9766 case VKI_PPWCONTROL:
9767 case VKI_PPFCONTROL:
9768 case VKI_PPDATADIR:
9769 case VKI_PPNEGOT:
9770 case VKI_PPWCTLONIRQ:
9771 case VKI_PPSETTIME:
9772 break;
9773 case VKI_PPGETMODE:
9774 POST_MEM_WRITE( ARG3, sizeof(int) );
9775 break;
9776 case VKI_PPGETPHASE:
9777 POST_MEM_WRITE( ARG3, sizeof(int) );
9778 break;
9779 case VKI_PPGETMODES:
9780 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9781 break;
9782 case VKI_PPGETFLAGS:
9783 POST_MEM_WRITE( ARG3, sizeof(int) );
9784 break;
9785 case VKI_PPRSTATUS:
9786 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9787 break;
9788 case VKI_PPRDATA:
9789 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9790 break;
9791 case VKI_PPRCONTROL:
9792 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
9793 break;
9794 case VKI_PPCLRIRQ:
9795 POST_MEM_WRITE( ARG3, sizeof(int) );
9796 break;
9797 case VKI_PPGETTIME:
9798 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9799 break;
9801 case VKI_GIO_FONT:
9802 POST_MEM_WRITE( ARG3, 32 * 256 );
9803 break;
9804 case VKI_PIO_FONT:
9805 break;
9807 case VKI_GIO_FONTX:
9808 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
9809 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
9810 break;
9811 case VKI_PIO_FONTX:
9812 break;
9814 case VKI_PIO_FONTRESET:
9815 break;
9817 case VKI_GIO_CMAP:
9818 POST_MEM_WRITE( ARG3, 16 * 3 );
9819 break;
9820 case VKI_PIO_CMAP:
9821 break;
9823 case VKI_KIOCSOUND:
9824 case VKI_KDMKTONE:
9825 break;
9827 case VKI_KDGETLED:
9828 POST_MEM_WRITE( ARG3, sizeof(char) );
9829 break;
9830 case VKI_KDSETLED:
9831 break;
9833 case VKI_KDGKBTYPE:
9834 POST_MEM_WRITE( ARG3, sizeof(char) );
9835 break;
9837 case VKI_KDADDIO:
9838 case VKI_KDDELIO:
9839 case VKI_KDENABIO:
9840 case VKI_KDDISABIO:
9841 break;
9843 case VKI_KDSETMODE:
9844 break;
9845 case VKI_KDGETMODE:
9846 POST_MEM_WRITE( ARG3, sizeof(int) );
9847 break;
9849 case VKI_KDMAPDISP:
9850 case VKI_KDUNMAPDISP:
9851 break;
9853 case VKI_GIO_SCRNMAP:
9854 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
9855 break;
9856 case VKI_PIO_SCRNMAP:
9857 break;
9858 case VKI_GIO_UNISCRNMAP:
9859 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
9860 break;
9861 case VKI_PIO_UNISCRNMAP:
9862 break;
9864 case VKI_GIO_UNIMAP:
9865 if ( ARG3 ) {
9866 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
9867 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
9868 POST_MEM_WRITE( (Addr)desc->entries,
9869 desc->entry_ct * sizeof(struct vki_unipair) );
9871 break;
9872 case VKI_PIO_UNIMAP:
9873 break;
9874 case VKI_PIO_UNIMAPCLR:
9875 break;
9877 case VKI_KDGKBMODE:
9878 POST_MEM_WRITE( ARG3, sizeof(int) );
9879 break;
9880 case VKI_KDSKBMODE:
9881 break;
9883 case VKI_KDGKBMETA:
9884 POST_MEM_WRITE( ARG3, sizeof(int) );
9885 break;
9886 case VKI_KDSKBMETA:
9887 break;
9889 case VKI_KDGKBLED:
9890 POST_MEM_WRITE( ARG3, sizeof(char) );
9891 break;
9892 case VKI_KDSKBLED:
9893 break;
9895 case VKI_KDGKBENT:
9896 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
9897 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
9898 break;
9899 case VKI_KDSKBENT:
9900 break;
9902 case VKI_KDGKBSENT:
9903 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
9904 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
9905 break;
9906 case VKI_KDSKBSENT:
9907 break;
9909 case VKI_KDGKBDIACR:
9910 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
9911 break;
9912 case VKI_KDSKBDIACR:
9913 break;
9915 case VKI_KDGETKEYCODE:
9916 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
9917 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
9918 break;
9919 case VKI_KDSETKEYCODE:
9920 break;
9922 case VKI_KDSIGACCEPT:
9923 break;
9925 case VKI_KDKBDREP:
9926 break;
9928 case VKI_KDFONTOP:
9929 if ( ARG3 ) {
9930 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
9931 switch ( op->op ) {
9932 case VKI_KD_FONT_OP_SET:
9933 break;
9934 case VKI_KD_FONT_OP_GET:
9935 if ( op->data )
9936 POST_MEM_WRITE( (Addr) op->data,
9937 (op->width + 7) / 8 * 32 * op->charcount );
9938 break;
9939 case VKI_KD_FONT_OP_SET_DEFAULT:
9940 break;
9941 case VKI_KD_FONT_OP_COPY:
9942 break;
9944 POST_MEM_WRITE( (Addr) op, sizeof(*op));
9946 break;
9948 case VKI_VT_OPENQRY:
9949 POST_MEM_WRITE( ARG3, sizeof(int) );
9950 break;
9951 case VKI_VT_GETMODE:
9952 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
9953 break;
9954 case VKI_VT_SETMODE:
9955 break;
9956 case VKI_VT_GETSTATE:
9957 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
9958 sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
9959 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
9960 sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
9961 break;
9962 case VKI_VT_RELDISP:
9963 case VKI_VT_ACTIVATE:
9964 case VKI_VT_WAITACTIVE:
9965 case VKI_VT_DISALLOCATE:
9966 break;
9967 case VKI_VT_RESIZE:
9968 break;
9969 case VKI_VT_RESIZEX:
9970 break;
9971 case VKI_VT_LOCKSWITCH:
9972 case VKI_VT_UNLOCKSWITCH:
9973 break;
9975 case VKI_USBDEVFS_CONTROL:
9976 if ( ARG3 ) {
9977 struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
9978 if (vkuc->bRequestType & 0x80)
9979 POST_MEM_WRITE((Addr)vkuc->data, RES);
9981 break;
9982 case VKI_USBDEVFS_BULK:
9983 if ( ARG3 ) {
9984 struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
9985 if (vkub->ep & 0x80)
9986 POST_MEM_WRITE((Addr)vkub->data, RES);
9988 break;
9989 case VKI_USBDEVFS_GETDRIVER:
9990 if ( ARG3 ) {
9991 struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
9992 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
9994 break;
9995 case VKI_USBDEVFS_REAPURB:
9996 case VKI_USBDEVFS_REAPURBNDELAY:
9997 if ( ARG3 ) {
9998 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
9999 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
10000 if (!*vkuu)
10001 break;
10002 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
10003 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10004 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10005 if (vkusp->bRequestType & 0x80)
10006 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10007 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10008 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10009 char *bp = (*vkuu)->buffer;
10010 int i;
10011 for(i=0; i<(*vkuu)->number_of_packets; i++) {
10012 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10013 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10014 if ((*vkuu)->endpoint & 0x80)
10015 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10016 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10018 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10019 } else {
10020 if ((*vkuu)->endpoint & 0x80)
10021 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10022 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10025 break;
10026 case VKI_USBDEVFS_CONNECTINFO:
10027 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10028 break;
10029 case VKI_USBDEVFS_IOCTL:
10030 if ( ARG3 ) {
10031 struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
10032 UInt dir2, size2;
10033 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
10034 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10035 if (size2 > 0) {
10036 if (dir2 & _VKI_IOC_READ)
10037 POST_MEM_WRITE((Addr)vkui->data, size2);
10040 break;
10042 /* I2C (/dev/i2c-*) ioctls */
10043 case VKI_I2C_SLAVE:
10044 case VKI_I2C_SLAVE_FORCE:
10045 case VKI_I2C_TENBIT:
10046 case VKI_I2C_PEC:
10047 break;
10048 case VKI_I2C_FUNCS:
10049 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10050 break;
10051 case VKI_I2C_RDWR:
10052 if ( ARG3 ) {
10053 struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
10054 UInt i;
10055 for (i=0; i < vkui->nmsgs; i++) {
10056 struct vki_i2c_msg *msg = vkui->msgs + i;
10057 if (msg->flags & VKI_I2C_M_RD)
10058 POST_MEM_WRITE((Addr)msg->buf, msg->len);
10061 break;
10062 case VKI_I2C_SMBUS:
10063 if ( ARG3 ) {
10064 struct vki_i2c_smbus_ioctl_data *vkis
10065 = (struct vki_i2c_smbus_ioctl_data *) ARG3;
10066 /* i2c_smbus_write_quick hides its value in read_write, so
10067 this variable can have a different meaning */
10068 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10069 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10070 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10071 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10072 UInt size;
10073 switch(vkis->size) {
10074 case VKI_I2C_SMBUS_BYTE:
10075 case VKI_I2C_SMBUS_BYTE_DATA:
10076 size = 1;
10077 break;
10078 case VKI_I2C_SMBUS_WORD_DATA:
10079 case VKI_I2C_SMBUS_PROC_CALL:
10080 size = 2;
10081 break;
10082 case VKI_I2C_SMBUS_BLOCK_DATA:
10083 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10084 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10085 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10086 size = 1 + vkis->data->block[0];
10087 break;
10088 default:
10089 size = 0;
10091 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10095 break;
10097 /* Wireless extensions ioctls */
10098 case VKI_SIOCSIWCOMMIT:
10099 case VKI_SIOCSIWNWID:
10100 case VKI_SIOCSIWFREQ:
10101 case VKI_SIOCSIWMODE:
10102 case VKI_SIOCSIWSENS:
10103 case VKI_SIOCSIWRANGE:
10104 case VKI_SIOCSIWPRIV:
10105 case VKI_SIOCSIWSTATS:
10106 case VKI_SIOCSIWSPY:
10107 case VKI_SIOCSIWTHRSPY:
10108 case VKI_SIOCSIWAP:
10109 case VKI_SIOCSIWSCAN:
10110 case VKI_SIOCSIWESSID:
10111 case VKI_SIOCSIWRATE:
10112 case VKI_SIOCSIWNICKN:
10113 case VKI_SIOCSIWRTS:
10114 case VKI_SIOCSIWFRAG:
10115 case VKI_SIOCSIWTXPOW:
10116 case VKI_SIOCSIWRETRY:
10117 case VKI_SIOCSIWENCODE:
10118 case VKI_SIOCSIWPOWER:
10119 case VKI_SIOCSIWGENIE:
10120 case VKI_SIOCSIWMLME:
10121 case VKI_SIOCSIWAUTH:
10122 case VKI_SIOCSIWENCODEEXT:
10123 case VKI_SIOCSIWPMKSA:
10124 break;
10125 case VKI_SIOCGIWNAME:
10126 if (ARG3) {
10127 POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
10128 sizeof(((struct vki_iwreq *)ARG3)->u.name));
10130 break;
10131 case VKI_SIOCGIWNWID:
10132 case VKI_SIOCGIWSENS:
10133 case VKI_SIOCGIWRATE:
10134 case VKI_SIOCGIWRTS:
10135 case VKI_SIOCGIWFRAG:
10136 case VKI_SIOCGIWTXPOW:
10137 case VKI_SIOCGIWRETRY:
10138 case VKI_SIOCGIWPOWER:
10139 case VKI_SIOCGIWAUTH:
10140 if (ARG3) {
10141 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
10142 sizeof(struct vki_iw_param));
10144 break;
10145 case VKI_SIOCGIWFREQ:
10146 if (ARG3) {
10147 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
10148 sizeof(struct vki_iw_freq));
10150 break;
10151 case VKI_SIOCGIWMODE:
10152 if (ARG3) {
10153 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
10154 sizeof(__vki_u32));
10156 break;
10157 case VKI_SIOCGIWRANGE:
10158 case VKI_SIOCGIWPRIV:
10159 case VKI_SIOCGIWSTATS:
10160 case VKI_SIOCGIWSPY:
10161 case VKI_SIOCGIWTHRSPY:
10162 case VKI_SIOCGIWAPLIST:
10163 case VKI_SIOCGIWSCAN:
10164 case VKI_SIOCGIWESSID:
10165 case VKI_SIOCGIWNICKN:
10166 case VKI_SIOCGIWENCODE:
10167 case VKI_SIOCGIWGENIE:
10168 case VKI_SIOCGIWENCODEEXT:
10169 if (ARG3) {
10170 struct vki_iw_point* point;
10171 point = &((struct vki_iwreq *)ARG3)->u.data;
10172 POST_MEM_WRITE((Addr)point->pointer, point->length);
10174 break;
10175 case VKI_SIOCGIWAP:
10176 if (ARG3) {
10177 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
10178 sizeof(struct vki_sockaddr));
10180 break;
10182 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10183 || defined(VGPV_mips32_linux_android) \
10184 || defined(VGPV_arm64_linux_android)
10185 /* ashmem */
10186 case VKI_ASHMEM_GET_SIZE:
10187 case VKI_ASHMEM_SET_SIZE:
10188 case VKI_ASHMEM_GET_PROT_MASK:
10189 case VKI_ASHMEM_SET_PROT_MASK:
10190 case VKI_ASHMEM_GET_PIN_STATUS:
10191 case VKI_ASHMEM_PURGE_ALL_CACHES:
10192 case VKI_ASHMEM_SET_NAME:
10193 case VKI_ASHMEM_PIN:
10194 case VKI_ASHMEM_UNPIN:
10195 break;
10196 case VKI_ASHMEM_GET_NAME:
10197 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10198 break;
10200 /* binder */
10201 case VKI_BINDER_WRITE_READ:
10202 if (ARG3) {
10203 struct vki_binder_write_read* bwr
10204 = (struct vki_binder_write_read*)ARG3;
10205 POST_FIELD_WRITE(bwr->write_consumed);
10206 POST_FIELD_WRITE(bwr->read_consumed);
10208 if (bwr->read_size)
10209 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10211 break;
10213 case VKI_BINDER_SET_IDLE_TIMEOUT:
10214 case VKI_BINDER_SET_MAX_THREADS:
10215 case VKI_BINDER_SET_IDLE_PRIORITY:
10216 case VKI_BINDER_SET_CONTEXT_MGR:
10217 case VKI_BINDER_THREAD_EXIT:
10218 break;
10219 case VKI_BINDER_VERSION:
10220 if (ARG3) {
10221 struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
10222 POST_FIELD_WRITE(bv->protocol_version);
10224 break;
10225 # endif /* defined(VGPV_*_linux_android) */
10227 case VKI_HCIGETDEVLIST:
10228 if (ARG3) {
10229 struct vki_hci_dev_list_req* dlr = (struct vki_hci_dev_list_req*)ARG3;
10230 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10231 dlr->dev_num * sizeof(struct vki_hci_dev_req));
10233 break;
10235 case VKI_HCIINQUIRY:
10236 if (ARG3) {
10237 struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
10238 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10239 ir->num_rsp * sizeof(struct vki_inquiry_info));
10241 break;
10243 case VKI_DRM_IOCTL_VERSION:
10244 if (ARG3) {
10245 struct vki_drm_version* data = (struct vki_drm_version *)ARG3;
10246 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10247 const vki_size_t orig_name_len = info->orig->name_len;
10248 const vki_size_t orig_date_len = info->orig->date_len;
10249 const vki_size_t orig_desc_len = info->orig->desc_len;
10250 *info->orig = info->data;
10251 ARG3 = (Addr)info->orig;
10252 data = info->orig;
10253 VG_(free)(info);
10254 if (SUCCESS) {
10255 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10256 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10257 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10258 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10259 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10260 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10261 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10262 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10263 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10266 break;
10267 case VKI_DRM_IOCTL_GET_UNIQUE:
10268 if (ARG3) {
10269 struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
10270 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10272 break;
10273 case VKI_DRM_IOCTL_GET_MAGIC:
10274 if (ARG3) {
10275 struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
10276 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10278 break;
10279 case VKI_DRM_IOCTL_WAIT_VBLANK:
10280 if (ARG3) {
10281 union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
10282 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10284 break;
10285 case VKI_DRM_IOCTL_GEM_FLINK:
10286 if (ARG3) {
10287 struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
10288 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10290 break;
10291 case VKI_DRM_IOCTL_GEM_OPEN:
10292 if (ARG3) {
10293 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
10294 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10295 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10297 break;
10298 case VKI_DRM_IOCTL_I915_GETPARAM:
10299 if (ARG3) {
10300 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
10301 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10303 break;
10304 case VKI_DRM_IOCTL_I915_GEM_BUSY:
10305 if (ARG3) {
10306 struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
10307 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10309 break;
10310 case VKI_DRM_IOCTL_I915_GEM_CREATE:
10311 if (ARG3) {
10312 struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
10313 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10315 break;
10316 case VKI_DRM_IOCTL_I915_GEM_PREAD:
10317 if (ARG3) {
10318 struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
10319 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10321 break;
10322 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10323 if (ARG3) {
10324 struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
10325 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10327 break;
10328 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10329 if (ARG3) {
10330 struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
10331 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10332 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10333 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10335 break;
10336 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10337 if (ARG3) {
10338 struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
10339 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10340 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10342 break;
10343 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10344 if (ARG3) {
10345 struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
10346 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10347 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10349 break;
10351 /* KVM ioctls that only write the system call return value */
10352 case VKI_KVM_GET_API_VERSION:
10353 case VKI_KVM_CREATE_VM:
10354 case VKI_KVM_CHECK_EXTENSION:
10355 case VKI_KVM_GET_VCPU_MMAP_SIZE:
10356 case VKI_KVM_S390_ENABLE_SIE:
10357 case VKI_KVM_CREATE_VCPU:
10358 case VKI_KVM_SET_TSS_ADDR:
10359 case VKI_KVM_CREATE_IRQCHIP:
10360 case VKI_KVM_RUN:
10361 case VKI_KVM_S390_INITIAL_RESET:
10362 case VKI_KVM_KVMCLOCK_CTRL:
10363 break;
10365 case VKI_KVM_S390_MEM_OP: {
10366 struct vki_kvm_s390_mem_op *args =
10367 (struct vki_kvm_s390_mem_op *)(ARG3);
10368 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
10369 break;
10370 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
10371 POST_MEM_WRITE((Addr)args->buf, args->size);
10373 break;
10375 #ifdef ENABLE_XEN
10376 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
10377 SyscallArgs harrghs;
10378 struct vki_xen_privcmd_hypercall *args =
10379 (struct vki_xen_privcmd_hypercall *)(ARG3);
10381 if (!args)
10382 break;
10384 VG_(memset)(&harrghs, 0, sizeof(harrghs));
10385 harrghs.sysno = args->op;
10386 harrghs.arg1 = args->arg[0];
10387 harrghs.arg2 = args->arg[1];
10388 harrghs.arg3 = args->arg[2];
10389 harrghs.arg4 = args->arg[3];
10390 harrghs.arg5 = args->arg[4];
10391 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
10393 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
10395 break;
10397 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
10398 break;
10399 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
10400 struct vki_xen_privcmd_mmapbatch *args =
10401 (struct vki_xen_privcmd_mmapbatch *)(ARG3);
10402 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
10404 break;
10405 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
10406 struct vki_xen_privcmd_mmapbatch_v2 *args =
10407 (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
10408 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
10410 break;
10412 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
10413 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
10414 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
10415 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
10416 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
10417 case VKI_XEN_IOCTL_EVTCHN_RESET:
10418 /* No output */
10419 break;
10420 #endif
10422 /* Lustre */
10423 case VKI_OBD_IOC_FID2PATH: {
10424 struct vki_getinfo_fid2path *args = (void *)(ARG3);
10425 POST_FIELD_WRITE(args->gf_recno);
10426 POST_FIELD_WRITE(args->gf_linkno);
10427 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
10428 break;
10431 case VKI_LL_IOC_PATH2FID:
10432 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
10433 break;
10435 case VKI_LL_IOC_GETPARENT: {
10436 struct vki_getparent *gp = (struct vki_getparent *)ARG3;
10437 POST_FIELD_WRITE(gp->gp_fid);
10438 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
10439 break;
10442 /* V4L2 */
10443 case VKI_V4L2_S_FMT:
10444 case VKI_V4L2_TRY_FMT:
10445 case VKI_V4L2_REQBUFS:
10446 case VKI_V4L2_OVERLAY:
10447 case VKI_V4L2_STREAMON:
10448 case VKI_V4L2_STREAMOFF:
10449 case VKI_V4L2_S_PARM:
10450 case VKI_V4L2_S_STD:
10451 case VKI_V4L2_S_FREQUENCY:
10452 case VKI_V4L2_S_CTRL:
10453 case VKI_V4L2_S_TUNER:
10454 case VKI_V4L2_S_AUDIO:
10455 case VKI_V4L2_S_INPUT:
10456 case VKI_V4L2_S_EDID:
10457 case VKI_V4L2_S_OUTPUT:
10458 case VKI_V4L2_S_AUDOUT:
10459 case VKI_V4L2_S_MODULATOR:
10460 case VKI_V4L2_S_JPEGCOMP:
10461 case VKI_V4L2_S_CROP:
10462 case VKI_V4L2_S_PRIORITY:
10463 case VKI_V4L2_S_HW_FREQ_SEEK:
10464 case VKI_V4L2_S_DV_TIMINGS:
10465 case VKI_V4L2_SUBSCRIBE_EVENT:
10466 case VKI_V4L2_UNSUBSCRIBE_EVENT:
10467 case VKI_V4L2_PREPARE_BUF:
10468 break;
10469 case VKI_V4L2_QUERYCAP: {
10470 struct vki_v4l2_capability *data = (struct vki_v4l2_capability *)ARG3;
10471 POST_MEM_WRITE((Addr)data, sizeof(*data));
10472 break;
10474 case VKI_V4L2_ENUM_FMT: {
10475 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)ARG3;
10476 POST_FIELD_WRITE(data->flags);
10477 POST_FIELD_WRITE(data->description);
10478 POST_FIELD_WRITE(data->pixelformat);
10479 POST_FIELD_WRITE(data->reserved);
10480 break;
10482 case VKI_V4L2_G_FMT: {
10483 struct vki_v4l2_format *data = (struct vki_v4l2_format *)ARG3;
10484 switch (data->type) {
10485 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10486 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10487 POST_FIELD_WRITE(data->fmt.pix);
10488 break;
10489 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10490 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10491 POST_FIELD_WRITE(data->fmt.vbi);
10492 break;
10493 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10494 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10495 POST_FIELD_WRITE(data->fmt.sliced);
10496 break;
10497 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10498 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10499 POST_FIELD_WRITE(data->fmt.win);
10500 break;
10501 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10502 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10503 POST_FIELD_WRITE(data->fmt.pix_mp);
10504 break;
10505 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10506 POST_FIELD_WRITE(data->fmt.sdr);
10507 break;
10509 break;
10511 case VKI_V4L2_QUERYBUF: {
10512 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10513 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10514 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10515 unsigned i;
10517 for (i = 0; i < data->length; i++) {
10518 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10519 POST_FIELD_WRITE(data->m.planes[i].length);
10520 POST_FIELD_WRITE(data->m.planes[i].m);
10521 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10522 POST_FIELD_WRITE(data->m.planes[i].reserved);
10524 } else {
10525 POST_FIELD_WRITE(data->m);
10526 POST_FIELD_WRITE(data->length);
10528 POST_FIELD_WRITE(data->bytesused);
10529 POST_FIELD_WRITE(data->flags);
10530 POST_FIELD_WRITE(data->field);
10531 POST_FIELD_WRITE(data->timestamp);
10532 POST_FIELD_WRITE(data->timecode);
10533 POST_FIELD_WRITE(data->sequence);
10534 POST_FIELD_WRITE(data->memory);
10535 POST_FIELD_WRITE(data->sequence);
10536 break;
10538 case VKI_V4L2_G_FBUF: {
10539 struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
10540 POST_MEM_WRITE((Addr)data, sizeof(*data));
10541 break;
10543 case VKI_V4L2_S_FBUF: {
10544 struct vki_v4l2_framebuffer *data = (struct vki_v4l2_framebuffer *)ARG3;
10545 POST_FIELD_WRITE(data->capability);
10546 POST_FIELD_WRITE(data->flags);
10547 POST_FIELD_WRITE(data->fmt);
10548 break;
10550 case VKI_V4L2_QBUF: {
10551 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10553 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10554 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10555 unsigned i;
10557 for (i = 0; i < data->length; i++) {
10558 POST_FIELD_WRITE(data->m.planes[i].length);
10559 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10560 POST_FIELD_WRITE(data->m.planes[i].m);
10562 } else {
10563 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10564 POST_FIELD_WRITE(data->m);
10565 POST_FIELD_WRITE(data->length);
10567 break;
10569 case VKI_V4L2_EXPBUF: {
10570 struct vki_v4l2_exportbuffer *data = (struct vki_v4l2_exportbuffer *)ARG3;
10571 POST_FIELD_WRITE(data->fd);
10572 break;
10574 case VKI_V4L2_DQBUF: {
10575 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)ARG3;
10576 POST_FIELD_WRITE(data->index);
10577 POST_FIELD_WRITE(data->bytesused);
10578 POST_FIELD_WRITE(data->field);
10579 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10580 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10581 unsigned i;
10583 for (i = 0; i < data->length; i++) {
10584 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10585 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10586 POST_FIELD_WRITE(data->m.planes[i].length);
10587 POST_FIELD_WRITE(data->m.planes[i].m);
10589 } else {
10590 POST_FIELD_WRITE(data->m);
10591 POST_FIELD_WRITE(data->length);
10592 POST_FIELD_WRITE(data->bytesused);
10593 POST_FIELD_WRITE(data->field);
10595 POST_FIELD_WRITE(data->timestamp);
10596 POST_FIELD_WRITE(data->timecode);
10597 POST_FIELD_WRITE(data->sequence);
10598 break;
10600 case VKI_V4L2_G_PARM: {
10601 struct vki_v4l2_streamparm *data = (struct vki_v4l2_streamparm *)ARG3;
10602 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
10603 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
10604 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
10605 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
10607 if (is_output)
10608 POST_MEM_WRITE((Addr)&data->parm.output,
10609 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
10610 else
10611 POST_MEM_WRITE((Addr)&data->parm.capture,
10612 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
10613 break;
10615 case VKI_V4L2_G_STD: {
10616 vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
10617 POST_MEM_WRITE((Addr)data, sizeof(*data));
10618 break;
10620 case VKI_V4L2_ENUMSTD: {
10621 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)ARG3;
10622 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
10623 break;
10625 case VKI_V4L2_ENUMINPUT: {
10626 struct vki_v4l2_input *data = (struct vki_v4l2_input *)ARG3;
10627 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10628 break;
10630 case VKI_V4L2_G_CTRL: {
10631 struct vki_v4l2_control *data = (struct vki_v4l2_control *)ARG3;
10632 POST_FIELD_WRITE(data->value);
10633 break;
10635 case VKI_V4L2_G_TUNER: {
10636 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)ARG3;
10637 POST_MEM_WRITE((Addr)data->name,
10638 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10639 break;
10641 case VKI_V4L2_G_AUDIO: {
10642 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
10643 POST_MEM_WRITE((Addr)data,
10644 sizeof(*data) - sizeof(data->reserved));
10645 break;
10647 case VKI_V4L2_QUERYCTRL: {
10648 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)ARG3;
10649 POST_MEM_WRITE((Addr)&data->type,
10650 sizeof(*data) - sizeof(data->id));
10651 break;
10653 case VKI_V4L2_QUERYMENU: {
10654 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)ARG3;
10655 POST_MEM_WRITE((Addr)data->name,
10656 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
10657 break;
10659 case VKI_V4L2_G_INPUT: {
10660 int *data = (int *)ARG3;
10661 POST_MEM_WRITE((Addr)data, sizeof(*data));
10662 break;
10664 case VKI_V4L2_G_EDID: {
10665 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)ARG3;
10666 if (data->blocks && data->edid)
10667 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
10668 break;
10670 case VKI_V4L2_G_OUTPUT: {
10671 int *data = (int *)ARG3;
10672 POST_MEM_WRITE((Addr)data, sizeof(*data));
10673 break;
10675 case VKI_V4L2_ENUMOUTPUT: {
10676 struct vki_v4l2_output *data = (struct vki_v4l2_output *)ARG3;
10677 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10678 break;
10680 case VKI_V4L2_G_AUDOUT: {
10681 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
10682 POST_MEM_WRITE((Addr)data,
10683 sizeof(*data) - sizeof(data->reserved));
10684 break;
10686 case VKI_V4L2_G_MODULATOR: {
10687 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)ARG3;
10688 POST_MEM_WRITE((Addr)data->name,
10689 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10690 break;
10692 case VKI_V4L2_G_FREQUENCY: {
10693 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)ARG3;
10694 POST_FIELD_WRITE(data->type);
10695 POST_FIELD_WRITE(data->frequency);
10696 break;
10698 case VKI_V4L2_CROPCAP: {
10699 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)ARG3;
10700 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
10701 break;
10703 case VKI_V4L2_G_CROP: {
10704 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)ARG3;
10705 POST_FIELD_WRITE(data->c);
10706 break;
10708 case VKI_V4L2_G_JPEGCOMP: {
10709 struct vki_v4l2_jpegcompression *data = (struct vki_v4l2_jpegcompression *)ARG3;
10710 POST_MEM_WRITE((Addr)data, sizeof(*data));
10711 break;
10713 case VKI_V4L2_QUERYSTD: {
10714 vki_v4l2_std_id *data = (vki_v4l2_std_id *)ARG3;
10715 POST_MEM_WRITE((Addr)data, sizeof(*data));
10716 break;
10718 case VKI_V4L2_ENUMAUDIO: {
10719 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)ARG3;
10720 POST_MEM_WRITE((Addr)data->name,
10721 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10722 break;
10724 case VKI_V4L2_ENUMAUDOUT: {
10725 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)ARG3;
10726 POST_MEM_WRITE((Addr)data->name,
10727 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10728 break;
10730 case VKI_V4L2_G_PRIORITY: {
10731 __vki_u32 *data = (__vki_u32 *)ARG3;
10732 POST_MEM_WRITE((Addr)data, sizeof(*data));
10733 break;
10735 case VKI_V4L2_G_SLICED_VBI_CAP: {
10736 struct vki_v4l2_sliced_vbi_cap *data = (struct vki_v4l2_sliced_vbi_cap *)ARG3;
10737 POST_MEM_WRITE((Addr)data,
10738 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
10739 break;
10741 case VKI_V4L2_G_EXT_CTRLS: {
10742 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10743 if (data->count) {
10744 unsigned i;
10746 for (i = 0; i < data->count; i++) {
10747 if (data->controls[i].size)
10748 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
10749 else
10750 POST_FIELD_WRITE(data->controls[i].value64);
10753 POST_FIELD_WRITE(data->error_idx);
10754 break;
10756 case VKI_V4L2_S_EXT_CTRLS: {
10757 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10758 POST_FIELD_WRITE(data->error_idx);
10759 break;
10761 case VKI_V4L2_TRY_EXT_CTRLS: {
10762 struct vki_v4l2_ext_controls *data = (struct vki_v4l2_ext_controls *)ARG3;
10763 POST_FIELD_WRITE(data->error_idx);
10764 break;
10766 case VKI_V4L2_ENUM_FRAMESIZES: {
10767 struct vki_v4l2_frmsizeenum *data = (struct vki_v4l2_frmsizeenum *)ARG3;
10768 POST_FIELD_WRITE(data->type);
10769 POST_FIELD_WRITE(data->stepwise);
10770 break;
10772 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
10773 struct vki_v4l2_frmivalenum *data = (struct vki_v4l2_frmivalenum *)ARG3;
10774 POST_FIELD_WRITE(data->type);
10775 POST_FIELD_WRITE(data->stepwise);
10776 break;
10778 case VKI_V4L2_G_ENC_INDEX: {
10779 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)ARG3;
10780 POST_MEM_WRITE((Addr)data, sizeof(*data));
10781 break;
10783 case VKI_V4L2_ENCODER_CMD: {
10784 struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10785 POST_FIELD_WRITE(data->flags);
10786 break;
10788 case VKI_V4L2_TRY_ENCODER_CMD: {
10789 struct vki_v4l2_encoder_cmd *data = (struct vki_v4l2_encoder_cmd *)ARG3;
10790 POST_FIELD_WRITE(data->flags);
10791 break;
10793 case VKI_V4L2_DBG_S_REGISTER: {
10794 struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10795 POST_FIELD_WRITE(data->size);
10796 break;
10798 case VKI_V4L2_DBG_G_REGISTER: {
10799 struct vki_v4l2_dbg_register *data = (struct vki_v4l2_dbg_register *)ARG3;
10800 POST_FIELD_WRITE(data->val);
10801 POST_FIELD_WRITE(data->size);
10802 break;
10804 case VKI_V4L2_G_DV_TIMINGS: {
10805 struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10806 POST_MEM_WRITE((Addr)data, sizeof(*data));
10807 break;
10809 case VKI_V4L2_DQEVENT: {
10810 struct vki_v4l2_event *data = (struct vki_v4l2_event *)ARG3;
10811 POST_MEM_WRITE((Addr)data, sizeof(*data));
10812 break;
10814 case VKI_V4L2_CREATE_BUFS: {
10815 struct vki_v4l2_create_buffers *data = (struct vki_v4l2_create_buffers *)ARG3;
10816 POST_FIELD_WRITE(data->index);
10817 break;
10819 case VKI_V4L2_G_SELECTION: {
10820 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10821 POST_FIELD_WRITE(data->r);
10822 break;
10824 case VKI_V4L2_S_SELECTION: {
10825 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)ARG3;
10826 POST_FIELD_WRITE(data->r);
10827 break;
10829 case VKI_V4L2_DECODER_CMD: {
10830 struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10831 POST_FIELD_WRITE(data->flags);
10832 break;
10834 case VKI_V4L2_TRY_DECODER_CMD: {
10835 struct vki_v4l2_decoder_cmd *data = (struct vki_v4l2_decoder_cmd *)ARG3;
10836 POST_FIELD_WRITE(data->flags);
10837 break;
10839 case VKI_V4L2_ENUM_DV_TIMINGS: {
10840 struct vki_v4l2_enum_dv_timings *data = (struct vki_v4l2_enum_dv_timings *)ARG3;
10841 POST_FIELD_WRITE(data->timings);
10842 break;
10844 case VKI_V4L2_QUERY_DV_TIMINGS: {
10845 struct vki_v4l2_dv_timings *data = (struct vki_v4l2_dv_timings *)ARG3;
10846 POST_MEM_WRITE((Addr)data, sizeof(*data));
10847 break;
10849 case VKI_V4L2_DV_TIMINGS_CAP: {
10850 struct vki_v4l2_dv_timings_cap *data = (struct vki_v4l2_dv_timings_cap *)ARG3;
10851 POST_MEM_WRITE((Addr)data, sizeof(*data));
10852 break;
10854 case VKI_V4L2_ENUM_FREQ_BANDS: {
10855 struct vki_v4l2_frequency_band *data = (struct vki_v4l2_frequency_band *)ARG3;
10856 POST_FIELD_WRITE(data->capability);
10857 POST_FIELD_WRITE(data->rangelow);
10858 POST_FIELD_WRITE(data->rangehigh);
10859 POST_FIELD_WRITE(data->modulation);
10860 break;
10862 case VKI_V4L2_DBG_G_CHIP_INFO: {
10863 struct vki_v4l2_dbg_chip_info *data = (struct vki_v4l2_dbg_chip_info *)ARG3;
10864 POST_FIELD_WRITE(data->name);
10865 POST_FIELD_WRITE(data->flags);
10866 break;
10868 case VKI_V4L2_QUERY_EXT_CTRL: {
10869 struct vki_v4l2_query_ext_ctrl *data = (struct vki_v4l2_query_ext_ctrl *)ARG3;
10870 POST_MEM_WRITE((Addr)&data->type,
10871 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
10872 break;
10875 case VKI_V4L2_SUBDEV_S_FMT:
10876 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
10877 case VKI_V4L2_SUBDEV_S_CROP:
10878 case VKI_V4L2_SUBDEV_S_SELECTION:
10879 break;
10881 case VKI_V4L2_SUBDEV_G_FMT: {
10882 struct vki_v4l2_subdev_format *data = (struct vki_v4l2_subdev_format *)ARG3;
10883 POST_FIELD_WRITE(data->format);
10884 break;
10886 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10887 struct vki_v4l2_subdev_frame_interval *data = (struct vki_v4l2_subdev_frame_interval *)ARG3;
10888 POST_FIELD_WRITE(data->interval);
10889 break;
10891 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10892 struct vki_v4l2_subdev_mbus_code_enum *data = (struct vki_v4l2_subdev_mbus_code_enum *)ARG3;
10893 POST_FIELD_WRITE(data->code);
10894 break;
10896 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10897 struct vki_v4l2_subdev_frame_size_enum *data = (struct vki_v4l2_subdev_frame_size_enum *)ARG3;
10898 POST_FIELD_WRITE(data->min_width);
10899 POST_FIELD_WRITE(data->min_height);
10900 POST_FIELD_WRITE(data->max_width);
10901 POST_FIELD_WRITE(data->max_height);
10902 break;
10904 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10905 struct vki_v4l2_subdev_frame_interval_enum *data = (struct vki_v4l2_subdev_frame_interval_enum *)ARG3;
10906 POST_FIELD_WRITE(data->interval);
10907 break;
10909 case VKI_V4L2_SUBDEV_G_CROP: {
10910 struct vki_v4l2_subdev_crop *data = (struct vki_v4l2_subdev_crop *)ARG3;
10911 POST_FIELD_WRITE(data->rect);
10912 break;
10914 case VKI_V4L2_SUBDEV_G_SELECTION: {
10915 struct vki_v4l2_subdev_selection *data = (struct vki_v4l2_subdev_selection *)ARG3;
10916 POST_FIELD_WRITE(data->r);
10917 break;
10919 case VKI_MEDIA_IOC_DEVICE_INFO: {
10920 struct vki_media_device_info *data = (struct vki_media_device_info *)ARG3;
10921 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
10922 break;
10924 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10925 struct vki_media_entity_desc *data = (struct vki_media_entity_desc *)ARG3;
10926 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
10927 break;
10929 case VKI_MEDIA_IOC_ENUM_LINKS:
10931 * This ioctl does write to the provided pointers, but it's not
10932 * possible to deduce the size of the array those pointers point to.
10934 break;
10935 case VKI_MEDIA_IOC_SETUP_LINK:
10936 break;
10938 /* Serial */
10939 case VKI_TIOCGSERIAL: {
10940 struct vki_serial_struct *data = (struct vki_serial_struct *)ARG3;
10941 POST_MEM_WRITE((Addr)data, sizeof(*data));
10942 break;
10944 case VKI_TIOCSSERIAL:
10945 break;
10947 case VKI_PERF_EVENT_IOC_ENABLE:
10948 case VKI_PERF_EVENT_IOC_DISABLE:
10949 case VKI_PERF_EVENT_IOC_REFRESH:
10950 case VKI_PERF_EVENT_IOC_RESET:
10951 case VKI_PERF_EVENT_IOC_PERIOD:
10952 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10953 case VKI_PERF_EVENT_IOC_SET_FILTER:
10954 case VKI_PERF_EVENT_IOC_SET_BPF:
10955 break;
10957 case VKI_PERF_EVENT_IOC_ID:
10958 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
10959 break;
10961 default:
10962 /* EVIOC* are variable length and return size written on success */
10963 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10964 case VKI_EVIOCGNAME(0):
10965 case VKI_EVIOCGPHYS(0):
10966 case VKI_EVIOCGUNIQ(0):
10967 case VKI_EVIOCGKEY(0):
10968 case VKI_EVIOCGLED(0):
10969 case VKI_EVIOCGSND(0):
10970 case VKI_EVIOCGSW(0):
10971 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10972 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10973 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10974 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10975 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10976 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10977 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10978 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10979 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10980 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10981 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10982 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10983 if (RES > 0)
10984 POST_MEM_WRITE(ARG3, RES);
10985 break;
10986 default:
10987 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
10988 break;
10990 break;
10993 post_sys_ioctl__out:
10994 {} /* keep C compilers happy */
10997 /* ---------------------------------------------------------------------
10998 socketcall wrapper helpers
10999 ------------------------------------------------------------------ */
11001 void
11002 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
11003 UWord arg0, UWord arg1, UWord arg2,
11004 UWord arg3, UWord arg4 )
11006 /* int getsockopt(int s, int level, int optname,
11007 void *optval, socklen_t *optlen); */
11008 Addr optval_p = arg3;
11009 Addr optlen_p = arg4;
11010 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11011 if (optval_p != (Addr)NULL) {
11012 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11013 "socketcall.getsockopt(optval)",
11014 "socketcall.getsockopt(optlen)" );
11015 if (arg1 == VKI_SOL_SCTP &&
11016 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11017 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11019 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11020 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11021 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11022 (Addr)ga->addrs, address_bytes );
11027 void
11028 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11029 SysRes res,
11030 UWord arg0, UWord arg1, UWord arg2,
11031 UWord arg3, UWord arg4 )
11033 Addr optval_p = arg3;
11034 Addr optlen_p = arg4;
11035 vg_assert(!sr_isError(res)); /* guaranteed by caller */
11036 if (optval_p != (Addr)NULL) {
11037 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11038 "socketcall.getsockopt(optlen_out)" );
11039 if (arg1 == VKI_SOL_SCTP &&
11040 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11041 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11043 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11044 struct vki_sockaddr *a = ga->addrs;
11045 int i;
11046 for (i = 0; i < ga->addr_num; i++) {
11047 int sl = 0;
11048 if (a->sa_family == VKI_AF_INET)
11049 sl = sizeof(struct vki_sockaddr_in);
11050 else if (a->sa_family == VKI_AF_INET6)
11051 sl = sizeof(struct vki_sockaddr_in6);
11052 else {
11053 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11054 "address type %d\n", a->sa_family);
11056 a = (struct vki_sockaddr*)((char*)a + sl);
11058 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11063 void
11064 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11065 UWord arg0, UWord arg1, UWord arg2,
11066 UWord arg3, UWord arg4 )
11068 /* int setsockopt(int s, int level, int optname,
11069 const void *optval, socklen_t optlen); */
11070 Addr optval_p = arg3;
11071 if (optval_p != (Addr)NULL) {
11073 * OK, let's handle at least some setsockopt levels and options
11074 * ourselves, so we don't get false claims of references to
11075 * uninitialized memory (such as padding in structures) and *do*
11076 * check what pointers in the argument point to.
11078 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11080 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11083 * struct sock_fprog has a 16-bit count of instructions,
11084 * followed by a pointer to an array of those instructions.
11085 * There's padding between those two elements.
11087 * So that we don't bogusly complain about the padding bytes,
11088 * we just report that we read len and and filter.
11090 * We then make sure that what filter points to is valid.
11092 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11093 (Addr)&fp->len, sizeof(fp->len) );
11094 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11095 (Addr)&fp->filter, sizeof(fp->filter) );
11097 /* len * sizeof (*filter) */
11098 if (fp->filter != NULL)
11100 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11101 (Addr)(fp->filter),
11102 fp->len * sizeof(*fp->filter) );
11105 else
11107 PRE_MEM_READ( "socketcall.setsockopt(optval)",
11108 arg3, /* optval */
11109 arg4 /* optlen */ );
11114 void
11115 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11116 UWord arg1, UWord arg2, UWord arg3,
11117 UWord arg4, UWord arg5 )
11119 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11120 HChar name[40]; // large enough
11121 UInt i;
11122 for (i = 0; i < arg3; i++) {
11123 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11124 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11125 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11126 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11128 if (arg5)
11129 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11132 void
11133 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11134 UWord arg1, UWord arg2, UWord arg3,
11135 UWord arg4, UWord arg5 )
11137 if (res > 0) {
11138 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11139 HChar name[32]; // large enough
11140 UInt i;
11141 for (i = 0; i < res; i++) {
11142 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11143 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11144 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11149 void
11150 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11151 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11153 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11154 HChar name[40]; // large enough
11155 UInt i;
11156 for (i = 0; i < arg3; i++) {
11157 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11158 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11159 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11160 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11164 void
11165 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11166 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11168 if (res > 0) {
11169 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11170 UInt i;
11171 for (i = 0; i < res; i++) {
11172 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11177 /* ---------------------------------------------------------------------
11178 ptrace wrapper helpers
11179 ------------------------------------------------------------------ */
11181 void
11182 ML_(linux_POST_traceme) ( ThreadId tid )
11184 ThreadState *tst = VG_(get_ThreadState)(tid);
11185 tst->ptrace = VKI_PT_PTRACED;
11188 void
11189 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11191 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11193 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11194 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11195 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11196 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11197 (Addr) iov->iov_base, iov->iov_len);
11201 void
11202 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11204 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11206 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11207 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11208 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11209 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11210 (Addr) iov->iov_base, iov->iov_len);
11214 void
11215 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11217 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11219 /* XXX: The actual amount of data written by the kernel might be
11220 less than iov_len, depending on the regset (arg3). */
11221 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11224 PRE(sys_kcmp)
11226 PRINT("kcmp ( %ld, %ld, %ld, %lu, %lu )", SARG1, SARG2, SARG3, ARG4, ARG5);
11227 switch (ARG3) {
11228 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11229 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11230 /* Most of the comparison types don't look at |idx1| or
11231 |idx2|. */
11232 PRE_REG_READ3(long, "kcmp",
11233 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11234 break;
11235 case VKI_KCMP_FILE:
11236 default:
11237 PRE_REG_READ5(long, "kcmp",
11238 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11239 unsigned long, idx1, unsigned long, idx2);
11240 break;
11244 #undef PRE
11245 #undef POST
11247 #endif // defined(VGO_linux)
11249 /*--------------------------------------------------------------------*/
11250 /*--- end ---*/
11251 /*--------------------------------------------------------------------*/