Add support for the Linux membarrier() system call
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob2336c297840fd2875a337a55b2d4f70528d584f5
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 %" FMT_REGWORD "u\n",
774 VG_(getpid)(), (RegWord)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 ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
799 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
800 ARG4, ARG5);
802 // Order of arguments differs between platforms.
803 #if defined(VGP_x86_linux) \
804 || defined(VGP_ppc32_linux) \
805 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
806 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
807 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
808 #define ARG_CHILD_TIDPTR ARG5
809 #define PRA_CHILD_TIDPTR PRA5
810 #define ARG_TLS ARG4
811 #define PRA_TLS PRA4
812 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
813 #define ARG_CHILD_TIDPTR ARG4
814 #define PRA_CHILD_TIDPTR PRA4
815 #define ARG_TLS ARG5
816 #define PRA_TLS PRA5
817 #else
818 # error Unknown platform
819 #endif
820 // And s390x is even more special, and inverts flags and child stack args
821 #if defined(VGP_s390x_linux)
822 #define ARG_FLAGS ARG2
823 #define PRA_FLAGS PRA2
824 #define ARG_CHILD_STACK ARG1
825 #define PRA_CHILD_STACK PRA1
826 #else
827 #define ARG_FLAGS ARG1
828 #define PRA_FLAGS PRA1
829 #define ARG_CHILD_STACK ARG2
830 #define PRA_CHILD_STACK PRA2
831 #endif
833 if (VG_(tdict).track_pre_reg_read) {
834 PRA_FLAGS("clone", unsigned long, flags);
835 PRA_CHILD_STACK("clone", void *, child_stack);
838 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID) {
839 if (VG_(tdict).track_pre_reg_read) {
840 PRA3("clone", int *, parent_tidptr);
842 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
843 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
844 VKI_PROT_WRITE)) {
845 badarg = True;
848 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
849 if (VG_(tdict).track_pre_reg_read) {
850 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
852 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
853 dummy type (that we define as a char). We only dereference/check the
854 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
855 if (sizeof(vki_modify_ldt_t) > 1) {
856 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
857 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
858 VKI_PROT_READ)) {
859 badarg = True;
863 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
864 if (VG_(tdict).track_pre_reg_read) {
865 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
867 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
868 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
869 VKI_PROT_WRITE)) {
870 badarg = True;
874 if (badarg) {
875 SET_STATUS_Failure( VKI_EFAULT );
876 return;
879 cloneflags = ARG_FLAGS;
881 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
882 SET_STATUS_Failure( VKI_EINVAL );
883 return;
886 /* Only look at the flags we really care about */
887 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
888 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
889 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
890 /* thread creation */
891 SET_STATUS_from_SysRes(
892 do_clone(tid,
893 ARG_FLAGS, /* flags */
894 (Addr)ARG_CHILD_STACK, /* child ESP */
895 (Int*)(Addr)ARG3, /* parent_tidptr */
896 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
897 (Addr)ARG_TLS)); /* set_tls */
898 break;
900 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
901 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
902 cloneflags &= ~VKI_CLONE_VM;
904 case 0: /* plain fork */
905 SET_STATUS_from_SysRes(
906 ML_(do_fork_clone)(tid,
907 cloneflags, /* flags */
908 (Int*)(Addr)ARG3, /* parent_tidptr */
909 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
910 (Addr)ARG_CHILD_STACK));
911 break;
913 default:
914 /* should we just ENOSYS? */
915 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
916 "x\n", ARG_FLAGS);
917 VG_(message)(Vg_UserMsg, "\n");
918 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
919 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
920 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
921 VG_(unimplemented)
922 ("Valgrind does not support general clone().");
925 if (SUCCESS) {
926 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
927 POST_MEM_WRITE(ARG3, sizeof(Int));
928 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
929 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
931 /* Thread creation was successful; let the child have the chance
932 to run */
933 *flags |= SfYieldAfter;
936 #undef ARG_CHILD_TIDPTR
937 #undef PRA_CHILD_TIDPTR
938 #undef ARG_TLS
939 #undef PRA_TLS
940 #undef ARG_FLAGS
941 #undef PRA_FLAGS
942 #undef ARG_CHILD_STACK
943 #undef PRA_CHILD_STACK
946 /* ---------------------------------------------------------------------
947 *mount wrappers
948 ------------------------------------------------------------------ */
950 PRE(sys_mount)
952 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
953 // We are conservative and check everything, except the memory pointed to
954 // by 'data'.
955 *flags |= SfMayBlock;
956 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
957 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
958 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
959 (HChar*)(Addr)ARG3, ARG4, ARG5);
960 PRE_REG_READ5(long, "mount",
961 char *, source, char *, target, char *, type,
962 unsigned long, flags, void *, data);
963 if (ARG1)
964 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
965 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
966 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
969 PRE(sys_oldumount)
971 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
972 PRE_REG_READ1(long, "umount", char *, path);
973 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
976 PRE(sys_umount)
978 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
979 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
980 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
983 /* Not actually wrapped by GLibc but does things with the system
984 * mounts so it is put here.
986 PRE(sys_pivot_root)
988 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
989 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
990 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
991 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
995 /* ---------------------------------------------------------------------
996 16- and 32-bit uid/gid wrappers
997 ------------------------------------------------------------------ */
999 PRE(sys_setfsuid16)
1001 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1002 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1005 PRE(sys_setfsuid)
1007 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1008 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1011 PRE(sys_setfsgid16)
1013 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1014 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1017 PRE(sys_setfsgid)
1019 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1020 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1023 PRE(sys_setresuid16)
1025 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1026 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1027 PRE_REG_READ3(long, "setresuid16",
1028 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1031 PRE(sys_setresuid)
1033 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1034 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1035 PRE_REG_READ3(long, "setresuid",
1036 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1039 PRE(sys_getresuid16)
1041 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1042 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1043 PRE_REG_READ3(long, "getresuid16",
1044 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1045 vki_old_uid_t *, suid);
1046 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1047 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1048 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1050 POST(sys_getresuid16)
1052 vg_assert(SUCCESS);
1053 if (RES == 0) {
1054 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1055 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1056 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1060 PRE(sys_getresuid)
1062 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1063 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1064 PRE_REG_READ3(long, "getresuid",
1065 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1066 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1067 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1068 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1070 POST(sys_getresuid)
1072 vg_assert(SUCCESS);
1073 if (RES == 0) {
1074 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1075 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1076 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1080 PRE(sys_setresgid16)
1082 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1083 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1084 PRE_REG_READ3(long, "setresgid16",
1085 vki_old_gid_t, rgid,
1086 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1089 PRE(sys_setresgid)
1091 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1092 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1093 PRE_REG_READ3(long, "setresgid",
1094 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1097 PRE(sys_getresgid16)
1099 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1100 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1101 PRE_REG_READ3(long, "getresgid16",
1102 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1103 vki_old_gid_t *, sgid);
1104 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1105 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1106 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1108 POST(sys_getresgid16)
1110 vg_assert(SUCCESS);
1111 if (RES == 0) {
1112 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1113 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1114 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1118 PRE(sys_getresgid)
1120 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1121 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1122 PRE_REG_READ3(long, "getresgid",
1123 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1124 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1125 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1126 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1128 POST(sys_getresgid)
1130 vg_assert(SUCCESS);
1131 if (RES == 0) {
1132 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1133 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1134 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1138 /* ---------------------------------------------------------------------
1139 miscellaneous wrappers
1140 ------------------------------------------------------------------ */
1142 PRE(sys_exit_group)
1144 ThreadId t;
1145 ThreadState* tst;
1147 PRINT("exit_group( %ld )", SARG1);
1148 PRE_REG_READ1(void, "exit_group", int, status);
1150 tst = VG_(get_ThreadState)(tid);
1151 /* A little complex; find all the threads with the same threadgroup
1152 as this one (including this one), and mark them to exit */
1153 /* It is unclear how one can get a threadgroup in this process which
1154 is not the threadgroup of the calling thread:
1155 The assignments to threadgroups are:
1156 = 0; /// scheduler.c os_state_clear
1157 = getpid(); /// scheduler.c in child after fork
1158 = getpid(); /// this file, in thread_wrapper
1159 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1160 copying the thread group of the thread doing clone
1161 So, the only case where the threadgroup might be different to the getpid
1162 value is in the child, just after fork. But then the fork syscall is
1163 still going on, the forked thread has had no chance yet to make this
1164 syscall. */
1165 for (t = 1; t < VG_N_THREADS; t++) {
1166 if ( /* not alive */
1167 VG_(threads)[t].status == VgTs_Empty
1169 /* not our group */
1170 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1172 continue;
1173 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1174 the exitreason. */
1175 VG_(threads)[t].os_state.exitcode = ARG1;
1178 /* Indicate in all other threads that the process is exiting.
1179 Then wait using VG_(reap_threads) for these threads to disappear.
1181 Can this give a deadlock if another thread is calling exit in parallel
1182 and would then wait for this thread to disappear ?
1183 The answer is no:
1184 Other threads are either blocked in a syscall or have yielded the CPU.
1186 A thread that has yielded the CPU is trying to get the big lock in
1187 VG_(scheduler). This thread will get the CPU thanks to the call
1188 to VG_(reap_threads). The scheduler will then check for signals,
1189 kill the process if this is a fatal signal, and otherwise prepare
1190 the thread for handling this signal. After this preparation, if
1191 the thread status is VG_(is_exiting), the scheduler exits the thread.
1192 So, a thread that has yielded the CPU does not have a chance to
1193 call exit => no deadlock for this thread.
1195 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1196 to all threads blocked in a syscall.
1197 The syscall will be interrupted, and the control will go to the
1198 scheduler. The scheduler will then return, as the thread is in
1199 exiting state. */
1201 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1202 VG_(reap_threads)(tid);
1203 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1204 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1205 is the thread calling exit_group and so its registers must be considered
1206 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1208 /* We have to claim the syscall already succeeded. */
1209 SET_STATUS_Success(0);
1212 PRE(sys_llseek)
1214 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1215 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1216 ARG1, ARG2, ARG3, ARG4, ARG5);
1217 PRE_REG_READ5(long, "llseek",
1218 unsigned int, fd, unsigned long, offset_high,
1219 unsigned long, offset_low, vki_loff_t *, result,
1220 unsigned int, whence);
1221 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1222 SET_STATUS_Failure( VKI_EBADF );
1223 else
1224 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1226 POST(sys_llseek)
1228 vg_assert(SUCCESS);
1229 if (RES == 0)
1230 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1233 PRE(sys_adjtimex)
1235 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1236 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1237 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1239 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1240 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1242 #define ADJX(bits,field) \
1243 if (tx->modes & (bits)) \
1244 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1245 (Addr)&tx->field, sizeof(tx->field))
1247 if (tx->modes & VKI_ADJ_ADJTIME) {
1248 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1249 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1250 } else {
1251 ADJX(VKI_ADJ_OFFSET, offset);
1252 ADJX(VKI_ADJ_FREQUENCY, freq);
1253 ADJX(VKI_ADJ_MAXERROR, maxerror);
1254 ADJX(VKI_ADJ_ESTERROR, esterror);
1255 ADJX(VKI_ADJ_STATUS, status);
1256 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1257 ADJX(VKI_ADJ_TICK, tick);
1259 #undef ADJX
1262 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1265 POST(sys_adjtimex)
1267 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1270 PRE(sys_clock_adjtime)
1272 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1273 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1274 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1275 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1277 #define ADJX(bits,field) \
1278 if (tx->modes & (bits)) \
1279 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1280 (Addr)&tx->field, sizeof(tx->field))
1282 if (tx->modes & VKI_ADJ_ADJTIME) {
1283 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1284 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1285 } else {
1286 ADJX(VKI_ADJ_OFFSET, offset);
1287 ADJX(VKI_ADJ_FREQUENCY, freq);
1288 ADJX(VKI_ADJ_MAXERROR, maxerror);
1289 ADJX(VKI_ADJ_ESTERROR, esterror);
1290 ADJX(VKI_ADJ_STATUS, status);
1291 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1292 ADJX(VKI_ADJ_TICK, tick);
1294 #undef ADJX
1296 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1299 POST(sys_clock_adjtime)
1301 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1304 PRE(sys_ioperm)
1306 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1307 ARG1, ARG2, SARG3 );
1308 PRE_REG_READ3(long, "ioperm",
1309 unsigned long, from, unsigned long, num, int, turn_on);
1312 PRE(sys_syslog)
1314 *flags |= SfMayBlock;
1315 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1316 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1317 switch (ARG1) {
1318 // The kernel uses magic numbers here, rather than named constants,
1319 // therefore so do we.
1320 case 2: case 3: case 4:
1321 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1322 break;
1323 default:
1324 break;
1327 POST(sys_syslog)
1329 switch (ARG1) {
1330 case 2: case 3: case 4:
1331 POST_MEM_WRITE( ARG2, ARG3 );
1332 break;
1333 default:
1334 break;
1338 PRE(sys_vhangup)
1340 PRINT("sys_vhangup ( )");
1341 PRE_REG_READ0(long, "vhangup");
1344 PRE(sys_sysinfo)
1346 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1347 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1348 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1350 POST(sys_sysinfo)
1352 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1355 PRE(sys_personality)
1357 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1358 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1361 PRE(sys_sysctl)
1363 struct __vki_sysctl_args *args;
1364 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1365 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1366 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1367 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1368 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1369 VKI_PROT_READ)) {
1370 SET_STATUS_Failure( VKI_EFAULT );
1371 return;
1374 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1375 if (args->newval != NULL)
1376 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1377 if (args->oldlenp != NULL) {
1378 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1379 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1382 POST(sys_sysctl)
1384 struct __vki_sysctl_args *args;
1385 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1386 if (args->oldlenp != NULL) {
1387 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1388 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1392 PRE(sys_prctl)
1394 *flags |= SfMayBlock;
1395 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1396 switch (ARG1) {
1397 case VKI_PR_SET_PDEATHSIG:
1398 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1399 break;
1400 case VKI_PR_GET_PDEATHSIG:
1401 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1402 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1403 break;
1404 case VKI_PR_GET_DUMPABLE:
1405 PRE_REG_READ1(int, "prctl", int, option);
1406 break;
1407 case VKI_PR_SET_DUMPABLE:
1408 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1409 break;
1410 case VKI_PR_GET_UNALIGN:
1411 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1412 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1413 break;
1414 case VKI_PR_SET_UNALIGN:
1415 PRE_REG_READ2(int, "prctl", int, option, int, value);
1416 break;
1417 case VKI_PR_GET_KEEPCAPS:
1418 PRE_REG_READ1(int, "prctl", int, option);
1419 break;
1420 case VKI_PR_SET_KEEPCAPS:
1421 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1422 break;
1423 case VKI_PR_GET_FPEMU:
1424 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1425 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1426 break;
1427 case VKI_PR_SET_FPEMU:
1428 PRE_REG_READ2(int, "prctl", int, option, int, value);
1429 break;
1430 case VKI_PR_GET_FPEXC:
1431 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1432 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1433 break;
1434 case VKI_PR_SET_FPEXC:
1435 PRE_REG_READ2(int, "prctl", int, option, int, value);
1436 break;
1437 case VKI_PR_GET_TIMING:
1438 PRE_REG_READ1(int, "prctl", int, option);
1439 break;
1440 case VKI_PR_SET_TIMING:
1441 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1442 break;
1443 case VKI_PR_SET_NAME:
1444 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1445 /* The name can be up to TASK_COMM_LEN(16) bytes long, including
1446 the terminating null byte. So do not check more than 16 bytes. */
1447 if (ML_(safe_to_deref)((const HChar *) (Addr)ARG2, VKI_TASK_COMM_LEN)) {
1448 SizeT len = VG_(strnlen)((const HChar *) (Addr)ARG2,
1449 VKI_TASK_COMM_LEN);
1450 if (len < VKI_TASK_COMM_LEN) {
1451 PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
1452 } else {
1453 PRE_MEM_READ("prctl(set-name)", ARG2, VKI_TASK_COMM_LEN);
1455 } else {
1456 /* Do it the slow way, one byte at a time, while checking for
1457 terminating '\0'. */
1458 const HChar *name = (const HChar *) (Addr)ARG2;
1459 for (UInt i = 0; i < VKI_TASK_COMM_LEN; i++) {
1460 PRE_MEM_READ("prctl(set-name)", (Addr) &name[i], 1);
1461 if (!ML_(safe_to_deref)(&name[i], 1) || name[i] == '\0') {
1462 break;
1466 break;
1467 case VKI_PR_GET_NAME:
1468 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1469 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1470 break;
1471 case VKI_PR_GET_ENDIAN:
1472 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1473 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1474 break;
1475 case VKI_PR_SET_ENDIAN:
1476 PRE_REG_READ2(int, "prctl", int, option, int, value);
1477 break;
1478 case VKI_PR_SET_PTRACER:
1479 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1480 break;
1481 case VKI_PR_SET_SECCOMP:
1482 /* This is a bit feeble in that it uses |option| before checking
1483 it, but at least both sides of the conditional check it. */
1484 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1485 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1486 if (ARG3) {
1487 /* Should check that ARG3 points at a valid struct sock_fprog.
1488 Sounds complex; hence be lame. */
1489 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1490 ARG3, 1 );
1492 } else {
1493 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1495 break;
1496 default:
1497 PRE_REG_READ5(long, "prctl",
1498 int, option, unsigned long, arg2, unsigned long, arg3,
1499 unsigned long, arg4, unsigned long, arg5);
1500 break;
1503 POST(sys_prctl)
1505 switch (ARG1) {
1506 case VKI_PR_GET_PDEATHSIG:
1507 POST_MEM_WRITE(ARG2, sizeof(Int));
1508 break;
1509 case VKI_PR_GET_UNALIGN:
1510 POST_MEM_WRITE(ARG2, sizeof(Int));
1511 break;
1512 case VKI_PR_GET_FPEMU:
1513 POST_MEM_WRITE(ARG2, sizeof(Int));
1514 break;
1515 case VKI_PR_GET_FPEXC:
1516 POST_MEM_WRITE(ARG2, sizeof(Int));
1517 break;
1518 case VKI_PR_GET_NAME:
1519 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1520 break;
1521 case VKI_PR_GET_ENDIAN:
1522 POST_MEM_WRITE(ARG2, sizeof(Int));
1523 break;
1524 case VKI_PR_SET_NAME:
1526 const HChar* new_name = (const HChar*) (Addr)ARG2;
1527 if (new_name) { // Paranoia
1528 ThreadState* tst = VG_(get_ThreadState)(tid);
1529 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1531 /* Don't bother reusing the memory. This is a rare event. */
1532 tst->thread_name =
1533 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1534 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1537 break;
1541 PRE(sys_sendfile)
1543 *flags |= SfMayBlock;
1544 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1545 SARG1, SARG2, ARG3, ARG4);
1546 PRE_REG_READ4(ssize_t, "sendfile",
1547 int, out_fd, int, in_fd, vki_off_t *, offset,
1548 vki_size_t, count);
1549 if (ARG3 != 0)
1550 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1552 POST(sys_sendfile)
1554 if (ARG3 != 0 ) {
1555 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1559 PRE(sys_sendfile64)
1561 *flags |= SfMayBlock;
1562 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1563 SARG1, SARG2, ARG3, ARG4);
1564 PRE_REG_READ4(ssize_t, "sendfile64",
1565 int, out_fd, int, in_fd, vki_loff_t *, offset,
1566 vki_size_t, count);
1567 if (ARG3 != 0)
1568 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1570 POST(sys_sendfile64)
1572 if (ARG3 != 0 ) {
1573 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1577 PRE(sys_futex)
1580 arg param used by ops
1582 ARG1 - u32 *futex all
1583 ARG2 - int op
1584 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1585 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1586 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1587 ARG6 - int val3 CMP_REQUEUE
1589 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1590 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1591 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1592 case VKI_FUTEX_CMP_REQUEUE:
1593 case VKI_FUTEX_WAKE_OP:
1594 case VKI_FUTEX_CMP_REQUEUE_PI:
1595 PRE_REG_READ6(long, "futex",
1596 vki_u32 *, futex, int, op, int, val,
1597 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1598 break;
1599 case VKI_FUTEX_REQUEUE:
1600 case VKI_FUTEX_WAIT_REQUEUE_PI:
1601 PRE_REG_READ5(long, "futex",
1602 vki_u32 *, futex, int, op, int, val,
1603 struct timespec *, utime, vki_u32 *, uaddr2);
1604 break;
1605 case VKI_FUTEX_WAIT_BITSET:
1606 /* Check that the address at least begins in client-accessible area. */
1607 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1608 SET_STATUS_Failure( VKI_EFAULT );
1609 return;
1611 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1612 PRE_REG_READ4(long, "futex",
1613 vki_u32 *, futex, int, op, int, val,
1614 struct timespec *, utime);
1615 } else {
1616 /* Note argument 5 is unused, but argument 6 is used.
1617 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1618 PRE_REG_READ4(long, "futex",
1619 vki_u32 *, futex, int, op, int, val,
1620 struct timespec *, utime);
1621 if (VG_(tdict).track_pre_reg_read)
1622 PRA6("futex",int,val3);
1624 break;
1625 case VKI_FUTEX_WAKE_BITSET:
1626 PRE_REG_READ3(long, "futex",
1627 vki_u32 *, futex, int, op, int, val);
1628 if (VG_(tdict).track_pre_reg_read) {
1629 PRA6("futex", int, val3);
1631 break;
1632 case VKI_FUTEX_WAIT:
1633 case VKI_FUTEX_LOCK_PI:
1634 PRE_REG_READ4(long, "futex",
1635 vki_u32 *, futex, int, op, int, val,
1636 struct timespec *, utime);
1637 break;
1638 case VKI_FUTEX_WAKE:
1639 case VKI_FUTEX_FD:
1640 PRE_REG_READ3(long, "futex",
1641 vki_u32 *, futex, int, op, int, val);
1642 break;
1643 case VKI_FUTEX_TRYLOCK_PI:
1644 case VKI_FUTEX_UNLOCK_PI:
1645 default:
1646 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1647 break;
1650 *flags |= SfMayBlock;
1652 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1653 case VKI_FUTEX_WAIT:
1654 case VKI_FUTEX_LOCK_PI:
1655 case VKI_FUTEX_WAIT_BITSET:
1656 case VKI_FUTEX_WAIT_REQUEUE_PI:
1657 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1658 if (ARG4 != 0)
1659 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1660 break;
1662 case VKI_FUTEX_REQUEUE:
1663 case VKI_FUTEX_CMP_REQUEUE:
1664 case VKI_FUTEX_CMP_REQUEUE_PI:
1665 case VKI_FUTEX_WAKE_OP:
1666 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1667 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1668 break;
1670 case VKI_FUTEX_FD:
1671 case VKI_FUTEX_TRYLOCK_PI:
1672 case VKI_FUTEX_UNLOCK_PI:
1673 case VKI_FUTEX_WAKE:
1674 case VKI_FUTEX_WAKE_BITSET:
1675 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1676 break;
1678 default:
1679 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1680 break;
1683 POST(sys_futex)
1685 vg_assert(SUCCESS);
1686 POST_MEM_WRITE( ARG1, sizeof(int) );
1687 if (ARG2 == VKI_FUTEX_FD) {
1688 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1689 VG_(close)(RES);
1690 SET_STATUS_Failure( VKI_EMFILE );
1691 } else {
1692 if (VG_(clo_track_fds))
1693 ML_(record_fd_open_nameless)(tid, RES);
1698 PRE(sys_set_robust_list)
1700 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1701 FMT_REGWORD "u )", ARG1, ARG2);
1702 PRE_REG_READ2(long, "set_robust_list",
1703 struct vki_robust_list_head *, head, vki_size_t, len);
1705 /* Just check the robust_list_head structure is readable - don't
1706 try and chase the list as the kernel will only read it when
1707 the thread exits so the current contents is irrelevant. */
1708 if (ARG1 != 0)
1709 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1712 PRE(sys_get_robust_list)
1714 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1715 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1716 PRE_REG_READ3(long, "get_robust_list",
1717 int, pid,
1718 struct vki_robust_list_head **, head_ptr,
1719 vki_size_t *, len_ptr);
1720 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1721 ARG2, sizeof(struct vki_robust_list_head *));
1722 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1723 ARG3, sizeof(struct vki_size_t *));
1725 POST(sys_get_robust_list)
1727 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1728 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1731 struct pselect_sized_sigset {
1732 const vki_sigset_t *ss;
1733 vki_size_t ss_len;
1735 struct pselect_adjusted_sigset {
1736 struct pselect_sized_sigset ss; /* The actual syscall arg */
1737 vki_sigset_t adjusted_ss;
1740 PRE(sys_pselect6)
1742 *flags |= SfMayBlock | SfPostOnFail;
1743 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1744 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1745 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1746 PRE_REG_READ6(long, "pselect6",
1747 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1748 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1749 void *, sig);
1750 // XXX: this possibly understates how much memory is read.
1751 if (ARG2 != 0)
1752 PRE_MEM_READ( "pselect6(readfds)",
1753 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1754 if (ARG3 != 0)
1755 PRE_MEM_READ( "pselect6(writefds)",
1756 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1757 if (ARG4 != 0)
1758 PRE_MEM_READ( "pselect6(exceptfds)",
1759 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1760 if (ARG5 != 0)
1761 PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1762 if (ARG6 != 0) {
1763 const struct pselect_sized_sigset *pss =
1764 (struct pselect_sized_sigset *)(Addr)ARG6;
1765 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1766 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1767 ARG6 = 1; /* Something recognisable to POST() hook. */
1768 } else {
1769 struct pselect_adjusted_sigset *pas;
1770 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1771 ARG6 = (Addr)pas;
1772 pas->ss.ss = (void *)1;
1773 pas->ss.ss_len = pss->ss_len;
1774 if (pss->ss_len == sizeof(*pss->ss)) {
1775 if (pss->ss == NULL) {
1776 pas->ss.ss = NULL;
1777 } else {
1778 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1779 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1780 pas->adjusted_ss = *pss->ss;
1781 pas->ss.ss = &pas->adjusted_ss;
1782 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1789 POST(sys_pselect6)
1791 if (ARG6 != 0 && ARG6 != 1) {
1792 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1796 PRE(sys_ppoll)
1798 UInt i;
1799 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1800 *flags |= SfMayBlock | SfPostOnFail;
1801 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1802 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1803 ARG1, ARG2, ARG3, ARG4, ARG5);
1804 PRE_REG_READ5(long, "ppoll",
1805 struct vki_pollfd *, ufds, unsigned int, nfds,
1806 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1807 vki_size_t, sigsetsize);
1809 for (i = 0; i < ARG2; i++) {
1810 PRE_MEM_READ( "ppoll(ufds.fd)",
1811 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1812 PRE_MEM_READ( "ppoll(ufds.events)",
1813 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1814 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1815 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1818 if (ARG3)
1819 PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1820 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1821 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1822 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1823 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1824 ARG4 = 1; /* Something recognisable to POST() hook. */
1825 } else {
1826 vki_sigset_t *vg_sigmask =
1827 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1828 ARG4 = (Addr)vg_sigmask;
1829 *vg_sigmask = *guest_sigmask;
1830 VG_(sanitize_client_sigmask)(vg_sigmask);
1835 POST(sys_ppoll)
1837 vg_assert(SUCCESS || FAILURE);
1838 if (SUCCESS && (RES >= 0)) {
1839 UInt i;
1840 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1841 for (i = 0; i < ARG2; i++)
1842 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1844 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1845 VG_(free)((vki_sigset_t *) (Addr)ARG4);
1850 /* ---------------------------------------------------------------------
1851 epoll_* wrappers
1852 ------------------------------------------------------------------ */
1854 PRE(sys_epoll_create)
1856 PRINT("sys_epoll_create ( %ld )", SARG1);
1857 PRE_REG_READ1(long, "epoll_create", int, size);
1859 POST(sys_epoll_create)
1861 vg_assert(SUCCESS);
1862 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1863 VG_(close)(RES);
1864 SET_STATUS_Failure( VKI_EMFILE );
1865 } else {
1866 if (VG_(clo_track_fds))
1867 ML_(record_fd_open_nameless) (tid, RES);
1871 PRE(sys_epoll_create1)
1873 PRINT("sys_epoll_create1 ( %ld )", SARG1);
1874 PRE_REG_READ1(long, "epoll_create1", int, flags);
1876 POST(sys_epoll_create1)
1878 vg_assert(SUCCESS);
1879 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1880 VG_(close)(RES);
1881 SET_STATUS_Failure( VKI_EMFILE );
1882 } else {
1883 if (VG_(clo_track_fds))
1884 ML_(record_fd_open_nameless) (tid, RES);
1888 PRE(sys_epoll_ctl)
1890 static const HChar* epoll_ctl_s[3] = {
1891 "EPOLL_CTL_ADD",
1892 "EPOLL_CTL_DEL",
1893 "EPOLL_CTL_MOD"
1895 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
1896 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1897 PRE_REG_READ4(long, "epoll_ctl",
1898 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1899 if (ARG2 != VKI_EPOLL_CTL_DEL)
1900 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1903 PRE(sys_epoll_wait)
1905 *flags |= SfMayBlock;
1906 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
1907 SARG1, ARG2, SARG3, SARG4);
1908 PRE_REG_READ4(long, "epoll_wait",
1909 int, epfd, struct vki_epoll_event *, events,
1910 int, maxevents, int, timeout);
1911 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1913 POST(sys_epoll_wait)
1915 vg_assert(SUCCESS);
1916 if (RES > 0)
1917 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1920 PRE(sys_epoll_pwait)
1922 *flags |= SfMayBlock;
1923 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
1924 FMT_REGWORD "x, %" FMT_REGWORD "u )",
1925 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1926 PRE_REG_READ6(long, "epoll_pwait",
1927 int, epfd, struct vki_epoll_event *, events,
1928 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1929 vki_size_t, sigsetsize);
1930 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1931 if (ARG5)
1932 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1934 POST(sys_epoll_pwait)
1936 vg_assert(SUCCESS);
1937 if (RES > 0)
1938 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1941 PRE(sys_eventfd)
1943 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
1944 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1946 POST(sys_eventfd)
1948 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1949 VG_(close)(RES);
1950 SET_STATUS_Failure( VKI_EMFILE );
1951 } else {
1952 if (VG_(clo_track_fds))
1953 ML_(record_fd_open_nameless) (tid, RES);
1957 PRE(sys_eventfd2)
1959 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
1960 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1962 POST(sys_eventfd2)
1964 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1965 VG_(close)(RES);
1966 SET_STATUS_Failure( VKI_EMFILE );
1967 } else {
1968 if (VG_(clo_track_fds))
1969 ML_(record_fd_open_nameless) (tid, RES);
1973 PRE(sys_fallocate)
1975 *flags |= SfMayBlock;
1976 #if VG_WORDSIZE == 4
1977 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1978 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
1979 PRE_REG_READ6(long, "fallocate",
1980 int, fd, int, mode,
1981 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1982 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1983 #elif VG_WORDSIZE == 8
1984 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
1985 SARG1, SARG2, SARG3, SARG4);
1986 PRE_REG_READ4(long, "fallocate",
1987 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1988 #else
1989 # error Unexpected word size
1990 #endif
1991 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1992 SET_STATUS_Failure( VKI_EBADF );
1995 PRE(sys_prlimit64)
1997 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
1998 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
1999 PRE_REG_READ4(long, "prlimit64",
2000 vki_pid_t, pid, unsigned int, resource,
2001 const struct rlimit64 *, new_rlim,
2002 struct rlimit64 *, old_rlim);
2003 if (ARG3)
2004 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2005 if (ARG4)
2006 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2008 if (ARG3 &&
2009 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2010 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2011 SET_STATUS_Failure( VKI_EINVAL );
2013 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2014 switch (ARG2) {
2015 case VKI_RLIMIT_NOFILE:
2016 SET_STATUS_Success( 0 );
2017 if (ARG4) {
2018 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2019 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2021 if (ARG3) {
2022 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2023 > VG_(fd_hard_limit) ||
2024 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2025 != VG_(fd_hard_limit)) {
2026 SET_STATUS_Failure( VKI_EPERM );
2028 else {
2029 VG_(fd_soft_limit) =
2030 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2033 break;
2035 case VKI_RLIMIT_DATA:
2036 SET_STATUS_Success( 0 );
2037 if (ARG4) {
2038 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2039 VG_(client_rlimit_data).rlim_cur;
2040 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2041 VG_(client_rlimit_data).rlim_max;
2043 if (ARG3) {
2044 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2045 > VG_(client_rlimit_data).rlim_max ||
2046 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2047 > VG_(client_rlimit_data).rlim_max) {
2048 SET_STATUS_Failure( VKI_EPERM );
2050 else {
2051 VG_(client_rlimit_data).rlim_cur =
2052 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2053 VG_(client_rlimit_data).rlim_max =
2054 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2057 break;
2059 case VKI_RLIMIT_STACK:
2060 SET_STATUS_Success( 0 );
2061 if (ARG4) {
2062 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2063 VG_(client_rlimit_stack).rlim_cur;
2064 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2065 VG_(client_rlimit_stack).rlim_max;
2067 if (ARG3) {
2068 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2069 > VG_(client_rlimit_stack).rlim_max ||
2070 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2071 > VG_(client_rlimit_stack).rlim_max) {
2072 SET_STATUS_Failure( VKI_EPERM );
2074 else {
2075 VG_(threads)[tid].client_stack_szB =
2076 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2077 VG_(client_rlimit_stack).rlim_cur =
2078 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2079 VG_(client_rlimit_stack).rlim_max =
2080 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2083 break;
2088 POST(sys_prlimit64)
2090 if (ARG4)
2091 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2094 /* ---------------------------------------------------------------------
2095 tid-related wrappers
2096 ------------------------------------------------------------------ */
2098 PRE(sys_gettid)
2100 PRINT("sys_gettid ()");
2101 PRE_REG_READ0(long, "gettid");
2104 PRE(sys_set_tid_address)
2106 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2107 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2110 PRE(sys_tkill)
2112 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2113 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2114 if (!ML_(client_signal_OK)(ARG2)) {
2115 SET_STATUS_Failure( VKI_EINVAL );
2116 return;
2119 /* Check to see if this kill gave us a pending signal */
2120 *flags |= SfPollAfter;
2122 if (VG_(clo_trace_signals))
2123 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2124 SARG2, SARG1);
2126 /* If we're sending SIGKILL, check to see if the target is one of
2127 our threads and handle it specially. */
2128 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2129 SET_STATUS_Success(0);
2130 return;
2133 /* Ask to handle this syscall via the slow route, since that's the
2134 only one that sets tst->status to VgTs_WaitSys. If the result
2135 of doing the syscall is an immediate run of
2136 async_signalhandler() in m_signals, then we need the thread to
2137 be properly tidied away. I have the impression the previous
2138 version of this wrapper worked on x86/amd64 only because the
2139 kernel did not immediately deliver the async signal to this
2140 thread (on ppc it did, which broke the assertion re tst->status
2141 at the top of async_signalhandler()). */
2142 *flags |= SfMayBlock;
2144 POST(sys_tkill)
2146 if (VG_(clo_trace_signals))
2147 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2148 SARG2, SARG1);
2151 PRE(sys_tgkill)
2153 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2154 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2155 if (!ML_(client_signal_OK)(ARG3)) {
2156 SET_STATUS_Failure( VKI_EINVAL );
2157 return;
2160 /* Check to see if this kill gave us a pending signal */
2161 *flags |= SfPollAfter;
2163 if (VG_(clo_trace_signals))
2164 VG_(message)(Vg_DebugMsg,
2165 "tgkill: sending signal %ld to pid %ld/%ld\n",
2166 SARG3, SARG1, SARG2);
2168 /* If we're sending SIGKILL, check to see if the target is one of
2169 our threads and handle it specially. */
2170 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2171 SET_STATUS_Success(0);
2172 return;
2175 /* Ask to handle this syscall via the slow route, since that's the
2176 only one that sets tst->status to VgTs_WaitSys. If the result
2177 of doing the syscall is an immediate run of
2178 async_signalhandler() in m_signals, then we need the thread to
2179 be properly tidied away. I have the impression the previous
2180 version of this wrapper worked on x86/amd64 only because the
2181 kernel did not immediately deliver the async signal to this
2182 thread (on ppc it did, which broke the assertion re tst->status
2183 at the top of async_signalhandler()). */
2184 *flags |= SfMayBlock;
2186 POST(sys_tgkill)
2188 if (VG_(clo_trace_signals))
2189 VG_(message)(Vg_DebugMsg,
2190 "tgkill: sent signal %ld to pid %ld/%ld\n",
2191 SARG3, SARG1, SARG2);
2194 /* ---------------------------------------------------------------------
2195 fadvise64* wrappers
2196 ------------------------------------------------------------------ */
2198 PRE(sys_fadvise64)
2200 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2201 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2202 PRE_REG_READ5(long, "fadvise64",
2203 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2204 vki_size_t, len, int, advice);
2207 PRE(sys_fadvise64_64)
2209 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2210 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2211 PRE_REG_READ6(long, "fadvise64_64",
2212 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2213 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2216 /* ---------------------------------------------------------------------
2217 io_* wrappers
2218 ------------------------------------------------------------------ */
2220 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2221 // and this allows us to control exactly the code that gets run while
2222 // the padding is in place.
2224 PRE(sys_io_setup)
2226 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2227 PRE_REG_READ2(long, "io_setup",
2228 unsigned, nr_events, vki_aio_context_t *, ctxp);
2229 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2232 POST(sys_io_setup)
2234 SizeT size;
2235 struct vki_aio_ring *r;
2237 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2238 ARG1*sizeof(struct vki_io_event));
2239 r = *(struct vki_aio_ring **)(Addr)ARG2;
2240 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2242 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2243 VKI_PROT_READ | VKI_PROT_WRITE,
2244 VKI_MAP_ANONYMOUS, -1, 0 );
2246 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2249 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2250 // after the syscall. We must get 'size' from the aio_ring structure,
2251 // before the syscall, while the aio_ring structure still exists. (And we
2252 // know that we must look at the aio_ring structure because Tom inspected the
2253 // kernel and glibc sources to see what they do, yuk.)
2255 // XXX This segment can be implicitly unmapped when aio
2256 // file-descriptors are closed...
2257 PRE(sys_io_destroy)
2259 SizeT size = 0;
2261 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2262 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2264 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2265 // possible...
2266 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2267 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2268 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2269 r->nr*sizeof(struct vki_io_event));
2272 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2274 if (SUCCESS && RES == 0) {
2275 Bool d = VG_(am_notify_munmap)( ARG1, size );
2276 VG_TRACK( die_mem_munmap, ARG1, size );
2277 if (d)
2278 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2279 "PRE(sys_io_destroy)" );
2283 PRE(sys_io_getevents)
2285 *flags |= SfMayBlock;
2286 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2287 FMT_REGWORD "x )",
2288 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2289 PRE_REG_READ5(long, "io_getevents",
2290 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2291 struct io_event *, events,
2292 struct timespec *, timeout);
2293 if (ARG3 > 0)
2294 PRE_MEM_WRITE( "io_getevents(events)",
2295 ARG4, sizeof(struct vki_io_event)*ARG3 );
2296 if (ARG5 != 0)
2297 PRE_MEM_READ( "io_getevents(timeout)",
2298 ARG5, sizeof(struct vki_timespec));
2300 POST(sys_io_getevents)
2302 Int i;
2303 vg_assert(SUCCESS);
2304 if (RES > 0) {
2305 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2306 for (i = 0; i < RES; i++) {
2307 const struct vki_io_event *vev =
2308 ((struct vki_io_event *)(Addr)ARG4) + i;
2309 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2311 switch (cb->aio_lio_opcode) {
2312 case VKI_IOCB_CMD_PREAD:
2313 if (vev->result > 0)
2314 POST_MEM_WRITE( cb->aio_buf, vev->result );
2315 break;
2317 case VKI_IOCB_CMD_PWRITE:
2318 break;
2320 case VKI_IOCB_CMD_FSYNC:
2321 break;
2323 case VKI_IOCB_CMD_FDSYNC:
2324 break;
2326 case VKI_IOCB_CMD_PREADV:
2327 if (vev->result > 0) {
2328 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2329 Int remains = vev->result;
2330 Int j;
2332 for (j = 0; j < cb->aio_nbytes; j++) {
2333 Int nReadThisBuf = vec[j].iov_len;
2334 if (nReadThisBuf > remains) nReadThisBuf = remains;
2335 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2336 remains -= nReadThisBuf;
2337 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2340 break;
2342 case VKI_IOCB_CMD_PWRITEV:
2343 break;
2345 default:
2346 VG_(message)(Vg_DebugMsg,
2347 "Warning: unhandled io_getevents opcode: %u\n",
2348 cb->aio_lio_opcode);
2349 break;
2355 PRE(sys_io_submit)
2357 Int i, j;
2359 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2360 ARG1, SARG2, ARG3);
2361 PRE_REG_READ3(long, "io_submit",
2362 vki_aio_context_t, ctx_id, long, nr,
2363 struct iocb **, iocbpp);
2364 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2365 if (ARG3 != 0) {
2366 for (i = 0; i < ARG2; i++) {
2367 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2368 struct vki_iovec *iov;
2370 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2371 switch (cb->aio_lio_opcode) {
2372 case VKI_IOCB_CMD_PREAD:
2373 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2374 break;
2376 case VKI_IOCB_CMD_PWRITE:
2377 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2378 break;
2380 case VKI_IOCB_CMD_FSYNC:
2381 break;
2383 case VKI_IOCB_CMD_FDSYNC:
2384 break;
2386 case VKI_IOCB_CMD_PREADV:
2387 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2388 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2389 for (j = 0; j < cb->aio_nbytes; j++)
2390 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2391 break;
2393 case VKI_IOCB_CMD_PWRITEV:
2394 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2395 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2396 for (j = 0; j < cb->aio_nbytes; j++)
2397 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2398 break;
2400 default:
2401 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2402 cb->aio_lio_opcode);
2403 break;
2409 PRE(sys_io_cancel)
2411 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2412 (ULong)ARG1, ARG2, ARG3);
2413 PRE_REG_READ3(long, "io_cancel",
2414 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2415 struct io_event *, result);
2416 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2417 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2419 POST(sys_io_cancel)
2421 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2424 /* ---------------------------------------------------------------------
2425 *_mempolicy wrappers
2426 ------------------------------------------------------------------ */
2428 PRE(sys_mbind)
2430 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2431 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2432 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2433 PRE_REG_READ6(long, "mbind",
2434 unsigned long, start, unsigned long, len,
2435 unsigned long, policy, unsigned long *, nodemask,
2436 unsigned long, maxnode, unsigned, flags);
2437 if (ARG1 != 0)
2438 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2439 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2442 PRE(sys_set_mempolicy)
2444 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2445 SARG1, ARG2, ARG3);
2446 PRE_REG_READ3(long, "set_mempolicy",
2447 int, policy, unsigned long *, nodemask,
2448 unsigned long, maxnode);
2449 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2450 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2453 PRE(sys_get_mempolicy)
2455 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2456 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2457 ARG1, ARG2, ARG3, ARG4, ARG5);
2458 PRE_REG_READ5(long, "get_mempolicy",
2459 int *, policy, unsigned long *, nodemask,
2460 unsigned long, maxnode, unsigned long, addr,
2461 unsigned long, flags);
2462 if (ARG1 != 0)
2463 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2464 if (ARG2 != 0)
2465 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2466 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2468 POST(sys_get_mempolicy)
2470 if (ARG1 != 0)
2471 POST_MEM_WRITE( ARG1, sizeof(Int) );
2472 if (ARG2 != 0)
2473 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2476 /* ---------------------------------------------------------------------
2477 fanotify_* wrappers
2478 ------------------------------------------------------------------ */
2480 PRE(sys_fanotify_init)
2482 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2483 ARG1, ARG2);
2484 PRE_REG_READ2(long, "fanotify_init",
2485 unsigned int, flags, unsigned int, event_f_flags);
2488 POST(sys_fanotify_init)
2490 vg_assert(SUCCESS);
2491 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2492 VG_(close)(RES);
2493 SET_STATUS_Failure( VKI_EMFILE );
2494 } else {
2495 if (VG_(clo_track_fds))
2496 ML_(record_fd_open_nameless) (tid, RES);
2500 PRE(sys_fanotify_mark)
2502 #if VG_WORDSIZE == 4
2503 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2504 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2505 (HChar *)(Addr)ARG6);
2506 PRE_REG_READ6(long, "sys_fanotify_mark",
2507 int, fanotify_fd, unsigned int, flags,
2508 __vki_u32, mask0, __vki_u32, mask1,
2509 int, dfd, const char *, pathname);
2510 if (ARG6)
2511 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2512 #elif VG_WORDSIZE == 8
2513 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2514 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2515 PRE_REG_READ5(long, "sys_fanotify_mark",
2516 int, fanotify_fd, unsigned int, flags,
2517 __vki_u64, mask,
2518 int, dfd, const char *, pathname);
2519 if (ARG5)
2520 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2521 #else
2522 # error Unexpected word size
2523 #endif
2526 /* ---------------------------------------------------------------------
2527 inotify_* wrappers
2528 ------------------------------------------------------------------ */
2530 PRE(sys_inotify_init)
2532 PRINT("sys_inotify_init ( )");
2533 PRE_REG_READ0(long, "inotify_init");
2535 POST(sys_inotify_init)
2537 vg_assert(SUCCESS);
2538 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2539 VG_(close)(RES);
2540 SET_STATUS_Failure( VKI_EMFILE );
2541 } else {
2542 if (VG_(clo_track_fds))
2543 ML_(record_fd_open_nameless) (tid, RES);
2547 PRE(sys_inotify_init1)
2549 PRINT("sys_inotify_init ( %ld )", SARG1);
2550 PRE_REG_READ1(long, "inotify_init", int, flag);
2553 POST(sys_inotify_init1)
2555 vg_assert(SUCCESS);
2556 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2557 VG_(close)(RES);
2558 SET_STATUS_Failure( VKI_EMFILE );
2559 } else {
2560 if (VG_(clo_track_fds))
2561 ML_(record_fd_open_nameless) (tid, RES);
2565 PRE(sys_inotify_add_watch)
2567 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2568 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2569 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2570 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2573 PRE(sys_inotify_rm_watch)
2575 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2576 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2579 /* ---------------------------------------------------------------------
2580 mq_* wrappers
2581 ------------------------------------------------------------------ */
2583 PRE(sys_mq_open)
2585 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2586 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2587 PRE_REG_READ4(long, "mq_open",
2588 const char *, name, int, oflag, vki_mode_t, mode,
2589 struct mq_attr *, attr);
2590 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2591 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2592 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2593 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2594 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2595 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2596 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2599 POST(sys_mq_open)
2601 vg_assert(SUCCESS);
2602 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2603 VG_(close)(RES);
2604 SET_STATUS_Failure( VKI_EMFILE );
2605 } else {
2606 if (VG_(clo_track_fds))
2607 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2611 PRE(sys_mq_unlink)
2613 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2614 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2615 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2618 PRE(sys_mq_timedsend)
2620 *flags |= SfMayBlock;
2621 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2622 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2623 SARG1,ARG2,ARG3,ARG4,ARG5);
2624 PRE_REG_READ5(long, "mq_timedsend",
2625 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2626 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2627 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2628 SET_STATUS_Failure( VKI_EBADF );
2629 } else {
2630 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2631 if (ARG5 != 0)
2632 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2633 sizeof(struct vki_timespec) );
2637 PRE(sys_mq_timedreceive)
2639 *flags |= SfMayBlock;
2640 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2641 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2642 SARG1,ARG2,ARG3,ARG4,ARG5);
2643 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2644 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2645 unsigned int *, msg_prio,
2646 const struct timespec *, abs_timeout);
2647 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2648 SET_STATUS_Failure( VKI_EBADF );
2649 } else {
2650 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2651 if (ARG4 != 0)
2652 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2653 ARG4, sizeof(unsigned int) );
2654 if (ARG5 != 0)
2655 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2656 ARG5, sizeof(struct vki_timespec) );
2659 POST(sys_mq_timedreceive)
2661 POST_MEM_WRITE( ARG2, RES );
2662 if (ARG4 != 0)
2663 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2666 PRE(sys_mq_notify)
2668 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2669 PRE_REG_READ2(long, "mq_notify",
2670 vki_mqd_t, mqdes, const struct sigevent *, notification);
2671 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2672 SET_STATUS_Failure( VKI_EBADF );
2673 else if (ARG2 != 0)
2674 PRE_MEM_READ( "mq_notify(notification)",
2675 ARG2, sizeof(struct vki_sigevent) );
2678 PRE(sys_mq_getsetattr)
2680 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2681 SARG1, ARG2, ARG3 );
2682 PRE_REG_READ3(long, "mq_getsetattr",
2683 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2684 struct mq_attr *, omqstat);
2685 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2686 SET_STATUS_Failure( VKI_EBADF );
2687 } else {
2688 if (ARG2 != 0) {
2689 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2690 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2691 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2693 if (ARG3 != 0)
2694 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2695 sizeof(struct vki_mq_attr) );
2698 POST(sys_mq_getsetattr)
2700 if (ARG3 != 0)
2701 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2704 /* ---------------------------------------------------------------------
2705 clock_* wrappers
2706 ------------------------------------------------------------------ */
2708 PRE(sys_clock_settime)
2710 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2711 PRE_REG_READ2(long, "clock_settime",
2712 vki_clockid_t, clk_id, const struct timespec *, tp);
2713 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2716 PRE(sys_clock_gettime)
2718 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2719 PRE_REG_READ2(long, "clock_gettime",
2720 vki_clockid_t, clk_id, struct timespec *, tp);
2721 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2723 POST(sys_clock_gettime)
2725 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2728 PRE(sys_clock_getres)
2730 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2731 // Nb: we can't use "RES" as the param name because that's a macro
2732 // defined above!
2733 PRE_REG_READ2(long, "clock_getres",
2734 vki_clockid_t, clk_id, struct timespec *, res);
2735 if (ARG2 != 0)
2736 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2738 POST(sys_clock_getres)
2740 if (ARG2 != 0)
2741 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2744 PRE(sys_clock_nanosleep)
2746 *flags |= SfMayBlock|SfPostOnFail;
2747 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
2748 FMT_REGWORD "x )",
2749 SARG1, SARG2, ARG3, ARG4);
2750 PRE_REG_READ4(int32_t, "clock_nanosleep",
2751 vki_clockid_t, clkid, int, flags,
2752 const struct timespec *, rqtp, struct timespec *, rmtp);
2753 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2754 if (ARG4 != 0)
2755 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2757 POST(sys_clock_nanosleep)
2759 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2760 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2763 /* ---------------------------------------------------------------------
2764 timer_* wrappers
2765 ------------------------------------------------------------------ */
2767 PRE(sys_timer_create)
2769 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2770 SARG1, ARG2, ARG3);
2771 PRE_REG_READ3(long, "timer_create",
2772 vki_clockid_t, clockid, struct sigevent *, evp,
2773 vki_timer_t *, timerid);
2774 if (ARG2 != 0) {
2775 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
2776 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2777 sizeof(vki_sigval_t) );
2778 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2779 sizeof(int) );
2780 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2781 sizeof(int) );
2782 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2783 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2784 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2785 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2787 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2789 POST(sys_timer_create)
2791 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2794 PRE(sys_timer_settime)
2796 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
2797 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
2798 PRE_REG_READ4(long, "timer_settime",
2799 vki_timer_t, timerid, int, flags,
2800 const struct itimerspec *, value,
2801 struct itimerspec *, ovalue);
2802 PRE_MEM_READ( "timer_settime(value)", ARG3,
2803 sizeof(struct vki_itimerspec) );
2804 if (ARG4 != 0)
2805 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2806 sizeof(struct vki_itimerspec) );
2808 POST(sys_timer_settime)
2810 if (ARG4 != 0)
2811 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2814 PRE(sys_timer_gettime)
2816 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2817 PRE_REG_READ2(long, "timer_gettime",
2818 vki_timer_t, timerid, struct itimerspec *, value);
2819 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2820 sizeof(struct vki_itimerspec));
2822 POST(sys_timer_gettime)
2824 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2827 PRE(sys_timer_getoverrun)
2829 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
2830 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2833 PRE(sys_timer_delete)
2835 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
2836 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2839 /* ---------------------------------------------------------------------
2840 timerfd* wrappers
2841 See also http://lwn.net/Articles/260172/ for an overview.
2842 See also /usr/src/linux/fs/timerfd.c for the implementation.
2843 ------------------------------------------------------------------ */
2845 /* Returns True if running on 2.6.22, else False (or False if
2846 cannot be determined). */
2847 static Bool linux_kernel_2_6_22(void)
2849 static Int result = -1;
2850 Int fd, read;
2851 HChar release[64]; // large enough
2852 SysRes res;
2854 if (result == -1) {
2855 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2856 if (sr_isError(res))
2857 return False;
2858 fd = sr_Res(res);
2859 read = VG_(read)(fd, release, sizeof(release) - 1);
2860 if (read < 0)
2861 return False;
2862 release[read] = 0;
2863 VG_(close)(fd);
2864 //VG_(printf)("kernel release = %s\n", release);
2865 result = VG_(strncmp)(release, "2.6.22", 6) == 0
2866 && ! VG_(isdigit)(release[6]);
2868 vg_assert(result == 0 || result == 1);
2869 return result == 1;
2872 PRE(sys_timerfd_create)
2874 if (linux_kernel_2_6_22()) {
2875 /* 2.6.22 kernel: timerfd system call. */
2876 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
2877 PRE_REG_READ3(long, "sys_timerfd",
2878 int, fd, int, clockid, const struct itimerspec *, tmr);
2879 PRE_MEM_READ("timerfd(tmr)", ARG3,
2880 sizeof(struct vki_itimerspec) );
2881 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2882 SET_STATUS_Failure( VKI_EBADF );
2883 } else {
2884 /* 2.6.24 and later kernels: timerfd_create system call. */
2885 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2886 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2889 POST(sys_timerfd_create)
2891 if (linux_kernel_2_6_22())
2893 /* 2.6.22 kernel: timerfd system call. */
2894 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2895 VG_(close)(RES);
2896 SET_STATUS_Failure( VKI_EMFILE );
2897 } else {
2898 if (VG_(clo_track_fds))
2899 ML_(record_fd_open_nameless) (tid, RES);
2902 else
2904 /* 2.6.24 and later kernels: timerfd_create system call. */
2905 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2906 VG_(close)(RES);
2907 SET_STATUS_Failure( VKI_EMFILE );
2908 } else {
2909 if (VG_(clo_track_fds))
2910 ML_(record_fd_open_nameless) (tid, RES);
2915 PRE(sys_timerfd_gettime)
2917 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2918 PRE_REG_READ2(long, "timerfd_gettime",
2919 int, ufd,
2920 struct vki_itimerspec*, otmr);
2921 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2922 SET_STATUS_Failure(VKI_EBADF);
2923 else
2924 PRE_MEM_WRITE("timerfd_gettime(result)",
2925 ARG2, sizeof(struct vki_itimerspec));
2927 POST(sys_timerfd_gettime)
2929 if (RES == 0)
2930 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2933 PRE(sys_timerfd_settime)
2935 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
2936 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
2937 PRE_REG_READ4(long, "timerfd_settime",
2938 int, ufd,
2939 int, flags,
2940 const struct vki_itimerspec*, utmr,
2941 struct vki_itimerspec*, otmr);
2942 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2943 SET_STATUS_Failure(VKI_EBADF);
2944 else
2946 PRE_MEM_READ("timerfd_settime(result)",
2947 ARG3, sizeof(struct vki_itimerspec));
2948 if (ARG4)
2950 PRE_MEM_WRITE("timerfd_settime(result)",
2951 ARG4, sizeof(struct vki_itimerspec));
2955 POST(sys_timerfd_settime)
2957 if (RES == 0 && ARG4 != 0)
2958 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2961 /* ---------------------------------------------------------------------
2962 capabilities wrappers
2963 ------------------------------------------------------------------ */
2965 PRE(sys_capget)
2967 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2968 PRE_REG_READ2(long, "capget",
2969 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2970 PRE_MEM_READ( "capget(header)", ARG1,
2971 sizeof(struct __vki_user_cap_header_struct) );
2972 if (ARG2 != (Addr)NULL)
2973 PRE_MEM_WRITE( "capget(data)", ARG2,
2974 sizeof(struct __vki_user_cap_data_struct) );
2976 POST(sys_capget)
2978 if (ARG2 != (Addr)NULL)
2979 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2982 PRE(sys_capset)
2984 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2985 PRE_REG_READ2(long, "capset",
2986 vki_cap_user_header_t, header,
2987 const vki_cap_user_data_t, data);
2988 PRE_MEM_READ( "capset(header)",
2989 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2990 PRE_MEM_READ( "capset(data)",
2991 ARG2, sizeof(struct __vki_user_cap_data_struct) );
2994 /* ---------------------------------------------------------------------
2995 16-bit uid/gid/groups wrappers
2996 ------------------------------------------------------------------ */
2998 PRE(sys_getuid16)
3000 PRINT("sys_getuid16 ( )");
3001 PRE_REG_READ0(long, "getuid16");
3004 PRE(sys_setuid16)
3006 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3007 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3010 PRE(sys_getgid16)
3012 PRINT("sys_getgid16 ( )");
3013 PRE_REG_READ0(long, "getgid16");
3016 PRE(sys_setgid16)
3018 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3019 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3022 PRE(sys_geteuid16)
3024 PRINT("sys_geteuid16 ( )");
3025 PRE_REG_READ0(long, "geteuid16");
3028 PRE(sys_getegid16)
3030 PRINT("sys_getegid16 ( )");
3031 PRE_REG_READ0(long, "getegid16");
3034 PRE(sys_setreuid16)
3036 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3037 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3040 PRE(sys_setregid16)
3042 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3043 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3046 PRE(sys_getgroups16)
3048 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3049 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3050 if (ARG1 > 0)
3051 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3053 POST(sys_getgroups16)
3055 vg_assert(SUCCESS);
3056 if (ARG1 > 0 && RES > 0)
3057 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3060 PRE(sys_setgroups16)
3062 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3063 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3064 if (ARG1 > 0)
3065 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3068 /* ---------------------------------------------------------------------
3069 *chown16 wrappers
3070 ------------------------------------------------------------------ */
3072 PRE(sys_chown16)
3074 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3075 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3076 PRE_REG_READ3(long, "chown16",
3077 const char *, path,
3078 vki_old_uid_t, owner, vki_old_gid_t, group);
3079 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3082 PRE(sys_fchown16)
3084 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3085 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3086 PRE_REG_READ3(long, "fchown16",
3087 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3090 /* ---------------------------------------------------------------------
3091 *xattr wrappers
3092 ------------------------------------------------------------------ */
3094 PRE(sys_setxattr)
3096 *flags |= SfMayBlock;
3097 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3098 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3099 ARG4, SARG5);
3100 PRE_REG_READ5(long, "setxattr",
3101 char *, path, char *, name,
3102 void *, value, vki_size_t, size, int, flags);
3103 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3104 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3105 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3108 PRE(sys_lsetxattr)
3110 *flags |= SfMayBlock;
3111 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3112 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3113 ARG1, ARG2, ARG3, ARG4, SARG5);
3114 PRE_REG_READ5(long, "lsetxattr",
3115 char *, path, char *, name,
3116 void *, value, vki_size_t, size, int, flags);
3117 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3118 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3119 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3122 PRE(sys_fsetxattr)
3124 *flags |= SfMayBlock;
3125 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3126 FMT_REGWORD "u, %ld )",
3127 SARG1, ARG2, ARG3, ARG4, SARG5);
3128 PRE_REG_READ5(long, "fsetxattr",
3129 int, fd, char *, name, void *, value,
3130 vki_size_t, size, int, flags);
3131 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3132 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3135 PRE(sys_getxattr)
3137 *flags |= SfMayBlock;
3138 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3139 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3140 PRE_REG_READ4(ssize_t, "getxattr",
3141 char *, path, char *, name, void *, value, vki_size_t, size);
3142 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3143 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3144 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3146 POST(sys_getxattr)
3148 vg_assert(SUCCESS);
3149 if (RES > 0 && ARG3 != (Addr)NULL) {
3150 POST_MEM_WRITE( ARG3, RES );
3154 PRE(sys_lgetxattr)
3156 *flags |= SfMayBlock;
3157 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3158 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3159 PRE_REG_READ4(ssize_t, "lgetxattr",
3160 char *, path, char *, name, void *, value, vki_size_t, size);
3161 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3162 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3163 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3165 POST(sys_lgetxattr)
3167 vg_assert(SUCCESS);
3168 if (RES > 0 && ARG3 != (Addr)NULL) {
3169 POST_MEM_WRITE( ARG3, RES );
3173 PRE(sys_fgetxattr)
3175 *flags |= SfMayBlock;
3176 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3177 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3178 PRE_REG_READ4(ssize_t, "fgetxattr",
3179 int, fd, char *, name, void *, value, vki_size_t, size);
3180 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3181 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3183 POST(sys_fgetxattr)
3185 if (RES > 0 && ARG3 != (Addr)NULL)
3186 POST_MEM_WRITE( ARG3, RES );
3189 PRE(sys_listxattr)
3191 *flags |= SfMayBlock;
3192 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3193 ARG1, ARG2, (ULong)ARG3);
3194 PRE_REG_READ3(ssize_t, "listxattr",
3195 char *, path, char *, list, vki_size_t, size);
3196 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3197 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3199 POST(sys_listxattr)
3201 if (RES > 0 && ARG2 != (Addr)NULL)
3202 POST_MEM_WRITE( ARG2, RES );
3205 PRE(sys_llistxattr)
3207 *flags |= SfMayBlock;
3208 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3209 ARG1, ARG2, (ULong)ARG3);
3210 PRE_REG_READ3(ssize_t, "llistxattr",
3211 char *, path, char *, list, vki_size_t, size);
3212 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3213 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3215 POST(sys_llistxattr)
3217 if (RES > 0 && ARG2 != (Addr)NULL)
3218 POST_MEM_WRITE( ARG2, RES );
3221 PRE(sys_flistxattr)
3223 *flags |= SfMayBlock;
3224 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3225 SARG1, ARG2, ARG3);
3226 PRE_REG_READ3(ssize_t, "flistxattr",
3227 int, fd, char *, list, vki_size_t, size);
3228 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3230 POST(sys_flistxattr)
3232 if (RES > 0 && ARG2 != (Addr)NULL)
3233 POST_MEM_WRITE( ARG2, RES );
3236 PRE(sys_removexattr)
3238 *flags |= SfMayBlock;
3239 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3240 ARG1, ARG2);
3241 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3242 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3243 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3246 PRE(sys_lremovexattr)
3248 *flags |= SfMayBlock;
3249 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3250 ARG1, ARG2);
3251 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3252 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3253 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3256 PRE(sys_fremovexattr)
3258 *flags |= SfMayBlock;
3259 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3260 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3261 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3264 /* ---------------------------------------------------------------------
3265 sched_* wrappers
3266 ------------------------------------------------------------------ */
3268 PRE(sys_sched_setparam)
3270 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3271 PRE_REG_READ2(long, "sched_setparam",
3272 vki_pid_t, pid, struct sched_param *, p);
3273 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3275 POST(sys_sched_setparam)
3277 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3280 PRE(sys_sched_getparam)
3282 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3283 PRE_REG_READ2(long, "sched_getparam",
3284 vki_pid_t, pid, struct sched_param *, p);
3285 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3287 POST(sys_sched_getparam)
3289 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3292 PRE(sys_sched_getscheduler)
3294 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3295 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3298 PRE(sys_sched_setscheduler)
3300 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3301 SARG1, SARG2, ARG3);
3302 PRE_REG_READ3(long, "sched_setscheduler",
3303 vki_pid_t, pid, int, policy, struct sched_param *, p);
3304 if (ARG3 != 0)
3305 PRE_MEM_READ( "sched_setscheduler(p)",
3306 ARG3, sizeof(struct vki_sched_param));
3309 PRE(sys_sched_yield)
3311 *flags |= SfMayBlock;
3312 PRINT("sched_yield()");
3313 PRE_REG_READ0(long, "sys_sched_yield");
3316 PRE(sys_sched_get_priority_max)
3318 PRINT("sched_get_priority_max ( %ld )", SARG1);
3319 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3322 PRE(sys_sched_get_priority_min)
3324 PRINT("sched_get_priority_min ( %ld )", SARG1);
3325 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3328 PRE(sys_sched_rr_get_interval)
3330 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3331 PRE_REG_READ2(int, "sched_rr_get_interval",
3332 vki_pid_t, pid,
3333 struct vki_timespec *, tp);
3334 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3335 ARG2, sizeof(struct vki_timespec));
3338 POST(sys_sched_rr_get_interval)
3340 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3343 PRE(sys_sched_setaffinity)
3345 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3346 SARG1, ARG2, ARG3);
3347 PRE_REG_READ3(long, "sched_setaffinity",
3348 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3349 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3352 PRE(sys_sched_getaffinity)
3354 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3355 SARG1, ARG2, ARG3);
3356 PRE_REG_READ3(long, "sched_getaffinity",
3357 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3358 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3360 POST(sys_sched_getaffinity)
3362 POST_MEM_WRITE(ARG3, ARG2);
3365 PRE(sys_unshare)
3367 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3368 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3371 /* ---------------------------------------------------------------------
3372 miscellaneous wrappers
3373 ------------------------------------------------------------------ */
3375 PRE(sys_munlockall)
3377 *flags |= SfMayBlock;
3378 PRINT("sys_munlockall ( )");
3379 PRE_REG_READ0(long, "munlockall");
3382 // This has different signatures for different platforms.
3384 // x86: int sys_pipe(unsigned long __user *fildes);
3385 // AMD64: long sys_pipe(int *fildes);
3386 // ppc32: int sys_pipe(int __user *fildes);
3387 // ppc64: int sys_pipe(int __user *fildes);
3389 // The type of the argument is most important, and it is an array of 32 bit
3390 // values in all cases. (The return type differs across platforms, but it
3391 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3392 // was caused by using an array of 'unsigned long's, which didn't work on
3393 // AMD64.
3394 PRE(sys_pipe)
3396 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3397 PRE_REG_READ1(int, "pipe", int *, filedes);
3398 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3400 POST(sys_pipe)
3402 Int *p = (Int *)(Addr)ARG1;
3403 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3404 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3405 VG_(close)(p[0]);
3406 VG_(close)(p[1]);
3407 SET_STATUS_Failure( VKI_EMFILE );
3408 } else {
3409 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3410 if (VG_(clo_track_fds)) {
3411 ML_(record_fd_open_nameless)(tid, p[0]);
3412 ML_(record_fd_open_nameless)(tid, p[1]);
3417 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3418 there's a second arg containing flags to be applied to the new file
3419 descriptors. It hardly seems worth the effort to factor out the
3420 duplicated code, hence: */
3421 PRE(sys_pipe2)
3423 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3424 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3425 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3427 POST(sys_pipe2)
3429 Int *p = (Int *)(Addr)ARG1;
3430 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3431 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3432 VG_(close)(p[0]);
3433 VG_(close)(p[1]);
3434 SET_STATUS_Failure( VKI_EMFILE );
3435 } else {
3436 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3437 if (VG_(clo_track_fds)) {
3438 ML_(record_fd_open_nameless)(tid, p[0]);
3439 ML_(record_fd_open_nameless)(tid, p[1]);
3444 PRE(sys_dup3)
3446 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3447 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3448 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3449 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3450 SET_STATUS_Failure( VKI_EBADF );
3453 POST(sys_dup3)
3455 vg_assert(SUCCESS);
3456 if (VG_(clo_track_fds))
3457 ML_(record_fd_open_named)(tid, RES);
3460 PRE(sys_quotactl)
3462 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3463 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3464 PRE_REG_READ4(long, "quotactl",
3465 unsigned int, cmd, const char *, special, vki_qid_t, id,
3466 void *, addr);
3467 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3470 PRE(sys_waitid)
3472 *flags |= SfMayBlock;
3473 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3474 SARG1, SARG2, ARG3, SARG4, ARG5);
3475 PRE_REG_READ5(int32_t, "sys_waitid",
3476 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3477 int, options, struct vki_rusage *, ru);
3478 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3479 if (ARG5 != 0)
3480 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3482 POST(sys_waitid)
3484 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3485 if (ARG5 != 0)
3486 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3489 PRE(sys_sync_file_range)
3491 *flags |= SfMayBlock;
3492 #if VG_WORDSIZE == 4
3493 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3494 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3495 PRE_REG_READ6(long, "sync_file_range",
3496 int, fd,
3497 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3498 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3499 unsigned int, flags);
3500 #elif VG_WORDSIZE == 8
3501 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3502 SARG1, SARG2, SARG3, ARG4);
3503 PRE_REG_READ4(long, "sync_file_range",
3504 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3505 unsigned int, flags);
3506 #else
3507 # error Unexpected word size
3508 #endif
3509 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3510 SET_STATUS_Failure( VKI_EBADF );
3513 PRE(sys_sync_file_range2)
3515 *flags |= SfMayBlock;
3516 #if VG_WORDSIZE == 4
3517 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3518 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3519 PRE_REG_READ6(long, "sync_file_range2",
3520 int, fd, unsigned int, flags,
3521 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3522 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3523 #elif VG_WORDSIZE == 8
3524 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3525 SARG1, ARG2, SARG3, SARG4);
3526 PRE_REG_READ4(long, "sync_file_range2",
3527 int, fd, unsigned int, flags,
3528 vki_loff_t, offset, vki_loff_t, nbytes);
3529 #else
3530 # error Unexpected word size
3531 #endif
3532 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3533 SET_STATUS_Failure( VKI_EBADF );
3536 PRE(sys_stime)
3538 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
3539 PRE_REG_READ1(int, "stime", vki_time_t*, t);
3540 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3543 PRE(sys_perf_event_open)
3545 struct vki_perf_event_attr *attr;
3546 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
3547 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
3548 PRE_REG_READ5(long, "perf_event_open",
3549 struct vki_perf_event_attr *, attr,
3550 vki_pid_t, pid, int, cpu, int, group_fd,
3551 unsigned long, flags);
3552 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
3553 PRE_MEM_READ( "perf_event_open(attr->size)",
3554 (Addr)&attr->size, sizeof(attr->size) );
3555 PRE_MEM_READ( "perf_event_open(attr)",
3556 (Addr)attr, attr->size );
3559 POST(sys_perf_event_open)
3561 vg_assert(SUCCESS);
3562 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3563 VG_(close)(RES);
3564 SET_STATUS_Failure( VKI_EMFILE );
3565 } else {
3566 if (VG_(clo_track_fds))
3567 ML_(record_fd_open_nameless)(tid, RES);
3571 PRE(sys_getcpu)
3573 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3574 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
3575 PRE_REG_READ3(int, "getcpu",
3576 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3577 if (ARG1 != 0)
3578 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3579 if (ARG2 != 0)
3580 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3581 if (ARG3 != 0)
3582 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3585 POST(sys_getcpu)
3587 if (ARG1 != 0)
3588 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3589 if (ARG2 != 0)
3590 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3591 if (ARG3 != 0)
3592 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3595 PRE(sys_move_pages)
3597 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
3598 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3599 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3600 PRE_REG_READ6(int, "move_pages",
3601 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3602 const int *, nodes, int *, status, int, flags);
3603 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3604 if (ARG4)
3605 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3606 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3609 POST(sys_move_pages)
3611 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3614 PRE(sys_getrandom)
3616 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3617 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
3618 PRE_REG_READ3(int, "getrandom",
3619 char *, buf, vki_size_t, count, unsigned int, flags);
3620 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3623 POST(sys_getrandom)
3625 POST_MEM_WRITE( ARG1, ARG2 );
3628 PRE(sys_memfd_create)
3630 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
3631 ARG1, ARG2);
3632 PRE_REG_READ2(int, "memfd_create",
3633 char *, uname, unsigned int, flags);
3634 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3637 POST(sys_memfd_create)
3639 vg_assert(SUCCESS);
3640 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3641 VG_(close)(RES);
3642 SET_STATUS_Failure( VKI_EMFILE );
3643 } else {
3644 if (VG_(clo_track_fds))
3645 ML_(record_fd_open_nameless)(tid, RES);
3649 PRE(sys_membarrier)
3651 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
3652 PRE_REG_READ1(int, "membarrier", int, flags);
3655 PRE(sys_syncfs)
3657 *flags |= SfMayBlock;
3658 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
3659 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3662 /* ---------------------------------------------------------------------
3663 utime wrapper
3664 ------------------------------------------------------------------ */
3666 PRE(sys_utime)
3668 *flags |= SfMayBlock;
3669 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
3670 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3671 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3672 if (ARG2 != 0)
3673 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3676 /* ---------------------------------------------------------------------
3677 lseek wrapper
3678 ------------------------------------------------------------------ */
3680 PRE(sys_lseek)
3682 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
3683 ARG1, SARG2, ARG3);
3684 PRE_REG_READ3(vki_off_t, "lseek",
3685 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3688 /* ---------------------------------------------------------------------
3689 readahead wrapper
3690 ------------------------------------------------------------------ */
3692 PRE(sys_readahead)
3694 *flags |= SfMayBlock;
3695 #if VG_WORDSIZE == 4
3696 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
3697 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3698 PRE_REG_READ4(vki_off_t, "readahead",
3699 int, fd, unsigned, MERGE64_FIRST(offset),
3700 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3701 #elif VG_WORDSIZE == 8
3702 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3703 PRE_REG_READ3(vki_off_t, "readahead",
3704 int, fd, vki_loff_t, offset, vki_size_t, count);
3705 #else
3706 # error Unexpected word size
3707 #endif
3708 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3709 SET_STATUS_Failure( VKI_EBADF );
3712 /* ---------------------------------------------------------------------
3713 sig* wrappers
3714 ------------------------------------------------------------------ */
3716 PRE(sys_sigpending)
3718 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
3719 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3720 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3722 POST(sys_sigpending)
3724 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3727 // This syscall is not used on amd64/Linux -- it only provides
3728 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3729 // This wrapper is only suitable for 32-bit architectures.
3730 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3731 // conditional compilation like this?)
3732 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3733 || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
3734 PRE(sys_sigprocmask)
3736 vki_old_sigset_t* set;
3737 vki_old_sigset_t* oldset;
3738 vki_sigset_t bigger_set;
3739 vki_sigset_t bigger_oldset;
3741 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3742 PRE_REG_READ3(long, "sigprocmask",
3743 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3744 if (ARG2 != 0)
3745 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3746 if (ARG3 != 0)
3747 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3749 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3750 // vki_sigset_t params.
3751 set = (vki_old_sigset_t*)(Addr)ARG2;
3752 oldset = (vki_old_sigset_t*)(Addr)ARG3;
3754 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
3755 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3756 if (set)
3757 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3759 SET_STATUS_from_SysRes(
3760 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3761 set ? &bigger_set : NULL,
3762 oldset ? &bigger_oldset : NULL)
3765 if (oldset)
3766 *oldset = bigger_oldset.sig[0];
3768 if (SUCCESS)
3769 *flags |= SfPollAfter;
3771 POST(sys_sigprocmask)
3773 vg_assert(SUCCESS);
3774 if (RES == 0 && ARG3 != 0)
3775 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3778 /* Convert from non-RT to RT sigset_t's */
3779 static
3780 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3782 VG_(sigemptyset)(set);
3783 set->sig[0] = *oldset;
3785 PRE(sys_sigaction)
3787 vki_sigaction_toK_t new, *newp;
3788 vki_sigaction_fromK_t old, *oldp;
3790 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3791 PRE_REG_READ3(int, "sigaction",
3792 int, signum, const struct old_sigaction *, act,
3793 struct old_sigaction *, oldact);
3795 newp = oldp = NULL;
3797 if (ARG2 != 0) {
3798 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
3799 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3800 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3801 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3802 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3803 && (sa->sa_flags & VKI_SA_RESTORER))
3804 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3807 if (ARG3 != 0) {
3808 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3809 oldp = &old;
3812 /* If the new or old sigaction is not NULL, but the structs
3813 aren't accessible then sigaction returns EFAULT and we cannot
3814 use either struct for our own bookkeeping. Just fail early. */
3815 if (ARG2 != 0
3816 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3817 sizeof(struct vki_old_sigaction))) {
3818 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3819 (void *)(Addr)ARG2);
3820 SET_STATUS_Failure ( VKI_EFAULT );
3821 } else if ((ARG3 != 0
3822 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3823 sizeof(struct vki_old_sigaction)))) {
3824 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3825 (void *)(Addr)ARG3);
3826 SET_STATUS_Failure ( VKI_EFAULT );
3827 } else {
3828 if (ARG2 != 0) {
3829 struct vki_old_sigaction *oldnew =
3830 (struct vki_old_sigaction *)(Addr)ARG2;
3832 new.ksa_handler = oldnew->ksa_handler;
3833 new.sa_flags = oldnew->sa_flags;
3834 new.sa_restorer = oldnew->sa_restorer;
3835 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3836 newp = &new;
3839 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3841 if (ARG3 != 0 && SUCCESS && RES == 0) {
3842 struct vki_old_sigaction *oldold =
3843 (struct vki_old_sigaction *)(Addr)ARG3;
3845 oldold->ksa_handler = oldp->ksa_handler;
3846 oldold->sa_flags = oldp->sa_flags;
3847 oldold->sa_restorer = oldp->sa_restorer;
3848 oldold->sa_mask = oldp->sa_mask.sig[0];
3852 POST(sys_sigaction)
3854 vg_assert(SUCCESS);
3855 if (RES == 0 && ARG3 != 0)
3856 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3858 #endif
3860 PRE(sys_signalfd)
3862 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
3863 (ULong)ARG3);
3864 PRE_REG_READ3(long, "sys_signalfd",
3865 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3866 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3867 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3868 SET_STATUS_Failure( VKI_EBADF );
3870 POST(sys_signalfd)
3872 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3873 VG_(close)(RES);
3874 SET_STATUS_Failure( VKI_EMFILE );
3875 } else {
3876 if (VG_(clo_track_fds))
3877 ML_(record_fd_open_nameless) (tid, RES);
3881 PRE(sys_signalfd4)
3883 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3884 SARG1, ARG2, ARG3, SARG4);
3885 PRE_REG_READ4(long, "sys_signalfd4",
3886 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3887 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3888 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3889 SET_STATUS_Failure( VKI_EBADF );
3891 POST(sys_signalfd4)
3893 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3894 VG_(close)(RES);
3895 SET_STATUS_Failure( VKI_EMFILE );
3896 } else {
3897 if (VG_(clo_track_fds))
3898 ML_(record_fd_open_nameless) (tid, RES);
3903 /* ---------------------------------------------------------------------
3904 rt_sig* wrappers
3905 ------------------------------------------------------------------ */
3907 PRE(sys_rt_sigaction)
3909 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3910 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3911 PRE_REG_READ4(long, "rt_sigaction",
3912 int, signum, const struct sigaction *, act,
3913 struct sigaction *, oldact, vki_size_t, sigsetsize);
3915 if (ARG2 != 0) {
3916 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
3917 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3918 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3919 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3920 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3921 && (sa->sa_flags & VKI_SA_RESTORER))
3922 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3924 if (ARG3 != 0)
3925 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3927 /* If the new or old sigaction is not NULL, but the structs
3928 aren't accessible then sigaction returns EFAULT and we cannot
3929 use either struct for our own bookkeeping. Just fail early. */
3930 if (ARG2 != 0
3931 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3932 sizeof(vki_sigaction_toK_t))) {
3933 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3934 (void *)(Addr)ARG2);
3935 SET_STATUS_Failure ( VKI_EFAULT );
3936 } else if ((ARG3 != 0
3937 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3938 sizeof(vki_sigaction_fromK_t)))) {
3939 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3940 (void *)(Addr)ARG3);
3941 SET_STATUS_Failure ( VKI_EFAULT );
3942 } else {
3944 // XXX: doesn't seem right to be calling do_sys_sigaction for
3945 // sys_rt_sigaction... perhaps this function should be renamed
3946 // VG_(do_sys_rt_sigaction)() --njn
3948 SET_STATUS_from_SysRes(
3949 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
3950 (vki_sigaction_fromK_t *)(Addr)ARG3)
3954 POST(sys_rt_sigaction)
3956 vg_assert(SUCCESS);
3957 if (RES == 0 && ARG3 != 0)
3958 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3961 PRE(sys_rt_sigprocmask)
3963 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3964 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3965 PRE_REG_READ4(long, "rt_sigprocmask",
3966 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3967 vki_size_t, sigsetsize);
3968 if (ARG2 != 0)
3969 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3970 if (ARG3 != 0)
3971 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3973 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3974 // Since we want to use the set and oldset for bookkeeping we also want
3975 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
3976 if (sizeof(vki_sigset_t) != ARG4)
3977 SET_STATUS_Failure( VKI_EINVAL );
3978 else if (ARG2 != 0
3979 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
3980 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
3981 (void *)(Addr)ARG2);
3982 SET_STATUS_Failure ( VKI_EFAULT );
3984 else if (ARG3 != 0
3985 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
3986 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
3987 (void *)(Addr)ARG3);
3988 SET_STATUS_Failure ( VKI_EFAULT );
3991 else {
3992 SET_STATUS_from_SysRes(
3993 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3994 (vki_sigset_t*) (Addr)ARG2,
3995 (vki_sigset_t*) (Addr)ARG3 )
3999 if (SUCCESS)
4000 *flags |= SfPollAfter;
4002 POST(sys_rt_sigprocmask)
4004 vg_assert(SUCCESS);
4005 if (RES == 0 && ARG3 != 0)
4006 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4009 PRE(sys_rt_sigpending)
4011 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4012 PRE_REG_READ2(long, "rt_sigpending",
4013 vki_sigset_t *, set, vki_size_t, sigsetsize);
4014 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4016 POST(sys_rt_sigpending)
4018 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4021 PRE(sys_rt_sigtimedwait)
4023 *flags |= SfMayBlock;
4024 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4025 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4026 ARG1, ARG2, ARG3, ARG4);
4027 PRE_REG_READ4(long, "rt_sigtimedwait",
4028 const vki_sigset_t *, set, vki_siginfo_t *, info,
4029 const struct timespec *, timeout, vki_size_t, sigsetsize);
4030 if (ARG1 != 0)
4031 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4032 if (ARG2 != 0)
4033 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4034 if (ARG3 != 0)
4035 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4036 ARG3, sizeof(struct vki_timespec) );
4038 POST(sys_rt_sigtimedwait)
4040 if (ARG2 != 0)
4041 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4044 PRE(sys_rt_sigqueueinfo)
4046 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4047 SARG1, SARG2, ARG3);
4048 PRE_REG_READ3(long, "rt_sigqueueinfo",
4049 int, pid, int, sig, vki_siginfo_t *, uinfo);
4050 if (ARG2 != 0)
4051 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4053 POST(sys_rt_sigqueueinfo)
4055 if (!ML_(client_signal_OK)(ARG2))
4056 SET_STATUS_Failure( VKI_EINVAL );
4059 PRE(sys_rt_tgsigqueueinfo)
4061 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4062 SARG1, SARG2, SARG3, ARG4);
4063 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4064 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4065 if (ARG3 != 0)
4066 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4069 POST(sys_rt_tgsigqueueinfo)
4071 if (!ML_(client_signal_OK)(ARG3))
4072 SET_STATUS_Failure( VKI_EINVAL );
4075 // XXX: x86-specific? The kernel prototypes for the different archs are
4076 // hard to decipher.
4077 PRE(sys_rt_sigsuspend)
4079 /* The C library interface to sigsuspend just takes a pointer to
4080 a signal mask but this system call has two arguments - a pointer
4081 to the mask and the number of bytes used by it. The kernel insists
4082 on the size being equal to sizeof(sigset_t) however and will just
4083 return EINVAL if it isn't.
4085 *flags |= SfMayBlock;
4086 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4087 ARG1, ARG2 );
4088 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4089 if (ARG1 != (Addr)NULL) {
4090 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4091 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4092 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4093 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4094 be killable by VG_(nuke_all_threads_except).
4095 We thus silently ignore the user request to mask this signal.
4096 Note that this is similar to what is done for e.g.
4097 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4098 } else {
4099 SET_STATUS_Failure(VKI_EFAULT);
4104 /* ---------------------------------------------------------------------
4105 linux msg* wrapper helpers
4106 ------------------------------------------------------------------ */
4108 void
4109 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4110 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4112 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4113 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4114 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4115 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4118 void
4119 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4120 UWord arg0, UWord arg1, UWord arg2,
4121 UWord arg3, UWord arg4 )
4123 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4124 long msgtyp, int msgflg); */
4125 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4126 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4127 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4129 void
4130 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4131 UWord res,
4132 UWord arg0, UWord arg1, UWord arg2,
4133 UWord arg3, UWord arg4 )
4135 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4136 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4137 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4140 void
4141 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4142 UWord arg0, UWord arg1, UWord arg2 )
4144 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4145 switch (arg1 /* cmd */) {
4146 case VKI_IPC_INFO:
4147 case VKI_MSG_INFO:
4148 case VKI_IPC_INFO|VKI_IPC_64:
4149 case VKI_MSG_INFO|VKI_IPC_64:
4150 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4151 arg2, sizeof(struct vki_msginfo) );
4152 break;
4153 case VKI_IPC_STAT:
4154 case VKI_MSG_STAT:
4155 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4156 arg2, sizeof(struct vki_msqid_ds) );
4157 break;
4158 case VKI_IPC_STAT|VKI_IPC_64:
4159 case VKI_MSG_STAT|VKI_IPC_64:
4160 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4161 arg2, sizeof(struct vki_msqid64_ds) );
4162 break;
4163 case VKI_IPC_SET:
4164 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4165 arg2, sizeof(struct vki_msqid_ds) );
4166 break;
4167 case VKI_IPC_SET|VKI_IPC_64:
4168 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4169 arg2, sizeof(struct vki_msqid64_ds) );
4170 break;
4173 void
4174 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4175 UWord res,
4176 UWord arg0, UWord arg1, UWord arg2 )
4178 switch (arg1 /* cmd */) {
4179 case VKI_IPC_INFO:
4180 case VKI_MSG_INFO:
4181 case VKI_IPC_INFO|VKI_IPC_64:
4182 case VKI_MSG_INFO|VKI_IPC_64:
4183 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4184 break;
4185 case VKI_IPC_STAT:
4186 case VKI_MSG_STAT:
4187 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4188 break;
4189 case VKI_IPC_STAT|VKI_IPC_64:
4190 case VKI_MSG_STAT|VKI_IPC_64:
4191 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4192 break;
4196 /* ---------------------------------------------------------------------
4197 Generic handler for sys_ipc
4198 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4199 are either direct system calls, or are all implemented via sys_ipc.
4200 ------------------------------------------------------------------ */
4201 #ifdef __NR_ipc
4202 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4204 Addr* a_p = (Addr*)a;
4205 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4206 return *a_p;
4209 static Bool semctl_cmd_has_4args (UWord cmd)
4211 switch (cmd & ~VKI_IPC_64)
4213 case VKI_IPC_INFO:
4214 case VKI_SEM_INFO:
4215 case VKI_IPC_STAT:
4216 case VKI_SEM_STAT:
4217 case VKI_IPC_SET:
4218 case VKI_GETALL:
4219 case VKI_SETALL:
4220 return True;
4221 default:
4222 return False;
4226 PRE(sys_ipc)
4228 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4229 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4231 switch (ARG1 /* call */) {
4232 case VKI_SEMOP:
4233 PRE_REG_READ5(int, "ipc",
4234 vki_uint, call, int, first, int, second, int, third,
4235 void *, ptr);
4236 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4237 *flags |= SfMayBlock;
4238 break;
4239 case VKI_SEMGET:
4240 PRE_REG_READ4(int, "ipc",
4241 vki_uint, call, int, first, int, second, int, third);
4242 break;
4243 case VKI_SEMCTL:
4245 PRE_REG_READ5(int, "ipc",
4246 vki_uint, call, int, first, int, second, int, third,
4247 void *, ptr);
4248 UWord arg;
4249 if (semctl_cmd_has_4args(ARG4))
4250 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4251 else
4252 arg = 0;
4253 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4254 break;
4256 case VKI_SEMTIMEDOP:
4257 PRE_REG_READ6(int, "ipc",
4258 vki_uint, call, int, first, int, second, int, third,
4259 void *, ptr, long, fifth);
4260 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4261 *flags |= SfMayBlock;
4262 break;
4263 case VKI_MSGSND:
4264 PRE_REG_READ5(int, "ipc",
4265 vki_uint, call, int, first, int, second, int, third,
4266 void *, ptr);
4267 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4268 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4269 *flags |= SfMayBlock;
4270 break;
4271 case VKI_MSGRCV:
4273 PRE_REG_READ5(int, "ipc",
4274 vki_uint, call, int, first, int, second, int, third,
4275 void *, ptr);
4276 Addr msgp;
4277 Word msgtyp;
4279 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4280 "msgrcv(msgp)" );
4281 msgtyp = deref_Addr( tid,
4282 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4283 "msgrcv(msgp)" );
4285 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4287 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4288 *flags |= SfMayBlock;
4289 break;
4291 case VKI_MSGGET:
4292 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4293 break;
4294 case VKI_MSGCTL:
4295 PRE_REG_READ5(int, "ipc",
4296 vki_uint, call, int, first, int, second, int, third,
4297 void *, ptr);
4298 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4299 break;
4300 case VKI_SHMAT:
4302 PRE_REG_READ5(int, "ipc",
4303 vki_uint, call, int, first, int, second, int, third,
4304 void *, ptr);
4305 UWord w;
4306 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4307 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4308 if (w == 0)
4309 SET_STATUS_Failure( VKI_EINVAL );
4310 else
4311 ARG5 = w;
4312 break;
4314 case VKI_SHMDT:
4315 PRE_REG_READ5(int, "ipc",
4316 vki_uint, call, int, first, int, second, int, third,
4317 void *, ptr);
4318 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4319 SET_STATUS_Failure( VKI_EINVAL );
4320 break;
4321 case VKI_SHMGET:
4322 PRE_REG_READ4(int, "ipc",
4323 vki_uint, call, int, first, int, second, int, third);
4324 if (ARG4 & VKI_SHM_HUGETLB) {
4325 static Bool warning_given = False;
4326 ARG4 &= ~VKI_SHM_HUGETLB;
4327 if (!warning_given) {
4328 warning_given = True;
4329 VG_(umsg)(
4330 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4333 break;
4334 case VKI_SHMCTL: /* IPCOP_shmctl */
4335 PRE_REG_READ5(int, "ipc",
4336 vki_uint, call, int, first, int, second, int, third,
4337 void *, ptr);
4338 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4339 break;
4340 default:
4341 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4342 VG_(core_panic)("... bye!\n");
4343 break; /*NOTREACHED*/
4347 POST(sys_ipc)
4349 vg_assert(SUCCESS);
4350 switch (ARG1 /* call */) {
4351 case VKI_SEMOP:
4352 case VKI_SEMGET:
4353 break;
4354 case VKI_SEMCTL:
4356 UWord arg;
4357 if (semctl_cmd_has_4args(ARG4))
4358 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4359 else
4360 arg = 0;
4361 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4362 break;
4364 case VKI_SEMTIMEDOP:
4365 case VKI_MSGSND:
4366 break;
4367 case VKI_MSGRCV:
4369 Addr msgp;
4370 Word msgtyp;
4372 msgp = deref_Addr( tid,
4373 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4374 "msgrcv(msgp)" );
4375 msgtyp = deref_Addr( tid,
4376 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4377 "msgrcv(msgp)" );
4379 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4380 break;
4382 case VKI_MSGGET:
4383 break;
4384 case VKI_MSGCTL:
4385 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4386 break;
4387 case VKI_SHMAT:
4389 Addr addr;
4391 /* force readability. before the syscall it is
4392 * indeed uninitialized, as can be seen in
4393 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4394 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4396 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4397 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4398 break;
4400 case VKI_SHMDT:
4401 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4402 break;
4403 case VKI_SHMGET:
4404 break;
4405 case VKI_SHMCTL:
4406 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4407 break;
4408 default:
4409 VG_(message)(Vg_DebugMsg,
4410 "FATAL: unhandled syscall(ipc) %lu\n",
4411 ARG1 );
4412 VG_(core_panic)("... bye!\n");
4413 break; /*NOTREACHED*/
4416 #endif
4418 PRE(sys_semget)
4420 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4421 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4424 PRE(sys_semop)
4426 *flags |= SfMayBlock;
4427 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4428 SARG1, ARG2, ARG3);
4429 PRE_REG_READ3(long, "semop",
4430 int, semid, struct sembuf *, sops, unsigned, nsoops);
4431 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4434 PRE(sys_semctl)
4436 switch (ARG3 & ~VKI_IPC_64) {
4437 case VKI_IPC_INFO:
4438 case VKI_SEM_INFO:
4439 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4440 SARG3, ARG4);
4441 PRE_REG_READ4(long, "semctl",
4442 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4443 break;
4444 case VKI_IPC_STAT:
4445 case VKI_SEM_STAT:
4446 case VKI_IPC_SET:
4447 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4448 SARG3, ARG4);
4449 PRE_REG_READ4(long, "semctl",
4450 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4451 break;
4452 case VKI_GETALL:
4453 case VKI_SETALL:
4454 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4455 SARG3, ARG4);
4456 PRE_REG_READ4(long, "semctl",
4457 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4458 break;
4459 default:
4460 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4461 PRE_REG_READ3(long, "semctl",
4462 int, semid, int, semnum, int, cmd);
4463 break;
4465 #ifdef VGP_amd64_linux
4466 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4467 #else
4468 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4469 #endif
4472 POST(sys_semctl)
4474 #ifdef VGP_amd64_linux
4475 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4476 #else
4477 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4478 #endif
4481 PRE(sys_semtimedop)
4483 *flags |= SfMayBlock;
4484 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
4485 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4486 PRE_REG_READ4(long, "semtimedop",
4487 int, semid, struct sembuf *, sops, unsigned, nsoops,
4488 struct timespec *, timeout);
4489 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4492 PRE(sys_msgget)
4494 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4495 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4498 PRE(sys_msgsnd)
4500 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4501 SARG1, ARG2, ARG3, SARG4);
4502 PRE_REG_READ4(long, "msgsnd",
4503 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4504 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4505 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4506 *flags |= SfMayBlock;
4509 PRE(sys_msgrcv)
4511 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
4512 SARG1, ARG2, ARG3, SARG4, SARG5);
4513 PRE_REG_READ5(long, "msgrcv",
4514 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4515 long, msgytp, int, msgflg);
4516 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4517 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4518 *flags |= SfMayBlock;
4520 POST(sys_msgrcv)
4522 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4525 PRE(sys_msgctl)
4527 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4528 PRE_REG_READ3(long, "msgctl",
4529 int, msqid, int, cmd, struct msqid_ds *, buf);
4530 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4533 POST(sys_msgctl)
4535 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4538 PRE(sys_shmget)
4540 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
4541 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4542 if (ARG3 & VKI_SHM_HUGETLB) {
4543 static Bool warning_given = False;
4544 ARG3 &= ~VKI_SHM_HUGETLB;
4545 if (!warning_given) {
4546 warning_given = True;
4547 VG_(umsg)(
4548 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4553 PRE(sys_shmat)
4555 UWord arg2tmp;
4556 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4557 PRE_REG_READ3(long, "shmat",
4558 int, shmid, const void *, shmaddr, int, shmflg);
4559 #if defined(VGP_arm_linux)
4560 /* Round the attach address down to an VKI_SHMLBA boundary if the
4561 client requested rounding. See #222545. This is necessary only
4562 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4563 other linux targets it is the same as the page size. */
4564 if (ARG3 & VKI_SHM_RND)
4565 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4566 #endif
4567 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4568 if (arg2tmp == 0)
4569 SET_STATUS_Failure( VKI_EINVAL );
4570 else
4571 ARG2 = arg2tmp; // used in POST
4574 POST(sys_shmat)
4576 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4579 PRE(sys_shmdt)
4581 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
4582 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4583 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4584 SET_STATUS_Failure( VKI_EINVAL );
4587 POST(sys_shmdt)
4589 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4592 PRE(sys_shmctl)
4594 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4595 PRE_REG_READ3(long, "shmctl",
4596 int, shmid, int, cmd, struct shmid_ds *, buf);
4597 #ifdef VGP_amd64_linux
4598 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4599 #else
4600 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4601 #endif
4604 POST(sys_shmctl)
4606 #ifdef VGP_amd64_linux
4607 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4608 #else
4609 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4610 #endif
4614 /* ---------------------------------------------------------------------
4615 Generic handler for sys_socketcall
4616 Depending on the platform, some socket related syscalls (e.g. socketpair,
4617 socket, bind, ...)
4618 are either direct system calls, or are all implemented via sys_socketcall.
4619 ------------------------------------------------------------------ */
4620 #ifdef __NR_socketcall
4621 PRE(sys_socketcall)
4623 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4624 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4625 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4626 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4627 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4628 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4630 // call PRE_MEM_READ and check for EFAULT result.
4631 #define PRE_MEM_READ_ef(msg, arg, size) \
4633 PRE_MEM_READ( msg, arg, size); \
4634 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
4635 SET_STATUS_Failure( VKI_EFAULT ); \
4636 break; \
4640 *flags |= SfMayBlock;
4641 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4642 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4644 switch (ARG1 /* request */) {
4646 case VKI_SYS_SOCKETPAIR:
4647 /* int socketpair(int d, int type, int protocol, int sv[2]); */
4648 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4649 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4650 break;
4652 case VKI_SYS_SOCKET:
4653 /* int socket(int domain, int type, int protocol); */
4654 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4655 break;
4657 case VKI_SYS_BIND:
4658 /* int bind(int sockfd, struct sockaddr *my_addr,
4659 int addrlen); */
4660 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4661 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4662 break;
4664 case VKI_SYS_LISTEN:
4665 /* int listen(int s, int backlog); */
4666 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4667 break;
4669 case VKI_SYS_ACCEPT:
4670 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4671 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4672 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4673 break;
4675 case VKI_SYS_ACCEPT4:
4676 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4677 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4678 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4679 break;
4681 case VKI_SYS_SENDTO:
4682 /* int sendto(int s, const void *msg, int len,
4683 unsigned int flags,
4684 const struct sockaddr *to, int tolen); */
4685 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4686 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4687 ARG2_3, ARG2_4, ARG2_5 );
4688 break;
4690 case VKI_SYS_SEND:
4691 /* int send(int s, const void *msg, size_t len, int flags); */
4692 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4693 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4694 break;
4696 case VKI_SYS_RECVFROM:
4697 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4698 struct sockaddr *from, int *fromlen); */
4699 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4700 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4701 ARG2_3, ARG2_4, ARG2_5 );
4702 break;
4704 case VKI_SYS_RECV:
4705 /* int recv(int s, void *buf, int len, unsigned int flags); */
4706 /* man 2 recv says:
4707 The recv call is normally used only on a connected socket
4708 (see connect(2)) and is identical to recvfrom with a NULL
4709 from parameter.
4711 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4712 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4713 break;
4715 case VKI_SYS_CONNECT:
4716 /* int connect(int sockfd,
4717 struct sockaddr *serv_addr, int addrlen ); */
4718 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4719 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4720 break;
4722 case VKI_SYS_SETSOCKOPT:
4723 /* int setsockopt(int s, int level, int optname,
4724 const void *optval, int optlen); */
4725 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4726 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4727 ARG2_3, ARG2_4 );
4728 break;
4730 case VKI_SYS_GETSOCKOPT:
4731 /* int getsockopt(int s, int level, int optname,
4732 void *optval, socklen_t *optlen); */
4733 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4734 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4735 ARG2_3, ARG2_4 );
4736 break;
4738 case VKI_SYS_GETSOCKNAME:
4739 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4740 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4741 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4742 break;
4744 case VKI_SYS_GETPEERNAME:
4745 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4746 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4747 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4748 break;
4750 case VKI_SYS_SHUTDOWN:
4751 /* int shutdown(int s, int how); */
4752 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4753 break;
4755 case VKI_SYS_SENDMSG:
4756 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4757 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4758 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
4759 (struct vki_msghdr *)(Addr)ARG2_1 );
4760 break;
4762 case VKI_SYS_RECVMSG:
4763 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4764 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4765 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
4766 (struct vki_msghdr *)(Addr)ARG2_1 );
4767 break;
4769 case VKI_SYS_RECVMMSG:
4770 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4771 struct timespec *timeout); */
4772 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4773 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4774 ARG2_4 );
4775 break;
4777 case VKI_SYS_SENDMMSG:
4778 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4779 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4780 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4781 break;
4783 default:
4784 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4785 SET_STATUS_Failure( VKI_EINVAL );
4786 break;
4788 # undef ARG2_0
4789 # undef ARG2_1
4790 # undef ARG2_2
4791 # undef ARG2_3
4792 # undef ARG2_4
4793 # undef ARG2_5
4796 POST(sys_socketcall)
4798 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4799 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4800 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4801 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4802 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4803 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4805 SysRes r;
4806 vg_assert(SUCCESS);
4807 switch (ARG1 /* request */) {
4809 case VKI_SYS_SOCKETPAIR:
4810 r = ML_(generic_POST_sys_socketpair)(
4811 tid, VG_(mk_SysRes_Success)(RES),
4812 ARG2_0, ARG2_1, ARG2_2, ARG2_3
4814 SET_STATUS_from_SysRes(r);
4815 break;
4817 case VKI_SYS_SOCKET:
4818 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4819 SET_STATUS_from_SysRes(r);
4820 break;
4822 case VKI_SYS_BIND:
4823 /* int bind(int sockfd, struct sockaddr *my_addr,
4824 int addrlen); */
4825 break;
4827 case VKI_SYS_LISTEN:
4828 /* int listen(int s, int backlog); */
4829 break;
4831 case VKI_SYS_ACCEPT:
4832 case VKI_SYS_ACCEPT4:
4833 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4834 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4835 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4836 ARG2_0, ARG2_1, ARG2_2 );
4837 SET_STATUS_from_SysRes(r);
4838 break;
4840 case VKI_SYS_SENDTO:
4841 break;
4843 case VKI_SYS_SEND:
4844 break;
4846 case VKI_SYS_RECVFROM:
4847 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4848 ARG2_0, ARG2_1, ARG2_2,
4849 ARG2_3, ARG2_4, ARG2_5 );
4850 break;
4852 case VKI_SYS_RECV:
4853 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4854 break;
4856 case VKI_SYS_CONNECT:
4857 break;
4859 case VKI_SYS_SETSOCKOPT:
4860 break;
4862 case VKI_SYS_GETSOCKOPT:
4863 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4864 ARG2_0, ARG2_1,
4865 ARG2_2, ARG2_3, ARG2_4 );
4866 break;
4868 case VKI_SYS_GETSOCKNAME:
4869 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4870 ARG2_0, ARG2_1, ARG2_2 );
4871 break;
4873 case VKI_SYS_GETPEERNAME:
4874 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4875 ARG2_0, ARG2_1, ARG2_2 );
4876 break;
4878 case VKI_SYS_SHUTDOWN:
4879 break;
4881 case VKI_SYS_SENDMSG:
4882 break;
4884 case VKI_SYS_RECVMSG:
4885 ML_(generic_POST_sys_recvmsg)( tid, "msg",
4886 (struct vki_msghdr *)(Addr)ARG2_1, RES );
4887 break;
4889 case VKI_SYS_RECVMMSG:
4890 ML_(linux_POST_sys_recvmmsg)( tid, RES,
4891 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4892 break;
4894 case VKI_SYS_SENDMMSG:
4895 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4896 break;
4898 default:
4899 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4900 VG_(core_panic)("... bye!\n");
4901 break; /*NOTREACHED*/
4903 # undef ARG2_0
4904 # undef ARG2_1
4905 # undef ARG2_2
4906 # undef ARG2_3
4907 # undef ARG2_4
4908 # undef ARG2_5
4910 #endif
4912 PRE(sys_socket)
4914 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4915 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4917 POST(sys_socket)
4919 SysRes r;
4920 vg_assert(SUCCESS);
4921 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4922 SET_STATUS_from_SysRes(r);
4925 PRE(sys_setsockopt)
4927 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
4928 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
4929 PRE_REG_READ5(long, "setsockopt",
4930 int, s, int, level, int, optname,
4931 const void *, optval, unsigned, optlen); // socklen_t
4932 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4935 PRE(sys_getsockopt)
4937 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
4938 SARG1, SARG2, SARG3, ARG4, SARG5);
4939 PRE_REG_READ5(long, "getsockopt",
4940 int, s, int, level, int, optname,
4941 void *, optval, int, *optlen);
4942 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4944 POST(sys_getsockopt)
4946 vg_assert(SUCCESS);
4947 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4948 ARG1,ARG2,ARG3,ARG4,ARG5);
4951 PRE(sys_connect)
4953 *flags |= SfMayBlock;
4954 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4955 PRE_REG_READ3(long, "connect",
4956 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4957 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4960 PRE(sys_accept)
4962 *flags |= SfMayBlock;
4963 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4964 SARG1, ARG2, ARG3);
4965 PRE_REG_READ3(long, "accept",
4966 int, s, struct sockaddr *, addr, int *, addrlen);
4967 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4969 POST(sys_accept)
4971 SysRes r;
4972 vg_assert(SUCCESS);
4973 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4974 ARG1,ARG2,ARG3);
4975 SET_STATUS_from_SysRes(r);
4978 PRE(sys_accept4)
4980 *flags |= SfMayBlock;
4981 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
4982 SARG1, ARG2, ARG3, SARG4);
4983 PRE_REG_READ4(long, "accept4",
4984 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
4985 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4987 POST(sys_accept4)
4989 SysRes r;
4990 vg_assert(SUCCESS);
4991 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4992 ARG1,ARG2,ARG3);
4993 SET_STATUS_from_SysRes(r);
4996 PRE(sys_send)
4998 *flags |= SfMayBlock;
4999 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5000 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5001 PRE_REG_READ4(long, "send",
5002 int, s, const void *, msg, vki_size_t, len,
5003 int, flags);
5005 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5008 PRE(sys_sendto)
5010 *flags |= SfMayBlock;
5011 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5012 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5013 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5014 PRE_REG_READ6(long, "sendto",
5015 int, s, const void *, msg, vki_size_t, len,
5016 unsigned int, flags,
5017 const struct sockaddr *, to, int, tolen);
5018 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5021 PRE (sys_recv)
5023 *flags |= SfMayBlock;
5024 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5025 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5026 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5027 unsigned int, flags);
5028 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5031 POST (sys_recv)
5033 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5036 PRE(sys_recvfrom)
5038 *flags |= SfMayBlock;
5039 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5040 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5041 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5042 PRE_REG_READ6(long, "recvfrom",
5043 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5044 struct sockaddr *, from, int *, fromlen);
5045 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5047 POST(sys_recvfrom)
5049 vg_assert(SUCCESS);
5050 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5051 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5054 PRE(sys_sendmsg)
5056 *flags |= SfMayBlock;
5057 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5058 SARG1, ARG2, ARG3);
5059 PRE_REG_READ3(long, "sendmsg",
5060 int, s, const struct msghdr *, msg, unsigned int, flags);
5061 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5064 PRE(sys_recvmsg)
5066 *flags |= SfMayBlock;
5067 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5068 SARG1, ARG2, ARG3);
5069 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5070 unsigned int, flags);
5071 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5073 POST(sys_recvmsg)
5075 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5076 RES);
5079 PRE(sys_shutdown)
5081 *flags |= SfMayBlock;
5082 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5083 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5086 PRE(sys_bind)
5088 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5089 PRE_REG_READ3(long, "bind",
5090 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5091 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5094 PRE(sys_listen)
5096 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5097 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5100 PRE(sys_getsockname)
5102 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5103 SARG1, ARG2, ARG3);
5104 PRE_REG_READ3(long, "getsockname",
5105 int, s, struct sockaddr *, name, int *, namelen);
5106 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5108 POST(sys_getsockname)
5110 vg_assert(SUCCESS);
5111 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5112 ARG1,ARG2,ARG3);
5115 PRE(sys_getpeername)
5117 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5118 SARG1, ARG2, ARG3);
5119 PRE_REG_READ3(long, "getpeername",
5120 int, s, struct sockaddr *, name, int *, namelen);
5121 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5123 POST(sys_getpeername)
5125 vg_assert(SUCCESS);
5126 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5127 ARG1,ARG2,ARG3);
5130 PRE(sys_socketpair)
5132 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5133 SARG3, ARG4);
5134 PRE_REG_READ4(long, "socketpair",
5135 int, d, int, type, int, protocol, int*, sv);
5136 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5138 POST(sys_socketpair)
5140 vg_assert(SUCCESS);
5141 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5142 ARG1,ARG2,ARG3,ARG4);
5146 /* ---------------------------------------------------------------------
5147 *at wrappers
5148 ------------------------------------------------------------------ */
5150 PRE(sys_openat)
5152 HChar name[30]; // large enough
5153 SysRes sres;
5155 if (ARG3 & VKI_O_CREAT) {
5156 // 4-arg version
5157 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5158 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5159 PRE_REG_READ4(long, "openat",
5160 int, dfd, const char *, filename, int, flags, int, mode);
5161 } else {
5162 // 3-arg version
5163 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5164 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5165 PRE_REG_READ3(long, "openat",
5166 int, dfd, const char *, filename, int, flags);
5169 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5171 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5172 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5173 be sure only to compare the bottom 32 bits. */
5174 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5175 && *(Char *)(Addr)ARG2 != '/'
5176 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5177 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5178 SET_STATUS_Failure( VKI_EBADF );
5180 /* Handle the case where the open is of /proc/self/cmdline or
5181 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5182 fake file we cooked up at startup (in m_main). Also, seek the
5183 cloned fd back to the start. */
5185 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5186 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5187 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5188 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5189 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5190 SET_STATUS_from_SysRes( sres );
5191 if (!sr_isError(sres)) {
5192 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5193 if (off < 0)
5194 SET_STATUS_Failure( VKI_EMFILE );
5196 return;
5199 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5201 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5202 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5203 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5204 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5205 sres = VG_(dup)( VG_(cl_auxv_fd) );
5206 SET_STATUS_from_SysRes( sres );
5207 if (!sr_isError(sres)) {
5208 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5209 if (off < 0)
5210 SET_STATUS_Failure( VKI_EMFILE );
5212 return;
5215 /* Otherwise handle normally */
5216 *flags |= SfMayBlock;
5219 POST(sys_openat)
5221 vg_assert(SUCCESS);
5222 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5223 VG_(close)(RES);
5224 SET_STATUS_Failure( VKI_EMFILE );
5225 } else {
5226 if (VG_(clo_track_fds))
5227 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5231 PRE(sys_mkdirat)
5233 *flags |= SfMayBlock;
5234 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5235 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5236 PRE_REG_READ3(long, "mkdirat",
5237 int, dfd, const char *, pathname, int, mode);
5238 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5241 PRE(sys_mknodat)
5243 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5244 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5245 PRE_REG_READ4(long, "mknodat",
5246 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5247 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5250 PRE(sys_fchownat)
5252 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5253 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5254 PRE_REG_READ4(long, "fchownat",
5255 int, dfd, const char *, path,
5256 vki_uid_t, owner, vki_gid_t, group);
5257 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5260 PRE(sys_futimesat)
5262 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5263 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5264 PRE_REG_READ3(long, "futimesat",
5265 int, dfd, char *, filename, struct timeval *, tvp);
5266 if (ARG2 != 0)
5267 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5268 if (ARG3 != 0)
5269 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5272 PRE(sys_utimensat)
5274 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5275 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5276 PRE_REG_READ4(long, "utimensat",
5277 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5278 if (ARG2 != 0)
5279 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5280 if (ARG3 != 0)
5281 PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
5284 PRE(sys_newfstatat)
5286 FUSE_COMPATIBLE_MAY_BLOCK();
5287 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5288 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5289 PRE_REG_READ3(long, "fstatat",
5290 int, dfd, char *, file_name, struct stat *, buf);
5291 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5292 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5295 POST(sys_newfstatat)
5297 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5300 PRE(sys_unlinkat)
5302 *flags |= SfMayBlock;
5303 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5304 (HChar*)(Addr)ARG2);
5305 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5306 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5309 PRE(sys_renameat)
5311 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5312 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5313 ARG4, (HChar*)(Addr)ARG4);
5314 PRE_REG_READ4(long, "renameat",
5315 int, olddfd, const char *, oldpath,
5316 int, newdfd, const char *, newpath);
5317 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5318 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5321 PRE(sys_renameat2)
5323 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5324 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5325 ARG4, (HChar*)(Addr)ARG4, ARG5);
5326 PRE_REG_READ5(long, "renameat2",
5327 int, olddfd, const char *, oldpath,
5328 int, newdfd, const char *, newpath,
5329 unsigned int, flags);
5330 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5331 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5334 PRE(sys_linkat)
5336 *flags |= SfMayBlock;
5337 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5338 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5339 (HChar*)(Addr)ARG4, SARG5);
5340 PRE_REG_READ5(long, "linkat",
5341 int, olddfd, const char *, oldpath,
5342 int, newdfd, const char *, newpath,
5343 int, flags);
5344 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5345 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5348 PRE(sys_symlinkat)
5350 *flags |= SfMayBlock;
5351 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5352 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5353 PRE_REG_READ3(long, "symlinkat",
5354 const char *, oldpath, int, newdfd, const char *, newpath);
5355 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5356 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5359 PRE(sys_readlinkat)
5361 HChar name[30]; // large enough
5362 Word saved = SYSNO;
5364 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5365 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5366 PRE_REG_READ4(long, "readlinkat",
5367 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5368 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5369 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5372 * Handle the case where readlinkat is looking at /proc/self/exe or
5373 * /proc/<pid>/exe.
5375 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5376 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5377 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5378 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5379 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5380 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5381 ARG3, ARG4));
5382 } else {
5383 /* Normal case */
5384 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5387 if (SUCCESS && RES > 0)
5388 POST_MEM_WRITE( ARG3, RES );
5391 PRE(sys_fchmodat)
5393 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5394 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5395 PRE_REG_READ3(long, "fchmodat",
5396 int, dfd, const char *, path, vki_mode_t, mode);
5397 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5400 PRE(sys_faccessat)
5402 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5403 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5404 PRE_REG_READ3(long, "faccessat",
5405 int, dfd, const char *, pathname, int, mode);
5406 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5409 PRE(sys_name_to_handle_at)
5411 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
5412 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
5413 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5414 PRE_REG_READ5(int, "name_to_handle_at",
5415 int, dfd, const char *, name,
5416 struct vki_file_handle *, handle,
5417 int *, mnt_id, int, flag);
5418 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5419 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
5420 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5421 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5422 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5424 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5427 POST(sys_name_to_handle_at)
5429 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5430 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5431 POST_MEM_WRITE( ARG4, sizeof(int) );
5434 PRE(sys_open_by_handle_at)
5436 *flags |= SfMayBlock;
5437 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
5438 ARG2, SARG3);
5439 PRE_REG_READ3(int, "open_by_handle_at",
5440 int, mountdirfd,
5441 struct vki_file_handle *, handle,
5442 int, flags);
5443 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
5444 sizeof(struct vki_file_handle) +
5445 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
5448 POST(sys_open_by_handle_at)
5450 vg_assert(SUCCESS);
5451 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5452 VG_(close)(RES);
5453 SET_STATUS_Failure( VKI_EMFILE );
5454 } else {
5455 if (VG_(clo_track_fds))
5456 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5460 /* ---------------------------------------------------------------------
5461 p{read,write}v wrappers
5462 ------------------------------------------------------------------ */
5464 PRE(sys_preadv)
5466 Int i;
5467 struct vki_iovec * vec;
5468 *flags |= SfMayBlock;
5469 #if VG_WORDSIZE == 4
5470 /* Note that the offset argument here is in lo+hi order on both
5471 big and little endian platforms... */
5472 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5473 "u, %lld )",
5474 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5475 PRE_REG_READ5(ssize_t, "preadv",
5476 unsigned long, fd, const struct iovec *, vector,
5477 unsigned long, count, vki_u32, offset_low,
5478 vki_u32, offset_high);
5479 #elif VG_WORDSIZE == 8
5480 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5481 PRE_REG_READ4(ssize_t, "preadv",
5482 unsigned long, fd, const struct iovec *, vector,
5483 unsigned long, count, Word, offset);
5484 #else
5485 # error Unexpected word size
5486 #endif
5487 if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
5488 SET_STATUS_Failure( VKI_EBADF );
5489 } else {
5490 PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5492 if (ARG2 != 0) {
5493 /* ToDo: don't do any of the following if the vector is invalid */
5494 vec = (struct vki_iovec *)(Addr)ARG2;
5495 for (i = 0; i < (Int)ARG3; i++)
5496 PRE_MEM_WRITE( "preadv(vector[...])",
5497 (Addr)vec[i].iov_base, vec[i].iov_len );
5502 POST(sys_preadv)
5504 vg_assert(SUCCESS);
5505 if (RES > 0) {
5506 Int i;
5507 struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
5508 Int remains = RES;
5510 /* RES holds the number of bytes read. */
5511 for (i = 0; i < (Int)ARG3; i++) {
5512 Int nReadThisBuf = vec[i].iov_len;
5513 if (nReadThisBuf > remains) nReadThisBuf = remains;
5514 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5515 remains -= nReadThisBuf;
5516 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5521 PRE(sys_pwritev)
5523 Int i;
5524 struct vki_iovec * vec;
5525 *flags |= SfMayBlock;
5526 #if VG_WORDSIZE == 4
5527 /* Note that the offset argument here is in lo+hi order on both
5528 big and little endian platforms... */
5529 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5530 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5531 PRE_REG_READ5(ssize_t, "pwritev",
5532 unsigned long, fd, const struct iovec *, vector,
5533 unsigned long, count, vki_u32, offset_low,
5534 vki_u32, offset_high);
5535 #elif VG_WORDSIZE == 8
5536 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5537 PRE_REG_READ4(ssize_t, "pwritev",
5538 unsigned long, fd, const struct iovec *, vector,
5539 unsigned long, count, Word, offset);
5540 #else
5541 # error Unexpected word size
5542 #endif
5543 if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
5544 SET_STATUS_Failure( VKI_EBADF );
5545 } else {
5546 PRE_MEM_READ( "pwritev(vector)",
5547 ARG2, ARG3 * sizeof(struct vki_iovec) );
5548 if (ARG2 != 0) {
5549 /* ToDo: don't do any of the following if the vector is invalid */
5550 vec = (struct vki_iovec *)(Addr)ARG2;
5551 for (i = 0; i < (Int)ARG3; i++)
5552 PRE_MEM_READ( "pwritev(vector[...])",
5553 (Addr)vec[i].iov_base, vec[i].iov_len );
5558 /* ---------------------------------------------------------------------
5559 process_vm_{read,write}v wrappers
5560 ------------------------------------------------------------------ */
5562 PRE(sys_process_vm_readv)
5564 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5565 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5566 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5567 PRE_REG_READ6(ssize_t, "process_vm_readv",
5568 vki_pid_t, pid,
5569 const struct iovec *, lvec,
5570 unsigned long, liovcnt,
5571 const struct iovec *, rvec,
5572 unsigned long, riovcnt,
5573 unsigned long, flags);
5574 PRE_MEM_READ( "process_vm_readv(lvec)",
5575 ARG2, ARG3 * sizeof(struct vki_iovec) );
5576 PRE_MEM_READ( "process_vm_readv(rvec)",
5577 ARG4, ARG5 * sizeof(struct vki_iovec) );
5578 if (ARG2 != 0
5579 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5580 sizeof(struct vki_iovec) * ARG3)) {
5581 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5582 UInt i;
5583 for (i = 0; i < ARG3; i++)
5584 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5585 (Addr)vec[i].iov_base, vec[i].iov_len );
5589 POST(sys_process_vm_readv)
5591 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5592 UInt remains = RES;
5593 UInt i;
5594 for (i = 0; i < ARG3; i++) {
5595 UInt nReadThisBuf = vec[i].iov_len <= remains ?
5596 vec[i].iov_len : remains;
5597 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5598 remains -= nReadThisBuf;
5602 PRE(sys_process_vm_writev)
5604 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5605 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5606 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5607 PRE_REG_READ6(ssize_t, "process_vm_writev",
5608 vki_pid_t, pid,
5609 const struct iovec *, lvec,
5610 unsigned long, liovcnt,
5611 const struct iovec *, rvec,
5612 unsigned long, riovcnt,
5613 unsigned long, flags);
5614 PRE_MEM_READ( "process_vm_writev(lvec)",
5615 ARG2, ARG3 * sizeof(struct vki_iovec) );
5616 PRE_MEM_READ( "process_vm_writev(rvec)",
5617 ARG4, ARG5 * sizeof(struct vki_iovec) );
5618 if (ARG2 != 0
5619 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5620 sizeof(struct vki_iovec) * ARG3)) {
5621 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5622 UInt i;
5623 for (i = 0; i < ARG3; i++)
5624 PRE_MEM_READ( "process_vm_writev(lvec[...])",
5625 (Addr)vec[i].iov_base, vec[i].iov_len );
5629 /* ---------------------------------------------------------------------
5630 {send,recv}mmsg wrappers
5631 ------------------------------------------------------------------ */
5633 PRE(sys_sendmmsg)
5635 *flags |= SfMayBlock;
5636 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
5637 SARG3, SARG4);
5638 PRE_REG_READ4(long, "sendmmsg",
5639 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5640 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5643 POST(sys_sendmmsg)
5645 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5648 PRE(sys_recvmmsg)
5650 *flags |= SfMayBlock;
5651 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
5652 FMT_REGWORD "x )",
5653 SARG1, ARG2, SARG3, SARG4, ARG5);
5654 PRE_REG_READ5(long, "recvmmsg",
5655 int, s, struct mmsghdr *, mmsg, int, vlen,
5656 int, flags, struct timespec *, timeout);
5657 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5660 POST(sys_recvmmsg)
5662 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5665 /* ---------------------------------------------------------------------
5666 key retention service wrappers
5667 ------------------------------------------------------------------ */
5669 PRE(sys_request_key)
5671 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5672 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
5673 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
5674 PRE_REG_READ4(long, "request_key",
5675 const char *, type, const char *, description,
5676 const char *, callout_info, vki_key_serial_t, keyring);
5677 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5678 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5679 if (ARG3 != (UWord)NULL)
5680 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5683 PRE(sys_add_key)
5685 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5686 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
5687 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5688 PRE_REG_READ5(long, "add_key",
5689 const char *, type, const char *, description,
5690 const void *, payload, vki_size_t, plen,
5691 vki_key_serial_t, keyring);
5692 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5693 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5694 if (ARG3 != (UWord)NULL)
5695 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5698 PRE(sys_keyctl)
5700 switch (ARG1 /* option */) {
5701 case VKI_KEYCTL_GET_KEYRING_ID:
5702 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5703 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5704 int, option, vki_key_serial_t, id, int, create);
5705 break;
5706 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5707 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
5708 "x(%s) )", ARG2,(char*)(Addr)ARG2);
5709 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5710 int, option, const char *, name);
5711 if (ARG2 != (UWord)NULL)
5712 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5713 break;
5714 case VKI_KEYCTL_UPDATE:
5715 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
5716 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5717 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5718 int, option, vki_key_serial_t, key,
5719 const void *, payload, vki_size_t, plen);
5720 if (ARG3 != (UWord)NULL)
5721 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5722 break;
5723 case VKI_KEYCTL_REVOKE:
5724 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5725 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5726 int, option, vki_key_serial_t, id);
5727 break;
5728 case VKI_KEYCTL_CHOWN:
5729 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
5730 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5731 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5732 int, option, vki_key_serial_t, id,
5733 vki_uid_t, uid, vki_gid_t, gid);
5734 break;
5735 case VKI_KEYCTL_SETPERM:
5736 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
5737 SARG2, ARG3);
5738 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5739 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5740 break;
5741 case VKI_KEYCTL_DESCRIBE:
5742 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
5743 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5744 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5745 int, option, vki_key_serial_t, id,
5746 char *, buffer, vki_size_t, buflen);
5747 if (ARG3 != (UWord)NULL)
5748 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5749 break;
5750 case VKI_KEYCTL_CLEAR:
5751 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5752 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5753 int, option, vki_key_serial_t, keyring);
5754 break;
5755 case VKI_KEYCTL_LINK:
5756 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5757 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5758 vki_key_serial_t, keyring, vki_key_serial_t, key);
5759 break;
5760 case VKI_KEYCTL_UNLINK:
5761 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5762 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5763 vki_key_serial_t, keyring, vki_key_serial_t, key);
5764 break;
5765 case VKI_KEYCTL_SEARCH:
5766 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
5767 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
5768 ARG4, (HChar*)(Addr)ARG4, SARG5);
5769 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5770 int, option, vki_key_serial_t, keyring,
5771 const char *, type, const char *, description,
5772 vki_key_serial_t, destring);
5773 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5774 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5775 break;
5776 case VKI_KEYCTL_READ:
5777 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5778 "u )", SARG2, ARG3, ARG4);
5779 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5780 int, option, vki_key_serial_t, keyring,
5781 char *, buffer, vki_size_t, buflen);
5782 if (ARG3 != (UWord)NULL)
5783 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5784 break;
5785 case VKI_KEYCTL_INSTANTIATE:
5786 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
5787 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
5788 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5789 int, option, vki_key_serial_t, key,
5790 char *, payload, vki_size_t, plen,
5791 vki_key_serial_t, keyring);
5792 if (ARG3 != (UWord)NULL)
5793 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5794 break;
5795 case VKI_KEYCTL_NEGATE:
5796 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
5797 SARG2, ARG3, SARG4);
5798 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5799 int, option, vki_key_serial_t, key,
5800 unsigned, timeout, vki_key_serial_t, keyring);
5801 break;
5802 case VKI_KEYCTL_SET_REQKEY_KEYRING:
5803 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5804 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5805 int, option, int, reqkey_defl);
5806 break;
5807 case VKI_KEYCTL_SET_TIMEOUT:
5808 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
5809 SARG2, ARG3);
5810 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5811 int, option, vki_key_serial_t, key, unsigned, timeout);
5812 break;
5813 case VKI_KEYCTL_ASSUME_AUTHORITY:
5814 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5815 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5816 int, option, vki_key_serial_t, key);
5817 break;
5818 default:
5819 PRINT("sys_keyctl ( %ld ) ", SARG1);
5820 PRE_REG_READ1(long, "keyctl", int, option);
5821 break;
5825 POST(sys_keyctl)
5827 vg_assert(SUCCESS);
5828 switch (ARG1 /* option */) {
5829 case VKI_KEYCTL_DESCRIBE:
5830 case VKI_KEYCTL_READ:
5831 if (RES > ARG4)
5832 POST_MEM_WRITE(ARG3, ARG4);
5833 else
5834 POST_MEM_WRITE(ARG3, RES);
5835 break;
5836 default:
5837 break;
5841 /* ---------------------------------------------------------------------
5842 ioprio_ wrappers
5843 ------------------------------------------------------------------ */
5845 PRE(sys_ioprio_set)
5847 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5848 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5851 PRE(sys_ioprio_get)
5853 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
5854 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5857 /* ---------------------------------------------------------------------
5858 _module wrappers
5859 ------------------------------------------------------------------ */
5861 PRE(sys_init_module)
5863 *flags |= SfMayBlock;
5864 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5865 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
5866 PRE_REG_READ3(long, "init_module",
5867 void *, umod, unsigned long, len, const char *, uargs);
5868 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5869 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5872 PRE(sys_finit_module)
5874 *flags |= SfMayBlock;
5876 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
5877 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5878 PRE_REG_READ3(long, "finit_module",
5879 int, fd, const char *, params, int, flags);
5880 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
5883 PRE(sys_delete_module)
5885 *flags |= SfMayBlock;
5886 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
5887 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
5888 PRE_REG_READ2(long, "delete_module",
5889 const char *, name_user, unsigned int, flags);
5890 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5893 /* ---------------------------------------------------------------------
5894 splice wrappers
5895 ------------------------------------------------------------------ */
5897 PRE(sys_splice)
5899 *flags |= SfMayBlock;
5900 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
5901 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5902 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
5903 PRE_REG_READ6(vki_ssize_t, "splice",
5904 int, fd_in, vki_loff_t *, off_in,
5905 int, fd_out, vki_loff_t *, off_out,
5906 vki_size_t, len, unsigned int, flags);
5907 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5908 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5909 SET_STATUS_Failure( VKI_EBADF );
5910 } else {
5911 if (ARG2 != 0)
5912 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5913 if (ARG4 != 0)
5914 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5918 PRE(sys_tee)
5920 *flags |= SfMayBlock;
5921 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5922 SARG1, SARG2, ARG3, ARG4);
5923 PRE_REG_READ4(vki_ssize_t, "tee",
5924 int, fd_in, int, fd_out,
5925 vki_size_t, len, unsigned int, flags);
5926 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5927 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5928 SET_STATUS_Failure( VKI_EBADF );
5932 PRE(sys_vmsplice)
5934 Int fdfl;
5935 *flags |= SfMayBlock;
5936 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5937 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5938 PRE_REG_READ4(vki_ssize_t, "splice",
5939 int, fd, struct vki_iovec *, iov,
5940 unsigned long, nr_segs, unsigned int, flags);
5941 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5942 SET_STATUS_Failure( VKI_EBADF );
5943 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5944 SET_STATUS_Failure( VKI_EBADF );
5945 } else {
5946 const struct vki_iovec *iov;
5947 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5948 for (iov = (struct vki_iovec *)(Addr)ARG2;
5949 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
5951 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
5952 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5953 PRE_MEM_WRITE( "vmsplice(iov[...])",
5954 (Addr)iov->iov_base, iov->iov_len );
5955 else
5956 PRE_MEM_READ( "vmsplice(iov[...])",
5957 (Addr)iov->iov_base, iov->iov_len );
5963 POST(sys_vmsplice)
5965 vg_assert(SUCCESS);
5966 if (RES > 0) {
5967 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
5968 vg_assert(fdfl >= 0);
5969 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5971 const struct vki_iovec *iov;
5972 for (iov = (struct vki_iovec *)(Addr)ARG2;
5973 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
5975 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
5981 /* ---------------------------------------------------------------------
5982 oprofile-related wrappers
5983 ------------------------------------------------------------------ */
5985 #if defined(VGP_x86_linux)
5986 PRE(sys_lookup_dcookie)
5988 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
5989 MERGE64(ARG1,ARG2), ARG3, ARG4);
5990 PRE_REG_READ4(long, "lookup_dcookie",
5991 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
5992 char *, buf, vki_size_t, len);
5993 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
5995 POST(sys_lookup_dcookie)
5997 vg_assert(SUCCESS);
5998 if (ARG3 != (Addr)NULL)
5999 POST_MEM_WRITE( ARG3, RES);
6001 #endif
6003 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6004 || defined(VGP_arm64_linux)
6005 PRE(sys_lookup_dcookie)
6007 *flags |= SfMayBlock;
6008 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6009 PRE_REG_READ3(int, "lookup_dcookie",
6010 unsigned long long, cookie, char *, buf, vki_size_t, len);
6012 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6015 POST(sys_lookup_dcookie)
6017 vg_assert(SUCCESS);
6018 if (ARG2 != (Addr)NULL)
6019 POST_MEM_WRITE( ARG2, RES );
6021 #endif
6023 /* ---------------------------------------------------------------------
6024 fcntl wrappers
6025 ------------------------------------------------------------------ */
6027 PRE(sys_fcntl)
6029 switch (ARG2) {
6030 // These ones ignore ARG3.
6031 case VKI_F_GETFD:
6032 case VKI_F_GETFL:
6033 case VKI_F_GETOWN:
6034 case VKI_F_GETSIG:
6035 case VKI_F_GETLEASE:
6036 case VKI_F_GETPIPE_SZ:
6037 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6038 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6039 break;
6041 // These ones use ARG3 as "arg".
6042 case VKI_F_DUPFD:
6043 case VKI_F_DUPFD_CLOEXEC:
6044 case VKI_F_SETFD:
6045 case VKI_F_SETFL:
6046 case VKI_F_SETLEASE:
6047 case VKI_F_NOTIFY:
6048 case VKI_F_SETOWN:
6049 case VKI_F_SETSIG:
6050 case VKI_F_SETPIPE_SZ:
6051 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6052 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6053 PRE_REG_READ3(long, "fcntl",
6054 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6055 break;
6057 // These ones use ARG3 as "lock".
6058 case VKI_F_GETLK:
6059 case VKI_F_SETLK:
6060 case VKI_F_SETLKW:
6061 case VKI_F_OFD_GETLK:
6062 case VKI_F_OFD_SETLK:
6063 case VKI_F_OFD_SETLKW:
6064 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6065 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6066 PRE_REG_READ3(long, "fcntl",
6067 unsigned int, fd, unsigned int, cmd,
6068 struct vki_flock *, lock);
6070 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6071 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6072 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6073 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6074 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6075 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6076 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6079 break;
6081 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6082 case VKI_F_GETLK64:
6083 case VKI_F_SETLK64:
6084 case VKI_F_SETLKW64:
6085 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6086 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6087 PRE_REG_READ3(long, "fcntl",
6088 unsigned int, fd, unsigned int, cmd,
6089 struct flock64 *, lock);
6091 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6092 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6093 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6094 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6095 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6096 if (ARG2 == VKI_F_GETLK64) {
6097 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6100 break;
6101 # endif
6103 case VKI_F_SETOWN_EX:
6104 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6105 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6106 PRE_REG_READ3(long, "fcntl",
6107 unsigned int, fd, unsigned int, cmd,
6108 struct vki_f_owner_ex *, arg);
6109 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6110 break;
6112 case VKI_F_GETOWN_EX:
6113 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6114 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6115 PRE_REG_READ3(long, "fcntl",
6116 unsigned int, fd, unsigned int, cmd,
6117 struct vki_f_owner_ex *, arg);
6118 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6119 break;
6121 default:
6122 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6123 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6124 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6125 ARG2);
6126 SET_STATUS_Failure( VKI_EINVAL );
6127 break;
6130 # if defined(VGP_x86_linux)
6131 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6132 # else
6133 if (ARG2 == VKI_F_SETLKW)
6134 # endif
6135 *flags |= SfMayBlock;
6138 POST(sys_fcntl)
6140 vg_assert(SUCCESS);
6141 if (ARG2 == VKI_F_DUPFD) {
6142 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6143 VG_(close)(RES);
6144 SET_STATUS_Failure( VKI_EMFILE );
6145 } else {
6146 if (VG_(clo_track_fds))
6147 ML_(record_fd_open_named)(tid, RES);
6150 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6151 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6152 VG_(close)(RES);
6153 SET_STATUS_Failure( VKI_EMFILE );
6154 } else {
6155 if (VG_(clo_track_fds))
6156 ML_(record_fd_open_named)(tid, RES);
6158 } else if (ARG2 == VKI_F_GETOWN_EX) {
6159 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6160 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6161 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6162 POST_FIELD_WRITE(lock->l_pid);
6163 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6164 } else if (ARG2 == VKI_F_GETLK64) {
6165 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6166 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6167 # endif
6171 // XXX: wrapper only suitable for 32-bit systems
6172 PRE(sys_fcntl64)
6174 switch (ARG2) {
6175 // These ones ignore ARG3.
6176 case VKI_F_GETFD:
6177 case VKI_F_GETFL:
6178 case VKI_F_GETOWN:
6179 case VKI_F_SETOWN:
6180 case VKI_F_GETSIG:
6181 case VKI_F_SETSIG:
6182 case VKI_F_GETLEASE:
6183 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6184 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6185 break;
6187 // These ones use ARG3 as "arg".
6188 case VKI_F_DUPFD:
6189 case VKI_F_DUPFD_CLOEXEC:
6190 case VKI_F_SETFD:
6191 case VKI_F_SETFL:
6192 case VKI_F_SETLEASE:
6193 case VKI_F_NOTIFY:
6194 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6195 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6196 PRE_REG_READ3(long, "fcntl64",
6197 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6198 break;
6200 // These ones use ARG3 as "lock".
6201 case VKI_F_GETLK:
6202 case VKI_F_SETLK:
6203 case VKI_F_SETLKW:
6204 # if defined(VGP_x86_linux)
6205 case VKI_F_GETLK64:
6206 case VKI_F_SETLK64:
6207 case VKI_F_SETLKW64:
6208 # endif
6209 case VKI_F_OFD_GETLK:
6210 case VKI_F_OFD_SETLK:
6211 case VKI_F_OFD_SETLKW:
6212 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6213 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6214 PRE_REG_READ3(long, "fcntl64",
6215 unsigned int, fd, unsigned int, cmd,
6216 struct flock64 *, lock);
6217 break;
6219 case VKI_F_SETOWN_EX:
6220 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6221 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6222 PRE_REG_READ3(long, "fcntl",
6223 unsigned int, fd, unsigned int, cmd,
6224 struct vki_f_owner_ex *, arg);
6225 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6226 break;
6228 case VKI_F_GETOWN_EX:
6229 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6230 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6231 PRE_REG_READ3(long, "fcntl",
6232 unsigned int, fd, unsigned int, cmd,
6233 struct vki_f_owner_ex *, arg);
6234 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6235 break;
6238 # if defined(VGP_x86_linux)
6239 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6240 # else
6241 if (ARG2 == VKI_F_SETLKW)
6242 # endif
6243 *flags |= SfMayBlock;
6246 POST(sys_fcntl64)
6248 vg_assert(SUCCESS);
6249 if (ARG2 == VKI_F_DUPFD) {
6250 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6251 VG_(close)(RES);
6252 SET_STATUS_Failure( VKI_EMFILE );
6253 } else {
6254 if (VG_(clo_track_fds))
6255 ML_(record_fd_open_named)(tid, RES);
6258 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6259 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6260 VG_(close)(RES);
6261 SET_STATUS_Failure( VKI_EMFILE );
6262 } else {
6263 if (VG_(clo_track_fds))
6264 ML_(record_fd_open_named)(tid, RES);
6266 } else if (ARG2 == VKI_F_GETOWN_EX) {
6267 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6271 /* ---------------------------------------------------------------------
6272 ioctl wrappers
6273 ------------------------------------------------------------------ */
6275 struct vg_drm_version_info {
6276 struct vki_drm_version data;
6277 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6280 PRE(sys_ioctl)
6282 *flags |= SfMayBlock;
6284 ARG2 = (UInt)ARG2;
6286 // We first handle the ones that don't use ARG3 (even as a
6287 // scalar/non-pointer argument).
6288 switch (ARG2 /* request */) {
6290 /* asm-generic/ioctls.h */
6291 case VKI_FIOCLEX:
6292 case VKI_FIONCLEX:
6293 case VKI_TIOCNOTTY:
6295 /* linux perf_event ioctls */
6296 case VKI_PERF_EVENT_IOC_ENABLE:
6297 case VKI_PERF_EVENT_IOC_DISABLE:
6299 /* linux/soundcard interface (ALSA) */
6300 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6301 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6302 case VKI_SNDRV_PCM_IOCTL_PREPARE:
6303 case VKI_SNDRV_PCM_IOCTL_RESET:
6304 case VKI_SNDRV_PCM_IOCTL_START:
6305 case VKI_SNDRV_PCM_IOCTL_DROP:
6306 case VKI_SNDRV_PCM_IOCTL_DRAIN:
6307 case VKI_SNDRV_PCM_IOCTL_RESUME:
6308 case VKI_SNDRV_PCM_IOCTL_XRUN:
6309 case VKI_SNDRV_PCM_IOCTL_UNLINK:
6310 case VKI_SNDRV_TIMER_IOCTL_START:
6311 case VKI_SNDRV_TIMER_IOCTL_STOP:
6312 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6313 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6315 /* SCSI no operand */
6316 case VKI_SCSI_IOCTL_DOORLOCK:
6317 case VKI_SCSI_IOCTL_DOORUNLOCK:
6319 /* CDROM stuff. */
6320 case VKI_CDROM_DISC_STATUS:
6321 case VKI_CDROMSTOP:
6323 /* DVD stuff */
6324 case VKI_DVD_READ_STRUCT:
6326 /* KVM ioctls that don't check for a numeric value as parameter */
6327 case VKI_KVM_S390_ENABLE_SIE:
6328 case VKI_KVM_CREATE_IRQCHIP:
6329 case VKI_KVM_S390_INITIAL_RESET:
6330 case VKI_KVM_KVMCLOCK_CTRL:
6332 /* vhost without parameter */
6333 case VKI_VHOST_SET_OWNER:
6334 case VKI_VHOST_RESET_OWNER:
6336 /* User input device creation */
6337 case VKI_UI_DEV_CREATE:
6338 case VKI_UI_DEV_DESTROY:
6340 /* InfiniBand */
6341 case VKI_IB_USER_MAD_ENABLE_PKEY:
6343 /* Lustre */
6344 case VKI_LL_IOC_GROUP_LOCK:
6345 case VKI_LL_IOC_GROUP_UNLOCK:
6347 /* V4L2 */
6348 case VKI_V4L2_LOG_STATUS:
6350 /* DVB */
6351 case VKI_DMX_STOP:
6352 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
6353 PRE_REG_READ2(long, "ioctl",
6354 unsigned int, fd, unsigned int, request);
6355 return;
6357 default:
6358 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
6359 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6360 PRE_REG_READ3(long, "ioctl",
6361 unsigned int, fd, unsigned int, request, unsigned long, arg);
6362 break;
6365 // We now handle those that do look at ARG3 (and unknown ones fall into
6366 // this category). Nb: some of these may well belong in the
6367 // doesn't-use-ARG3 switch above.
6368 switch (ARG2 /* request */) {
6370 case VKI_ION_IOC_ALLOC: {
6371 struct vki_ion_allocation_data* data
6372 = (struct vki_ion_allocation_data*)(Addr)ARG3;
6373 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
6374 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
6375 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6376 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
6377 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
6378 break;
6380 case VKI_ION_IOC_MAP: {
6381 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6382 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6383 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
6384 break;
6386 case VKI_ION_IOC_IMPORT: {
6387 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6388 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
6389 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6390 break;
6393 case VKI_SYNC_IOC_MERGE: {
6394 struct vki_sync_merge_data* data =
6395 (struct vki_sync_merge_data*)(Addr)ARG3;
6396 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
6397 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
6398 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6399 break;
6402 case VKI_TCSETS:
6403 case VKI_TCSETSW:
6404 case VKI_TCSETSF:
6405 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6406 break;
6407 case VKI_TCGETS:
6408 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6409 break;
6410 case VKI_TCSETA:
6411 case VKI_TCSETAW:
6412 case VKI_TCSETAF:
6413 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6414 break;
6415 case VKI_TCGETA:
6416 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6417 break;
6418 case VKI_TCSBRK:
6419 case VKI_TCXONC:
6420 case VKI_TCSBRKP:
6421 case VKI_TCFLSH:
6422 case VKI_TIOCSIG:
6423 /* These just take an int by value */
6424 break;
6425 case VKI_TIOCGWINSZ:
6426 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6427 break;
6428 case VKI_TIOCSWINSZ:
6429 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
6430 break;
6431 case VKI_TIOCMBIS:
6432 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
6433 break;
6434 case VKI_TIOCMBIC:
6435 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
6436 break;
6437 case VKI_TIOCMSET:
6438 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
6439 break;
6440 case VKI_TIOCMGET:
6441 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
6442 break;
6443 case VKI_TIOCLINUX:
6444 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
6445 if (*(char *)(Addr)ARG3 == 11) {
6446 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6448 break;
6449 case VKI_TIOCGPGRP:
6450 /* Get process group ID for foreground processing group. */
6451 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6452 break;
6453 case VKI_TIOCSPGRP:
6454 /* Set a process group ID? */
6455 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6456 break;
6457 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6458 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6459 break;
6460 case VKI_TIOCSCTTY:
6461 /* Just takes an int value. */
6462 break;
6463 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6464 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6465 break;
6466 case VKI_FIONBIO:
6467 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
6468 break;
6469 case VKI_FIOASYNC:
6470 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
6471 break;
6472 case VKI_FIONREAD: /* identical to SIOCINQ */
6473 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
6474 break;
6475 case VKI_FIOQSIZE:
6476 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
6477 break;
6479 case VKI_TIOCSERGETLSR:
6480 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6481 break;
6482 case VKI_TIOCGICOUNT:
6483 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6484 sizeof(struct vki_serial_icounter_struct) );
6485 break;
6487 case VKI_SG_SET_COMMAND_Q:
6488 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6489 break;
6490 case VKI_SG_IO:
6491 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6493 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
6494 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6495 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6496 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6497 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6500 break;
6501 case VKI_SG_GET_SCSI_ID:
6502 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6503 break;
6504 case VKI_SG_SET_RESERVED_SIZE:
6505 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6506 break;
6507 case VKI_SG_SET_TIMEOUT:
6508 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6509 break;
6510 case VKI_SG_GET_RESERVED_SIZE:
6511 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6512 break;
6513 case VKI_SG_GET_TIMEOUT:
6514 break;
6515 case VKI_SG_GET_VERSION_NUM:
6516 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
6517 break;
6518 case VKI_SG_EMULATED_HOST: /* 0x2203 */
6519 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
6520 break;
6521 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6522 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6523 break;
6525 case VKI_IIOCGETCPS:
6526 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6527 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6528 break;
6529 case VKI_IIOCNETGPN:
6530 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6531 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
6532 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
6533 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6534 sizeof(vki_isdn_net_ioctl_phone) );
6535 break;
6537 /* These all use struct ifreq AFAIK */
6538 case VKI_SIOCGIFINDEX: /* get iface index */
6539 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6540 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6541 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6542 break;
6543 case VKI_SIOCGIFFLAGS: /* get flags */
6544 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6545 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6546 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6547 break;
6548 case VKI_SIOCGIFHWADDR: /* Get hardware address */
6549 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6550 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6551 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6552 break;
6553 case VKI_SIOCGIFMTU: /* get MTU size */
6554 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6555 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6556 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6557 break;
6558 case VKI_SIOCGIFADDR: /* get PA address */
6559 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6560 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6561 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6562 break;
6563 case VKI_SIOCGIFNETMASK: /* get network PA mask */
6564 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6565 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6566 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6567 break;
6568 case VKI_SIOCGIFMETRIC: /* get metric */
6569 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6570 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6571 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6572 break;
6573 case VKI_SIOCGIFMAP: /* Get device parameters */
6574 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6575 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6576 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6577 break;
6578 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
6579 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6580 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6581 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6582 break;
6583 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
6584 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6585 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6586 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6587 break;
6588 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
6589 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6590 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6591 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6592 break;
6593 case VKI_SIOCGIFNAME: /* get iface name */
6594 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6595 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
6596 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
6597 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6598 break;
6599 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
6600 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
6601 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
6602 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
6603 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6604 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6605 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6606 case VKI_ETHTOOL_GSET:
6607 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6608 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6609 break;
6610 case VKI_ETHTOOL_SSET:
6611 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6612 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6613 break;
6614 case VKI_ETHTOOL_GDRVINFO:
6615 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6616 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6617 break;
6618 case VKI_ETHTOOL_GREGS:
6619 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6620 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6621 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6622 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6623 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6624 break;
6625 case VKI_ETHTOOL_GWOL:
6626 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6627 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6628 break;
6629 case VKI_ETHTOOL_SWOL:
6630 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6631 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6632 break;
6633 case VKI_ETHTOOL_GMSGLVL:
6634 case VKI_ETHTOOL_GLINK:
6635 case VKI_ETHTOOL_GRXCSUM:
6636 case VKI_ETHTOOL_GSG:
6637 case VKI_ETHTOOL_GTSO:
6638 case VKI_ETHTOOL_GUFO:
6639 case VKI_ETHTOOL_GGSO:
6640 case VKI_ETHTOOL_GFLAGS:
6641 case VKI_ETHTOOL_GGRO:
6642 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6643 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6644 break;
6645 case VKI_ETHTOOL_SMSGLVL:
6646 case VKI_ETHTOOL_SRXCSUM:
6647 case VKI_ETHTOOL_SSG:
6648 case VKI_ETHTOOL_STSO:
6649 case VKI_ETHTOOL_SUFO:
6650 case VKI_ETHTOOL_SGSO:
6651 case VKI_ETHTOOL_SFLAGS:
6652 case VKI_ETHTOOL_SGRO:
6653 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6654 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6655 break;
6656 case VKI_ETHTOOL_NWAY_RST:
6657 break;
6658 case VKI_ETHTOOL_GRINGPARAM:
6659 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6660 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6661 break;
6662 case VKI_ETHTOOL_SRINGPARAM:
6663 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6664 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6665 break;
6666 case VKI_ETHTOOL_TEST:
6667 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6668 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6669 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6670 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6671 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6672 break;
6673 case VKI_ETHTOOL_PHYS_ID:
6674 break;
6675 case VKI_ETHTOOL_GPERMADDR:
6676 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6677 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6678 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6679 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6680 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6681 break;
6682 case VKI_ETHTOOL_RESET:
6683 break;
6684 case VKI_ETHTOOL_GSSET_INFO:
6685 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6686 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6687 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6688 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6689 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6690 break;
6691 case VKI_ETHTOOL_GFEATURES:
6692 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6693 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6694 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6695 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6696 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6697 break;
6698 case VKI_ETHTOOL_SFEATURES:
6699 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6700 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6701 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6702 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6703 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6704 break;
6705 case VKI_ETHTOOL_GCHANNELS:
6706 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6707 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6708 break;
6709 case VKI_ETHTOOL_SCHANNELS:
6710 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6711 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6712 break;
6713 case VKI_ETHTOOL_GET_TS_INFO:
6714 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6715 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6716 break;
6718 break;
6720 case VKI_SIOCGMIIPHY: /* get hardware entry */
6721 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6722 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6723 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6724 break;
6725 case VKI_SIOCGMIIREG: /* get hardware entry registers */
6726 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6727 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6728 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6729 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6730 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6731 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6732 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6733 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6734 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6735 sizeof(struct vki_ifreq));
6736 break;
6737 case VKI_SIOCGIFCONF: /* get iface list */
6738 /* WAS:
6739 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6740 KERNEL_DO_SYSCALL(tid,RES);
6741 if (!VG_(is_kerror)(RES) && RES == 0)
6742 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6744 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6745 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
6746 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
6747 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6748 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
6749 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
6750 if ( ARG3 ) {
6751 // TODO len must be readable and writable
6752 // buf pointer only needs to be readable
6753 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
6754 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6755 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6757 break;
6758 case VKI_SIOCGSTAMP:
6759 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6760 break;
6761 case VKI_SIOCGSTAMPNS:
6762 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6763 break;
6764 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6765 the number of bytes currently in that socket's send buffer.
6766 It writes this value as an int to the memory location
6767 indicated by the third argument of ioctl(2). */
6768 case VKI_SIOCOUTQ:
6769 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6770 break;
6771 case VKI_SIOCGRARP: /* get RARP table entry */
6772 case VKI_SIOCGARP: /* get ARP table entry */
6773 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6774 break;
6776 case VKI_SIOCSIFFLAGS: /* set flags */
6777 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6778 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6779 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6780 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6781 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6782 break;
6783 case VKI_SIOCSIFMAP: /* Set device parameters */
6784 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6785 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6786 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6787 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
6788 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
6789 break;
6790 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
6791 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
6792 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6793 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
6794 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
6795 sizeof(struct vki_hwtstamp_config) );
6796 break;
6797 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
6798 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
6799 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6800 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
6801 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
6802 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
6803 break;
6804 case VKI_SIOCSIFADDR: /* set PA address */
6805 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
6806 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
6807 case VKI_SIOCSIFNETMASK: /* set network PA mask */
6808 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
6809 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6810 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
6811 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
6812 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
6813 break;
6814 case VKI_SIOCSIFMETRIC: /* set metric */
6815 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
6816 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6817 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
6818 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
6819 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
6820 break;
6821 case VKI_SIOCSIFMTU: /* set MTU size */
6822 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
6823 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6824 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
6825 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
6826 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
6827 break;
6828 case VKI_SIOCSIFHWADDR: /* set hardware address */
6829 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6830 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6831 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6832 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
6833 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
6834 break;
6835 case VKI_SIOCSMIIREG: /* set hardware entry registers */
6836 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6837 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6838 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6839 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6840 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6841 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6842 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6843 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6844 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6845 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
6846 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
6847 break;
6848 /* Routing table calls. */
6849 case VKI_SIOCADDRT: /* add routing table entry */
6850 case VKI_SIOCDELRT: /* delete routing table entry */
6851 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6852 sizeof(struct vki_rtentry));
6853 break;
6855 /* tun/tap related ioctls */
6856 case VKI_TUNSETNOCSUM:
6857 case VKI_TUNSETDEBUG:
6858 break;
6859 case VKI_TUNSETIFF:
6860 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6861 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6862 PRE_MEM_READ( "ioctl(TUNSETIFF)",
6863 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6864 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6865 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6866 break;
6867 case VKI_TUNSETPERSIST:
6868 case VKI_TUNSETOWNER:
6869 case VKI_TUNSETLINK:
6870 case VKI_TUNSETGROUP:
6871 break;
6872 case VKI_TUNGETFEATURES:
6873 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6874 break;
6875 case VKI_TUNSETOFFLOAD:
6876 break;
6877 case VKI_TUNGETIFF:
6878 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6879 break;
6880 case VKI_TUNGETSNDBUF:
6881 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6882 break;
6883 case VKI_TUNSETSNDBUF:
6884 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6885 break;
6886 case VKI_TUNGETVNETHDRSZ:
6887 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6888 break;
6889 case VKI_TUNSETVNETHDRSZ:
6890 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6891 break;
6892 case VKI_TUNSETQUEUE:
6893 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6894 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6895 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6896 break;
6897 case VKI_TUNSETIFINDEX:
6898 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6899 break;
6901 /* RARP cache control calls. */
6902 case VKI_SIOCDRARP: /* delete RARP table entry */
6903 case VKI_SIOCSRARP: /* set RARP table entry */
6904 /* ARP cache control calls. */
6905 case VKI_SIOCSARP: /* set ARP table entry */
6906 case VKI_SIOCDARP: /* delete ARP table entry */
6907 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6908 break;
6910 case VKI_SIOCGPGRP:
6911 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6912 break;
6913 case VKI_SIOCSPGRP:
6914 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6915 //tst->sys_flags &= ~SfMayBlock;
6916 break;
6918 case VKI_SIOCATMARK:
6919 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6920 break;
6922 /* linux/soundcard interface (OSS) */
6923 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6924 case VKI_SNDCTL_SEQ_GETINCOUNT:
6925 case VKI_SNDCTL_SEQ_PERCMODE:
6926 case VKI_SNDCTL_SEQ_TESTMIDI:
6927 case VKI_SNDCTL_SEQ_RESETSAMPLES:
6928 case VKI_SNDCTL_SEQ_NRSYNTHS:
6929 case VKI_SNDCTL_SEQ_NRMIDIS:
6930 case VKI_SNDCTL_SEQ_GETTIME:
6931 case VKI_SNDCTL_DSP_GETBLKSIZE:
6932 case VKI_SNDCTL_DSP_GETFMTS:
6933 case VKI_SNDCTL_DSP_GETTRIGGER:
6934 case VKI_SNDCTL_DSP_GETODELAY:
6935 case VKI_SNDCTL_DSP_GETSPDIF:
6936 case VKI_SNDCTL_DSP_GETCAPS:
6937 case VKI_SOUND_PCM_READ_RATE:
6938 case VKI_SOUND_PCM_READ_CHANNELS:
6939 case VKI_SOUND_PCM_READ_BITS:
6940 case VKI_SOUND_PCM_READ_FILTER:
6941 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6942 ARG3, sizeof(int));
6943 break;
6944 case VKI_SNDCTL_SEQ_CTRLRATE:
6945 case VKI_SNDCTL_DSP_SPEED:
6946 case VKI_SNDCTL_DSP_STEREO:
6947 case VKI_SNDCTL_DSP_CHANNELS:
6948 case VKI_SOUND_PCM_WRITE_FILTER:
6949 case VKI_SNDCTL_DSP_SUBDIVIDE:
6950 case VKI_SNDCTL_DSP_SETFRAGMENT:
6951 case VKI_SNDCTL_DSP_SETFMT:
6952 case VKI_SNDCTL_DSP_GETCHANNELMASK:
6953 case VKI_SNDCTL_DSP_BIND_CHANNEL:
6954 case VKI_SNDCTL_TMR_TIMEBASE:
6955 case VKI_SNDCTL_TMR_TEMPO:
6956 case VKI_SNDCTL_TMR_SOURCE:
6957 case VKI_SNDCTL_MIDI_PRETIME:
6958 case VKI_SNDCTL_MIDI_MPUMODE:
6959 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6960 ARG3, sizeof(int));
6961 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6962 ARG3, sizeof(int));
6963 break;
6964 case VKI_SNDCTL_DSP_GETOSPACE:
6965 case VKI_SNDCTL_DSP_GETISPACE:
6966 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
6967 ARG3, sizeof(vki_audio_buf_info));
6968 break;
6969 case VKI_SNDCTL_DSP_NONBLOCK:
6970 break;
6971 case VKI_SNDCTL_DSP_SETTRIGGER:
6972 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
6973 ARG3, sizeof(int));
6974 break;
6976 case VKI_SNDCTL_DSP_POST:
6977 case VKI_SNDCTL_DSP_RESET:
6978 case VKI_SNDCTL_DSP_SYNC:
6979 case VKI_SNDCTL_DSP_SETSYNCRO:
6980 case VKI_SNDCTL_DSP_SETDUPLEX:
6981 break;
6983 /* linux/soundcard interface (ALSA) */
6984 case VKI_SNDRV_PCM_IOCTL_PAUSE:
6985 case VKI_SNDRV_PCM_IOCTL_LINK:
6986 /* these just take an int by value */
6987 break;
6988 case VKI_SNDRV_CTL_IOCTL_PVERSION:
6989 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
6990 break;
6991 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
6992 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
6993 break;
6994 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
6995 struct vki_snd_ctl_elem_list *data =
6996 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
6997 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
6998 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
6999 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7000 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7001 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7002 if (data->pids) {
7003 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7005 break;
7007 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7008 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7009 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7010 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7011 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7012 break;
7014 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7015 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7016 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7017 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7018 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7019 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7020 break;
7023 /* Real Time Clock (/dev/rtc) ioctls */
7024 case VKI_RTC_UIE_ON:
7025 case VKI_RTC_UIE_OFF:
7026 case VKI_RTC_AIE_ON:
7027 case VKI_RTC_AIE_OFF:
7028 case VKI_RTC_PIE_ON:
7029 case VKI_RTC_PIE_OFF:
7030 case VKI_RTC_IRQP_SET:
7031 break;
7032 case VKI_RTC_RD_TIME:
7033 case VKI_RTC_ALM_READ:
7034 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7035 ARG3, sizeof(struct vki_rtc_time));
7036 break;
7037 case VKI_RTC_ALM_SET:
7038 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7039 break;
7040 case VKI_RTC_IRQP_READ:
7041 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7042 break;
7044 /* Block devices */
7045 case VKI_BLKROSET:
7046 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7047 break;
7048 case VKI_BLKROGET:
7049 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7050 break;
7051 case VKI_BLKGETSIZE:
7052 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7053 break;
7054 case VKI_BLKFLSBUF:
7055 break;
7056 case VKI_BLKRASET:
7057 break;
7058 case VKI_BLKRAGET:
7059 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7060 break;
7061 case VKI_BLKFRASET:
7062 break;
7063 case VKI_BLKFRAGET:
7064 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7065 break;
7066 case VKI_BLKSECTGET:
7067 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7068 break;
7069 case VKI_BLKSSZGET:
7070 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7071 break;
7072 case VKI_BLKBSZGET:
7073 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7074 break;
7075 case VKI_BLKBSZSET:
7076 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7077 break;
7078 case VKI_BLKGETSIZE64:
7079 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7080 break;
7081 case VKI_BLKPBSZGET:
7082 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7083 break;
7084 case VKI_BLKDISCARDZEROES:
7085 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7086 break;
7087 case VKI_BLKREPORTZONE:
7088 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7089 sizeof(struct vki_blk_zone_report));
7090 break;
7091 case VKI_BLKRESETZONE:
7092 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7093 sizeof(struct vki_blk_zone_range));
7094 break;
7096 /* Hard disks */
7097 case VKI_HDIO_GETGEO: /* 0x0301 */
7098 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7099 break;
7100 case VKI_HDIO_GET_DMA: /* 0x030b */
7101 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7102 break;
7103 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7104 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7105 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7106 break;
7108 /* SCSI */
7109 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7110 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7111 break;
7112 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7113 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7114 break;
7116 /* CD ROM stuff (??) */
7117 case VKI_CDROM_GET_MCN:
7118 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7119 sizeof(struct vki_cdrom_mcn) );
7120 break;
7121 case VKI_CDROM_SEND_PACKET:
7122 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7123 sizeof(struct vki_cdrom_generic_command));
7124 break;
7125 case VKI_CDROMSUBCHNL:
7126 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7127 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7128 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7129 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7130 sizeof(struct vki_cdrom_subchnl));
7131 break;
7132 case VKI_CDROMREADMODE1: /*0x530d*/
7133 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7134 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7135 break;
7136 case VKI_CDROMREADMODE2: /*0x530c*/
7137 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7138 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7139 break;
7140 case VKI_CDROMREADTOCHDR:
7141 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7142 sizeof(struct vki_cdrom_tochdr));
7143 break;
7144 case VKI_CDROMREADTOCENTRY:
7145 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7146 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7147 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7148 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7149 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7150 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7151 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7152 sizeof(struct vki_cdrom_tocentry));
7153 break;
7154 case VKI_CDROMMULTISESSION: /* 0x5310 */
7155 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7156 sizeof(struct vki_cdrom_multisession));
7157 break;
7158 case VKI_CDROMVOLREAD: /* 0x5313 */
7159 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7160 sizeof(struct vki_cdrom_volctrl));
7161 break;
7162 case VKI_CDROMREADRAW: /* 0x5314 */
7163 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7164 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7165 break;
7166 case VKI_CDROMREADAUDIO: /* 0x530e */
7167 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7168 sizeof (struct vki_cdrom_read_audio));
7169 if ( ARG3 ) {
7170 /* ToDo: don't do any of the following if the structure is invalid */
7171 struct vki_cdrom_read_audio *cra =
7172 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7173 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7174 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7176 break;
7177 case VKI_CDROMPLAYMSF:
7178 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7179 break;
7180 /* The following two are probably bogus (should check args
7181 for readability). JRS 20021117 */
7182 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7183 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7184 break;
7185 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7186 break;
7188 case VKI_FIGETBSZ:
7189 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7190 break;
7191 case VKI_FIBMAP:
7192 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7193 break;
7195 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7196 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7197 sizeof(struct vki_fb_var_screeninfo));
7198 break;
7199 case VKI_FBIOPUT_VSCREENINFO:
7200 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7201 sizeof(struct vki_fb_var_screeninfo));
7202 break;
7203 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7204 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7205 sizeof(struct vki_fb_fix_screeninfo));
7206 break;
7207 case VKI_FBIOPAN_DISPLAY:
7208 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7209 sizeof(struct vki_fb_var_screeninfo));
7211 break;
7212 case VKI_PPCLAIM:
7213 case VKI_PPEXCL:
7214 case VKI_PPYIELD:
7215 case VKI_PPRELEASE:
7216 break;
7217 case VKI_PPSETMODE:
7218 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7219 break;
7220 case VKI_PPGETMODE:
7221 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7222 break;
7223 case VKI_PPSETPHASE:
7224 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7225 break;
7226 case VKI_PPGETPHASE:
7227 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7228 break;
7229 case VKI_PPGETMODES:
7230 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7231 break;
7232 case VKI_PPSETFLAGS:
7233 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7234 break;
7235 case VKI_PPGETFLAGS:
7236 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7237 break;
7238 case VKI_PPRSTATUS:
7239 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
7240 break;
7241 case VKI_PPRDATA:
7242 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
7243 break;
7244 case VKI_PPRCONTROL:
7245 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7246 break;
7247 case VKI_PPWDATA:
7248 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
7249 break;
7250 case VKI_PPWCONTROL:
7251 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7252 break;
7253 case VKI_PPFCONTROL:
7254 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7255 break;
7256 case VKI_PPDATADIR:
7257 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
7258 break;
7259 case VKI_PPNEGOT:
7260 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
7261 break;
7262 case VKI_PPWCTLONIRQ:
7263 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7264 break;
7265 case VKI_PPCLRIRQ:
7266 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
7267 break;
7268 case VKI_PPSETTIME:
7269 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
7270 break;
7271 case VKI_PPGETTIME:
7272 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
7273 break;
7275 case VKI_GIO_FONT:
7276 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7277 break;
7278 case VKI_PIO_FONT:
7279 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7280 break;
7282 case VKI_GIO_FONTX:
7283 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7284 if ( ARG3 ) {
7285 /* ToDo: don't do any of the following if the structure is invalid */
7286 struct vki_consolefontdesc *cfd =
7287 (struct vki_consolefontdesc *)(Addr)ARG3;
7288 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7289 32 * cfd->charcount );
7291 break;
7292 case VKI_PIO_FONTX:
7293 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7294 if ( ARG3 ) {
7295 /* ToDo: don't do any of the following if the structure is invalid */
7296 struct vki_consolefontdesc *cfd =
7297 (struct vki_consolefontdesc *)(Addr)ARG3;
7298 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7299 32 * cfd->charcount );
7301 break;
7303 case VKI_PIO_FONTRESET:
7304 break;
7306 case VKI_GIO_CMAP:
7307 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7308 break;
7309 case VKI_PIO_CMAP:
7310 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7311 break;
7313 case VKI_KIOCSOUND:
7314 case VKI_KDMKTONE:
7315 break;
7317 case VKI_KDGETLED:
7318 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7319 break;
7320 case VKI_KDSETLED:
7321 break;
7323 case VKI_KDGKBTYPE:
7324 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7325 break;
7327 case VKI_KDADDIO:
7328 case VKI_KDDELIO:
7329 case VKI_KDENABIO:
7330 case VKI_KDDISABIO:
7331 break;
7333 case VKI_KDSETMODE:
7334 break;
7335 case VKI_KDGETMODE:
7336 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7337 break;
7339 case VKI_KDMAPDISP:
7340 case VKI_KDUNMAPDISP:
7341 break;
7343 case VKI_GIO_SCRNMAP:
7344 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7345 break;
7346 case VKI_PIO_SCRNMAP:
7347 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7348 break;
7349 case VKI_GIO_UNISCRNMAP:
7350 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7351 VKI_E_TABSZ * sizeof(unsigned short) );
7352 break;
7353 case VKI_PIO_UNISCRNMAP:
7354 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7355 VKI_E_TABSZ * sizeof(unsigned short) );
7356 break;
7358 case VKI_GIO_UNIMAP:
7359 if ( ARG3 ) {
7360 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7361 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7362 sizeof(unsigned short));
7363 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7364 sizeof(struct vki_unipair *));
7365 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7366 desc->entry_ct * sizeof(struct vki_unipair));
7368 break;
7369 case VKI_PIO_UNIMAP:
7370 if ( ARG3 ) {
7371 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7372 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7373 sizeof(unsigned short) );
7374 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7375 sizeof(struct vki_unipair *) );
7376 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7377 desc->entry_ct * sizeof(struct vki_unipair) );
7379 break;
7380 case VKI_PIO_UNIMAPCLR:
7381 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7382 break;
7384 case VKI_KDGKBMODE:
7385 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7386 break;
7387 case VKI_KDSKBMODE:
7388 break;
7390 case VKI_KDGKBMETA:
7391 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7392 break;
7393 case VKI_KDSKBMETA:
7394 break;
7396 case VKI_KDGKBLED:
7397 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7398 break;
7399 case VKI_KDSKBLED:
7400 break;
7402 case VKI_KDGKBENT:
7403 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7404 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7405 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7406 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7407 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7408 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7409 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7410 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7411 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7412 break;
7413 case VKI_KDSKBENT:
7414 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7415 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7416 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7417 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7418 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7419 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7420 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7421 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7422 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7423 break;
7425 case VKI_KDGKBSENT:
7426 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7427 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7428 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7429 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7430 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
7431 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
7432 break;
7433 case VKI_KDSKBSENT:
7434 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7435 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7436 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7437 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7438 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
7439 break;
7441 case VKI_KDGKBDIACR:
7442 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7443 break;
7444 case VKI_KDSKBDIACR:
7445 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7446 break;
7448 case VKI_KDGETKEYCODE:
7449 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7450 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7451 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7452 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7453 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7454 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7455 break;
7456 case VKI_KDSETKEYCODE:
7457 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7458 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7459 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7460 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7461 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7462 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7463 break;
7465 case VKI_KDSIGACCEPT:
7466 break;
7468 case VKI_KDKBDREP:
7469 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7470 break;
7472 case VKI_KDFONTOP:
7473 if ( ARG3 ) {
7474 struct vki_console_font_op *op =
7475 (struct vki_console_font_op *) (Addr)ARG3;
7476 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7477 sizeof(struct vki_console_font_op) );
7478 switch ( op->op ) {
7479 case VKI_KD_FONT_OP_SET:
7480 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7481 (Addr)op->data,
7482 (op->width + 7) / 8 * 32 * op->charcount );
7483 break;
7484 case VKI_KD_FONT_OP_GET:
7485 if ( op->data )
7486 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7487 (Addr)op->data,
7488 (op->width + 7) / 8 * 32 * op->charcount );
7489 break;
7490 case VKI_KD_FONT_OP_SET_DEFAULT:
7491 if ( op->data )
7492 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7493 (Addr)op->data );
7494 break;
7495 case VKI_KD_FONT_OP_COPY:
7496 break;
7499 break;
7501 case VKI_VT_OPENQRY:
7502 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7503 break;
7504 case VKI_VT_GETMODE:
7505 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7506 break;
7507 case VKI_VT_SETMODE:
7508 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7509 break;
7510 case VKI_VT_GETSTATE:
7511 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7512 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
7513 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
7514 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7515 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
7516 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
7517 break;
7518 case VKI_VT_RELDISP:
7519 case VKI_VT_ACTIVATE:
7520 case VKI_VT_WAITACTIVE:
7521 case VKI_VT_DISALLOCATE:
7522 break;
7523 case VKI_VT_RESIZE:
7524 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7525 break;
7526 case VKI_VT_RESIZEX:
7527 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7528 break;
7529 case VKI_VT_LOCKSWITCH:
7530 case VKI_VT_UNLOCKSWITCH:
7531 break;
7533 case VKI_USBDEVFS_CONTROL:
7534 if ( ARG3 ) {
7535 struct vki_usbdevfs_ctrltransfer *vkuc =
7536 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
7537 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7538 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7539 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7540 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7541 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7542 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7543 if (vkuc->bRequestType & 0x80)
7544 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7545 else
7546 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7548 break;
7549 case VKI_USBDEVFS_BULK:
7550 if ( ARG3 ) {
7551 struct vki_usbdevfs_bulktransfer *vkub =
7552 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
7553 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7554 if (vkub->ep & 0x80)
7555 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7556 else
7557 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7559 break;
7560 case VKI_USBDEVFS_GETDRIVER:
7561 if ( ARG3 ) {
7562 struct vki_usbdevfs_getdriver *vkugd =
7563 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
7564 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7566 break;
7567 case VKI_USBDEVFS_SUBMITURB:
7568 if ( ARG3 ) {
7569 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
7571 /* Not the whole struct needs to be initialized */
7572 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7573 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7574 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7575 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7576 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7577 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7578 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7579 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7580 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7581 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7582 if (vkusp->bRequestType & 0x80)
7583 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7584 else
7585 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7586 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7587 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7588 int total_length = 0;
7589 int i;
7590 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7591 for(i=0; i<vkuu->number_of_packets; i++) {
7592 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7593 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));
7594 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7595 total_length += vkuu->iso_frame_desc[i].length;
7597 if (vkuu->endpoint & 0x80)
7598 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7599 else
7600 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7601 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7602 } else {
7603 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7604 if (vkuu->endpoint & 0x80)
7605 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7606 else
7607 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7608 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7611 break;
7612 case VKI_USBDEVFS_DISCARDURB:
7613 break;
7614 case VKI_USBDEVFS_REAPURB:
7615 if ( ARG3 ) {
7616 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7618 break;
7619 case VKI_USBDEVFS_REAPURBNDELAY:
7620 if ( ARG3 ) {
7621 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7623 break;
7624 case VKI_USBDEVFS_CONNECTINFO:
7625 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7626 break;
7627 case VKI_USBDEVFS_IOCTL:
7628 if ( ARG3 ) {
7629 struct vki_usbdevfs_ioctl *vkui =
7630 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
7631 UInt dir2, size2;
7632 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7633 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
7634 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7635 if (size2 > 0) {
7636 if (dir2 & _VKI_IOC_WRITE)
7637 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7638 else if (dir2 & _VKI_IOC_READ)
7639 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7642 break;
7643 case VKI_USBDEVFS_RESET:
7644 break;
7646 /* I2C (/dev/i2c-*) ioctls */
7647 case VKI_I2C_SLAVE:
7648 case VKI_I2C_SLAVE_FORCE:
7649 case VKI_I2C_TENBIT:
7650 case VKI_I2C_PEC:
7651 break;
7652 case VKI_I2C_FUNCS:
7653 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7654 break;
7655 case VKI_I2C_RDWR:
7656 if ( ARG3 ) {
7657 struct vki_i2c_rdwr_ioctl_data *vkui =
7658 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
7659 UInt i;
7660 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7661 for (i=0; i < vkui->nmsgs; i++) {
7662 struct vki_i2c_msg *msg = vkui->msgs + i;
7663 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7664 if (msg->flags & VKI_I2C_M_RD)
7665 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7666 else
7667 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7670 break;
7671 case VKI_I2C_SMBUS:
7672 if ( ARG3 ) {
7673 struct vki_i2c_smbus_ioctl_data *vkis
7674 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
7675 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7676 (Addr)&vkis->read_write, sizeof(vkis->read_write));
7677 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7678 (Addr)&vkis->size, sizeof(vkis->size));
7679 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7680 (Addr)&vkis->command, sizeof(vkis->command));
7681 /* i2c_smbus_write_quick hides its value in read_write, so
7682 this variable can have a different meaning */
7683 /* to make matters worse i2c_smbus_write_byte stores its
7684 value in command */
7685 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7686 ((vkis->size == VKI_I2C_SMBUS_BYTE)
7687 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
7688 /* the rest uses the byte array to store the data,
7689 some the first byte for size */
7690 UInt size;
7691 switch(vkis->size) {
7692 case VKI_I2C_SMBUS_BYTE_DATA:
7693 size = 1;
7694 break;
7695 case VKI_I2C_SMBUS_WORD_DATA:
7696 case VKI_I2C_SMBUS_PROC_CALL:
7697 size = 2;
7698 break;
7699 case VKI_I2C_SMBUS_BLOCK_DATA:
7700 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7701 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7702 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7703 size = 1 + vkis->data->block[0];
7704 break;
7705 default:
7706 size = 0;
7709 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7710 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7711 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7712 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7713 ".i2c_smbus_ioctl_data.data",
7714 (Addr)&vkis->data->block[0], size);
7715 else
7716 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7717 "i2c_smbus_ioctl_data.data",
7718 (Addr)&vkis->data->block[0], size);
7721 break;
7723 /* Wireless extensions ioctls */
7724 case VKI_SIOCSIWCOMMIT:
7725 case VKI_SIOCSIWNWID:
7726 case VKI_SIOCSIWFREQ:
7727 case VKI_SIOCSIWMODE:
7728 case VKI_SIOCSIWSENS:
7729 case VKI_SIOCSIWRANGE:
7730 case VKI_SIOCSIWPRIV:
7731 case VKI_SIOCSIWSTATS:
7732 case VKI_SIOCSIWSPY:
7733 case VKI_SIOCSIWTHRSPY:
7734 case VKI_SIOCSIWAP:
7735 case VKI_SIOCSIWSCAN:
7736 case VKI_SIOCSIWESSID:
7737 case VKI_SIOCSIWRATE:
7738 case VKI_SIOCSIWNICKN:
7739 case VKI_SIOCSIWRTS:
7740 case VKI_SIOCSIWFRAG:
7741 case VKI_SIOCSIWTXPOW:
7742 case VKI_SIOCSIWRETRY:
7743 case VKI_SIOCSIWENCODE:
7744 case VKI_SIOCSIWPOWER:
7745 case VKI_SIOCSIWGENIE:
7746 case VKI_SIOCSIWMLME:
7747 case VKI_SIOCSIWAUTH:
7748 case VKI_SIOCSIWENCODEEXT:
7749 case VKI_SIOCSIWPMKSA:
7750 break;
7751 case VKI_SIOCGIWNAME:
7752 if (ARG3) {
7753 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7754 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
7755 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
7757 break;
7758 case VKI_SIOCGIWNWID:
7759 case VKI_SIOCGIWSENS:
7760 case VKI_SIOCGIWRATE:
7761 case VKI_SIOCGIWRTS:
7762 case VKI_SIOCGIWFRAG:
7763 case VKI_SIOCGIWTXPOW:
7764 case VKI_SIOCGIWRETRY:
7765 case VKI_SIOCGIWPOWER:
7766 case VKI_SIOCGIWAUTH:
7767 if (ARG3) {
7768 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7769 "RETRY|PARAM|AUTH])",
7770 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
7771 sizeof(struct vki_iw_param));
7773 break;
7774 case VKI_SIOCGIWFREQ:
7775 if (ARG3) {
7776 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7777 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
7778 sizeof(struct vki_iw_freq));
7780 break;
7781 case VKI_SIOCGIWMODE:
7782 if (ARG3) {
7783 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
7784 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
7785 sizeof(__vki_u32));
7787 break;
7788 case VKI_SIOCGIWRANGE:
7789 case VKI_SIOCGIWPRIV:
7790 case VKI_SIOCGIWSTATS:
7791 case VKI_SIOCGIWSPY:
7792 case VKI_SIOCGIWTHRSPY:
7793 case VKI_SIOCGIWAPLIST:
7794 case VKI_SIOCGIWSCAN:
7795 case VKI_SIOCGIWESSID:
7796 case VKI_SIOCGIWNICKN:
7797 case VKI_SIOCGIWENCODE:
7798 case VKI_SIOCGIWGENIE:
7799 case VKI_SIOCGIWENCODEEXT:
7800 if (ARG3) {
7801 struct vki_iw_point* point;
7802 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
7803 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
7804 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
7805 (Addr)point->pointer, point->length);
7807 break;
7808 case VKI_SIOCGIWAP:
7809 if (ARG3) {
7810 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
7811 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
7812 sizeof(struct vki_sockaddr));
7814 break;
7816 /* User input device creation */
7817 case VKI_UI_SET_EVBIT:
7818 case VKI_UI_SET_KEYBIT:
7819 case VKI_UI_SET_RELBIT:
7820 case VKI_UI_SET_ABSBIT:
7821 case VKI_UI_SET_MSCBIT:
7822 case VKI_UI_SET_LEDBIT:
7823 case VKI_UI_SET_SNDBIT:
7824 case VKI_UI_SET_FFBIT:
7825 case VKI_UI_SET_SWBIT:
7826 case VKI_UI_SET_PROPBIT:
7827 /* These just take an int by value */
7828 break;
7830 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7831 || defined(VGPV_mips32_linux_android) \
7832 || defined(VGPV_arm64_linux_android)
7833 /* ashmem */
7834 case VKI_ASHMEM_GET_SIZE:
7835 case VKI_ASHMEM_SET_SIZE:
7836 case VKI_ASHMEM_GET_PROT_MASK:
7837 case VKI_ASHMEM_SET_PROT_MASK:
7838 case VKI_ASHMEM_GET_PIN_STATUS:
7839 case VKI_ASHMEM_PURGE_ALL_CACHES:
7840 break;
7841 case VKI_ASHMEM_GET_NAME:
7842 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
7843 break;
7844 case VKI_ASHMEM_SET_NAME:
7845 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
7846 break;
7847 case VKI_ASHMEM_PIN:
7848 case VKI_ASHMEM_UNPIN:
7849 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
7850 ARG3, sizeof(struct vki_ashmem_pin) );
7851 break;
7853 /* binder */
7854 case VKI_BINDER_WRITE_READ:
7855 if (ARG3) {
7856 struct vki_binder_write_read* bwr
7857 = (struct vki_binder_write_read*)(Addr)ARG3;
7859 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7860 bwr->write_buffer);
7861 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7862 bwr->write_size);
7863 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7864 bwr->write_consumed);
7865 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7866 bwr->read_buffer);
7867 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7868 bwr->read_size);
7869 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7870 bwr->read_consumed);
7872 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7873 bwr->write_consumed);
7874 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7875 bwr->read_consumed);
7877 if (bwr->read_size)
7878 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7879 (Addr)bwr->read_buffer, bwr->read_size);
7880 if (bwr->write_size)
7881 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7882 (Addr)bwr->write_buffer, bwr->write_size);
7884 break;
7886 case VKI_BINDER_SET_IDLE_TIMEOUT:
7887 case VKI_BINDER_SET_MAX_THREADS:
7888 case VKI_BINDER_SET_IDLE_PRIORITY:
7889 case VKI_BINDER_SET_CONTEXT_MGR:
7890 case VKI_BINDER_THREAD_EXIT:
7891 break;
7892 case VKI_BINDER_VERSION:
7893 if (ARG3) {
7894 struct vki_binder_version* bv =
7895 (struct vki_binder_version*)(Addr)ARG3;
7896 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7898 break;
7899 # endif /* defined(VGPV_*_linux_android) */
7901 case VKI_HCIGETDEVLIST:
7902 if (ARG3) {
7903 struct vki_hci_dev_list_req* dlr =
7904 (struct vki_hci_dev_list_req*)(Addr)ARG3;
7905 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7906 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7907 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7908 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7909 dlr->dev_num * sizeof(struct vki_hci_dev_req));
7911 break;
7913 case VKI_HCIINQUIRY:
7914 if (ARG3) {
7915 struct vki_hci_inquiry_req* ir =
7916 (struct vki_hci_inquiry_req*)(Addr)ARG3;
7917 PRE_MEM_READ("ioctl(HCIINQUIRY)",
7918 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7919 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7920 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7921 ir->num_rsp * sizeof(struct vki_inquiry_info));
7923 break;
7925 case VKI_DRM_IOCTL_VERSION:
7926 if (ARG3) {
7927 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
7928 struct vg_drm_version_info* info;
7929 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7930 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7931 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7932 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7933 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7934 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7935 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7936 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7937 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7938 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7939 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7940 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7941 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
7942 // To ensure we VG_(free) info even when syscall fails:
7943 *flags |= SfPostOnFail;
7944 info->data = *data;
7945 info->orig = data;
7946 ARG3 = (Addr)&info->data;
7948 break;
7949 case VKI_DRM_IOCTL_GET_UNIQUE:
7950 if (ARG3) {
7951 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
7952 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7953 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7954 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7956 break;
7957 case VKI_DRM_IOCTL_GET_MAGIC:
7958 if (ARG3) {
7959 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
7960 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
7962 break;
7963 case VKI_DRM_IOCTL_WAIT_VBLANK:
7964 if (ARG3) {
7965 union vki_drm_wait_vblank *data =
7966 (union vki_drm_wait_vblank *)(Addr)ARG3;
7967 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
7968 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
7969 /* XXX: It seems request.signal isn't used */
7970 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
7972 break;
7973 case VKI_DRM_IOCTL_GEM_CLOSE:
7974 if (ARG3) {
7975 struct vki_drm_gem_close *data =
7976 (struct vki_drm_gem_close *)(Addr)ARG3;
7977 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
7979 break;
7980 case VKI_DRM_IOCTL_GEM_FLINK:
7981 if (ARG3) {
7982 struct vki_drm_gem_flink *data =
7983 (struct vki_drm_gem_flink *)(Addr)ARG3;
7984 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
7985 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
7987 break;
7988 case VKI_DRM_IOCTL_GEM_OPEN:
7989 if (ARG3) {
7990 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
7991 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
7992 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
7993 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
7995 break;
7996 case VKI_DRM_IOCTL_I915_GETPARAM:
7997 if (ARG3) {
7998 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
7999 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8000 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8002 break;
8003 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8004 if (ARG3) {
8005 struct vki_drm_i915_gem_busy *data =
8006 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8007 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8008 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8010 break;
8011 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8012 if (ARG3) {
8013 struct vki_drm_i915_gem_create *data =
8014 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8015 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8016 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8018 break;
8019 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8020 if (ARG3) {
8021 struct vki_drm_i915_gem_pread *data =
8022 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8023 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8024 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8025 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8026 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8027 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8029 break;
8030 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8031 if (ARG3) {
8032 struct vki_drm_i915_gem_pwrite *data =
8033 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8034 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8035 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8036 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8037 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8038 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8039 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8040 * interleaved vertex attributes may have a wide stride with uninitialized data between
8041 * consecutive vertices) */
8043 break;
8044 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8045 if (ARG3) {
8046 struct vki_drm_i915_gem_mmap_gtt *data =
8047 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8048 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8049 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8051 break;
8052 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8053 if (ARG3) {
8054 struct vki_drm_i915_gem_set_domain *data =
8055 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8056 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8057 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8058 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8060 break;
8061 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8062 if (ARG3) {
8063 struct vki_drm_i915_gem_set_tiling *data =
8064 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8065 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8066 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8067 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8068 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8070 break;
8071 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8072 if (ARG3) {
8073 struct vki_drm_i915_gem_get_tiling *data =
8074 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8075 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8076 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8077 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8079 break;
8080 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8081 if (ARG3) {
8082 struct vki_drm_i915_gem_get_aperture *data =
8083 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8084 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8085 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8087 break;
8089 /* KVM ioctls that check for a numeric value as parameter */
8090 case VKI_KVM_GET_API_VERSION:
8091 case VKI_KVM_CREATE_VM:
8092 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8093 case VKI_KVM_CHECK_EXTENSION:
8094 case VKI_KVM_SET_TSS_ADDR:
8095 case VKI_KVM_CREATE_VCPU:
8096 case VKI_KVM_RUN:
8097 break;
8099 case VKI_KVM_S390_MEM_OP: {
8100 struct vki_kvm_s390_mem_op *args =
8101 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8102 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8103 sizeof(struct vki_kvm_s390_mem_op));
8104 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8105 break;
8106 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8107 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8108 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8109 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8111 break;
8114 #ifdef ENABLE_XEN
8115 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8116 SyscallArgs harrghs;
8117 struct vki_xen_privcmd_hypercall *args =
8118 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8120 if (!args)
8121 break;
8123 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8124 harrghs.sysno = args->op;
8125 harrghs.arg1 = args->arg[0];
8126 harrghs.arg2 = args->arg[1];
8127 harrghs.arg3 = args->arg[2];
8128 harrghs.arg4 = args->arg[3];
8129 harrghs.arg5 = args->arg[4];
8130 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8132 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8134 /* HACK. arg8 is used to return the number of hypercall
8135 * arguments actually consumed! */
8136 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8137 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8139 break;
8142 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8143 struct vki_xen_privcmd_mmap *args =
8144 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8145 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8146 (Addr)&args->num, sizeof(args->num));
8147 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8148 (Addr)&args->dom, sizeof(args->dom));
8149 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8150 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8151 break;
8153 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8154 struct vki_xen_privcmd_mmapbatch *args =
8155 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8156 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8157 (Addr)&args->num, sizeof(args->num));
8158 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8159 (Addr)&args->dom, sizeof(args->dom));
8160 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8161 (Addr)&args->addr, sizeof(args->addr));
8162 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8163 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8164 break;
8166 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8167 struct vki_xen_privcmd_mmapbatch_v2 *args =
8168 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8169 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8170 (Addr)&args->num, sizeof(args->num));
8171 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8172 (Addr)&args->dom, sizeof(args->dom));
8173 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8174 (Addr)&args->addr, sizeof(args->addr));
8175 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8176 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8177 break;
8180 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8181 struct vki_xen_ioctl_evtchn_bind_virq *args =
8182 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8183 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8184 (Addr)&args->virq, sizeof(args->virq));
8186 break;
8187 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8188 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8189 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8190 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8191 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8192 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8193 (Addr)&args->remote_port, sizeof(args->remote_port));
8195 break;
8196 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8197 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8198 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8199 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8200 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8202 break;
8203 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8204 struct vki_xen_ioctl_evtchn_unbind *args =
8205 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8206 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8207 (Addr)&args->port, sizeof(args->port));
8209 break;
8210 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8211 struct vki_xen_ioctl_evtchn_notify *args =
8212 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
8213 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8214 (Addr)&args->port, sizeof(args->port));
8216 break;
8217 case VKI_XEN_IOCTL_EVTCHN_RESET:
8218 /* No input*/
8219 break;
8220 #endif
8222 /* Lustre */
8223 case VKI_OBD_IOC_FID2PATH: {
8224 struct vki_getinfo_fid2path *gf =
8225 (struct vki_getinfo_fid2path *)(Addr)ARG3;
8226 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8227 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8228 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8229 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8230 break;
8233 case VKI_LL_IOC_PATH2FID:
8234 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8235 break;
8237 case VKI_LL_IOC_GETPARENT: {
8238 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
8239 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8240 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8241 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8242 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8243 break;
8246 /* V4L2 */
8247 case VKI_V4L2_QUERYCAP: {
8248 struct vki_v4l2_capability *data =
8249 (struct vki_v4l2_capability *)(Addr)ARG3;
8250 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8251 break;
8253 case VKI_V4L2_ENUM_FMT: {
8254 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
8255 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8256 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8257 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8258 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8259 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8260 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8261 break;
8263 case VKI_V4L2_G_FMT: {
8264 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8265 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8266 switch (data->type) {
8267 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8268 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8269 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8270 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8271 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8272 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8273 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8274 break;
8275 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8276 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8277 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8278 break;
8279 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8280 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8281 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8282 break;
8283 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8284 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8285 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8286 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8287 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8288 if (data->fmt.win.clipcount && data->fmt.win.clips)
8289 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8290 (Addr)data->fmt.win.clips,
8291 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8292 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8293 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8294 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8295 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8296 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8297 break;
8298 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8299 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8300 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8301 break;
8302 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8303 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8304 break;
8306 break;
8308 case VKI_V4L2_S_FMT: {
8309 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8310 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8311 switch (data->type) {
8312 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8313 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8314 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8315 (Addr)&data->type + sizeof(data->type),
8316 sizeof(*data) - sizeof(data->type));
8317 break;
8318 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8319 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8320 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8321 break;
8322 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8323 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8324 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8325 break;
8326 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8327 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8328 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8329 if (data->fmt.win.clipcount && data->fmt.win.clips)
8330 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8331 (Addr)data->fmt.win.clips,
8332 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8333 if (data->fmt.win.bitmap)
8334 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8335 (Addr)data->fmt.win.bitmap,
8336 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8337 break;
8338 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8339 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8340 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8341 break;
8342 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8343 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8344 break;
8346 break;
8348 case VKI_V4L2_TRY_FMT: {
8349 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8350 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8351 switch (data->type) {
8352 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8353 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8354 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8355 (Addr)&data->type + sizeof(data->type),
8356 sizeof(*data) - sizeof(data->type));
8357 break;
8358 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8359 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8360 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8361 break;
8362 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8363 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8364 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8365 break;
8366 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8367 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8368 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8369 if (data->fmt.win.clipcount && data->fmt.win.clips)
8370 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8371 (Addr)data->fmt.win.clips,
8372 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8373 if (data->fmt.win.bitmap)
8374 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8375 (Addr)data->fmt.win.bitmap,
8376 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8377 break;
8378 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8379 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8380 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8381 break;
8382 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8383 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8384 break;
8386 break;
8388 case VKI_V4L2_REQBUFS: {
8389 struct vki_v4l2_requestbuffers *data =
8390 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
8391 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8392 break;
8394 case VKI_V4L2_QUERYBUF: {
8395 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8396 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8397 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8398 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8399 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8400 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8401 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8402 unsigned i;
8404 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8405 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8406 for (i = 0; i < data->length; i++) {
8407 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8408 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8409 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8410 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8411 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8413 } else {
8414 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8415 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8417 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8418 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8419 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8420 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8421 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8422 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8423 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8424 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8425 break;
8427 case VKI_V4L2_G_FBUF: {
8428 struct vki_v4l2_framebuffer *data =
8429 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8430 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8431 break;
8433 case VKI_V4L2_S_FBUF: {
8434 struct vki_v4l2_framebuffer *data =
8435 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8436 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8437 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8438 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8439 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8440 break;
8442 case VKI_V4L2_OVERLAY: {
8443 int *data = (int *)(Addr)ARG3;
8444 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8445 break;
8447 case VKI_V4L2_QBUF: {
8448 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8449 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8450 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8451 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8452 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8454 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8455 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8456 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8457 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8458 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8459 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8460 if (is_output) {
8461 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8462 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8464 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8465 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8466 unsigned i;
8468 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8469 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8470 for (i = 0; i < data->length; i++) {
8471 if (is_output) {
8472 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8473 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8475 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8476 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8477 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8478 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8479 else
8480 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8481 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8483 } else {
8484 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8485 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8486 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8487 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8488 else
8489 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8490 if (is_output) {
8491 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8492 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8495 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8496 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8497 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8499 break;
8501 case VKI_V4L2_EXPBUF: {
8502 struct vki_v4l2_exportbuffer *data =
8503 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
8504 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8505 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8506 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8507 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8508 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8509 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8510 break;
8512 case VKI_V4L2_DQBUF: {
8513 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8514 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8515 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8516 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8517 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8518 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8519 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8520 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8521 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8522 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8523 unsigned i;
8525 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8526 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8527 for (i = 0; i < data->length; i++) {
8528 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8529 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8530 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8531 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8532 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8534 } else {
8535 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8536 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8537 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8538 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8540 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8541 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8542 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8543 break;
8545 case VKI_V4L2_STREAMON: {
8546 int *data = (int *)(Addr)ARG3;
8547 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8548 break;
8550 case VKI_V4L2_STREAMOFF: {
8551 int *data = (int *)(Addr)ARG3;
8552 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8553 break;
8555 case VKI_V4L2_G_PARM: {
8556 struct vki_v4l2_streamparm *data =
8557 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8558 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8559 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8560 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8561 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8563 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8564 if (is_output) {
8565 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8566 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8567 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8568 } else {
8569 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8570 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8571 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8573 break;
8575 case VKI_V4L2_S_PARM: {
8576 struct vki_v4l2_streamparm *data =
8577 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8578 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8579 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8580 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8581 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8583 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8584 if (is_output)
8585 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8586 else
8587 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8588 break;
8590 case VKI_V4L2_G_STD: {
8591 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8592 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8593 break;
8595 case VKI_V4L2_S_STD: {
8596 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8597 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8598 break;
8600 case VKI_V4L2_ENUMSTD: {
8601 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
8602 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8603 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8604 break;
8606 case VKI_V4L2_ENUMINPUT: {
8607 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
8608 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8609 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8610 break;
8612 case VKI_V4L2_G_CTRL: {
8613 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8614 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8615 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8616 break;
8618 case VKI_V4L2_S_CTRL: {
8619 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8620 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8621 break;
8623 case VKI_V4L2_G_TUNER: {
8624 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8625 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8626 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8627 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8628 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8629 break;
8631 case VKI_V4L2_S_TUNER: {
8632 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8633 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8634 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8635 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8636 break;
8638 case VKI_V4L2_G_AUDIO: {
8639 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8640 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8641 sizeof(*data) - sizeof(data->reserved));
8642 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8643 break;
8645 case VKI_V4L2_S_AUDIO: {
8646 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8647 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8648 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8649 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8650 break;
8652 case VKI_V4L2_QUERYCTRL: {
8653 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
8654 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8655 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8656 sizeof(*data) - sizeof(data->id));
8657 break;
8659 case VKI_V4L2_QUERYMENU: {
8660 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
8661 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8662 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8663 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8664 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8665 break;
8667 case VKI_V4L2_G_INPUT: {
8668 int *data = (int *)(Addr)ARG3;
8669 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8670 break;
8672 case VKI_V4L2_S_INPUT: {
8673 int *data = (int *)(Addr)ARG3;
8674 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8675 break;
8677 case VKI_V4L2_G_EDID: {
8678 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8679 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8680 if (data->blocks && data->edid)
8681 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8682 break;
8684 case VKI_V4L2_S_EDID: {
8685 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8686 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8687 if (data->blocks && data->edid)
8688 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8689 break;
8691 case VKI_V4L2_G_OUTPUT: {
8692 int *data = (int *)(Addr)ARG3;
8693 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8694 break;
8696 case VKI_V4L2_S_OUTPUT: {
8697 int *data = (int *)(Addr)ARG3;
8698 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8699 break;
8701 case VKI_V4L2_ENUMOUTPUT: {
8702 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
8703 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8704 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8705 break;
8707 case VKI_V4L2_G_AUDOUT: {
8708 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8709 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8710 sizeof(*data) - sizeof(data->reserved));
8711 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8712 break;
8714 case VKI_V4L2_S_AUDOUT: {
8715 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8716 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8717 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8718 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8719 break;
8721 case VKI_V4L2_G_MODULATOR: {
8722 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8723 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8724 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8725 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8726 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8727 break;
8729 case VKI_V4L2_S_MODULATOR: {
8730 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8731 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8732 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8733 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8734 break;
8736 case VKI_V4L2_G_FREQUENCY: {
8737 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8738 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8739 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8740 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8741 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8742 break;
8744 case VKI_V4L2_S_FREQUENCY: {
8745 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8746 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8747 break;
8749 case VKI_V4L2_CROPCAP: {
8750 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
8751 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8752 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8753 break;
8755 case VKI_V4L2_G_CROP: {
8756 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8757 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8758 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8759 break;
8761 case VKI_V4L2_S_CROP: {
8762 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8763 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
8764 break;
8766 case VKI_V4L2_G_JPEGCOMP: {
8767 struct vki_v4l2_jpegcompression *data =
8768 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8769 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
8770 break;
8772 case VKI_V4L2_S_JPEGCOMP: {
8773 struct vki_v4l2_jpegcompression *data =
8774 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8775 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
8776 break;
8778 case VKI_V4L2_QUERYSTD: {
8779 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8780 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
8781 break;
8783 case VKI_V4L2_ENUMAUDIO: {
8784 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8785 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
8786 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
8787 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
8788 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8789 break;
8791 case VKI_V4L2_ENUMAUDOUT: {
8792 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8793 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
8794 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
8795 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
8796 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8797 break;
8799 case VKI_V4L2_G_PRIORITY: {
8800 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8801 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
8802 break;
8804 case VKI_V4L2_S_PRIORITY: {
8805 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8806 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
8807 break;
8809 case VKI_V4L2_G_SLICED_VBI_CAP: {
8810 struct vki_v4l2_sliced_vbi_cap *data =
8811 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
8812 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
8813 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
8814 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
8815 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
8816 break;
8818 case VKI_V4L2_G_EXT_CTRLS: {
8819 struct vki_v4l2_ext_controls *data =
8820 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8821 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
8822 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
8823 if (data->count) {
8824 unsigned i;
8826 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
8827 for (i = 0; i < data->count; i++) {
8828 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
8829 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
8830 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
8831 if (data->controls[i].size) {
8832 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
8833 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
8834 (Addr)data->controls[i].ptr, data->controls[i].size);
8835 } else {
8836 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
8837 data->controls[i].value64);
8841 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
8842 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
8843 break;
8845 case VKI_V4L2_S_EXT_CTRLS: {
8846 struct vki_v4l2_ext_controls *data =
8847 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8848 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
8849 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
8850 if (data->count) {
8851 unsigned i;
8853 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
8854 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
8855 data->count * sizeof(data->controls[0]));
8856 for (i = 0; i < data->count; i++) {
8857 if (data->controls[i].size) {
8858 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
8859 (Addr)data->controls[i].ptr, data->controls[i].size);
8863 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
8864 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
8865 break;
8867 case VKI_V4L2_TRY_EXT_CTRLS: {
8868 struct vki_v4l2_ext_controls *data =
8869 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8870 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
8871 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
8872 if (data->count) {
8873 unsigned i;
8875 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
8876 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
8877 data->count * sizeof(data->controls[0]));
8878 for (i = 0; i < data->count; i++) {
8879 if (data->controls[i].size) {
8880 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
8881 (Addr)data->controls[i].ptr, data->controls[i].size);
8885 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
8886 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
8887 break;
8889 case VKI_V4L2_ENUM_FRAMESIZES: {
8890 struct vki_v4l2_frmsizeenum *data =
8891 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
8892 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
8893 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
8894 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
8895 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
8896 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
8897 break;
8899 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
8900 struct vki_v4l2_frmivalenum *data =
8901 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
8902 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
8903 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
8904 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
8905 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
8906 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8907 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8908 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8909 break;
8911 case VKI_V4L2_G_ENC_INDEX: {
8912 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
8913 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8914 break;
8916 case VKI_V4L2_ENCODER_CMD: {
8917 struct vki_v4l2_encoder_cmd *data =
8918 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8919 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8920 break;
8922 case VKI_V4L2_TRY_ENCODER_CMD: {
8923 struct vki_v4l2_encoder_cmd *data =
8924 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8925 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8926 break;
8928 case VKI_V4L2_DBG_S_REGISTER: {
8929 struct vki_v4l2_dbg_register *data =
8930 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8931 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8932 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8933 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8934 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8935 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8936 break;
8938 case VKI_V4L2_DBG_G_REGISTER: {
8939 struct vki_v4l2_dbg_register *data =
8940 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8941 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8942 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8943 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8944 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8945 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8946 break;
8948 case VKI_V4L2_S_HW_FREQ_SEEK: {
8949 struct vki_v4l2_hw_freq_seek *data =
8950 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
8951 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8952 break;
8954 case VKI_V4L2_S_DV_TIMINGS: {
8955 struct vki_v4l2_dv_timings *data =
8956 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
8957 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
8958 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
8959 break;
8961 case VKI_V4L2_G_DV_TIMINGS: {
8962 struct vki_v4l2_dv_timings *data =
8963 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
8964 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
8965 break;
8967 case VKI_V4L2_DQEVENT: {
8968 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
8969 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
8970 break;
8972 case VKI_V4L2_SUBSCRIBE_EVENT: {
8973 struct vki_v4l2_event_subscription *data =
8974 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
8975 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8976 break;
8978 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
8979 struct vki_v4l2_event_subscription *data =
8980 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
8981 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
8982 break;
8984 case VKI_V4L2_CREATE_BUFS: {
8985 struct vki_v4l2_create_buffers *data =
8986 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
8987 struct vki_v4l2_format *fmt = &data->format;
8988 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
8989 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
8990 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
8991 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
8992 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
8993 switch (fmt->type) {
8994 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8995 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8996 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
8997 break;
8998 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8999 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9000 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9001 break;
9002 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9003 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9004 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9005 break;
9006 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9007 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9008 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9009 break;
9010 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9011 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9012 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9013 break;
9014 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9015 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9016 break;
9018 break;
9020 case VKI_V4L2_PREPARE_BUF: {
9021 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9022 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9023 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9024 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9025 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9026 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9027 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9028 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9029 unsigned i;
9031 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9032 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9033 for (i = 0; i < data->length; i++) {
9034 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9037 break;
9039 case VKI_V4L2_G_SELECTION: {
9040 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9041 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9042 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9043 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9044 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9045 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9046 break;
9048 case VKI_V4L2_S_SELECTION: {
9049 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9050 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9051 break;
9053 case VKI_V4L2_DECODER_CMD: {
9054 struct vki_v4l2_decoder_cmd *data =
9055 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9056 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9057 break;
9059 case VKI_V4L2_TRY_DECODER_CMD: {
9060 struct vki_v4l2_decoder_cmd *data =
9061 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9062 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9063 break;
9065 case VKI_V4L2_ENUM_DV_TIMINGS: {
9066 struct vki_v4l2_enum_dv_timings *data =
9067 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9068 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9069 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9070 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9071 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9072 break;
9074 case VKI_V4L2_QUERY_DV_TIMINGS: {
9075 struct vki_v4l2_dv_timings *data =
9076 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9077 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9078 break;
9080 case VKI_V4L2_DV_TIMINGS_CAP: {
9081 struct vki_v4l2_dv_timings_cap *data =
9082 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9083 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9084 break;
9086 case VKI_V4L2_ENUM_FREQ_BANDS: {
9087 struct vki_v4l2_frequency_band *data =
9088 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9089 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9090 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9091 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9092 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9093 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9094 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9095 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9096 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9097 break;
9099 case VKI_V4L2_DBG_G_CHIP_INFO: {
9100 struct vki_v4l2_dbg_chip_info *data =
9101 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9102 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9103 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9104 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9105 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9106 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9107 break;
9109 case VKI_V4L2_QUERY_EXT_CTRL: {
9110 struct vki_v4l2_query_ext_ctrl *data =
9111 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9112 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9113 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9114 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9115 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9116 break;
9118 case VKI_V4L2_SUBDEV_G_FMT: {
9119 struct vki_v4l2_subdev_format *data =
9120 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9121 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9122 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9123 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9124 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9125 break;
9127 case VKI_V4L2_SUBDEV_S_FMT: {
9128 struct vki_v4l2_subdev_format *data =
9129 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9130 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9131 break;
9133 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9134 struct vki_v4l2_subdev_frame_interval *data =
9135 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9136 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9137 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9138 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9139 break;
9141 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9142 struct vki_v4l2_subdev_frame_interval *data =
9143 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9144 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9145 break;
9147 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9148 struct vki_v4l2_subdev_mbus_code_enum *data =
9149 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9150 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9151 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9152 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9153 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9154 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9155 break;
9157 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9158 struct vki_v4l2_subdev_frame_size_enum *data =
9159 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9160 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9161 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9162 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9163 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9164 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9165 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9166 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9167 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9168 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9169 break;
9171 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9172 struct vki_v4l2_subdev_frame_interval_enum *data =
9173 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9174 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9175 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9176 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9177 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9178 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9179 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9180 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9181 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9182 break;
9184 case VKI_V4L2_SUBDEV_G_CROP: {
9185 struct vki_v4l2_subdev_crop *data =
9186 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9187 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9188 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9189 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9190 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9191 break;
9193 case VKI_V4L2_SUBDEV_S_CROP: {
9194 struct vki_v4l2_subdev_crop *data =
9195 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9196 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9197 break;
9199 case VKI_V4L2_SUBDEV_G_SELECTION: {
9200 struct vki_v4l2_subdev_selection *data =
9201 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9202 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9203 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9204 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9205 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9206 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9207 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9208 break;
9210 case VKI_V4L2_SUBDEV_S_SELECTION: {
9211 struct vki_v4l2_subdev_selection *data =
9212 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9213 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
9214 break;
9216 case VKI_MEDIA_IOC_DEVICE_INFO: {
9217 struct vki_media_device_info *data =
9218 (struct vki_media_device_info *)(Addr)ARG3;
9219 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
9220 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
9221 (Addr)data, sizeof(*data) - sizeof(data->reserved));
9222 break;
9224 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
9225 struct vki_media_entity_desc *data =
9226 (struct vki_media_entity_desc *)(Addr)ARG3;
9227 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
9228 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
9229 (Addr)data->name, sizeof(*data) - sizeof(data->id));
9230 break;
9232 case VKI_MEDIA_IOC_ENUM_LINKS: {
9233 struct vki_media_links_enum *data =
9234 (struct vki_media_links_enum *)(Addr)ARG3;
9235 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
9236 break;
9238 case VKI_MEDIA_IOC_SETUP_LINK: {
9239 struct vki_media_link_desc *data =
9240 (struct vki_media_link_desc *)(Addr)ARG3;
9241 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
9242 break;
9245 /* Serial */
9246 case VKI_TIOCGSERIAL: {
9247 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9248 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9249 break;
9251 case VKI_TIOCSSERIAL: {
9252 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9253 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9254 break;
9257 case VKI_PERF_EVENT_IOC_RESET:
9258 case VKI_PERF_EVENT_IOC_REFRESH:
9259 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9260 case VKI_PERF_EVENT_IOC_SET_BPF:
9261 /* These take scalar arguments, so already handled above */
9262 break;
9264 case VKI_PERF_EVENT_IOC_PERIOD:
9265 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9266 break;
9268 case VKI_PERF_EVENT_IOC_SET_FILTER:
9269 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9270 break;
9272 case VKI_PERF_EVENT_IOC_ID:
9273 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9274 break;
9276 default:
9277 /* EVIOC* are variable length and return size written on success */
9278 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9279 case VKI_EVIOCGNAME(0):
9280 case VKI_EVIOCGPHYS(0):
9281 case VKI_EVIOCGUNIQ(0):
9282 case VKI_EVIOCGKEY(0):
9283 case VKI_EVIOCGLED(0):
9284 case VKI_EVIOCGSND(0):
9285 case VKI_EVIOCGSW(0):
9286 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9287 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9288 case VKI_EVIOCGBIT(VKI_EV_REL,0):
9289 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9290 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9291 case VKI_EVIOCGBIT(VKI_EV_SW,0):
9292 case VKI_EVIOCGBIT(VKI_EV_LED,0):
9293 case VKI_EVIOCGBIT(VKI_EV_SND,0):
9294 case VKI_EVIOCGBIT(VKI_EV_REP,0):
9295 case VKI_EVIOCGBIT(VKI_EV_FF,0):
9296 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9297 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9298 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9299 break;
9300 default:
9301 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9302 break;
9304 break;
9308 POST(sys_ioctl)
9310 ARG2 = (UInt)ARG2;
9312 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9314 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9316 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9317 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9318 VG_(clo_kernel_variant))) {
9320 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9321 /* What's going on here: there appear to be a bunch of ioctls
9322 of the form 0xC01C67xx which are undocumented, and if
9323 unhandled give rise to a vast number of false positives in
9324 Memcheck.
9326 The "normal" interpretation of an ioctl of this form would
9327 be that the 3rd arg is a pointer to an area of size 0x1C
9328 (28 bytes) which is filled in by the kernel. Hence you
9329 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9330 But it doesn't.
9332 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9333 One interpretation of this is that ARG3 really does point
9334 to a 28 byte struct, but inside that are pointers to other
9335 areas also filled in by the kernel. If these happen to be
9336 allocated just back up the stack then the 256 byte paint
9337 might cover them too, somewhat indiscriminately.
9339 By printing out ARG3 and also the 28 bytes that it points
9340 at, it's possible to guess that the 7 word structure has
9341 this form
9343 0 1 2 3 4 5 6
9344 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9346 Unfortunately that doesn't seem to work for some reason,
9347 so stay with the blunt-instrument approach for the time
9348 being.
9350 if (1) {
9351 /* blunt-instrument approach */
9352 POST_MEM_WRITE(ARG3, 256);
9353 } else {
9354 /* be a bit more sophisticated */
9355 POST_MEM_WRITE(ARG3, 28);
9356 UInt* word = (UInt*)(Addr)ARG3;
9357 if (word && word[2] && word[3] < 0x200/*stay sane*/)
9358 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9359 if (word && word[4] && word[5] < 0x200/*stay sane*/)
9360 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9362 goto post_sys_ioctl__out;
9365 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9367 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9368 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9369 VG_(clo_kernel_variant))) {
9370 if (ARG2 == 0xC00C0902) {
9371 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9372 goto post_sys_ioctl__out;
9375 /* END undocumented ioctls for Qualcomm Adreno 3xx */
9377 /* --- END special IOCTL handlers for specific Android hardware --- */
9379 /* --- normal handling --- */
9380 switch (ARG2 /* request */) {
9382 /* The Linux kernel "ion" memory allocator, used on Android. Note:
9383 this is pretty poor given that there's no pre-handling to check
9384 that writable areas are addressable. */
9385 case VKI_ION_IOC_ALLOC: {
9386 struct vki_ion_allocation_data* data
9387 = (struct vki_ion_allocation_data*)(Addr)ARG3;
9388 POST_FIELD_WRITE(data->handle);
9389 break;
9391 case VKI_ION_IOC_MAP: {
9392 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9393 POST_FIELD_WRITE(data->fd);
9394 break;
9396 case VKI_ION_IOC_FREE: // is this necessary?
9397 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9398 break;
9399 case VKI_ION_IOC_SHARE:
9400 break;
9401 case VKI_ION_IOC_IMPORT: {
9402 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9403 POST_FIELD_WRITE(data->handle);
9404 break;
9406 case VKI_ION_IOC_SYNC:
9407 break;
9408 case VKI_ION_IOC_CUSTOM: // is this necessary?
9409 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9410 break;
9412 case VKI_SYNC_IOC_MERGE: {
9413 struct vki_sync_merge_data* data =
9414 (struct vki_sync_merge_data*)(Addr)ARG3;
9415 POST_FIELD_WRITE(data->fence);
9416 break;
9419 case VKI_TCSETS:
9420 case VKI_TCSETSW:
9421 case VKI_TCSETSF:
9422 case VKI_IB_USER_MAD_ENABLE_PKEY:
9423 break;
9424 case VKI_TCGETS:
9425 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9426 break;
9427 case VKI_TCSETA:
9428 case VKI_TCSETAW:
9429 case VKI_TCSETAF:
9430 break;
9431 case VKI_TCGETA:
9432 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9433 break;
9434 case VKI_TCSBRK:
9435 case VKI_TCXONC:
9436 case VKI_TCSBRKP:
9437 case VKI_TCFLSH:
9438 case VKI_TIOCSIG:
9439 break;
9440 case VKI_TIOCGWINSZ:
9441 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9442 break;
9443 case VKI_TIOCSWINSZ:
9444 case VKI_TIOCMBIS:
9445 case VKI_TIOCMBIC:
9446 case VKI_TIOCMSET:
9447 break;
9448 case VKI_TIOCMGET:
9449 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9450 break;
9451 case VKI_TIOCLINUX:
9452 POST_MEM_WRITE( ARG3, sizeof(char *) );
9453 break;
9454 case VKI_TIOCGPGRP:
9455 /* Get process group ID for foreground processing group. */
9456 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9457 break;
9458 case VKI_TIOCSPGRP:
9459 /* Set a process group ID? */
9460 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9461 break;
9462 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9463 POST_MEM_WRITE( ARG3, sizeof(int));
9464 break;
9465 case VKI_TIOCSCTTY:
9466 break;
9467 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9468 break;
9469 case VKI_FIONBIO:
9470 break;
9471 case VKI_FIONCLEX:
9472 break;
9473 case VKI_FIOCLEX:
9474 break;
9475 case VKI_TIOCNOTTY:
9476 break;
9477 case VKI_FIOASYNC:
9478 break;
9479 case VKI_FIONREAD: /* identical to SIOCINQ */
9480 POST_MEM_WRITE( ARG3, sizeof(int) );
9481 break;
9482 case VKI_FIOQSIZE:
9483 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9484 break;
9486 case VKI_TIOCSERGETLSR:
9487 POST_MEM_WRITE( ARG3, sizeof(int) );
9488 break;
9489 case VKI_TIOCGICOUNT:
9490 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9491 break;
9493 case VKI_SG_SET_COMMAND_Q:
9494 break;
9495 case VKI_SG_IO:
9497 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
9498 if ( sgio->sbp ) {
9499 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9501 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9502 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9503 int transferred = sgio->dxfer_len - sgio->resid;
9504 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9507 break;
9508 case VKI_SG_GET_SCSI_ID:
9509 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9510 break;
9511 case VKI_SG_SET_RESERVED_SIZE:
9512 break;
9513 case VKI_SG_SET_TIMEOUT:
9514 break;
9515 case VKI_SG_GET_RESERVED_SIZE:
9516 POST_MEM_WRITE(ARG3, sizeof(int));
9517 break;
9518 case VKI_SG_GET_TIMEOUT:
9519 break;
9520 case VKI_SG_GET_VERSION_NUM:
9521 POST_MEM_WRITE(ARG3, sizeof(int));
9522 break;
9523 case VKI_SG_EMULATED_HOST:
9524 POST_MEM_WRITE(ARG3, sizeof(int));
9525 break;
9526 case VKI_SG_GET_SG_TABLESIZE:
9527 POST_MEM_WRITE(ARG3, sizeof(int));
9528 break;
9530 case VKI_IIOCGETCPS:
9531 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9532 break;
9533 case VKI_IIOCNETGPN:
9534 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9535 break;
9537 /* These all use struct ifreq AFAIK */
9538 case VKI_SIOCGIFINDEX: /* get iface index */
9539 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
9540 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
9541 break;
9542 case VKI_SIOCGIFFLAGS: /* get flags */
9543 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9544 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
9545 break;
9546 case VKI_SIOCGIFHWADDR: /* Get hardware address */
9547 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
9548 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
9549 break;
9550 case VKI_SIOCGIFMTU: /* get MTU size */
9551 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
9552 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
9553 break;
9554 case VKI_SIOCGIFADDR: /* get PA address */
9555 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
9556 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
9557 case VKI_SIOCGIFNETMASK: /* get network PA mask */
9558 POST_MEM_WRITE(
9559 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
9560 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
9561 break;
9562 case VKI_SIOCGIFMETRIC: /* get metric */
9563 POST_MEM_WRITE(
9564 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
9565 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
9566 break;
9567 case VKI_SIOCGIFMAP: /* Get device parameters */
9568 POST_MEM_WRITE(
9569 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
9570 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
9571 break;
9572 break;
9573 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
9574 POST_MEM_WRITE(
9575 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
9576 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
9577 break;
9578 case VKI_SIOCGIFNAME: /* get iface name */
9579 POST_MEM_WRITE(
9580 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9581 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9582 break;
9583 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
9584 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
9585 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9586 case VKI_ETHTOOL_GSET:
9587 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9588 break;
9589 case VKI_ETHTOOL_SSET:
9590 break;
9591 case VKI_ETHTOOL_GDRVINFO:
9592 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9593 break;
9594 case VKI_ETHTOOL_GREGS:
9595 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9596 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9597 break;
9598 case VKI_ETHTOOL_GWOL:
9599 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9600 break;
9601 case VKI_ETHTOOL_SWOL:
9602 break;
9603 case VKI_ETHTOOL_GMSGLVL:
9604 case VKI_ETHTOOL_GLINK:
9605 case VKI_ETHTOOL_GRXCSUM:
9606 case VKI_ETHTOOL_GSG:
9607 case VKI_ETHTOOL_GTSO:
9608 case VKI_ETHTOOL_GUFO:
9609 case VKI_ETHTOOL_GGSO:
9610 case VKI_ETHTOOL_GFLAGS:
9611 case VKI_ETHTOOL_GGRO:
9612 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9613 break;
9614 case VKI_ETHTOOL_SMSGLVL:
9615 case VKI_ETHTOOL_SRXCSUM:
9616 case VKI_ETHTOOL_SSG:
9617 case VKI_ETHTOOL_STSO:
9618 case VKI_ETHTOOL_SUFO:
9619 case VKI_ETHTOOL_SGSO:
9620 case VKI_ETHTOOL_SFLAGS:
9621 case VKI_ETHTOOL_SGRO:
9622 break;
9623 case VKI_ETHTOOL_NWAY_RST:
9624 break;
9625 case VKI_ETHTOOL_GRINGPARAM:
9626 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9627 break;
9628 case VKI_ETHTOOL_SRINGPARAM:
9629 break;
9630 case VKI_ETHTOOL_TEST:
9631 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9632 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9633 break;
9634 case VKI_ETHTOOL_PHYS_ID:
9635 break;
9636 case VKI_ETHTOOL_GPERMADDR:
9637 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9638 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9639 break;
9640 case VKI_ETHTOOL_RESET:
9641 break;
9642 case VKI_ETHTOOL_GSSET_INFO:
9643 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9644 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9645 break;
9646 case VKI_ETHTOOL_GFEATURES:
9647 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9648 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9649 break;
9650 case VKI_ETHTOOL_SFEATURES:
9651 break;
9652 case VKI_ETHTOOL_GCHANNELS:
9653 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9654 break;
9655 case VKI_ETHTOOL_SCHANNELS:
9656 break;
9657 case VKI_ETHTOOL_GET_TS_INFO:
9658 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9659 break;
9661 break;
9663 case VKI_SIOCGMIIPHY: /* get hardware entry */
9664 POST_MEM_WRITE(
9665 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
9666 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
9667 break;
9668 case VKI_SIOCGMIIREG: /* get hardware entry registers */
9669 POST_MEM_WRITE(
9670 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
9671 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
9672 break;
9674 /* tun/tap related ioctls */
9675 case VKI_TUNSETIFF:
9676 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9677 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9678 break;
9679 case VKI_TUNGETFEATURES:
9680 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9681 break;
9682 case VKI_TUNGETIFF:
9683 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9684 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9685 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9686 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
9687 break;
9688 case VKI_TUNGETSNDBUF:
9689 POST_MEM_WRITE( ARG3, sizeof(int) );
9690 break;
9691 case VKI_TUNGETVNETHDRSZ:
9692 POST_MEM_WRITE( ARG3, sizeof(int) );
9693 break;
9695 case VKI_SIOCGIFCONF: /* get iface list */
9696 /* WAS:
9697 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
9698 KERNEL_DO_SYSCALL(tid,RES);
9699 if (!VG_(is_kerror)(RES) && RES == 0)
9700 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
9702 if (RES == 0 && ARG3 ) {
9703 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
9704 if (ifc->vki_ifc_buf != NULL)
9705 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
9707 break;
9708 case VKI_SIOCGSTAMP:
9709 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9710 break;
9711 case VKI_SIOCGSTAMPNS:
9712 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
9713 break;
9714 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
9715 the number of bytes currently in that socket's send buffer.
9716 It writes this value as an int to the memory location
9717 indicated by the third argument of ioctl(2). */
9718 case VKI_SIOCOUTQ:
9719 POST_MEM_WRITE(ARG3, sizeof(int));
9720 break;
9721 case VKI_SIOCGRARP: /* get RARP table entry */
9722 case VKI_SIOCGARP: /* get ARP table entry */
9723 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
9724 break;
9726 case VKI_SIOCSIFFLAGS: /* set flags */
9727 case VKI_SIOCSIFMAP: /* Set device parameters */
9728 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
9729 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
9730 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
9731 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
9732 case VKI_SIOCSIFNETMASK: /* set network PA mask */
9733 case VKI_SIOCSIFMETRIC: /* set metric */
9734 case VKI_SIOCSIFADDR: /* set PA address */
9735 case VKI_SIOCSIFMTU: /* set MTU size */
9736 case VKI_SIOCSIFHWADDR: /* set hardware address */
9737 case VKI_SIOCSMIIREG: /* set hardware entry registers */
9738 break;
9739 /* Routing table calls. */
9740 case VKI_SIOCADDRT: /* add routing table entry */
9741 case VKI_SIOCDELRT: /* delete routing table entry */
9742 break;
9744 /* RARP cache control calls. */
9745 case VKI_SIOCDRARP: /* delete RARP table entry */
9746 case VKI_SIOCSRARP: /* set RARP table entry */
9747 /* ARP cache control calls. */
9748 case VKI_SIOCSARP: /* set ARP table entry */
9749 case VKI_SIOCDARP: /* delete ARP table entry */
9750 break;
9752 case VKI_SIOCGPGRP:
9753 POST_MEM_WRITE(ARG3, sizeof(int));
9754 break;
9755 case VKI_SIOCSPGRP:
9756 break;
9758 case VKI_SIOCATMARK:
9759 POST_MEM_WRITE(ARG3, sizeof(int));
9760 break;
9762 /* linux/soundcard interface (OSS) */
9763 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
9764 case VKI_SNDCTL_SEQ_GETINCOUNT:
9765 case VKI_SNDCTL_SEQ_PERCMODE:
9766 case VKI_SNDCTL_SEQ_TESTMIDI:
9767 case VKI_SNDCTL_SEQ_RESETSAMPLES:
9768 case VKI_SNDCTL_SEQ_NRSYNTHS:
9769 case VKI_SNDCTL_SEQ_NRMIDIS:
9770 case VKI_SNDCTL_SEQ_GETTIME:
9771 case VKI_SNDCTL_DSP_GETBLKSIZE:
9772 case VKI_SNDCTL_DSP_GETFMTS:
9773 case VKI_SNDCTL_DSP_SETFMT:
9774 case VKI_SNDCTL_DSP_GETTRIGGER:
9775 case VKI_SNDCTL_DSP_GETODELAY:
9776 case VKI_SNDCTL_DSP_GETSPDIF:
9777 case VKI_SNDCTL_DSP_GETCAPS:
9778 case VKI_SOUND_PCM_READ_RATE:
9779 case VKI_SOUND_PCM_READ_CHANNELS:
9780 case VKI_SOUND_PCM_READ_BITS:
9781 case VKI_SOUND_PCM_READ_FILTER:
9782 POST_MEM_WRITE(ARG3, sizeof(int));
9783 break;
9784 case VKI_SNDCTL_SEQ_CTRLRATE:
9785 case VKI_SNDCTL_DSP_SPEED:
9786 case VKI_SNDCTL_DSP_STEREO:
9787 case VKI_SNDCTL_DSP_CHANNELS:
9788 case VKI_SOUND_PCM_WRITE_FILTER:
9789 case VKI_SNDCTL_DSP_SUBDIVIDE:
9790 case VKI_SNDCTL_DSP_SETFRAGMENT:
9791 case VKI_SNDCTL_DSP_GETCHANNELMASK:
9792 case VKI_SNDCTL_DSP_BIND_CHANNEL:
9793 case VKI_SNDCTL_TMR_TIMEBASE:
9794 case VKI_SNDCTL_TMR_TEMPO:
9795 case VKI_SNDCTL_TMR_SOURCE:
9796 case VKI_SNDCTL_MIDI_PRETIME:
9797 case VKI_SNDCTL_MIDI_MPUMODE:
9798 break;
9799 case VKI_SNDCTL_DSP_GETOSPACE:
9800 case VKI_SNDCTL_DSP_GETISPACE:
9801 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
9802 break;
9803 case VKI_SNDCTL_DSP_NONBLOCK:
9804 break;
9805 case VKI_SNDCTL_DSP_SETTRIGGER:
9806 break;
9808 case VKI_SNDCTL_DSP_POST:
9809 case VKI_SNDCTL_DSP_RESET:
9810 case VKI_SNDCTL_DSP_SYNC:
9811 case VKI_SNDCTL_DSP_SETSYNCRO:
9812 case VKI_SNDCTL_DSP_SETDUPLEX:
9813 break;
9815 /* linux/soundcard interface (ALSA) */
9816 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
9817 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
9818 case VKI_SNDRV_PCM_IOCTL_PREPARE:
9819 case VKI_SNDRV_PCM_IOCTL_RESET:
9820 case VKI_SNDRV_PCM_IOCTL_START:
9821 case VKI_SNDRV_PCM_IOCTL_DROP:
9822 case VKI_SNDRV_PCM_IOCTL_DRAIN:
9823 case VKI_SNDRV_PCM_IOCTL_RESUME:
9824 case VKI_SNDRV_PCM_IOCTL_XRUN:
9825 case VKI_SNDRV_PCM_IOCTL_UNLINK:
9826 case VKI_SNDRV_TIMER_IOCTL_START:
9827 case VKI_SNDRV_TIMER_IOCTL_STOP:
9828 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
9829 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
9830 break;
9832 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
9833 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
9834 break;
9836 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
9837 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
9838 break;
9839 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
9840 struct vki_snd_ctl_elem_list *data =
9841 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
9842 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
9843 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
9844 if (data->pids) {
9845 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
9847 break;
9849 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
9850 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
9851 POST_MEM_WRITE( (Addr)data->tlv, data->length );
9852 break;
9854 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
9855 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
9856 break;
9858 /* SCSI no operand */
9859 case VKI_SCSI_IOCTL_DOORLOCK:
9860 case VKI_SCSI_IOCTL_DOORUNLOCK:
9861 break;
9863 /* Real Time Clock (/dev/rtc) ioctls */
9864 case VKI_RTC_UIE_ON:
9865 case VKI_RTC_UIE_OFF:
9866 case VKI_RTC_AIE_ON:
9867 case VKI_RTC_AIE_OFF:
9868 case VKI_RTC_PIE_ON:
9869 case VKI_RTC_PIE_OFF:
9870 case VKI_RTC_IRQP_SET:
9871 break;
9872 case VKI_RTC_RD_TIME:
9873 case VKI_RTC_ALM_READ:
9874 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
9875 break;
9876 case VKI_RTC_ALM_SET:
9877 break;
9878 case VKI_RTC_IRQP_READ:
9879 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9880 break;
9882 /* Block devices */
9883 case VKI_BLKROSET:
9884 break;
9885 case VKI_BLKROGET:
9886 POST_MEM_WRITE(ARG3, sizeof(int));
9887 break;
9888 case VKI_BLKGETSIZE:
9889 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9890 break;
9891 case VKI_BLKFLSBUF:
9892 break;
9893 case VKI_BLKRASET:
9894 break;
9895 case VKI_BLKRAGET:
9896 POST_MEM_WRITE(ARG3, sizeof(long));
9897 break;
9898 case VKI_BLKFRASET:
9899 break;
9900 case VKI_BLKFRAGET:
9901 POST_MEM_WRITE(ARG3, sizeof(long));
9902 break;
9903 case VKI_BLKSECTGET:
9904 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
9905 break;
9906 case VKI_BLKSSZGET:
9907 POST_MEM_WRITE(ARG3, sizeof(int));
9908 break;
9909 case VKI_BLKBSZGET:
9910 POST_MEM_WRITE(ARG3, sizeof(int));
9911 break;
9912 case VKI_BLKBSZSET:
9913 break;
9914 case VKI_BLKGETSIZE64:
9915 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
9916 break;
9917 case VKI_BLKPBSZGET:
9918 POST_MEM_WRITE(ARG3, sizeof(int));
9919 break;
9920 case VKI_BLKDISCARDZEROES:
9921 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
9922 break;
9923 case VKI_BLKREPORTZONE: {
9924 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
9926 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
9927 break;
9929 case VKI_BLKRESETZONE:
9930 break;
9932 /* Hard disks */
9933 case VKI_HDIO_GETGEO: /* 0x0301 */
9934 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
9935 break;
9936 case VKI_HDIO_GET_DMA: /* 0x030b */
9937 POST_MEM_WRITE(ARG3, sizeof(long));
9938 break;
9939 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
9940 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
9941 break;
9943 /* SCSI */
9944 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
9945 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
9946 break;
9947 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
9948 POST_MEM_WRITE(ARG3, sizeof(int));
9949 break;
9951 /* CD ROM stuff (??) */
9952 case VKI_CDROM_DISC_STATUS:
9953 case VKI_CDROMSTOP:
9954 break;
9955 case VKI_CDROMSUBCHNL:
9956 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
9957 break;
9958 case VKI_CDROMREADTOCHDR:
9959 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
9960 break;
9961 case VKI_CDROMREADTOCENTRY:
9962 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
9963 break;
9964 case VKI_CDROMMULTISESSION:
9965 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
9966 break;
9967 case VKI_CDROMVOLREAD:
9968 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
9969 break;
9970 case VKI_CDROMREADMODE1:
9971 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
9972 break;
9973 case VKI_CDROMREADMODE2:
9974 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
9975 break;
9976 case VKI_CDROMREADRAW:
9977 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
9978 break;
9979 case VKI_CDROMREADAUDIO:
9981 struct vki_cdrom_read_audio *cra =
9982 (struct vki_cdrom_read_audio *) (Addr)ARG3;
9983 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
9984 break;
9987 case VKI_CDROMPLAYMSF:
9988 break;
9989 /* The following two are probably bogus (should check args
9990 for readability). JRS 20021117 */
9991 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
9992 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
9993 break;
9994 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
9995 break;
9997 /* DVD stuff */
9998 case VKI_DVD_READ_STRUCT:
9999 break;
10001 case VKI_FIGETBSZ:
10002 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10003 break;
10004 case VKI_FIBMAP:
10005 POST_MEM_WRITE(ARG3, sizeof(int));
10006 break;
10008 case VKI_FBIOGET_VSCREENINFO: //0x4600
10009 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10010 break;
10011 case VKI_FBIOGET_FSCREENINFO: //0x4602
10012 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10013 break;
10015 case VKI_PPCLAIM:
10016 case VKI_PPEXCL:
10017 case VKI_PPYIELD:
10018 case VKI_PPRELEASE:
10019 case VKI_PPSETMODE:
10020 case VKI_PPSETPHASE:
10021 case VKI_PPSETFLAGS:
10022 case VKI_PPWDATA:
10023 case VKI_PPWCONTROL:
10024 case VKI_PPFCONTROL:
10025 case VKI_PPDATADIR:
10026 case VKI_PPNEGOT:
10027 case VKI_PPWCTLONIRQ:
10028 case VKI_PPSETTIME:
10029 break;
10030 case VKI_PPGETMODE:
10031 POST_MEM_WRITE( ARG3, sizeof(int) );
10032 break;
10033 case VKI_PPGETPHASE:
10034 POST_MEM_WRITE( ARG3, sizeof(int) );
10035 break;
10036 case VKI_PPGETMODES:
10037 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10038 break;
10039 case VKI_PPGETFLAGS:
10040 POST_MEM_WRITE( ARG3, sizeof(int) );
10041 break;
10042 case VKI_PPRSTATUS:
10043 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10044 break;
10045 case VKI_PPRDATA:
10046 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10047 break;
10048 case VKI_PPRCONTROL:
10049 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10050 break;
10051 case VKI_PPCLRIRQ:
10052 POST_MEM_WRITE( ARG3, sizeof(int) );
10053 break;
10054 case VKI_PPGETTIME:
10055 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10056 break;
10058 case VKI_GIO_FONT:
10059 POST_MEM_WRITE( ARG3, 32 * 256 );
10060 break;
10061 case VKI_PIO_FONT:
10062 break;
10064 case VKI_GIO_FONTX:
10065 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10066 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10067 break;
10068 case VKI_PIO_FONTX:
10069 break;
10071 case VKI_PIO_FONTRESET:
10072 break;
10074 case VKI_GIO_CMAP:
10075 POST_MEM_WRITE( ARG3, 16 * 3 );
10076 break;
10077 case VKI_PIO_CMAP:
10078 break;
10080 case VKI_KIOCSOUND:
10081 case VKI_KDMKTONE:
10082 break;
10084 case VKI_KDGETLED:
10085 POST_MEM_WRITE( ARG3, sizeof(char) );
10086 break;
10087 case VKI_KDSETLED:
10088 break;
10090 case VKI_KDGKBTYPE:
10091 POST_MEM_WRITE( ARG3, sizeof(char) );
10092 break;
10094 case VKI_KDADDIO:
10095 case VKI_KDDELIO:
10096 case VKI_KDENABIO:
10097 case VKI_KDDISABIO:
10098 break;
10100 case VKI_KDSETMODE:
10101 break;
10102 case VKI_KDGETMODE:
10103 POST_MEM_WRITE( ARG3, sizeof(int) );
10104 break;
10106 case VKI_KDMAPDISP:
10107 case VKI_KDUNMAPDISP:
10108 break;
10110 case VKI_GIO_SCRNMAP:
10111 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
10112 break;
10113 case VKI_PIO_SCRNMAP:
10114 break;
10115 case VKI_GIO_UNISCRNMAP:
10116 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
10117 break;
10118 case VKI_PIO_UNISCRNMAP:
10119 break;
10121 case VKI_GIO_UNIMAP:
10122 if ( ARG3 ) {
10123 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
10124 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
10125 POST_MEM_WRITE( (Addr)desc->entries,
10126 desc->entry_ct * sizeof(struct vki_unipair) );
10128 break;
10129 case VKI_PIO_UNIMAP:
10130 break;
10131 case VKI_PIO_UNIMAPCLR:
10132 break;
10134 case VKI_KDGKBMODE:
10135 POST_MEM_WRITE( ARG3, sizeof(int) );
10136 break;
10137 case VKI_KDSKBMODE:
10138 break;
10140 case VKI_KDGKBMETA:
10141 POST_MEM_WRITE( ARG3, sizeof(int) );
10142 break;
10143 case VKI_KDSKBMETA:
10144 break;
10146 case VKI_KDGKBLED:
10147 POST_MEM_WRITE( ARG3, sizeof(char) );
10148 break;
10149 case VKI_KDSKBLED:
10150 break;
10152 case VKI_KDGKBENT:
10153 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
10154 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
10155 break;
10156 case VKI_KDSKBENT:
10157 break;
10159 case VKI_KDGKBSENT:
10160 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
10161 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
10162 break;
10163 case VKI_KDSKBSENT:
10164 break;
10166 case VKI_KDGKBDIACR:
10167 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
10168 break;
10169 case VKI_KDSKBDIACR:
10170 break;
10172 case VKI_KDGETKEYCODE:
10173 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
10174 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
10175 break;
10176 case VKI_KDSETKEYCODE:
10177 break;
10179 case VKI_KDSIGACCEPT:
10180 break;
10182 case VKI_KDKBDREP:
10183 break;
10185 case VKI_KDFONTOP:
10186 if ( ARG3 ) {
10187 struct vki_console_font_op *op =
10188 (struct vki_console_font_op *) (Addr)ARG3;
10189 switch ( op->op ) {
10190 case VKI_KD_FONT_OP_SET:
10191 break;
10192 case VKI_KD_FONT_OP_GET:
10193 if ( op->data )
10194 POST_MEM_WRITE( (Addr) op->data,
10195 (op->width + 7) / 8 * 32 * op->charcount );
10196 break;
10197 case VKI_KD_FONT_OP_SET_DEFAULT:
10198 break;
10199 case VKI_KD_FONT_OP_COPY:
10200 break;
10202 POST_MEM_WRITE( (Addr) op, sizeof(*op));
10204 break;
10206 case VKI_VT_OPENQRY:
10207 POST_MEM_WRITE( ARG3, sizeof(int) );
10208 break;
10209 case VKI_VT_GETMODE:
10210 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
10211 break;
10212 case VKI_VT_SETMODE:
10213 break;
10214 case VKI_VT_GETSTATE:
10215 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
10216 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
10217 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
10218 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
10219 break;
10220 case VKI_VT_RELDISP:
10221 case VKI_VT_ACTIVATE:
10222 case VKI_VT_WAITACTIVE:
10223 case VKI_VT_DISALLOCATE:
10224 break;
10225 case VKI_VT_RESIZE:
10226 break;
10227 case VKI_VT_RESIZEX:
10228 break;
10229 case VKI_VT_LOCKSWITCH:
10230 case VKI_VT_UNLOCKSWITCH:
10231 break;
10233 case VKI_USBDEVFS_CONTROL:
10234 if ( ARG3 ) {
10235 struct vki_usbdevfs_ctrltransfer *vkuc =
10236 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
10237 if (vkuc->bRequestType & 0x80)
10238 POST_MEM_WRITE((Addr)vkuc->data, RES);
10240 break;
10241 case VKI_USBDEVFS_BULK:
10242 if ( ARG3 ) {
10243 struct vki_usbdevfs_bulktransfer *vkub =
10244 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
10245 if (vkub->ep & 0x80)
10246 POST_MEM_WRITE((Addr)vkub->data, RES);
10248 break;
10249 case VKI_USBDEVFS_GETDRIVER:
10250 if ( ARG3 ) {
10251 struct vki_usbdevfs_getdriver *vkugd =
10252 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
10253 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
10255 break;
10256 case VKI_USBDEVFS_REAPURB:
10257 case VKI_USBDEVFS_REAPURBNDELAY:
10258 if ( ARG3 ) {
10259 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
10260 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
10261 if (!*vkuu)
10262 break;
10263 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
10264 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10265 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10266 if (vkusp->bRequestType & 0x80)
10267 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10268 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10269 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10270 char *bp = (*vkuu)->buffer;
10271 int i;
10272 for(i=0; i<(*vkuu)->number_of_packets; i++) {
10273 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10274 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10275 if ((*vkuu)->endpoint & 0x80)
10276 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10277 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10279 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10280 } else {
10281 if ((*vkuu)->endpoint & 0x80)
10282 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10283 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10286 break;
10287 case VKI_USBDEVFS_CONNECTINFO:
10288 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10289 break;
10290 case VKI_USBDEVFS_IOCTL:
10291 if ( ARG3 ) {
10292 struct vki_usbdevfs_ioctl *vkui =
10293 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
10294 UInt dir2, size2;
10295 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
10296 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10297 if (size2 > 0) {
10298 if (dir2 & _VKI_IOC_READ)
10299 POST_MEM_WRITE((Addr)vkui->data, size2);
10302 break;
10304 /* I2C (/dev/i2c-*) ioctls */
10305 case VKI_I2C_SLAVE:
10306 case VKI_I2C_SLAVE_FORCE:
10307 case VKI_I2C_TENBIT:
10308 case VKI_I2C_PEC:
10309 break;
10310 case VKI_I2C_FUNCS:
10311 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10312 break;
10313 case VKI_I2C_RDWR:
10314 if ( ARG3 ) {
10315 struct vki_i2c_rdwr_ioctl_data *vkui =
10316 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
10317 UInt i;
10318 for (i=0; i < vkui->nmsgs; i++) {
10319 struct vki_i2c_msg *msg = vkui->msgs + i;
10320 if (msg->flags & VKI_I2C_M_RD)
10321 POST_MEM_WRITE((Addr)msg->buf, msg->len);
10324 break;
10325 case VKI_I2C_SMBUS:
10326 if ( ARG3 ) {
10327 struct vki_i2c_smbus_ioctl_data *vkis
10328 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
10329 /* i2c_smbus_write_quick hides its value in read_write, so
10330 this variable can have a different meaning */
10331 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10332 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10333 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10334 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10335 UInt size;
10336 switch(vkis->size) {
10337 case VKI_I2C_SMBUS_BYTE:
10338 case VKI_I2C_SMBUS_BYTE_DATA:
10339 size = 1;
10340 break;
10341 case VKI_I2C_SMBUS_WORD_DATA:
10342 case VKI_I2C_SMBUS_PROC_CALL:
10343 size = 2;
10344 break;
10345 case VKI_I2C_SMBUS_BLOCK_DATA:
10346 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10347 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10348 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10349 size = 1 + vkis->data->block[0];
10350 break;
10351 default:
10352 size = 0;
10354 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10358 break;
10360 /* Wireless extensions ioctls */
10361 case VKI_SIOCSIWCOMMIT:
10362 case VKI_SIOCSIWNWID:
10363 case VKI_SIOCSIWFREQ:
10364 case VKI_SIOCSIWMODE:
10365 case VKI_SIOCSIWSENS:
10366 case VKI_SIOCSIWRANGE:
10367 case VKI_SIOCSIWPRIV:
10368 case VKI_SIOCSIWSTATS:
10369 case VKI_SIOCSIWSPY:
10370 case VKI_SIOCSIWTHRSPY:
10371 case VKI_SIOCSIWAP:
10372 case VKI_SIOCSIWSCAN:
10373 case VKI_SIOCSIWESSID:
10374 case VKI_SIOCSIWRATE:
10375 case VKI_SIOCSIWNICKN:
10376 case VKI_SIOCSIWRTS:
10377 case VKI_SIOCSIWFRAG:
10378 case VKI_SIOCSIWTXPOW:
10379 case VKI_SIOCSIWRETRY:
10380 case VKI_SIOCSIWENCODE:
10381 case VKI_SIOCSIWPOWER:
10382 case VKI_SIOCSIWGENIE:
10383 case VKI_SIOCSIWMLME:
10384 case VKI_SIOCSIWAUTH:
10385 case VKI_SIOCSIWENCODEEXT:
10386 case VKI_SIOCSIWPMKSA:
10387 break;
10388 case VKI_SIOCGIWNAME:
10389 if (ARG3) {
10390 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
10391 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
10393 break;
10394 case VKI_SIOCGIWNWID:
10395 case VKI_SIOCGIWSENS:
10396 case VKI_SIOCGIWRATE:
10397 case VKI_SIOCGIWRTS:
10398 case VKI_SIOCGIWFRAG:
10399 case VKI_SIOCGIWTXPOW:
10400 case VKI_SIOCGIWRETRY:
10401 case VKI_SIOCGIWPOWER:
10402 case VKI_SIOCGIWAUTH:
10403 if (ARG3) {
10404 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
10405 sizeof(struct vki_iw_param));
10407 break;
10408 case VKI_SIOCGIWFREQ:
10409 if (ARG3) {
10410 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
10411 sizeof(struct vki_iw_freq));
10413 break;
10414 case VKI_SIOCGIWMODE:
10415 if (ARG3) {
10416 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
10417 sizeof(__vki_u32));
10419 break;
10420 case VKI_SIOCGIWRANGE:
10421 case VKI_SIOCGIWPRIV:
10422 case VKI_SIOCGIWSTATS:
10423 case VKI_SIOCGIWSPY:
10424 case VKI_SIOCGIWTHRSPY:
10425 case VKI_SIOCGIWAPLIST:
10426 case VKI_SIOCGIWSCAN:
10427 case VKI_SIOCGIWESSID:
10428 case VKI_SIOCGIWNICKN:
10429 case VKI_SIOCGIWENCODE:
10430 case VKI_SIOCGIWGENIE:
10431 case VKI_SIOCGIWENCODEEXT:
10432 if (ARG3) {
10433 struct vki_iw_point* point;
10434 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
10435 POST_MEM_WRITE((Addr)point->pointer, point->length);
10437 break;
10438 case VKI_SIOCGIWAP:
10439 if (ARG3) {
10440 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
10441 sizeof(struct vki_sockaddr));
10443 break;
10445 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10446 || defined(VGPV_mips32_linux_android) \
10447 || defined(VGPV_arm64_linux_android)
10448 /* ashmem */
10449 case VKI_ASHMEM_GET_SIZE:
10450 case VKI_ASHMEM_SET_SIZE:
10451 case VKI_ASHMEM_GET_PROT_MASK:
10452 case VKI_ASHMEM_SET_PROT_MASK:
10453 case VKI_ASHMEM_GET_PIN_STATUS:
10454 case VKI_ASHMEM_PURGE_ALL_CACHES:
10455 case VKI_ASHMEM_SET_NAME:
10456 case VKI_ASHMEM_PIN:
10457 case VKI_ASHMEM_UNPIN:
10458 break;
10459 case VKI_ASHMEM_GET_NAME:
10460 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10461 break;
10463 /* binder */
10464 case VKI_BINDER_WRITE_READ:
10465 if (ARG3) {
10466 struct vki_binder_write_read* bwr
10467 = (struct vki_binder_write_read*)(Addr)ARG3;
10468 POST_FIELD_WRITE(bwr->write_consumed);
10469 POST_FIELD_WRITE(bwr->read_consumed);
10471 if (bwr->read_size)
10472 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10474 break;
10476 case VKI_BINDER_SET_IDLE_TIMEOUT:
10477 case VKI_BINDER_SET_MAX_THREADS:
10478 case VKI_BINDER_SET_IDLE_PRIORITY:
10479 case VKI_BINDER_SET_CONTEXT_MGR:
10480 case VKI_BINDER_THREAD_EXIT:
10481 break;
10482 case VKI_BINDER_VERSION:
10483 if (ARG3) {
10484 struct vki_binder_version* bv =
10485 (struct vki_binder_version*)(Addr)ARG3;
10486 POST_FIELD_WRITE(bv->protocol_version);
10488 break;
10489 # endif /* defined(VGPV_*_linux_android) */
10491 case VKI_HCIGETDEVLIST:
10492 if (ARG3) {
10493 struct vki_hci_dev_list_req* dlr =
10494 (struct vki_hci_dev_list_req*)(Addr)ARG3;
10495 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10496 dlr->dev_num * sizeof(struct vki_hci_dev_req));
10498 break;
10500 case VKI_HCIINQUIRY:
10501 if (ARG3) {
10502 struct vki_hci_inquiry_req* ir =
10503 (struct vki_hci_inquiry_req*)(Addr)ARG3;
10504 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10505 ir->num_rsp * sizeof(struct vki_inquiry_info));
10507 break;
10509 case VKI_DRM_IOCTL_VERSION:
10510 if (ARG3) {
10511 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
10512 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10513 const vki_size_t orig_name_len = info->orig->name_len;
10514 const vki_size_t orig_date_len = info->orig->date_len;
10515 const vki_size_t orig_desc_len = info->orig->desc_len;
10516 *info->orig = info->data;
10517 ARG3 = (Addr)info->orig;
10518 data = info->orig;
10519 VG_(free)(info);
10520 if (SUCCESS) {
10521 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10522 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10523 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10524 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10525 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10526 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10527 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10528 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10529 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10532 break;
10533 case VKI_DRM_IOCTL_GET_UNIQUE:
10534 if (ARG3) {
10535 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
10536 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10538 break;
10539 case VKI_DRM_IOCTL_GET_MAGIC:
10540 if (ARG3) {
10541 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
10542 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10544 break;
10545 case VKI_DRM_IOCTL_WAIT_VBLANK:
10546 if (ARG3) {
10547 union vki_drm_wait_vblank *data =
10548 (union vki_drm_wait_vblank *)(Addr)ARG3;
10549 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10551 break;
10552 case VKI_DRM_IOCTL_GEM_FLINK:
10553 if (ARG3) {
10554 struct vki_drm_gem_flink *data =
10555 (struct vki_drm_gem_flink *)(Addr)ARG3;
10556 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10558 break;
10559 case VKI_DRM_IOCTL_GEM_OPEN:
10560 if (ARG3) {
10561 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
10562 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10563 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10565 break;
10566 case VKI_DRM_IOCTL_I915_GETPARAM:
10567 if (ARG3) {
10568 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
10569 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10571 break;
10572 case VKI_DRM_IOCTL_I915_GEM_BUSY:
10573 if (ARG3) {
10574 struct vki_drm_i915_gem_busy *data =
10575 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
10576 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10578 break;
10579 case VKI_DRM_IOCTL_I915_GEM_CREATE:
10580 if (ARG3) {
10581 struct vki_drm_i915_gem_create *data =
10582 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
10583 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10585 break;
10586 case VKI_DRM_IOCTL_I915_GEM_PREAD:
10587 if (ARG3) {
10588 struct vki_drm_i915_gem_pread *data =
10589 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
10590 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10592 break;
10593 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10594 if (ARG3) {
10595 struct vki_drm_i915_gem_mmap_gtt *data =
10596 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
10597 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10599 break;
10600 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10601 if (ARG3) {
10602 struct vki_drm_i915_gem_set_tiling *data =
10603 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
10604 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10605 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10606 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10608 break;
10609 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10610 if (ARG3) {
10611 struct vki_drm_i915_gem_get_tiling *data =
10612 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
10613 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10614 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10616 break;
10617 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10618 if (ARG3) {
10619 struct vki_drm_i915_gem_get_aperture *data =
10620 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
10621 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10622 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10624 break;
10626 /* KVM ioctls that only write the system call return value */
10627 case VKI_KVM_GET_API_VERSION:
10628 case VKI_KVM_CREATE_VM:
10629 case VKI_KVM_CHECK_EXTENSION:
10630 case VKI_KVM_GET_VCPU_MMAP_SIZE:
10631 case VKI_KVM_S390_ENABLE_SIE:
10632 case VKI_KVM_CREATE_VCPU:
10633 case VKI_KVM_SET_TSS_ADDR:
10634 case VKI_KVM_CREATE_IRQCHIP:
10635 case VKI_KVM_RUN:
10636 case VKI_KVM_S390_INITIAL_RESET:
10637 case VKI_KVM_KVMCLOCK_CTRL:
10638 break;
10640 case VKI_KVM_S390_MEM_OP: {
10641 struct vki_kvm_s390_mem_op *args =
10642 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
10643 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
10644 break;
10645 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
10646 POST_MEM_WRITE((Addr)args->buf, args->size);
10648 break;
10650 #ifdef ENABLE_XEN
10651 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
10652 SyscallArgs harrghs;
10653 struct vki_xen_privcmd_hypercall *args =
10654 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
10656 if (!args)
10657 break;
10659 VG_(memset)(&harrghs, 0, sizeof(harrghs));
10660 harrghs.sysno = args->op;
10661 harrghs.arg1 = args->arg[0];
10662 harrghs.arg2 = args->arg[1];
10663 harrghs.arg3 = args->arg[2];
10664 harrghs.arg4 = args->arg[3];
10665 harrghs.arg5 = args->arg[4];
10666 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
10668 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
10670 break;
10672 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
10673 break;
10674 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
10675 struct vki_xen_privcmd_mmapbatch *args =
10676 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
10677 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
10679 break;
10680 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
10681 struct vki_xen_privcmd_mmapbatch_v2 *args =
10682 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
10683 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
10685 break;
10687 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
10688 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
10689 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
10690 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
10691 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
10692 case VKI_XEN_IOCTL_EVTCHN_RESET:
10693 /* No output */
10694 break;
10695 #endif
10697 /* Lustre */
10698 case VKI_OBD_IOC_FID2PATH: {
10699 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
10700 POST_FIELD_WRITE(args->gf_recno);
10701 POST_FIELD_WRITE(args->gf_linkno);
10702 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
10703 break;
10706 case VKI_LL_IOC_PATH2FID:
10707 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
10708 break;
10710 case VKI_LL_IOC_GETPARENT: {
10711 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
10712 POST_FIELD_WRITE(gp->gp_fid);
10713 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
10714 break;
10717 /* V4L2 */
10718 case VKI_V4L2_S_FMT:
10719 case VKI_V4L2_TRY_FMT:
10720 case VKI_V4L2_REQBUFS:
10721 case VKI_V4L2_OVERLAY:
10722 case VKI_V4L2_STREAMON:
10723 case VKI_V4L2_STREAMOFF:
10724 case VKI_V4L2_S_PARM:
10725 case VKI_V4L2_S_STD:
10726 case VKI_V4L2_S_FREQUENCY:
10727 case VKI_V4L2_S_CTRL:
10728 case VKI_V4L2_S_TUNER:
10729 case VKI_V4L2_S_AUDIO:
10730 case VKI_V4L2_S_INPUT:
10731 case VKI_V4L2_S_EDID:
10732 case VKI_V4L2_S_OUTPUT:
10733 case VKI_V4L2_S_AUDOUT:
10734 case VKI_V4L2_S_MODULATOR:
10735 case VKI_V4L2_S_JPEGCOMP:
10736 case VKI_V4L2_S_CROP:
10737 case VKI_V4L2_S_PRIORITY:
10738 case VKI_V4L2_S_HW_FREQ_SEEK:
10739 case VKI_V4L2_S_DV_TIMINGS:
10740 case VKI_V4L2_SUBSCRIBE_EVENT:
10741 case VKI_V4L2_UNSUBSCRIBE_EVENT:
10742 case VKI_V4L2_PREPARE_BUF:
10743 break;
10744 case VKI_V4L2_QUERYCAP: {
10745 struct vki_v4l2_capability *data =
10746 (struct vki_v4l2_capability *)(Addr)ARG3;
10747 POST_MEM_WRITE((Addr)data, sizeof(*data));
10748 break;
10750 case VKI_V4L2_ENUM_FMT: {
10751 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
10752 POST_FIELD_WRITE(data->flags);
10753 POST_FIELD_WRITE(data->description);
10754 POST_FIELD_WRITE(data->pixelformat);
10755 POST_FIELD_WRITE(data->reserved);
10756 break;
10758 case VKI_V4L2_G_FMT: {
10759 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
10760 switch (data->type) {
10761 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10762 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10763 POST_FIELD_WRITE(data->fmt.pix);
10764 break;
10765 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10766 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10767 POST_FIELD_WRITE(data->fmt.vbi);
10768 break;
10769 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10770 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10771 POST_FIELD_WRITE(data->fmt.sliced);
10772 break;
10773 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10774 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10775 POST_FIELD_WRITE(data->fmt.win);
10776 break;
10777 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10778 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10779 POST_FIELD_WRITE(data->fmt.pix_mp);
10780 break;
10781 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10782 POST_FIELD_WRITE(data->fmt.sdr);
10783 break;
10785 break;
10787 case VKI_V4L2_QUERYBUF: {
10788 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10789 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10790 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10791 unsigned i;
10793 for (i = 0; i < data->length; i++) {
10794 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10795 POST_FIELD_WRITE(data->m.planes[i].length);
10796 POST_FIELD_WRITE(data->m.planes[i].m);
10797 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10798 POST_FIELD_WRITE(data->m.planes[i].reserved);
10800 } else {
10801 POST_FIELD_WRITE(data->m);
10802 POST_FIELD_WRITE(data->length);
10804 POST_FIELD_WRITE(data->bytesused);
10805 POST_FIELD_WRITE(data->flags);
10806 POST_FIELD_WRITE(data->field);
10807 POST_FIELD_WRITE(data->timestamp);
10808 POST_FIELD_WRITE(data->timecode);
10809 POST_FIELD_WRITE(data->sequence);
10810 POST_FIELD_WRITE(data->memory);
10811 POST_FIELD_WRITE(data->sequence);
10812 break;
10814 case VKI_V4L2_G_FBUF: {
10815 struct vki_v4l2_framebuffer *data =
10816 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10817 POST_MEM_WRITE((Addr)data, sizeof(*data));
10818 break;
10820 case VKI_V4L2_S_FBUF: {
10821 struct vki_v4l2_framebuffer *data =
10822 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10823 POST_FIELD_WRITE(data->capability);
10824 POST_FIELD_WRITE(data->flags);
10825 POST_FIELD_WRITE(data->fmt);
10826 break;
10828 case VKI_V4L2_QBUF: {
10829 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10831 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10832 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10833 unsigned i;
10835 for (i = 0; i < data->length; i++) {
10836 POST_FIELD_WRITE(data->m.planes[i].length);
10837 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10838 POST_FIELD_WRITE(data->m.planes[i].m);
10840 } else {
10841 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10842 POST_FIELD_WRITE(data->m);
10843 POST_FIELD_WRITE(data->length);
10845 break;
10847 case VKI_V4L2_EXPBUF: {
10848 struct vki_v4l2_exportbuffer *data =
10849 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
10850 POST_FIELD_WRITE(data->fd);
10851 break;
10853 case VKI_V4L2_DQBUF: {
10854 struct vki_v4l2_buffer *data =
10855 (struct vki_v4l2_buffer *)(Addr)ARG3;
10856 POST_FIELD_WRITE(data->index);
10857 POST_FIELD_WRITE(data->bytesused);
10858 POST_FIELD_WRITE(data->field);
10859 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10860 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10861 unsigned i;
10863 for (i = 0; i < data->length; i++) {
10864 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10865 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10866 POST_FIELD_WRITE(data->m.planes[i].length);
10867 POST_FIELD_WRITE(data->m.planes[i].m);
10869 } else {
10870 POST_FIELD_WRITE(data->m);
10871 POST_FIELD_WRITE(data->length);
10872 POST_FIELD_WRITE(data->bytesused);
10873 POST_FIELD_WRITE(data->field);
10875 POST_FIELD_WRITE(data->timestamp);
10876 POST_FIELD_WRITE(data->timecode);
10877 POST_FIELD_WRITE(data->sequence);
10878 break;
10880 case VKI_V4L2_G_PARM: {
10881 struct vki_v4l2_streamparm *data =
10882 (struct vki_v4l2_streamparm *)(Addr)ARG3;
10883 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
10884 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
10885 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
10886 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
10888 if (is_output)
10889 POST_MEM_WRITE((Addr)&data->parm.output,
10890 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
10891 else
10892 POST_MEM_WRITE((Addr)&data->parm.capture,
10893 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
10894 break;
10896 case VKI_V4L2_G_STD: {
10897 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
10898 POST_MEM_WRITE((Addr)data, sizeof(*data));
10899 break;
10901 case VKI_V4L2_ENUMSTD: {
10902 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
10903 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
10904 break;
10906 case VKI_V4L2_ENUMINPUT: {
10907 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
10908 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10909 break;
10911 case VKI_V4L2_G_CTRL: {
10912 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
10913 POST_FIELD_WRITE(data->value);
10914 break;
10916 case VKI_V4L2_G_TUNER: {
10917 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
10918 POST_MEM_WRITE((Addr)data->name,
10919 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10920 break;
10922 case VKI_V4L2_G_AUDIO: {
10923 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
10924 POST_MEM_WRITE((Addr)data,
10925 sizeof(*data) - sizeof(data->reserved));
10926 break;
10928 case VKI_V4L2_QUERYCTRL: {
10929 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
10930 POST_MEM_WRITE((Addr)&data->type,
10931 sizeof(*data) - sizeof(data->id));
10932 break;
10934 case VKI_V4L2_QUERYMENU: {
10935 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
10936 POST_MEM_WRITE((Addr)data->name,
10937 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
10938 break;
10940 case VKI_V4L2_G_INPUT: {
10941 int *data = (int *)(Addr)ARG3;
10942 POST_MEM_WRITE((Addr)data, sizeof(*data));
10943 break;
10945 case VKI_V4L2_G_EDID: {
10946 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
10947 if (data->blocks && data->edid)
10948 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
10949 break;
10951 case VKI_V4L2_G_OUTPUT: {
10952 int *data = (int *)(Addr)ARG3;
10953 POST_MEM_WRITE((Addr)data, sizeof(*data));
10954 break;
10956 case VKI_V4L2_ENUMOUTPUT: {
10957 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
10958 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10959 break;
10961 case VKI_V4L2_G_AUDOUT: {
10962 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
10963 POST_MEM_WRITE((Addr)data,
10964 sizeof(*data) - sizeof(data->reserved));
10965 break;
10967 case VKI_V4L2_G_MODULATOR: {
10968 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
10969 POST_MEM_WRITE((Addr)data->name,
10970 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10971 break;
10973 case VKI_V4L2_G_FREQUENCY: {
10974 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
10975 POST_FIELD_WRITE(data->type);
10976 POST_FIELD_WRITE(data->frequency);
10977 break;
10979 case VKI_V4L2_CROPCAP: {
10980 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
10981 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
10982 break;
10984 case VKI_V4L2_G_CROP: {
10985 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
10986 POST_FIELD_WRITE(data->c);
10987 break;
10989 case VKI_V4L2_G_JPEGCOMP: {
10990 struct vki_v4l2_jpegcompression *data =
10991 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
10992 POST_MEM_WRITE((Addr)data, sizeof(*data));
10993 break;
10995 case VKI_V4L2_QUERYSTD: {
10996 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
10997 POST_MEM_WRITE((Addr)data, sizeof(*data));
10998 break;
11000 case VKI_V4L2_ENUMAUDIO: {
11001 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11002 POST_MEM_WRITE((Addr)data->name,
11003 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11004 break;
11006 case VKI_V4L2_ENUMAUDOUT: {
11007 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11008 POST_MEM_WRITE((Addr)data->name,
11009 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11010 break;
11012 case VKI_V4L2_G_PRIORITY: {
11013 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11014 POST_MEM_WRITE((Addr)data, sizeof(*data));
11015 break;
11017 case VKI_V4L2_G_SLICED_VBI_CAP: {
11018 struct vki_v4l2_sliced_vbi_cap *data =
11019 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11020 POST_MEM_WRITE((Addr)data,
11021 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11022 break;
11024 case VKI_V4L2_G_EXT_CTRLS: {
11025 struct vki_v4l2_ext_controls *data =
11026 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11027 if (data->count) {
11028 unsigned i;
11030 for (i = 0; i < data->count; i++) {
11031 if (data->controls[i].size)
11032 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11033 else
11034 POST_FIELD_WRITE(data->controls[i].value64);
11037 POST_FIELD_WRITE(data->error_idx);
11038 break;
11040 case VKI_V4L2_S_EXT_CTRLS: {
11041 struct vki_v4l2_ext_controls *data =
11042 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11043 POST_FIELD_WRITE(data->error_idx);
11044 break;
11046 case VKI_V4L2_TRY_EXT_CTRLS: {
11047 struct vki_v4l2_ext_controls *data =
11048 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11049 POST_FIELD_WRITE(data->error_idx);
11050 break;
11052 case VKI_V4L2_ENUM_FRAMESIZES: {
11053 struct vki_v4l2_frmsizeenum *data =
11054 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11055 POST_FIELD_WRITE(data->type);
11056 POST_FIELD_WRITE(data->stepwise);
11057 break;
11059 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11060 struct vki_v4l2_frmivalenum *data =
11061 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11062 POST_FIELD_WRITE(data->type);
11063 POST_FIELD_WRITE(data->stepwise);
11064 break;
11066 case VKI_V4L2_G_ENC_INDEX: {
11067 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11068 POST_MEM_WRITE((Addr)data, sizeof(*data));
11069 break;
11071 case VKI_V4L2_ENCODER_CMD: {
11072 struct vki_v4l2_encoder_cmd *data =
11073 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11074 POST_FIELD_WRITE(data->flags);
11075 break;
11077 case VKI_V4L2_TRY_ENCODER_CMD: {
11078 struct vki_v4l2_encoder_cmd *data =
11079 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11080 POST_FIELD_WRITE(data->flags);
11081 break;
11083 case VKI_V4L2_DBG_S_REGISTER: {
11084 struct vki_v4l2_dbg_register *data =
11085 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11086 POST_FIELD_WRITE(data->size);
11087 break;
11089 case VKI_V4L2_DBG_G_REGISTER: {
11090 struct vki_v4l2_dbg_register *data =
11091 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11092 POST_FIELD_WRITE(data->val);
11093 POST_FIELD_WRITE(data->size);
11094 break;
11096 case VKI_V4L2_G_DV_TIMINGS: {
11097 struct vki_v4l2_dv_timings *data =
11098 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11099 POST_MEM_WRITE((Addr)data, sizeof(*data));
11100 break;
11102 case VKI_V4L2_DQEVENT: {
11103 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
11104 POST_MEM_WRITE((Addr)data, sizeof(*data));
11105 break;
11107 case VKI_V4L2_CREATE_BUFS: {
11108 struct vki_v4l2_create_buffers *data =
11109 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
11110 POST_FIELD_WRITE(data->index);
11111 break;
11113 case VKI_V4L2_G_SELECTION: {
11114 struct vki_v4l2_selection *data =
11115 (struct vki_v4l2_selection *)(Addr)ARG3;
11116 POST_FIELD_WRITE(data->r);
11117 break;
11119 case VKI_V4L2_S_SELECTION: {
11120 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
11121 POST_FIELD_WRITE(data->r);
11122 break;
11124 case VKI_V4L2_DECODER_CMD: {
11125 struct vki_v4l2_decoder_cmd *data =
11126 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11127 POST_FIELD_WRITE(data->flags);
11128 break;
11130 case VKI_V4L2_TRY_DECODER_CMD: {
11131 struct vki_v4l2_decoder_cmd *data =
11132 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11133 POST_FIELD_WRITE(data->flags);
11134 break;
11136 case VKI_V4L2_ENUM_DV_TIMINGS: {
11137 struct vki_v4l2_enum_dv_timings *data =
11138 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
11139 POST_FIELD_WRITE(data->timings);
11140 break;
11142 case VKI_V4L2_QUERY_DV_TIMINGS: {
11143 struct vki_v4l2_dv_timings *data =
11144 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11145 POST_MEM_WRITE((Addr)data, sizeof(*data));
11146 break;
11148 case VKI_V4L2_DV_TIMINGS_CAP: {
11149 struct vki_v4l2_dv_timings_cap *data =
11150 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
11151 POST_MEM_WRITE((Addr)data, sizeof(*data));
11152 break;
11154 case VKI_V4L2_ENUM_FREQ_BANDS: {
11155 struct vki_v4l2_frequency_band *data =
11156 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
11157 POST_FIELD_WRITE(data->capability);
11158 POST_FIELD_WRITE(data->rangelow);
11159 POST_FIELD_WRITE(data->rangehigh);
11160 POST_FIELD_WRITE(data->modulation);
11161 break;
11163 case VKI_V4L2_DBG_G_CHIP_INFO: {
11164 struct vki_v4l2_dbg_chip_info *data =
11165 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
11166 POST_FIELD_WRITE(data->name);
11167 POST_FIELD_WRITE(data->flags);
11168 break;
11170 case VKI_V4L2_QUERY_EXT_CTRL: {
11171 struct vki_v4l2_query_ext_ctrl *data =
11172 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
11173 POST_MEM_WRITE((Addr)&data->type,
11174 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
11175 break;
11178 case VKI_V4L2_SUBDEV_S_FMT:
11179 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
11180 case VKI_V4L2_SUBDEV_S_CROP:
11181 case VKI_V4L2_SUBDEV_S_SELECTION:
11182 break;
11184 case VKI_V4L2_SUBDEV_G_FMT: {
11185 struct vki_v4l2_subdev_format *data =
11186 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
11187 POST_FIELD_WRITE(data->format);
11188 break;
11190 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
11191 struct vki_v4l2_subdev_frame_interval *data =
11192 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
11193 POST_FIELD_WRITE(data->interval);
11194 break;
11196 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
11197 struct vki_v4l2_subdev_mbus_code_enum *data =
11198 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
11199 POST_FIELD_WRITE(data->code);
11200 break;
11202 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
11203 struct vki_v4l2_subdev_frame_size_enum *data =
11204 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
11205 POST_FIELD_WRITE(data->min_width);
11206 POST_FIELD_WRITE(data->min_height);
11207 POST_FIELD_WRITE(data->max_width);
11208 POST_FIELD_WRITE(data->max_height);
11209 break;
11211 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
11212 struct vki_v4l2_subdev_frame_interval_enum *data =
11213 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
11214 POST_FIELD_WRITE(data->interval);
11215 break;
11217 case VKI_V4L2_SUBDEV_G_CROP: {
11218 struct vki_v4l2_subdev_crop *data =
11219 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
11220 POST_FIELD_WRITE(data->rect);
11221 break;
11223 case VKI_V4L2_SUBDEV_G_SELECTION: {
11224 struct vki_v4l2_subdev_selection *data =
11225 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
11226 POST_FIELD_WRITE(data->r);
11227 break;
11229 case VKI_MEDIA_IOC_DEVICE_INFO: {
11230 struct vki_media_device_info *data =
11231 (struct vki_media_device_info *)(Addr)ARG3;
11232 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
11233 break;
11235 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
11236 struct vki_media_entity_desc *data =
11237 (struct vki_media_entity_desc *)(Addr)ARG3;
11238 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
11239 break;
11241 case VKI_MEDIA_IOC_ENUM_LINKS:
11243 * This ioctl does write to the provided pointers, but it's not
11244 * possible to deduce the size of the array those pointers point to.
11246 break;
11247 case VKI_MEDIA_IOC_SETUP_LINK:
11248 break;
11250 /* Serial */
11251 case VKI_TIOCGSERIAL: {
11252 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
11253 POST_MEM_WRITE((Addr)data, sizeof(*data));
11254 break;
11256 case VKI_TIOCSSERIAL:
11257 break;
11259 case VKI_PERF_EVENT_IOC_ENABLE:
11260 case VKI_PERF_EVENT_IOC_DISABLE:
11261 case VKI_PERF_EVENT_IOC_REFRESH:
11262 case VKI_PERF_EVENT_IOC_RESET:
11263 case VKI_PERF_EVENT_IOC_PERIOD:
11264 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
11265 case VKI_PERF_EVENT_IOC_SET_FILTER:
11266 case VKI_PERF_EVENT_IOC_SET_BPF:
11267 break;
11269 case VKI_PERF_EVENT_IOC_ID:
11270 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
11271 break;
11273 default:
11274 /* EVIOC* are variable length and return size written on success */
11275 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
11276 case VKI_EVIOCGNAME(0):
11277 case VKI_EVIOCGPHYS(0):
11278 case VKI_EVIOCGUNIQ(0):
11279 case VKI_EVIOCGKEY(0):
11280 case VKI_EVIOCGLED(0):
11281 case VKI_EVIOCGSND(0):
11282 case VKI_EVIOCGSW(0):
11283 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
11284 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
11285 case VKI_EVIOCGBIT(VKI_EV_REL,0):
11286 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
11287 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
11288 case VKI_EVIOCGBIT(VKI_EV_SW,0):
11289 case VKI_EVIOCGBIT(VKI_EV_LED,0):
11290 case VKI_EVIOCGBIT(VKI_EV_SND,0):
11291 case VKI_EVIOCGBIT(VKI_EV_REP,0):
11292 case VKI_EVIOCGBIT(VKI_EV_FF,0):
11293 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
11294 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
11295 if (RES > 0)
11296 POST_MEM_WRITE(ARG3, RES);
11297 break;
11298 default:
11299 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
11300 break;
11302 break;
11305 post_sys_ioctl__out:
11306 {} /* keep C compilers happy */
11309 /* ---------------------------------------------------------------------
11310 socketcall wrapper helpers
11311 ------------------------------------------------------------------ */
11313 void
11314 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
11315 UWord arg0, UWord arg1, UWord arg2,
11316 UWord arg3, UWord arg4 )
11318 /* int getsockopt(int s, int level, int optname,
11319 void *optval, socklen_t *optlen); */
11320 Addr optval_p = arg3;
11321 Addr optlen_p = arg4;
11322 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11323 if (optval_p != (Addr)NULL) {
11324 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11325 "socketcall.getsockopt(optval)",
11326 "socketcall.getsockopt(optlen)" );
11327 if (arg1 == VKI_SOL_SCTP &&
11328 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11329 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11331 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11332 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11333 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11334 (Addr)ga->addrs, address_bytes );
11339 void
11340 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11341 SysRes res,
11342 UWord arg0, UWord arg1, UWord arg2,
11343 UWord arg3, UWord arg4 )
11345 Addr optval_p = arg3;
11346 Addr optlen_p = arg4;
11347 vg_assert(!sr_isError(res)); /* guaranteed by caller */
11348 if (optval_p != (Addr)NULL) {
11349 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11350 "socketcall.getsockopt(optlen_out)" );
11351 if (arg1 == VKI_SOL_SCTP &&
11352 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11353 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11355 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11356 struct vki_sockaddr *a = ga->addrs;
11357 int i;
11358 for (i = 0; i < ga->addr_num; i++) {
11359 int sl = 0;
11360 if (a->sa_family == VKI_AF_INET)
11361 sl = sizeof(struct vki_sockaddr_in);
11362 else if (a->sa_family == VKI_AF_INET6)
11363 sl = sizeof(struct vki_sockaddr_in6);
11364 else {
11365 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11366 "address type %d\n", a->sa_family);
11368 a = (struct vki_sockaddr*)((char*)a + sl);
11370 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11375 void
11376 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11377 UWord arg0, UWord arg1, UWord arg2,
11378 UWord arg3, UWord arg4 )
11380 /* int setsockopt(int s, int level, int optname,
11381 const void *optval, socklen_t optlen); */
11382 Addr optval_p = arg3;
11383 if (optval_p != (Addr)NULL) {
11385 * OK, let's handle at least some setsockopt levels and options
11386 * ourselves, so we don't get false claims of references to
11387 * uninitialized memory (such as padding in structures) and *do*
11388 * check what pointers in the argument point to.
11390 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11392 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11395 * struct sock_fprog has a 16-bit count of instructions,
11396 * followed by a pointer to an array of those instructions.
11397 * There's padding between those two elements.
11399 * So that we don't bogusly complain about the padding bytes,
11400 * we just report that we read len and and filter.
11402 * We then make sure that what filter points to is valid.
11404 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11405 (Addr)&fp->len, sizeof(fp->len) );
11406 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11407 (Addr)&fp->filter, sizeof(fp->filter) );
11409 /* len * sizeof (*filter) */
11410 if (fp->filter != NULL)
11412 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11413 (Addr)(fp->filter),
11414 fp->len * sizeof(*fp->filter) );
11417 else
11419 PRE_MEM_READ( "socketcall.setsockopt(optval)",
11420 arg3, /* optval */
11421 arg4 /* optlen */ );
11426 void
11427 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11428 UWord arg1, UWord arg2, UWord arg3,
11429 UWord arg4, UWord arg5 )
11431 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11432 HChar name[40]; // large enough
11433 UInt i;
11434 for (i = 0; i < arg3; i++) {
11435 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11436 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11437 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11438 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11440 if (arg5)
11441 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11444 void
11445 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11446 UWord arg1, UWord arg2, UWord arg3,
11447 UWord arg4, UWord arg5 )
11449 if (res > 0) {
11450 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11451 HChar name[32]; // large enough
11452 UInt i;
11453 for (i = 0; i < res; i++) {
11454 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11455 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11456 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11461 void
11462 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11463 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11465 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11466 HChar name[40]; // large enough
11467 UInt i;
11468 for (i = 0; i < arg3; i++) {
11469 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11470 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11471 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11472 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11476 void
11477 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11478 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11480 if (res > 0) {
11481 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11482 UInt i;
11483 for (i = 0; i < res; i++) {
11484 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11489 /* ---------------------------------------------------------------------
11490 ptrace wrapper helpers
11491 ------------------------------------------------------------------ */
11493 void
11494 ML_(linux_POST_traceme) ( ThreadId tid )
11496 ThreadState *tst = VG_(get_ThreadState)(tid);
11497 tst->ptrace = VKI_PT_PTRACED;
11500 void
11501 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11503 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11505 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11506 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11507 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11508 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11509 (Addr) iov->iov_base, iov->iov_len);
11513 void
11514 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11516 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11518 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11519 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11520 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11521 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11522 (Addr) iov->iov_base, iov->iov_len);
11526 void
11527 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11529 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11531 /* XXX: The actual amount of data written by the kernel might be
11532 less than iov_len, depending on the regset (arg3). */
11533 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11536 PRE(sys_kcmp)
11538 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
11539 SARG1, SARG2, SARG3, ARG4, ARG5);
11540 switch (ARG3) {
11541 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11542 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11543 /* Most of the comparison types don't look at |idx1| or
11544 |idx2|. */
11545 PRE_REG_READ3(long, "kcmp",
11546 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11547 break;
11548 case VKI_KCMP_FILE:
11549 default:
11550 PRE_REG_READ5(long, "kcmp",
11551 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11552 unsigned long, idx1, unsigned long, idx2);
11553 break;
11557 #undef PRE
11558 #undef POST
11560 #endif // defined(VGO_linux)
11562 /*--------------------------------------------------------------------*/
11563 /*--- end ---*/
11564 /*--------------------------------------------------------------------*/