Add support for the Linux io_uring system calls
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob36d09d6e09411db1b673739c1856be67fe2da84a
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, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_linux)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
37 #include "pub_core_transtab.h" // VG_(discard_translations)
38 #include "pub_core_xarray.h"
39 #include "pub_core_clientstate.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_libcproc.h"
46 #include "pub_core_libcsignal.h"
47 #include "pub_core_machine.h" // VG_(get_SP)
48 #include "pub_core_mallocfree.h"
49 #include "pub_core_tooliface.h"
50 #include "pub_core_options.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_signals.h"
53 #include "pub_core_stacks.h"
54 #include "pub_core_syscall.h"
55 #include "pub_core_syswrap.h"
56 #include "pub_core_inner.h"
57 #if defined(ENABLE_INNER_CLIENT_REQUEST)
58 #include "pub_core_clreq.h"
59 #endif
61 #include "priv_types_n_macros.h"
62 #include "priv_syswrap-generic.h"
63 #include "priv_syswrap-linux.h"
64 #include "priv_syswrap-main.h"
65 #include "priv_syswrap-xen.h"
67 // Run a thread from beginning to end and return the thread's
68 // scheduler-return-code.
69 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
71 VgSchedReturnCode ret;
72 ThreadId tid = (ThreadId)tidW;
73 ThreadState* tst = VG_(get_ThreadState)(tid);
75 VG_(debugLog)(1, "syswrap-linux",
76 "thread_wrapper(tid=%u): entry\n",
77 tid);
79 vg_assert(tst->status == VgTs_Init);
81 /* make sure we get the CPU lock before doing anything significant */
82 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
84 if (0)
85 VG_(printf)("thread tid %u started: stack = %p\n",
86 tid, (void *)&tid);
88 /* Make sure error reporting is enabled in the new thread. */
89 tst->err_disablement_level = 0;
91 VG_TRACK(pre_thread_first_insn, tid);
93 tst->os_state.lwpid = VG_(gettid)();
94 /* Set the threadgroup for real. This overwrites the provisional value set
95 in do_clone(). See comments in do_clone for background, also #226116. */
96 tst->os_state.threadgroup = VG_(getpid)();
98 /* Thread created with all signals blocked; scheduler will set the
99 appropriate mask */
101 ret = VG_(scheduler)(tid);
103 vg_assert(VG_(is_exiting)(tid));
105 vg_assert(tst->status == VgTs_Runnable);
106 vg_assert(VG_(is_running_thread)(tid));
108 VG_(debugLog)(1, "syswrap-linux",
109 "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
110 tid, VG_(name_of_VgSchedReturnCode)(ret));
112 /* Return to caller, still holding the lock. */
113 return ret;
117 /* ---------------------------------------------------------------------
118 clone-related stuff
119 ------------------------------------------------------------------ */
121 /* Run a thread all the way to the end, then do appropriate exit actions
122 (this is the last-one-out-turn-off-the-lights bit). */
123 static void run_a_thread_NORETURN ( Word tidW )
125 ThreadId tid = (ThreadId)tidW;
126 VgSchedReturnCode src;
127 Int c;
128 ThreadState* tst;
129 #ifdef ENABLE_INNER_CLIENT_REQUEST
130 Int registered_vgstack_id;
131 #endif
133 VG_(debugLog)(1, "syswrap-linux",
134 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
135 tid);
137 tst = VG_(get_ThreadState)(tid);
138 vg_assert(tst);
140 /* An thread has two stacks:
141 * the simulated stack (used by the synthetic cpu. Guest process
142 is using this stack).
143 * the valgrind stack (used by the real cpu. Valgrind code is running
144 on this stack).
145 When Valgrind runs as an inner, it must signals that its (real) stack
146 is the stack to use by the outer to e.g. do stacktraces.
148 INNER_REQUEST
149 (registered_vgstack_id
150 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
151 tst->os_state.valgrind_stack_init_SP));
153 /* Run the thread all the way through. */
154 src = thread_wrapper(tid);
156 VG_(debugLog)(1, "syswrap-linux",
157 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
158 tid);
160 c = VG_(count_living_threads)();
161 vg_assert(c >= 1); /* stay sane */
163 /* Deregister thread's stack. */
164 if (tst->os_state.stk_id != NULL_STK_ID)
165 VG_(deregister_stack)(tst->os_state.stk_id);
167 // Tell the tool this thread is exiting
168 VG_TRACK( pre_thread_ll_exit, tid );
170 /* If the thread is exiting with errors disabled, complain loudly;
171 doing so is bad (does the user know this has happened?) Also,
172 in all cases, be paranoid and clear the flag anyway so that the
173 thread slot is safe in this respect if later reallocated. This
174 should be unnecessary since the flag should be cleared when the
175 slot is reallocated, in thread_wrapper(). */
176 if (tst->err_disablement_level > 0) {
177 VG_(umsg)(
178 "WARNING: exiting thread has error reporting disabled.\n"
179 "WARNING: possibly as a result of some mistake in the use\n"
180 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
182 VG_(debugLog)(
183 1, "syswrap-linux",
184 "run_a_thread_NORETURN(tid=%u): "
185 "WARNING: exiting thread has err_disablement_level = %u\n",
186 tid, tst->err_disablement_level
189 tst->err_disablement_level = 0;
191 if (c == 1) {
193 VG_(debugLog)(1, "syswrap-linux",
194 "run_a_thread_NORETURN(tid=%u): "
195 "last one standing\n",
196 tid);
198 /* We are the last one standing. Keep hold of the lock and
199 carry on to show final tool results, then exit the entire system.
200 Use the continuation pointer set at startup in m_main. */
201 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
202 } else {
204 VG_(debugLog)(1, "syswrap-linux",
205 "run_a_thread_NORETURN(tid=%u): "
206 "not last one standing\n",
207 tid);
209 /* OK, thread is dead, but others still exist. Just exit. */
211 /* This releases the run lock */
212 VG_(exit_thread)(tid);
213 vg_assert(tst->status == VgTs_Zombie);
214 vg_assert(sizeof(tst->status) == 4);
215 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
217 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
219 /* We have to use this sequence to terminate the thread to
220 prevent a subtle race. If VG_(exit_thread)() had left the
221 ThreadState as Empty, then it could have been reallocated,
222 reusing the stack while we're doing these last cleanups.
223 Instead, VG_(exit_thread) leaves it as Zombie to prevent
224 reallocation. We need to make sure we don't touch the stack
225 between marking it Empty and exiting. Hence the
226 assembler. */
227 #if defined(VGP_x86_linux)
228 asm volatile (
229 "pushl %%ebx\n"
230 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
231 "movl %2, %%eax\n" /* set %eax = __NR_exit */
232 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
233 "int $0x80\n" /* exit(tst->os_state.exitcode) */
234 "popl %%ebx\n"
235 : "=m" (tst->status)
236 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
237 : "eax"
239 #elif defined(VGP_amd64_linux)
240 asm volatile (
241 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
242 "movq %2, %%rax\n" /* set %rax = __NR_exit */
243 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
244 "syscall\n" /* exit(tst->os_state.exitcode) */
245 : "=m" (tst->status)
246 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
247 : "rax", "rdi"
249 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
250 || defined(VGP_ppc64le_linux)
251 { UInt vgts_empty = (UInt)VgTs_Empty;
252 asm volatile (
253 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
254 "li 0,%2\n\t" /* set r0 = __NR_exit */
255 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
256 "sc\n\t" /* exit(tst->os_state.exitcode) */
257 : "=m" (tst->status)
258 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
259 : "r0", "r3"
262 #elif defined(VGP_arm_linux)
263 asm volatile (
264 "str %1, %0\n" /* set tst->status = VgTs_Empty */
265 "mov r7, %2\n" /* set %r7 = __NR_exit */
266 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
267 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
268 : "=m" (tst->status)
269 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
270 : "r0", "r7"
272 #elif defined(VGP_arm64_linux)
273 asm volatile (
274 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
275 "mov x8, %2\n" /* set %x8 = __NR_exit */
276 "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */
277 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
278 : "=m" (tst->status)
279 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
280 : "x0", "x8"
282 #elif defined(VGP_s390x_linux)
283 asm volatile (
284 "st %1, %0\n" /* set tst->status = VgTs_Empty */
285 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
286 "svc %2\n" /* exit(tst->os_state.exitcode) */
287 : "=m" (tst->status)
288 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
289 : "2"
291 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
292 asm volatile (
293 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
294 "li $2, %2\n\t" /* set v0 = __NR_exit */
295 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
296 "syscall\n\t" /* exit(tst->os_state.exitcode) */
297 "nop"
298 : "=m" (tst->status)
299 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
300 : "cc", "memory" , "v0", "a0"
302 #else
303 # error Unknown platform
304 #endif
306 VG_(core_panic)("Thread exit failed?\n");
309 /*NOTREACHED*/
310 vg_assert(0);
313 Word ML_(start_thread_NORETURN) ( void* arg )
315 ThreadState* tst = (ThreadState*)arg;
316 ThreadId tid = tst->tid;
318 run_a_thread_NORETURN ( (Word)tid );
319 /*NOTREACHED*/
320 vg_assert(0);
323 /* Allocate a stack for this thread, if it doesn't already have one.
324 They're allocated lazily, and never freed. Returns the initial stack
325 pointer value to use, or 0 if allocation failed. */
326 Addr ML_(allocstack)(ThreadId tid)
328 ThreadState* tst = VG_(get_ThreadState)(tid);
329 VgStack* stack;
330 Addr initial_SP;
332 /* Either the stack_base and stack_init_SP are both zero (in which
333 case a stack hasn't been allocated) or they are both non-zero,
334 in which case it has. */
336 if (tst->os_state.valgrind_stack_base == 0)
337 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
339 if (tst->os_state.valgrind_stack_base != 0)
340 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
342 /* If no stack is present, allocate one. */
344 if (tst->os_state.valgrind_stack_base == 0) {
345 stack = VG_(am_alloc_VgStack)( &initial_SP );
346 if (stack) {
347 tst->os_state.valgrind_stack_base = (Addr)stack;
348 tst->os_state.valgrind_stack_init_SP = initial_SP;
352 if (0)
353 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
354 tid,
355 (void*)tst->os_state.valgrind_stack_base,
356 (void*)tst->os_state.valgrind_stack_init_SP );
358 return tst->os_state.valgrind_stack_init_SP;
361 /* Allocate a stack for the main thread, and run it all the way to the
362 end. Although we already have a working VgStack
363 (VG_(interim_stack)) it's better to allocate a new one, so that
364 overflow detection works uniformly for all threads.
366 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
368 Addr sp;
369 VG_(debugLog)(1, "syswrap-linux",
370 "entering VG_(main_thread_wrapper_NORETURN)\n");
372 sp = ML_(allocstack)(tid);
373 #if defined(ENABLE_INNER_CLIENT_REQUEST)
375 // we must register the main thread stack before the call
376 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
377 // reports 'write error' on the non registered stack.
378 ThreadState* tst = VG_(get_ThreadState)(tid);
379 INNER_REQUEST
380 ((void)
381 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
382 tst->os_state.valgrind_stack_init_SP));
384 #endif
386 #if defined(VGP_ppc32_linux)
387 /* make a stack frame */
388 sp -= 16;
389 sp &= ~0xF;
390 *(UWord *)sp = 0;
391 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
392 /* make a stack frame */
393 sp -= 112;
394 sp &= ~((Addr)0xF);
395 *(UWord *)sp = 0;
396 #elif defined(VGP_s390x_linux)
397 /* make a stack frame */
398 sp -= 160;
399 sp &= ~((Addr)0xF);
400 *(UWord *)sp = 0;
401 #endif
403 /* If we can't even allocate the first thread's stack, we're hosed.
404 Give up. */
405 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
407 /* shouldn't be any other threads around yet */
408 vg_assert( VG_(count_living_threads)() == 1 );
410 ML_(call_on_new_stack_0_1)(
411 (Addr)sp, /* stack */
412 0, /* bogus return address */
413 run_a_thread_NORETURN, /* fn to call */
414 (Word)tid /* arg to give it */
417 /*NOTREACHED*/
418 vg_assert(0);
421 /* Clone a new thread. Note that in the clone syscalls, we hard-code
422 tlsaddr argument as NULL : the guest TLS is emulated via guest
423 registers, and Valgrind itself has no thread local storage. */
424 static SysRes clone_new_thread ( Word (*fn)(void *),
425 void* stack,
426 Word flags,
427 ThreadState* ctst,
428 Int* child_tidptr,
429 Int* parent_tidptr)
431 SysRes res;
432 /* Note that in all the below, we make sys_clone appear to have returned
433 Success(0) in the child, by assigning the relevant child guest
434 register(s) just before the clone syscall. */
435 #if defined(VGP_x86_linux)
436 Int eax;
437 ctst->arch.vex.guest_EAX = 0;
438 eax = do_syscall_clone_x86_linux
439 (ML_(start_thread_NORETURN), stack, flags, ctst,
440 child_tidptr, parent_tidptr, NULL);
441 res = VG_(mk_SysRes_x86_linux)( eax );
442 #elif defined(VGP_amd64_linux)
443 Long rax;
444 ctst->arch.vex.guest_RAX = 0;
445 rax = do_syscall_clone_amd64_linux
446 (ML_(start_thread_NORETURN), stack, flags, ctst,
447 child_tidptr, parent_tidptr, NULL);
448 res = VG_(mk_SysRes_amd64_linux)( rax );
449 #elif defined(VGP_ppc32_linux)
450 ULong word64;
451 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
452 /* %r3 = 0 */
453 ctst->arch.vex.guest_GPR3 = 0;
454 /* %cr0.so = 0 */
455 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
456 word64 = do_syscall_clone_ppc32_linux
457 (ML_(start_thread_NORETURN), stack, flags, ctst,
458 child_tidptr, parent_tidptr, NULL);
459 /* High half word64 is syscall return value. Low half is
460 the entire CR, from which we need to extract CR0.SO. */
461 /* VG_(printf)("word64 = 0x%llx\n", word64); */
462 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
463 /*errflag*/ (((UInt)word64) >> 28) & 1);
464 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
465 ULong word64;
466 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
467 /* %r3 = 0 */
468 ctst->arch.vex.guest_GPR3 = 0;
469 /* %cr0.so = 0 */
470 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
471 word64 = do_syscall_clone_ppc64_linux
472 (ML_(start_thread_NORETURN), stack, flags, ctst,
473 child_tidptr, parent_tidptr, NULL);
474 /* Low half word64 is syscall return value. Hi half is
475 the entire CR, from which we need to extract CR0.SO. */
476 /* VG_(printf)("word64 = 0x%llx\n", word64); */
477 res = VG_(mk_SysRes_ppc64_linux)
478 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
479 /*errflag*/ (UInt)((word64 >> (32+28)) & 1));
480 #elif defined(VGP_s390x_linux)
481 ULong r2;
482 ctst->arch.vex.guest_r2 = 0;
483 r2 = do_syscall_clone_s390x_linux
484 (stack, flags, parent_tidptr, child_tidptr, NULL,
485 ML_(start_thread_NORETURN), ctst);
486 res = VG_(mk_SysRes_s390x_linux)( r2 );
487 #elif defined(VGP_arm64_linux)
488 ULong x0;
489 ctst->arch.vex.guest_X0 = 0;
490 x0 = do_syscall_clone_arm64_linux
491 (ML_(start_thread_NORETURN), stack, flags, ctst,
492 child_tidptr, parent_tidptr, NULL);
493 res = VG_(mk_SysRes_arm64_linux)( x0 );
494 #elif defined(VGP_arm_linux)
495 UInt r0;
496 ctst->arch.vex.guest_R0 = 0;
497 r0 = do_syscall_clone_arm_linux
498 (ML_(start_thread_NORETURN), stack, flags, ctst,
499 child_tidptr, parent_tidptr, NULL);
500 res = VG_(mk_SysRes_arm_linux)( r0 );
501 #elif defined(VGP_mips64_linux)
502 UInt ret = 0;
503 ctst->arch.vex.guest_r2 = 0;
504 ctst->arch.vex.guest_r7 = 0;
505 ret = do_syscall_clone_mips64_linux
506 (ML_(start_thread_NORETURN), stack, flags, ctst,
507 parent_tidptr, NULL, child_tidptr);
508 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
509 #elif defined(VGP_mips32_linux)
510 UInt ret = 0;
511 ctst->arch.vex.guest_r2 = 0;
512 ctst->arch.vex.guest_r7 = 0;
513 ret = do_syscall_clone_mips_linux
514 (ML_(start_thread_NORETURN), stack, flags, ctst,
515 child_tidptr, parent_tidptr, NULL);
516 /* High half word64 is syscall return value. Low half is
517 the entire CR, from which we need to extract CR0.SO. */
518 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
519 #else
520 # error Unknown platform
521 #endif
522 return res;
525 static void setup_child ( /*OUT*/ ThreadArchState *child,
526 /*IN*/ ThreadArchState *parent )
528 /* We inherit our parent's guest state. */
529 child->vex = parent->vex;
530 child->vex_shadow1 = parent->vex_shadow1;
531 child->vex_shadow2 = parent->vex_shadow2;
533 #if defined(VGP_x86_linux)
534 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
535 /*IN*/ ThreadArchState *parent );
536 ML_(x86_setup_LDT_GDT)(child, parent);
537 #endif
540 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
542 static const Bool debug = False;
543 ThreadState* ctst = VG_(get_ThreadState)(ctid);
544 // res is succesful by default, overriden if a real syscall is needed/done.
545 SysRes res = VG_(mk_SysRes_Success)(0);
547 if (debug)
548 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
550 #if defined(VGP_x86_linux)
551 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
552 if (debug)
553 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
554 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
555 tlsinfo, tlsinfo->entry_number,
556 tlsinfo->base_addr, tlsinfo->limit,
557 ctst->arch.vex.guest_ESP,
558 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
559 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
560 #elif defined(VGP_amd64_linux)
561 ctst->arch.vex.guest_FS_CONST = tlsaddr;
562 #elif defined(VGP_ppc32_linux)
563 ctst->arch.vex.guest_GPR2 = tlsaddr;
564 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
565 ctst->arch.vex.guest_GPR13 = tlsaddr;
566 #elif defined(VGP_s390x_linux)
567 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
568 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
569 #elif defined(VGP_arm64_linux)
570 /* Just assign the tls pointer in the guest TPIDR_EL0. */
571 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
572 #elif defined(VGP_arm_linux)
573 /* Just assign the tls pointer in the guest TPIDRURO. */
574 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
575 #elif defined(VGP_mips64_linux)
576 ctst->arch.vex.guest_ULR = tlsaddr;
577 ctst->arch.vex.guest_r27 = tlsaddr;
578 #elif defined(VGP_mips32_linux)
579 ctst->arch.vex.guest_ULR = tlsaddr;
580 ctst->arch.vex.guest_r27 = tlsaddr;
581 #else
582 # error Unknown platform
583 #endif
584 return res;
588 When a client clones, we need to keep track of the new thread. This means:
589 1. allocate a ThreadId+ThreadState+stack for the thread
591 2. initialize the thread's new VCPU state
593 3. create the thread using the same args as the client requested,
594 but using the scheduler entrypoint for EIP, and a separate stack
595 for ESP.
597 static SysRes do_clone ( ThreadId ptid,
598 UWord flags, Addr sp,
599 Int* parent_tidptr,
600 Int* child_tidptr,
601 Addr tlsaddr)
603 ThreadId ctid = VG_(alloc_ThreadState)();
604 ThreadState* ptst = VG_(get_ThreadState)(ptid);
605 ThreadState* ctst = VG_(get_ThreadState)(ctid);
606 UWord* stack;
607 SysRes res;
608 vki_sigset_t blockall, savedmask;
610 VG_(sigfillset)(&blockall);
612 vg_assert(VG_(is_running_thread)(ptid));
613 vg_assert(VG_(is_valid_tid)(ctid));
615 stack = (UWord*)ML_(allocstack)(ctid);
616 if (stack == NULL) {
617 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
618 goto out;
621 /* Copy register state
623 Both parent and child return to the same place, and the code
624 following the clone syscall works out which is which, so we
625 don't need to worry about it.
627 The parent gets the child's new tid returned from clone, but the
628 child gets 0.
630 If the clone call specifies a NULL sp for the new thread, then
631 it actually gets a copy of the parent's sp.
633 setup_child( &ctst->arch, &ptst->arch );
635 if (sp != 0)
636 VG_(set_SP)(ctid, sp);
638 ctst->os_state.parent = ptid;
640 /* inherit signal mask */
641 ctst->sig_mask = ptst->sig_mask;
642 ctst->tmp_sig_mask = ptst->sig_mask;
644 /* Start the child with its threadgroup being the same as the
645 parent's. This is so that any exit_group calls that happen
646 after the child is created but before it sets its
647 os_state.threadgroup field for real (in thread_wrapper in
648 syswrap-linux.c), really kill the new thread. a.k.a this avoids
649 a race condition in which the thread is unkillable (via
650 exit_group) because its threadgroup is not set. The race window
651 is probably only a few hundred or a few thousand cycles long.
652 See #226116. */
653 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
655 ML_(guess_and_register_stack) (sp, ctst);
657 /* Assume the clone will succeed, and tell any tool that wants to
658 know that this thread has come into existence. We cannot defer
659 it beyond this point because setup_tls, just below,
660 causes checks to assert by making references to the new ThreadId
661 if we don't state the new thread exists prior to that point.
662 If the clone fails, we'll send out a ll_exit notification for it
663 at the out: label below, to clean up. */
664 vg_assert(VG_(owns_BigLock_LL)(ptid));
665 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
667 if (flags & VKI_CLONE_SETTLS) {
668 res = setup_child_tls(ctid, tlsaddr);
669 if (sr_isError(res))
670 goto out;
672 flags &= ~VKI_CLONE_SETTLS;
674 /* start the thread with everything blocked */
675 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
677 /* Create the new thread */
678 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
679 child_tidptr, parent_tidptr);
681 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
683 out:
684 if (sr_isError(res)) {
685 /* clone failed */
686 VG_(cleanup_thread)(&ctst->arch);
687 ctst->status = VgTs_Empty;
688 /* oops. Better tell the tool the thread exited in a hurry :-) */
689 VG_TRACK( pre_thread_ll_exit, ctid );
692 return res;
695 /* Do a clone which is really a fork().
696 ML_(do_fork_clone) uses the clone syscall to fork a child process.
697 Note that this should not be called for a thread creation.
698 Also, some flags combinations are not supported, and such combinations
699 are handled either by masking the non supported flags or by asserting.
701 The CLONE_VFORK flag is accepted, as this just tells that the parent is
702 suspended till the child exits or calls execve. We better keep this flag,
703 just in case the guests parent/client code depends on this synchronisation.
705 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
706 instructions in the child process, that will mess up the parent host
707 memory. So, we hope for the best and assumes that the guest application does
708 not (really) depends on sharing the memory between parent and child in the
709 interval between clone and exits/execve.
711 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
712 clone syscall, before child guest instructions are executed. */
713 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
714 Int* parent_tidptr, Int* child_tidptr,
715 Addr child_sp)
717 vki_sigset_t fork_saved_mask;
718 vki_sigset_t mask;
719 SysRes res;
721 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
722 | VKI_CLONE_FILES))
723 return VG_(mk_SysRes_Error)( VKI_EINVAL );
725 /* Block all signals during fork, so that we can fix things up in
726 the child without being interrupted. */
727 VG_(sigfillset)(&mask);
728 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
730 VG_(do_atfork_pre)(tid);
732 /* Since this is the fork() form of clone, we don't need all that
733 VG_(clone) stuff */
734 #if defined(VGP_x86_linux) \
735 || defined(VGP_ppc32_linux) \
736 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
737 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
738 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
739 res = VG_(do_syscall5)( __NR_clone, flags,
740 (UWord)NULL, (UWord)parent_tidptr,
741 (UWord)NULL, (UWord)child_tidptr );
742 #elif defined(VGP_amd64_linux)
743 /* note that the last two arguments are the opposite way round to x86 and
744 ppc32 as the amd64 kernel expects the arguments in a different order */
745 res = VG_(do_syscall5)( __NR_clone, flags,
746 (UWord)NULL, (UWord)parent_tidptr,
747 (UWord)child_tidptr, (UWord)NULL );
748 #elif defined(VGP_s390x_linux)
749 /* Note that s390 has the stack first and then the flags */
750 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
751 (UWord)parent_tidptr, (UWord)child_tidptr);
752 #else
753 # error Unknown platform
754 #endif
756 if (!sr_isError(res) && sr_Res(res) == 0) {
757 /* child */
758 if (child_sp != 0)
759 VG_(set_SP)(tid, child_sp);
760 VG_(do_atfork_child)(tid);
762 /* restore signal mask */
763 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
765 else
766 if (!sr_isError(res) && sr_Res(res) > 0) {
767 /* parent */
768 VG_(do_atfork_parent)(tid);
770 if (VG_(clo_trace_syscalls))
771 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
772 VG_(getpid)(), (RegWord)sr_Res(res));
774 /* restore signal mask */
775 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
778 return res;
781 /* ---------------------------------------------------------------------
782 PRE/POST wrappers for arch-generic, Linux-specific syscalls
783 ------------------------------------------------------------------ */
785 // Nb: See the comment above the generic PRE/POST wrappers in
786 // m_syswrap/syswrap-generic.c for notes about how they work.
788 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
789 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
791 PRE(sys_clone)
793 UInt cloneflags;
794 Bool badarg = False;
796 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
797 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
798 ARG4, ARG5);
800 // Order of arguments differs between platforms.
801 #if defined(VGP_x86_linux) \
802 || defined(VGP_ppc32_linux) \
803 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
804 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
805 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
806 #define ARG_CHILD_TIDPTR ARG5
807 #define PRA_CHILD_TIDPTR PRA5
808 #define ARG_TLS ARG4
809 #define PRA_TLS PRA4
810 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
811 #define ARG_CHILD_TIDPTR ARG4
812 #define PRA_CHILD_TIDPTR PRA4
813 #define ARG_TLS ARG5
814 #define PRA_TLS PRA5
815 #else
816 # error Unknown platform
817 #endif
818 // And s390x is even more special, and inverts flags and child stack args
819 #if defined(VGP_s390x_linux)
820 #define ARG_FLAGS ARG2
821 #define PRA_FLAGS PRA2
822 #define ARG_CHILD_STACK ARG1
823 #define PRA_CHILD_STACK PRA1
824 #else
825 #define ARG_FLAGS ARG1
826 #define PRA_FLAGS PRA1
827 #define ARG_CHILD_STACK ARG2
828 #define PRA_CHILD_STACK PRA2
829 #endif
831 if (VG_(tdict).track_pre_reg_read) {
832 PRA_FLAGS("clone", unsigned long, flags);
833 PRA_CHILD_STACK("clone", void *, child_stack);
836 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID) {
837 if (VG_(tdict).track_pre_reg_read) {
838 PRA3("clone", int *, parent_tidptr);
840 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
841 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
842 VKI_PROT_WRITE)) {
843 badarg = True;
846 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
847 if (VG_(tdict).track_pre_reg_read) {
848 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
850 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
851 dummy type (that we define as a char). We only dereference/check the
852 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
853 if (sizeof(vki_modify_ldt_t) > 1) {
854 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
855 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
856 VKI_PROT_READ)) {
857 badarg = True;
861 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
862 if (VG_(tdict).track_pre_reg_read) {
863 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
865 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
866 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
867 VKI_PROT_WRITE)) {
868 badarg = True;
872 if (badarg) {
873 SET_STATUS_Failure( VKI_EFAULT );
874 return;
877 cloneflags = ARG_FLAGS;
879 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
880 SET_STATUS_Failure( VKI_EINVAL );
881 return;
884 /* Only look at the flags we really care about */
885 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
886 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
887 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
888 /* thread creation */
889 SET_STATUS_from_SysRes(
890 do_clone(tid,
891 ARG_FLAGS, /* flags */
892 (Addr)ARG_CHILD_STACK, /* child ESP */
893 (Int*)(Addr)ARG3, /* parent_tidptr */
894 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
895 (Addr)ARG_TLS)); /* set_tls */
896 break;
898 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
899 cloneflags &= ~VKI_CLONE_VM;
900 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
902 case 0: /* plain fork */
903 SET_STATUS_from_SysRes(
904 ML_(do_fork_clone)(tid,
905 cloneflags, /* flags */
906 (Int*)(Addr)ARG3, /* parent_tidptr */
907 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
908 (Addr)ARG_CHILD_STACK));
909 break;
911 default:
912 /* should we just ENOSYS? */
913 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
914 "x\n", ARG_FLAGS);
915 VG_(message)(Vg_UserMsg, "\n");
916 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
917 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
918 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
919 VG_(unimplemented)
920 ("Valgrind does not support general clone().");
923 if (SUCCESS) {
924 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
925 POST_MEM_WRITE(ARG3, sizeof(Int));
926 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
927 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
929 /* Thread creation was successful; let the child have the chance
930 to run */
931 *flags |= SfYieldAfter;
934 #undef ARG_CHILD_TIDPTR
935 #undef PRA_CHILD_TIDPTR
936 #undef ARG_TLS
937 #undef PRA_TLS
938 #undef ARG_FLAGS
939 #undef PRA_FLAGS
940 #undef ARG_CHILD_STACK
941 #undef PRA_CHILD_STACK
944 /* ---------------------------------------------------------------------
945 *mount wrappers
946 ------------------------------------------------------------------ */
948 PRE(sys_mount)
950 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
951 // We are conservative and check everything, except the memory pointed to
952 // by 'data'.
953 *flags |= SfMayBlock;
954 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
955 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
956 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
957 (HChar*)(Addr)ARG3, ARG4, ARG5);
958 PRE_REG_READ5(long, "mount",
959 char *, source, char *, target, char *, type,
960 unsigned long, flags, void *, data);
961 if (ARG1)
962 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
963 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
964 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
967 PRE(sys_oldumount)
969 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
970 PRE_REG_READ1(long, "umount", char *, path);
971 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
974 PRE(sys_umount)
976 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
977 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
978 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
981 /* Not actually wrapped by GLibc but does things with the system
982 * mounts so it is put here.
984 PRE(sys_pivot_root)
986 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
987 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
988 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
989 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
993 /* ---------------------------------------------------------------------
994 16- and 32-bit uid/gid wrappers
995 ------------------------------------------------------------------ */
997 PRE(sys_setfsuid16)
999 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1000 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1003 PRE(sys_setfsuid)
1005 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1006 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1009 PRE(sys_setfsgid16)
1011 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1012 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1015 PRE(sys_setfsgid)
1017 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1018 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1021 PRE(sys_setresuid16)
1023 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1024 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1025 PRE_REG_READ3(long, "setresuid16",
1026 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1029 PRE(sys_setresuid)
1031 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1032 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1033 PRE_REG_READ3(long, "setresuid",
1034 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1037 PRE(sys_getresuid16)
1039 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1040 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1041 PRE_REG_READ3(long, "getresuid16",
1042 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1043 vki_old_uid_t *, suid);
1044 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1045 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1046 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1048 POST(sys_getresuid16)
1050 vg_assert(SUCCESS);
1051 if (RES == 0) {
1052 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1053 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1054 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1058 PRE(sys_getresuid)
1060 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1061 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1062 PRE_REG_READ3(long, "getresuid",
1063 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1064 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1065 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1066 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1068 POST(sys_getresuid)
1070 vg_assert(SUCCESS);
1071 if (RES == 0) {
1072 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1073 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1074 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1078 PRE(sys_setresgid16)
1080 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1081 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1082 PRE_REG_READ3(long, "setresgid16",
1083 vki_old_gid_t, rgid,
1084 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1087 PRE(sys_setresgid)
1089 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1090 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1091 PRE_REG_READ3(long, "setresgid",
1092 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1095 PRE(sys_getresgid16)
1097 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1098 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1099 PRE_REG_READ3(long, "getresgid16",
1100 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1101 vki_old_gid_t *, sgid);
1102 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1103 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1104 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1106 POST(sys_getresgid16)
1108 vg_assert(SUCCESS);
1109 if (RES == 0) {
1110 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1111 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1112 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1116 PRE(sys_getresgid)
1118 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1119 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1120 PRE_REG_READ3(long, "getresgid",
1121 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1122 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1123 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1124 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1126 POST(sys_getresgid)
1128 vg_assert(SUCCESS);
1129 if (RES == 0) {
1130 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1131 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1132 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1136 /* ---------------------------------------------------------------------
1137 miscellaneous wrappers
1138 ------------------------------------------------------------------ */
1140 PRE(sys_exit_group)
1142 ThreadId t;
1143 ThreadState* tst;
1145 PRINT("exit_group( %ld )", SARG1);
1146 PRE_REG_READ1(void, "exit_group", int, status);
1148 tst = VG_(get_ThreadState)(tid);
1149 /* A little complex; find all the threads with the same threadgroup
1150 as this one (including this one), and mark them to exit */
1151 /* It is unclear how one can get a threadgroup in this process which
1152 is not the threadgroup of the calling thread:
1153 The assignments to threadgroups are:
1154 = 0; /// scheduler.c os_state_clear
1155 = getpid(); /// scheduler.c in child after fork
1156 = getpid(); /// this file, in thread_wrapper
1157 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1158 copying the thread group of the thread doing clone
1159 So, the only case where the threadgroup might be different to the getpid
1160 value is in the child, just after fork. But then the fork syscall is
1161 still going on, the forked thread has had no chance yet to make this
1162 syscall. */
1163 for (t = 1; t < VG_N_THREADS; t++) {
1164 if ( /* not alive */
1165 VG_(threads)[t].status == VgTs_Empty
1167 /* not our group */
1168 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1170 continue;
1171 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1172 the exitreason. */
1173 VG_(threads)[t].os_state.exitcode = ARG1;
1176 /* Indicate in all other threads that the process is exiting.
1177 Then wait using VG_(reap_threads) for these threads to disappear.
1179 Can this give a deadlock if another thread is calling exit in parallel
1180 and would then wait for this thread to disappear ?
1181 The answer is no:
1182 Other threads are either blocked in a syscall or have yielded the CPU.
1184 A thread that has yielded the CPU is trying to get the big lock in
1185 VG_(scheduler). This thread will get the CPU thanks to the call
1186 to VG_(reap_threads). The scheduler will then check for signals,
1187 kill the process if this is a fatal signal, and otherwise prepare
1188 the thread for handling this signal. After this preparation, if
1189 the thread status is VG_(is_exiting), the scheduler exits the thread.
1190 So, a thread that has yielded the CPU does not have a chance to
1191 call exit => no deadlock for this thread.
1193 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1194 to all threads blocked in a syscall.
1195 The syscall will be interrupted, and the control will go to the
1196 scheduler. The scheduler will then return, as the thread is in
1197 exiting state. */
1199 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1200 VG_(reap_threads)(tid);
1201 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1202 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1203 is the thread calling exit_group and so its registers must be considered
1204 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1206 /* We have to claim the syscall already succeeded. */
1207 SET_STATUS_Success(0);
1210 PRE(sys_llseek)
1212 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1213 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1214 ARG1, ARG2, ARG3, ARG4, ARG5);
1215 PRE_REG_READ5(long, "llseek",
1216 unsigned int, fd, unsigned long, offset_high,
1217 unsigned long, offset_low, vki_loff_t *, result,
1218 unsigned int, whence);
1219 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1220 SET_STATUS_Failure( VKI_EBADF );
1221 else
1222 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1224 POST(sys_llseek)
1226 vg_assert(SUCCESS);
1227 if (RES == 0)
1228 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1231 PRE(sys_adjtimex)
1233 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1234 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1235 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1237 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1238 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1240 #define ADJX(bits,field) \
1241 if (tx->modes & (bits)) \
1242 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1243 (Addr)&tx->field, sizeof(tx->field))
1245 if (tx->modes & VKI_ADJ_ADJTIME) {
1246 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1247 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1248 } else {
1249 ADJX(VKI_ADJ_OFFSET, offset);
1250 ADJX(VKI_ADJ_FREQUENCY, freq);
1251 ADJX(VKI_ADJ_MAXERROR, maxerror);
1252 ADJX(VKI_ADJ_ESTERROR, esterror);
1253 ADJX(VKI_ADJ_STATUS, status);
1254 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1255 ADJX(VKI_ADJ_TICK, tick);
1257 #undef ADJX
1260 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1263 POST(sys_adjtimex)
1265 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1268 PRE(sys_clock_adjtime)
1270 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1271 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1272 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1273 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1275 #define ADJX(bits,field) \
1276 if (tx->modes & (bits)) \
1277 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1278 (Addr)&tx->field, sizeof(tx->field))
1280 if (tx->modes & VKI_ADJ_ADJTIME) {
1281 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1282 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1283 } else {
1284 ADJX(VKI_ADJ_OFFSET, offset);
1285 ADJX(VKI_ADJ_FREQUENCY, freq);
1286 ADJX(VKI_ADJ_MAXERROR, maxerror);
1287 ADJX(VKI_ADJ_ESTERROR, esterror);
1288 ADJX(VKI_ADJ_STATUS, status);
1289 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1290 ADJX(VKI_ADJ_TICK, tick);
1292 #undef ADJX
1294 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1297 POST(sys_clock_adjtime)
1299 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1302 PRE(sys_ioperm)
1304 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1305 ARG1, ARG2, SARG3 );
1306 PRE_REG_READ3(long, "ioperm",
1307 unsigned long, from, unsigned long, num, int, turn_on);
1310 PRE(sys_syslog)
1312 *flags |= SfMayBlock;
1313 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1314 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1315 switch (ARG1) {
1316 // The kernel uses magic numbers here, rather than named constants,
1317 // therefore so do we.
1318 case 2: case 3: case 4:
1319 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1320 break;
1321 default:
1322 break;
1325 POST(sys_syslog)
1327 switch (ARG1) {
1328 case 2: case 3: case 4:
1329 POST_MEM_WRITE( ARG2, ARG3 );
1330 break;
1331 default:
1332 break;
1336 PRE(sys_vhangup)
1338 PRINT("sys_vhangup ( )");
1339 PRE_REG_READ0(long, "vhangup");
1342 PRE(sys_sysinfo)
1344 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1345 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1346 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1348 POST(sys_sysinfo)
1350 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1353 PRE(sys_personality)
1355 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1356 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1359 PRE(sys_sysctl)
1361 struct __vki_sysctl_args *args;
1362 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1363 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1364 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1365 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1366 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1367 VKI_PROT_READ)) {
1368 SET_STATUS_Failure( VKI_EFAULT );
1369 return;
1372 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1373 if (args->newval != NULL)
1374 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1375 if (args->oldlenp != NULL) {
1376 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1377 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1380 POST(sys_sysctl)
1382 struct __vki_sysctl_args *args;
1383 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1384 if (args->oldlenp != NULL) {
1385 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1386 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1390 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1391 const char *attr_name)
1393 const HChar *step_str = (const HChar *)str;
1394 SizeT len;
1395 UInt i;
1398 * The name can be up to maxlen bytes long, including the terminating null
1399 * byte. So do not check more than maxlen bytes.
1401 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1402 len = VG_(strnlen)((const HChar *)str, maxlen);
1403 if (len < maxlen)
1404 PRE_MEM_RASCIIZ(attr_name, str);
1405 else
1406 PRE_MEM_READ(attr_name, str, maxlen);
1407 } else {
1409 * Do it the slow way, one byte at a time, while checking for terminating
1410 * '\0'.
1412 for (i = 0; i < maxlen; i++) {
1413 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1414 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1415 break;
1420 PRE(sys_prctl)
1422 *flags |= SfMayBlock;
1423 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1424 switch (ARG1) {
1425 case VKI_PR_SET_PDEATHSIG:
1426 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1427 break;
1428 case VKI_PR_GET_PDEATHSIG:
1429 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1430 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1431 break;
1432 case VKI_PR_GET_DUMPABLE:
1433 PRE_REG_READ1(int, "prctl", int, option);
1434 break;
1435 case VKI_PR_SET_DUMPABLE:
1436 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1437 break;
1438 case VKI_PR_GET_UNALIGN:
1439 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1440 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1441 break;
1442 case VKI_PR_SET_UNALIGN:
1443 PRE_REG_READ2(int, "prctl", int, option, int, value);
1444 break;
1445 case VKI_PR_GET_KEEPCAPS:
1446 PRE_REG_READ1(int, "prctl", int, option);
1447 break;
1448 case VKI_PR_SET_KEEPCAPS:
1449 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1450 break;
1451 case VKI_PR_GET_FPEMU:
1452 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1453 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1454 break;
1455 case VKI_PR_SET_FPEMU:
1456 PRE_REG_READ2(int, "prctl", int, option, int, value);
1457 break;
1458 case VKI_PR_GET_FPEXC:
1459 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1460 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1461 break;
1462 case VKI_PR_SET_FPEXC:
1463 PRE_REG_READ2(int, "prctl", int, option, int, value);
1464 break;
1465 case VKI_PR_GET_TIMING:
1466 PRE_REG_READ1(int, "prctl", int, option);
1467 break;
1468 case VKI_PR_SET_TIMING:
1469 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1470 break;
1471 case VKI_PR_SET_NAME:
1472 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1473 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1474 break;
1475 case VKI_PR_GET_NAME:
1476 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1477 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1478 break;
1479 case VKI_PR_GET_ENDIAN:
1480 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1481 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1482 break;
1483 case VKI_PR_SET_ENDIAN:
1484 PRE_REG_READ2(int, "prctl", int, option, int, value);
1485 break;
1486 case VKI_PR_SET_PTRACER:
1487 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1488 break;
1489 case VKI_PR_SET_SECCOMP:
1490 /* This is a bit feeble in that it uses |option| before checking
1491 it, but at least both sides of the conditional check it. */
1492 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1493 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1494 if (ARG3) {
1495 /* Should check that ARG3 points at a valid struct sock_fprog.
1496 Sounds complex; hence be lame. */
1497 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1498 ARG3, 1 );
1500 } else {
1501 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1503 break;
1504 default:
1505 PRE_REG_READ5(long, "prctl",
1506 int, option, unsigned long, arg2, unsigned long, arg3,
1507 unsigned long, arg4, unsigned long, arg5);
1508 break;
1511 POST(sys_prctl)
1513 switch (ARG1) {
1514 case VKI_PR_GET_PDEATHSIG:
1515 POST_MEM_WRITE(ARG2, sizeof(Int));
1516 break;
1517 case VKI_PR_GET_UNALIGN:
1518 POST_MEM_WRITE(ARG2, sizeof(Int));
1519 break;
1520 case VKI_PR_GET_FPEMU:
1521 POST_MEM_WRITE(ARG2, sizeof(Int));
1522 break;
1523 case VKI_PR_GET_FPEXC:
1524 POST_MEM_WRITE(ARG2, sizeof(Int));
1525 break;
1526 case VKI_PR_GET_NAME:
1527 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1528 break;
1529 case VKI_PR_GET_ENDIAN:
1530 POST_MEM_WRITE(ARG2, sizeof(Int));
1531 break;
1532 case VKI_PR_SET_NAME:
1534 const HChar* new_name = (const HChar*) (Addr)ARG2;
1535 if (new_name) { // Paranoia
1536 ThreadState* tst = VG_(get_ThreadState)(tid);
1537 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1539 /* Don't bother reusing the memory. This is a rare event. */
1540 tst->thread_name =
1541 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1542 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1545 break;
1549 PRE(sys_sendfile)
1551 *flags |= SfMayBlock;
1552 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1553 SARG1, SARG2, ARG3, ARG4);
1554 PRE_REG_READ4(ssize_t, "sendfile",
1555 int, out_fd, int, in_fd, vki_off_t *, offset,
1556 vki_size_t, count);
1557 if (ARG3 != 0)
1558 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1560 POST(sys_sendfile)
1562 if (ARG3 != 0 ) {
1563 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1567 PRE(sys_sendfile64)
1569 *flags |= SfMayBlock;
1570 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1571 SARG1, SARG2, ARG3, ARG4);
1572 PRE_REG_READ4(ssize_t, "sendfile64",
1573 int, out_fd, int, in_fd, vki_loff_t *, offset,
1574 vki_size_t, count);
1575 if (ARG3 != 0)
1576 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1578 POST(sys_sendfile64)
1580 if (ARG3 != 0 ) {
1581 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1585 PRE(sys_futex)
1588 arg param used by ops
1590 ARG1 - u32 *futex all
1591 ARG2 - int op
1592 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1593 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1594 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1595 ARG6 - int val3 CMP_REQUEUE
1597 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1598 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1599 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1600 case VKI_FUTEX_CMP_REQUEUE:
1601 case VKI_FUTEX_WAKE_OP:
1602 case VKI_FUTEX_CMP_REQUEUE_PI:
1603 PRE_REG_READ6(long, "futex",
1604 vki_u32 *, futex, int, op, int, val,
1605 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1606 break;
1607 case VKI_FUTEX_REQUEUE:
1608 case VKI_FUTEX_WAIT_REQUEUE_PI:
1609 PRE_REG_READ5(long, "futex",
1610 vki_u32 *, futex, int, op, int, val,
1611 struct timespec *, utime, vki_u32 *, uaddr2);
1612 break;
1613 case VKI_FUTEX_WAIT_BITSET:
1614 /* Check that the address at least begins in client-accessible area. */
1615 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1616 SET_STATUS_Failure( VKI_EFAULT );
1617 return;
1619 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1620 PRE_REG_READ4(long, "futex",
1621 vki_u32 *, futex, int, op, int, val,
1622 struct timespec *, utime);
1623 } else {
1624 /* Note argument 5 is unused, but argument 6 is used.
1625 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1626 PRE_REG_READ4(long, "futex",
1627 vki_u32 *, futex, int, op, int, val,
1628 struct timespec *, utime);
1629 if (VG_(tdict).track_pre_reg_read)
1630 PRA6("futex",int,val3);
1632 break;
1633 case VKI_FUTEX_WAKE_BITSET:
1634 PRE_REG_READ3(long, "futex",
1635 vki_u32 *, futex, int, op, int, val);
1636 if (VG_(tdict).track_pre_reg_read) {
1637 PRA6("futex", int, val3);
1639 break;
1640 case VKI_FUTEX_WAIT:
1641 case VKI_FUTEX_LOCK_PI:
1642 PRE_REG_READ4(long, "futex",
1643 vki_u32 *, futex, int, op, int, val,
1644 struct timespec *, utime);
1645 break;
1646 case VKI_FUTEX_WAKE:
1647 case VKI_FUTEX_FD:
1648 PRE_REG_READ3(long, "futex",
1649 vki_u32 *, futex, int, op, int, val);
1650 break;
1651 case VKI_FUTEX_TRYLOCK_PI:
1652 case VKI_FUTEX_UNLOCK_PI:
1653 default:
1654 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1655 break;
1658 *flags |= SfMayBlock;
1660 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1661 case VKI_FUTEX_WAIT:
1662 case VKI_FUTEX_LOCK_PI:
1663 case VKI_FUTEX_WAIT_BITSET:
1664 case VKI_FUTEX_WAIT_REQUEUE_PI:
1665 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1666 if (ARG4 != 0)
1667 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1668 break;
1670 case VKI_FUTEX_REQUEUE:
1671 case VKI_FUTEX_CMP_REQUEUE:
1672 case VKI_FUTEX_CMP_REQUEUE_PI:
1673 case VKI_FUTEX_WAKE_OP:
1674 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1675 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1676 break;
1678 case VKI_FUTEX_FD:
1679 case VKI_FUTEX_TRYLOCK_PI:
1680 case VKI_FUTEX_UNLOCK_PI:
1681 case VKI_FUTEX_WAKE:
1682 case VKI_FUTEX_WAKE_BITSET:
1683 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1684 break;
1686 default:
1687 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1688 break;
1691 POST(sys_futex)
1693 vg_assert(SUCCESS);
1694 POST_MEM_WRITE( ARG1, sizeof(int) );
1695 if (ARG2 == VKI_FUTEX_FD) {
1696 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1697 VG_(close)(RES);
1698 SET_STATUS_Failure( VKI_EMFILE );
1699 } else {
1700 if (VG_(clo_track_fds))
1701 ML_(record_fd_open_nameless)(tid, RES);
1706 PRE(sys_set_robust_list)
1708 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1709 FMT_REGWORD "u )", ARG1, ARG2);
1710 PRE_REG_READ2(long, "set_robust_list",
1711 struct vki_robust_list_head *, head, vki_size_t, len);
1713 /* Just check the robust_list_head structure is readable - don't
1714 try and chase the list as the kernel will only read it when
1715 the thread exits so the current contents is irrelevant. */
1716 if (ARG1 != 0)
1717 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1720 PRE(sys_get_robust_list)
1722 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1723 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1724 PRE_REG_READ3(long, "get_robust_list",
1725 int, pid,
1726 struct vki_robust_list_head **, head_ptr,
1727 vki_size_t *, len_ptr);
1728 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1729 ARG2, sizeof(struct vki_robust_list_head *));
1730 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1731 ARG3, sizeof(struct vki_size_t *));
1733 POST(sys_get_robust_list)
1735 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1736 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1739 struct pselect_sized_sigset {
1740 const vki_sigset_t *ss;
1741 vki_size_t ss_len;
1743 struct pselect_adjusted_sigset {
1744 struct pselect_sized_sigset ss; /* The actual syscall arg */
1745 vki_sigset_t adjusted_ss;
1748 PRE(sys_pselect6)
1750 *flags |= SfMayBlock | SfPostOnFail;
1751 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1752 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1753 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1754 PRE_REG_READ6(long, "pselect6",
1755 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1756 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1757 void *, sig);
1758 // XXX: this possibly understates how much memory is read.
1759 if (ARG2 != 0)
1760 PRE_MEM_READ( "pselect6(readfds)",
1761 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1762 if (ARG3 != 0)
1763 PRE_MEM_READ( "pselect6(writefds)",
1764 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1765 if (ARG4 != 0)
1766 PRE_MEM_READ( "pselect6(exceptfds)",
1767 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1768 if (ARG5 != 0)
1769 PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1770 if (ARG6 != 0) {
1771 const struct pselect_sized_sigset *pss =
1772 (struct pselect_sized_sigset *)(Addr)ARG6;
1773 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1774 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1775 ARG6 = 1; /* Something recognisable to POST() hook. */
1776 } else {
1777 struct pselect_adjusted_sigset *pas;
1778 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1779 ARG6 = (Addr)pas;
1780 pas->ss.ss = (void *)1;
1781 pas->ss.ss_len = pss->ss_len;
1782 if (pss->ss_len == sizeof(*pss->ss)) {
1783 if (pss->ss == NULL) {
1784 pas->ss.ss = NULL;
1785 } else {
1786 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1787 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1788 pas->adjusted_ss = *pss->ss;
1789 pas->ss.ss = &pas->adjusted_ss;
1790 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1797 POST(sys_pselect6)
1799 if (ARG6 != 0 && ARG6 != 1) {
1800 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1804 PRE(sys_ppoll)
1806 UInt i;
1807 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1808 *flags |= SfMayBlock | SfPostOnFail;
1809 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1810 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1811 ARG1, ARG2, ARG3, ARG4, ARG5);
1812 PRE_REG_READ5(long, "ppoll",
1813 struct vki_pollfd *, ufds, unsigned int, nfds,
1814 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1815 vki_size_t, sigsetsize);
1817 for (i = 0; i < ARG2; i++) {
1818 PRE_MEM_READ( "ppoll(ufds.fd)",
1819 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1820 PRE_MEM_READ( "ppoll(ufds.events)",
1821 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1822 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1823 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1826 if (ARG3)
1827 PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1828 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1829 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1830 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1831 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1832 ARG4 = 1; /* Something recognisable to POST() hook. */
1833 } else {
1834 vki_sigset_t *vg_sigmask =
1835 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1836 ARG4 = (Addr)vg_sigmask;
1837 *vg_sigmask = *guest_sigmask;
1838 VG_(sanitize_client_sigmask)(vg_sigmask);
1843 POST(sys_ppoll)
1845 vg_assert(SUCCESS || FAILURE);
1846 if (SUCCESS && (RES >= 0)) {
1847 UInt i;
1848 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1849 for (i = 0; i < ARG2; i++)
1850 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1852 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1853 VG_(free)((vki_sigset_t *) (Addr)ARG4);
1858 /* ---------------------------------------------------------------------
1859 epoll_* wrappers
1860 ------------------------------------------------------------------ */
1862 PRE(sys_epoll_create)
1864 PRINT("sys_epoll_create ( %ld )", SARG1);
1865 PRE_REG_READ1(long, "epoll_create", int, size);
1867 POST(sys_epoll_create)
1869 vg_assert(SUCCESS);
1870 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1871 VG_(close)(RES);
1872 SET_STATUS_Failure( VKI_EMFILE );
1873 } else {
1874 if (VG_(clo_track_fds))
1875 ML_(record_fd_open_nameless) (tid, RES);
1879 PRE(sys_epoll_create1)
1881 PRINT("sys_epoll_create1 ( %ld )", SARG1);
1882 PRE_REG_READ1(long, "epoll_create1", int, flags);
1884 POST(sys_epoll_create1)
1886 vg_assert(SUCCESS);
1887 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1888 VG_(close)(RES);
1889 SET_STATUS_Failure( VKI_EMFILE );
1890 } else {
1891 if (VG_(clo_track_fds))
1892 ML_(record_fd_open_nameless) (tid, RES);
1896 PRE(sys_epoll_ctl)
1898 static const HChar* epoll_ctl_s[3] = {
1899 "EPOLL_CTL_ADD",
1900 "EPOLL_CTL_DEL",
1901 "EPOLL_CTL_MOD"
1903 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
1904 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1905 PRE_REG_READ4(long, "epoll_ctl",
1906 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1907 if (ARG2 != VKI_EPOLL_CTL_DEL)
1908 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1911 PRE(sys_epoll_wait)
1913 *flags |= SfMayBlock;
1914 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
1915 SARG1, ARG2, SARG3, SARG4);
1916 PRE_REG_READ4(long, "epoll_wait",
1917 int, epfd, struct vki_epoll_event *, events,
1918 int, maxevents, int, timeout);
1919 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1921 POST(sys_epoll_wait)
1923 vg_assert(SUCCESS);
1924 if (RES > 0)
1925 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1928 PRE(sys_epoll_pwait)
1930 *flags |= SfMayBlock;
1931 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
1932 FMT_REGWORD "x, %" FMT_REGWORD "u )",
1933 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1934 PRE_REG_READ6(long, "epoll_pwait",
1935 int, epfd, struct vki_epoll_event *, events,
1936 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1937 vki_size_t, sigsetsize);
1938 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1939 if (ARG5)
1940 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1942 POST(sys_epoll_pwait)
1944 vg_assert(SUCCESS);
1945 if (RES > 0)
1946 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1949 PRE(sys_eventfd)
1951 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
1952 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1954 POST(sys_eventfd)
1956 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1957 VG_(close)(RES);
1958 SET_STATUS_Failure( VKI_EMFILE );
1959 } else {
1960 if (VG_(clo_track_fds))
1961 ML_(record_fd_open_nameless) (tid, RES);
1965 PRE(sys_eventfd2)
1967 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
1968 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1970 POST(sys_eventfd2)
1972 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1973 VG_(close)(RES);
1974 SET_STATUS_Failure( VKI_EMFILE );
1975 } else {
1976 if (VG_(clo_track_fds))
1977 ML_(record_fd_open_nameless) (tid, RES);
1981 PRE(sys_fallocate)
1983 *flags |= SfMayBlock;
1984 #if VG_WORDSIZE == 4
1985 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1986 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
1987 PRE_REG_READ6(long, "fallocate",
1988 int, fd, int, mode,
1989 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1990 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1991 #elif VG_WORDSIZE == 8
1992 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
1993 SARG1, SARG2, SARG3, SARG4);
1994 PRE_REG_READ4(long, "fallocate",
1995 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
1996 #else
1997 # error Unexpected word size
1998 #endif
1999 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2000 SET_STATUS_Failure( VKI_EBADF );
2003 PRE(sys_prlimit64)
2005 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2006 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2007 PRE_REG_READ4(long, "prlimit64",
2008 vki_pid_t, pid, unsigned int, resource,
2009 const struct rlimit64 *, new_rlim,
2010 struct rlimit64 *, old_rlim);
2011 if (ARG3)
2012 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2013 if (ARG4)
2014 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2016 if (ARG3 &&
2017 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2018 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2019 SET_STATUS_Failure( VKI_EINVAL );
2021 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2022 switch (ARG2) {
2023 case VKI_RLIMIT_NOFILE:
2024 SET_STATUS_Success( 0 );
2025 if (ARG4) {
2026 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2027 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2029 if (ARG3) {
2030 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2031 > VG_(fd_hard_limit) ||
2032 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2033 != VG_(fd_hard_limit)) {
2034 SET_STATUS_Failure( VKI_EPERM );
2036 else {
2037 VG_(fd_soft_limit) =
2038 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2041 break;
2043 case VKI_RLIMIT_DATA:
2044 SET_STATUS_Success( 0 );
2045 if (ARG4) {
2046 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2047 VG_(client_rlimit_data).rlim_cur;
2048 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2049 VG_(client_rlimit_data).rlim_max;
2051 if (ARG3) {
2052 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2053 > VG_(client_rlimit_data).rlim_max ||
2054 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2055 > VG_(client_rlimit_data).rlim_max) {
2056 SET_STATUS_Failure( VKI_EPERM );
2058 else {
2059 VG_(client_rlimit_data).rlim_cur =
2060 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2061 VG_(client_rlimit_data).rlim_max =
2062 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2065 break;
2067 case VKI_RLIMIT_STACK:
2068 SET_STATUS_Success( 0 );
2069 if (ARG4) {
2070 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2071 VG_(client_rlimit_stack).rlim_cur;
2072 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2073 VG_(client_rlimit_stack).rlim_max;
2075 if (ARG3) {
2076 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2077 > VG_(client_rlimit_stack).rlim_max ||
2078 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2079 > VG_(client_rlimit_stack).rlim_max) {
2080 SET_STATUS_Failure( VKI_EPERM );
2082 else {
2083 VG_(threads)[tid].client_stack_szB =
2084 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2085 VG_(client_rlimit_stack).rlim_cur =
2086 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2087 VG_(client_rlimit_stack).rlim_max =
2088 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2091 break;
2096 POST(sys_prlimit64)
2098 if (ARG4)
2099 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2102 /* ---------------------------------------------------------------------
2103 tid-related wrappers
2104 ------------------------------------------------------------------ */
2106 PRE(sys_gettid)
2108 PRINT("sys_gettid ()");
2109 PRE_REG_READ0(long, "gettid");
2112 PRE(sys_set_tid_address)
2114 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2115 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2118 PRE(sys_tkill)
2120 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2121 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2122 if (!ML_(client_signal_OK)(ARG2)) {
2123 SET_STATUS_Failure( VKI_EINVAL );
2124 return;
2127 /* Check to see if this kill gave us a pending signal */
2128 *flags |= SfPollAfter;
2130 if (VG_(clo_trace_signals))
2131 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2132 SARG2, SARG1);
2134 /* If we're sending SIGKILL, check to see if the target is one of
2135 our threads and handle it specially. */
2136 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2137 SET_STATUS_Success(0);
2138 return;
2141 /* Ask to handle this syscall via the slow route, since that's the
2142 only one that sets tst->status to VgTs_WaitSys. If the result
2143 of doing the syscall is an immediate run of
2144 async_signalhandler() in m_signals, then we need the thread to
2145 be properly tidied away. I have the impression the previous
2146 version of this wrapper worked on x86/amd64 only because the
2147 kernel did not immediately deliver the async signal to this
2148 thread (on ppc it did, which broke the assertion re tst->status
2149 at the top of async_signalhandler()). */
2150 *flags |= SfMayBlock;
2152 POST(sys_tkill)
2154 if (VG_(clo_trace_signals))
2155 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2156 SARG2, SARG1);
2159 PRE(sys_tgkill)
2161 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2162 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2163 if (!ML_(client_signal_OK)(ARG3)) {
2164 SET_STATUS_Failure( VKI_EINVAL );
2165 return;
2168 /* Check to see if this kill gave us a pending signal */
2169 *flags |= SfPollAfter;
2171 if (VG_(clo_trace_signals))
2172 VG_(message)(Vg_DebugMsg,
2173 "tgkill: sending signal %ld to pid %ld/%ld\n",
2174 SARG3, SARG1, SARG2);
2176 /* If we're sending SIGKILL, check to see if the target is one of
2177 our threads and handle it specially. */
2178 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2179 SET_STATUS_Success(0);
2180 return;
2183 /* Ask to handle this syscall via the slow route, since that's the
2184 only one that sets tst->status to VgTs_WaitSys. If the result
2185 of doing the syscall is an immediate run of
2186 async_signalhandler() in m_signals, then we need the thread to
2187 be properly tidied away. I have the impression the previous
2188 version of this wrapper worked on x86/amd64 only because the
2189 kernel did not immediately deliver the async signal to this
2190 thread (on ppc it did, which broke the assertion re tst->status
2191 at the top of async_signalhandler()). */
2192 *flags |= SfMayBlock;
2194 POST(sys_tgkill)
2196 if (VG_(clo_trace_signals))
2197 VG_(message)(Vg_DebugMsg,
2198 "tgkill: sent signal %ld to pid %ld/%ld\n",
2199 SARG3, SARG1, SARG2);
2202 /* ---------------------------------------------------------------------
2203 fadvise64* wrappers
2204 ------------------------------------------------------------------ */
2206 PRE(sys_fadvise64)
2208 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2209 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2210 PRE_REG_READ5(long, "fadvise64",
2211 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2212 vki_size_t, len, int, advice);
2215 PRE(sys_fadvise64_64)
2217 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2218 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2219 PRE_REG_READ6(long, "fadvise64_64",
2220 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2221 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2224 /* ---------------------------------------------------------------------
2225 io_* wrappers
2226 ------------------------------------------------------------------ */
2228 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2229 // and this allows us to control exactly the code that gets run while
2230 // the padding is in place.
2232 PRE(sys_io_setup)
2234 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2235 PRE_REG_READ2(long, "io_setup",
2236 unsigned, nr_events, vki_aio_context_t *, ctxp);
2237 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2240 POST(sys_io_setup)
2242 SizeT size;
2243 struct vki_aio_ring *r;
2245 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2246 ARG1*sizeof(struct vki_io_event));
2247 r = *(struct vki_aio_ring **)(Addr)ARG2;
2248 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2250 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2251 VKI_PROT_READ | VKI_PROT_WRITE,
2252 VKI_MAP_ANONYMOUS, -1, 0 );
2254 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2257 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2258 // after the syscall. We must get 'size' from the aio_ring structure,
2259 // before the syscall, while the aio_ring structure still exists. (And we
2260 // know that we must look at the aio_ring structure because Tom inspected the
2261 // kernel and glibc sources to see what they do, yuk.)
2263 // XXX This segment can be implicitly unmapped when aio
2264 // file-descriptors are closed...
2265 PRE(sys_io_destroy)
2267 SizeT size = 0;
2269 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2270 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2272 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2273 // possible...
2274 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2275 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2276 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2277 r->nr*sizeof(struct vki_io_event));
2280 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2282 if (SUCCESS && RES == 0) {
2283 Bool d = VG_(am_notify_munmap)( ARG1, size );
2284 VG_TRACK( die_mem_munmap, ARG1, size );
2285 if (d)
2286 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2287 "PRE(sys_io_destroy)" );
2291 PRE(sys_io_getevents)
2293 *flags |= SfMayBlock;
2294 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2295 FMT_REGWORD "x )",
2296 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2297 PRE_REG_READ5(long, "io_getevents",
2298 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2299 struct io_event *, events,
2300 struct timespec *, timeout);
2301 if (ARG3 > 0)
2302 PRE_MEM_WRITE( "io_getevents(events)",
2303 ARG4, sizeof(struct vki_io_event)*ARG3 );
2304 if (ARG5 != 0)
2305 PRE_MEM_READ( "io_getevents(timeout)",
2306 ARG5, sizeof(struct vki_timespec));
2308 POST(sys_io_getevents)
2310 Int i;
2311 vg_assert(SUCCESS);
2312 if (RES > 0) {
2313 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2314 for (i = 0; i < RES; i++) {
2315 const struct vki_io_event *vev =
2316 ((struct vki_io_event *)(Addr)ARG4) + i;
2317 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2319 switch (cb->aio_lio_opcode) {
2320 case VKI_IOCB_CMD_PREAD:
2321 if (vev->result > 0)
2322 POST_MEM_WRITE( cb->aio_buf, vev->result );
2323 break;
2325 case VKI_IOCB_CMD_PWRITE:
2326 break;
2328 case VKI_IOCB_CMD_FSYNC:
2329 break;
2331 case VKI_IOCB_CMD_FDSYNC:
2332 break;
2334 case VKI_IOCB_CMD_PREADV:
2335 if (vev->result > 0) {
2336 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2337 Int remains = vev->result;
2338 Int j;
2340 for (j = 0; j < cb->aio_nbytes; j++) {
2341 Int nReadThisBuf = vec[j].iov_len;
2342 if (nReadThisBuf > remains) nReadThisBuf = remains;
2343 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2344 remains -= nReadThisBuf;
2345 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2348 break;
2350 case VKI_IOCB_CMD_PWRITEV:
2351 break;
2353 default:
2354 VG_(message)(Vg_DebugMsg,
2355 "Warning: unhandled io_getevents opcode: %u\n",
2356 cb->aio_lio_opcode);
2357 break;
2363 PRE(sys_io_submit)
2365 Int i, j;
2367 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2368 ARG1, SARG2, ARG3);
2369 PRE_REG_READ3(long, "io_submit",
2370 vki_aio_context_t, ctx_id, long, nr,
2371 struct iocb **, iocbpp);
2372 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2373 if (ARG3 != 0) {
2374 for (i = 0; i < ARG2; i++) {
2375 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2376 struct vki_iovec *iov;
2378 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2379 switch (cb->aio_lio_opcode) {
2380 case VKI_IOCB_CMD_PREAD:
2381 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2382 break;
2384 case VKI_IOCB_CMD_PWRITE:
2385 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2386 break;
2388 case VKI_IOCB_CMD_FSYNC:
2389 break;
2391 case VKI_IOCB_CMD_FDSYNC:
2392 break;
2394 case VKI_IOCB_CMD_PREADV:
2395 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2396 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2397 for (j = 0; j < cb->aio_nbytes; j++)
2398 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2399 break;
2401 case VKI_IOCB_CMD_PWRITEV:
2402 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2403 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2404 for (j = 0; j < cb->aio_nbytes; j++)
2405 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2406 break;
2408 default:
2409 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2410 cb->aio_lio_opcode);
2411 break;
2417 PRE(sys_io_cancel)
2419 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2420 (ULong)ARG1, ARG2, ARG3);
2421 PRE_REG_READ3(long, "io_cancel",
2422 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2423 struct io_event *, result);
2424 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2425 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2427 POST(sys_io_cancel)
2429 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2432 /* ---------------------------------------------------------------------
2433 *_mempolicy wrappers
2434 ------------------------------------------------------------------ */
2436 PRE(sys_mbind)
2438 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2439 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2440 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2441 PRE_REG_READ6(long, "mbind",
2442 unsigned long, start, unsigned long, len,
2443 unsigned long, policy, unsigned long *, nodemask,
2444 unsigned long, maxnode, unsigned, flags);
2445 if (ARG1 != 0)
2446 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2447 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2450 PRE(sys_set_mempolicy)
2452 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2453 SARG1, ARG2, ARG3);
2454 PRE_REG_READ3(long, "set_mempolicy",
2455 int, policy, unsigned long *, nodemask,
2456 unsigned long, maxnode);
2457 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2458 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2461 PRE(sys_get_mempolicy)
2463 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2464 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2465 ARG1, ARG2, ARG3, ARG4, ARG5);
2466 PRE_REG_READ5(long, "get_mempolicy",
2467 int *, policy, unsigned long *, nodemask,
2468 unsigned long, maxnode, unsigned long, addr,
2469 unsigned long, flags);
2470 if (ARG1 != 0)
2471 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2472 if (ARG2 != 0)
2473 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2474 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2476 POST(sys_get_mempolicy)
2478 if (ARG1 != 0)
2479 POST_MEM_WRITE( ARG1, sizeof(Int) );
2480 if (ARG2 != 0)
2481 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2484 /* ---------------------------------------------------------------------
2485 fanotify_* wrappers
2486 ------------------------------------------------------------------ */
2488 PRE(sys_fanotify_init)
2490 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2491 ARG1, ARG2);
2492 PRE_REG_READ2(long, "fanotify_init",
2493 unsigned int, flags, unsigned int, event_f_flags);
2496 POST(sys_fanotify_init)
2498 vg_assert(SUCCESS);
2499 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2500 VG_(close)(RES);
2501 SET_STATUS_Failure( VKI_EMFILE );
2502 } else {
2503 if (VG_(clo_track_fds))
2504 ML_(record_fd_open_nameless) (tid, RES);
2508 PRE(sys_fanotify_mark)
2510 #if VG_WORDSIZE == 4
2511 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2512 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2513 (HChar *)(Addr)ARG6);
2514 PRE_REG_READ6(long, "sys_fanotify_mark",
2515 int, fanotify_fd, unsigned int, flags,
2516 __vki_u32, mask0, __vki_u32, mask1,
2517 int, dfd, const char *, pathname);
2518 if (ARG6)
2519 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2520 #elif VG_WORDSIZE == 8
2521 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2522 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2523 PRE_REG_READ5(long, "sys_fanotify_mark",
2524 int, fanotify_fd, unsigned int, flags,
2525 __vki_u64, mask,
2526 int, dfd, const char *, pathname);
2527 if (ARG5)
2528 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2529 #else
2530 # error Unexpected word size
2531 #endif
2534 /* ---------------------------------------------------------------------
2535 inotify_* wrappers
2536 ------------------------------------------------------------------ */
2538 PRE(sys_inotify_init)
2540 PRINT("sys_inotify_init ( )");
2541 PRE_REG_READ0(long, "inotify_init");
2543 POST(sys_inotify_init)
2545 vg_assert(SUCCESS);
2546 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2547 VG_(close)(RES);
2548 SET_STATUS_Failure( VKI_EMFILE );
2549 } else {
2550 if (VG_(clo_track_fds))
2551 ML_(record_fd_open_nameless) (tid, RES);
2555 PRE(sys_inotify_init1)
2557 PRINT("sys_inotify_init ( %ld )", SARG1);
2558 PRE_REG_READ1(long, "inotify_init", int, flag);
2561 POST(sys_inotify_init1)
2563 vg_assert(SUCCESS);
2564 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2565 VG_(close)(RES);
2566 SET_STATUS_Failure( VKI_EMFILE );
2567 } else {
2568 if (VG_(clo_track_fds))
2569 ML_(record_fd_open_nameless) (tid, RES);
2573 PRE(sys_inotify_add_watch)
2575 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2576 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2577 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2578 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2581 PRE(sys_inotify_rm_watch)
2583 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2584 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2587 /* ---------------------------------------------------------------------
2588 mq_* wrappers
2589 ------------------------------------------------------------------ */
2591 PRE(sys_mq_open)
2593 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2594 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2595 PRE_REG_READ4(long, "mq_open",
2596 const char *, name, int, oflag, vki_mode_t, mode,
2597 struct mq_attr *, attr);
2598 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2599 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2600 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2601 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2602 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2603 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2604 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2607 POST(sys_mq_open)
2609 vg_assert(SUCCESS);
2610 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2611 VG_(close)(RES);
2612 SET_STATUS_Failure( VKI_EMFILE );
2613 } else {
2614 if (VG_(clo_track_fds))
2615 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2619 PRE(sys_mq_unlink)
2621 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2622 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2623 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2626 PRE(sys_mq_timedsend)
2628 *flags |= SfMayBlock;
2629 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2630 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2631 SARG1,ARG2,ARG3,ARG4,ARG5);
2632 PRE_REG_READ5(long, "mq_timedsend",
2633 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2634 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2635 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2636 SET_STATUS_Failure( VKI_EBADF );
2637 } else {
2638 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2639 if (ARG5 != 0)
2640 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2641 sizeof(struct vki_timespec) );
2645 PRE(sys_mq_timedreceive)
2647 *flags |= SfMayBlock;
2648 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2649 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2650 SARG1,ARG2,ARG3,ARG4,ARG5);
2651 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2652 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2653 unsigned int *, msg_prio,
2654 const struct timespec *, abs_timeout);
2655 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2656 SET_STATUS_Failure( VKI_EBADF );
2657 } else {
2658 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2659 if (ARG4 != 0)
2660 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2661 ARG4, sizeof(unsigned int) );
2662 if (ARG5 != 0)
2663 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2664 ARG5, sizeof(struct vki_timespec) );
2667 POST(sys_mq_timedreceive)
2669 POST_MEM_WRITE( ARG2, RES );
2670 if (ARG4 != 0)
2671 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2674 PRE(sys_mq_notify)
2676 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2677 PRE_REG_READ2(long, "mq_notify",
2678 vki_mqd_t, mqdes, const struct sigevent *, notification);
2679 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2680 SET_STATUS_Failure( VKI_EBADF );
2681 else if (ARG2 != 0)
2682 PRE_MEM_READ( "mq_notify(notification)",
2683 ARG2, sizeof(struct vki_sigevent) );
2686 PRE(sys_mq_getsetattr)
2688 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2689 SARG1, ARG2, ARG3 );
2690 PRE_REG_READ3(long, "mq_getsetattr",
2691 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2692 struct mq_attr *, omqstat);
2693 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2694 SET_STATUS_Failure( VKI_EBADF );
2695 } else {
2696 if (ARG2 != 0) {
2697 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2698 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2699 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2701 if (ARG3 != 0)
2702 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2703 sizeof(struct vki_mq_attr) );
2706 POST(sys_mq_getsetattr)
2708 if (ARG3 != 0)
2709 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2712 /* ---------------------------------------------------------------------
2713 clock_* wrappers
2714 ------------------------------------------------------------------ */
2716 PRE(sys_clock_settime)
2718 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2719 PRE_REG_READ2(long, "clock_settime",
2720 vki_clockid_t, clk_id, const struct timespec *, tp);
2721 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2724 PRE(sys_clock_gettime)
2726 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2727 PRE_REG_READ2(long, "clock_gettime",
2728 vki_clockid_t, clk_id, struct timespec *, tp);
2729 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2731 POST(sys_clock_gettime)
2733 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2736 PRE(sys_clock_getres)
2738 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2739 // Nb: we can't use "RES" as the param name because that's a macro
2740 // defined above!
2741 PRE_REG_READ2(long, "clock_getres",
2742 vki_clockid_t, clk_id, struct timespec *, res);
2743 if (ARG2 != 0)
2744 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2746 POST(sys_clock_getres)
2748 if (ARG2 != 0)
2749 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2752 PRE(sys_clock_nanosleep)
2754 *flags |= SfMayBlock|SfPostOnFail;
2755 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
2756 FMT_REGWORD "x )",
2757 SARG1, SARG2, ARG3, ARG4);
2758 PRE_REG_READ4(int32_t, "clock_nanosleep",
2759 vki_clockid_t, clkid, int, flags,
2760 const struct timespec *, rqtp, struct timespec *, rmtp);
2761 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2762 if (ARG4 != 0)
2763 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2765 POST(sys_clock_nanosleep)
2767 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2768 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2771 /* ---------------------------------------------------------------------
2772 timer_* wrappers
2773 ------------------------------------------------------------------ */
2775 PRE(sys_timer_create)
2777 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2778 SARG1, ARG2, ARG3);
2779 PRE_REG_READ3(long, "timer_create",
2780 vki_clockid_t, clockid, struct sigevent *, evp,
2781 vki_timer_t *, timerid);
2782 if (ARG2 != 0) {
2783 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
2784 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2785 sizeof(vki_sigval_t) );
2786 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2787 sizeof(int) );
2788 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2789 sizeof(int) );
2790 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2791 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2792 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2793 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2795 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2797 POST(sys_timer_create)
2799 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2802 PRE(sys_timer_settime)
2804 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
2805 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
2806 PRE_REG_READ4(long, "timer_settime",
2807 vki_timer_t, timerid, int, flags,
2808 const struct itimerspec *, value,
2809 struct itimerspec *, ovalue);
2810 PRE_MEM_READ( "timer_settime(value)", ARG3,
2811 sizeof(struct vki_itimerspec) );
2812 if (ARG4 != 0)
2813 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2814 sizeof(struct vki_itimerspec) );
2816 POST(sys_timer_settime)
2818 if (ARG4 != 0)
2819 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2822 PRE(sys_timer_gettime)
2824 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2825 PRE_REG_READ2(long, "timer_gettime",
2826 vki_timer_t, timerid, struct itimerspec *, value);
2827 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2828 sizeof(struct vki_itimerspec));
2830 POST(sys_timer_gettime)
2832 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2835 PRE(sys_timer_getoverrun)
2837 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
2838 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2841 PRE(sys_timer_delete)
2843 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
2844 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2847 /* ---------------------------------------------------------------------
2848 timerfd* wrappers
2849 See also http://lwn.net/Articles/260172/ for an overview.
2850 See also /usr/src/linux/fs/timerfd.c for the implementation.
2851 ------------------------------------------------------------------ */
2853 /* Returns True if running on 2.6.22, else False (or False if
2854 cannot be determined). */
2855 static Bool linux_kernel_2_6_22(void)
2857 static Int result = -1;
2858 Int fd, read;
2859 HChar release[64]; // large enough
2860 SysRes res;
2862 if (result == -1) {
2863 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2864 if (sr_isError(res))
2865 return False;
2866 fd = sr_Res(res);
2867 read = VG_(read)(fd, release, sizeof(release) - 1);
2868 if (read < 0)
2869 return False;
2870 release[read] = 0;
2871 VG_(close)(fd);
2872 //VG_(printf)("kernel release = %s\n", release);
2873 result = VG_(strncmp)(release, "2.6.22", 6) == 0
2874 && ! VG_(isdigit)(release[6]);
2876 vg_assert(result == 0 || result == 1);
2877 return result == 1;
2880 PRE(sys_timerfd_create)
2882 if (linux_kernel_2_6_22()) {
2883 /* 2.6.22 kernel: timerfd system call. */
2884 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
2885 PRE_REG_READ3(long, "sys_timerfd",
2886 int, fd, int, clockid, const struct itimerspec *, tmr);
2887 PRE_MEM_READ("timerfd(tmr)", ARG3,
2888 sizeof(struct vki_itimerspec) );
2889 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2890 SET_STATUS_Failure( VKI_EBADF );
2891 } else {
2892 /* 2.6.24 and later kernels: timerfd_create system call. */
2893 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2894 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2897 POST(sys_timerfd_create)
2899 if (linux_kernel_2_6_22())
2901 /* 2.6.22 kernel: timerfd system call. */
2902 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2903 VG_(close)(RES);
2904 SET_STATUS_Failure( VKI_EMFILE );
2905 } else {
2906 if (VG_(clo_track_fds))
2907 ML_(record_fd_open_nameless) (tid, RES);
2910 else
2912 /* 2.6.24 and later kernels: timerfd_create system call. */
2913 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2914 VG_(close)(RES);
2915 SET_STATUS_Failure( VKI_EMFILE );
2916 } else {
2917 if (VG_(clo_track_fds))
2918 ML_(record_fd_open_nameless) (tid, RES);
2923 PRE(sys_timerfd_gettime)
2925 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2926 PRE_REG_READ2(long, "timerfd_gettime",
2927 int, ufd,
2928 struct vki_itimerspec*, otmr);
2929 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2930 SET_STATUS_Failure(VKI_EBADF);
2931 else
2932 PRE_MEM_WRITE("timerfd_gettime(result)",
2933 ARG2, sizeof(struct vki_itimerspec));
2935 POST(sys_timerfd_gettime)
2937 if (RES == 0)
2938 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2941 PRE(sys_timerfd_settime)
2943 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
2944 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
2945 PRE_REG_READ4(long, "timerfd_settime",
2946 int, ufd,
2947 int, flags,
2948 const struct vki_itimerspec*, utmr,
2949 struct vki_itimerspec*, otmr);
2950 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2951 SET_STATUS_Failure(VKI_EBADF);
2952 else
2954 PRE_MEM_READ("timerfd_settime(result)",
2955 ARG3, sizeof(struct vki_itimerspec));
2956 if (ARG4)
2958 PRE_MEM_WRITE("timerfd_settime(result)",
2959 ARG4, sizeof(struct vki_itimerspec));
2963 POST(sys_timerfd_settime)
2965 if (RES == 0 && ARG4 != 0)
2966 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2969 /* ---------------------------------------------------------------------
2970 capabilities wrappers
2971 ------------------------------------------------------------------ */
2973 PRE(sys_capget)
2975 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2976 PRE_REG_READ2(long, "capget",
2977 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2978 PRE_MEM_READ( "capget(header)", ARG1,
2979 sizeof(struct __vki_user_cap_header_struct) );
2980 if (ARG2 != (Addr)NULL)
2981 PRE_MEM_WRITE( "capget(data)", ARG2,
2982 sizeof(struct __vki_user_cap_data_struct) );
2984 POST(sys_capget)
2986 if (ARG2 != (Addr)NULL)
2987 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2990 PRE(sys_capset)
2992 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2993 PRE_REG_READ2(long, "capset",
2994 vki_cap_user_header_t, header,
2995 const vki_cap_user_data_t, data);
2996 PRE_MEM_READ( "capset(header)",
2997 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2998 PRE_MEM_READ( "capset(data)",
2999 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3002 /* ---------------------------------------------------------------------
3003 16-bit uid/gid/groups wrappers
3004 ------------------------------------------------------------------ */
3006 PRE(sys_getuid16)
3008 PRINT("sys_getuid16 ( )");
3009 PRE_REG_READ0(long, "getuid16");
3012 PRE(sys_setuid16)
3014 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3015 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3018 PRE(sys_getgid16)
3020 PRINT("sys_getgid16 ( )");
3021 PRE_REG_READ0(long, "getgid16");
3024 PRE(sys_setgid16)
3026 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3027 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3030 PRE(sys_geteuid16)
3032 PRINT("sys_geteuid16 ( )");
3033 PRE_REG_READ0(long, "geteuid16");
3036 PRE(sys_getegid16)
3038 PRINT("sys_getegid16 ( )");
3039 PRE_REG_READ0(long, "getegid16");
3042 PRE(sys_setreuid16)
3044 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3045 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3048 PRE(sys_setregid16)
3050 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3051 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3054 PRE(sys_getgroups16)
3056 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3057 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3058 if (ARG1 > 0)
3059 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3061 POST(sys_getgroups16)
3063 vg_assert(SUCCESS);
3064 if (ARG1 > 0 && RES > 0)
3065 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3068 PRE(sys_setgroups16)
3070 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3071 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3072 if (ARG1 > 0)
3073 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3076 /* ---------------------------------------------------------------------
3077 *chown16 wrappers
3078 ------------------------------------------------------------------ */
3080 PRE(sys_chown16)
3082 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3083 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3084 PRE_REG_READ3(long, "chown16",
3085 const char *, path,
3086 vki_old_uid_t, owner, vki_old_gid_t, group);
3087 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3090 PRE(sys_fchown16)
3092 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3093 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3094 PRE_REG_READ3(long, "fchown16",
3095 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3098 /* ---------------------------------------------------------------------
3099 *xattr wrappers
3100 ------------------------------------------------------------------ */
3102 PRE(sys_setxattr)
3104 *flags |= SfMayBlock;
3105 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3106 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3107 ARG4, SARG5);
3108 PRE_REG_READ5(long, "setxattr",
3109 char *, path, char *, name,
3110 void *, value, vki_size_t, size, int, flags);
3111 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3112 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3113 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3116 PRE(sys_lsetxattr)
3118 *flags |= SfMayBlock;
3119 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3120 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3121 ARG1, ARG2, ARG3, ARG4, SARG5);
3122 PRE_REG_READ5(long, "lsetxattr",
3123 char *, path, char *, name,
3124 void *, value, vki_size_t, size, int, flags);
3125 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3126 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3127 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3130 PRE(sys_fsetxattr)
3132 *flags |= SfMayBlock;
3133 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3134 FMT_REGWORD "u, %ld )",
3135 SARG1, ARG2, ARG3, ARG4, SARG5);
3136 PRE_REG_READ5(long, "fsetxattr",
3137 int, fd, char *, name, void *, value,
3138 vki_size_t, size, int, flags);
3139 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3140 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3143 PRE(sys_getxattr)
3145 *flags |= SfMayBlock;
3146 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3147 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3148 PRE_REG_READ4(ssize_t, "getxattr",
3149 char *, path, char *, name, void *, value, vki_size_t, size);
3150 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3151 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3152 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3154 POST(sys_getxattr)
3156 vg_assert(SUCCESS);
3157 if (RES > 0 && ARG3 != (Addr)NULL) {
3158 POST_MEM_WRITE( ARG3, RES );
3162 PRE(sys_lgetxattr)
3164 *flags |= SfMayBlock;
3165 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3166 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3167 PRE_REG_READ4(ssize_t, "lgetxattr",
3168 char *, path, char *, name, void *, value, vki_size_t, size);
3169 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3170 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3171 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3173 POST(sys_lgetxattr)
3175 vg_assert(SUCCESS);
3176 if (RES > 0 && ARG3 != (Addr)NULL) {
3177 POST_MEM_WRITE( ARG3, RES );
3181 PRE(sys_fgetxattr)
3183 *flags |= SfMayBlock;
3184 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3185 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3186 PRE_REG_READ4(ssize_t, "fgetxattr",
3187 int, fd, char *, name, void *, value, vki_size_t, size);
3188 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3189 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3191 POST(sys_fgetxattr)
3193 if (RES > 0 && ARG3 != (Addr)NULL)
3194 POST_MEM_WRITE( ARG3, RES );
3197 PRE(sys_listxattr)
3199 *flags |= SfMayBlock;
3200 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3201 ARG1, ARG2, (ULong)ARG3);
3202 PRE_REG_READ3(ssize_t, "listxattr",
3203 char *, path, char *, list, vki_size_t, size);
3204 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3205 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3207 POST(sys_listxattr)
3209 if (RES > 0 && ARG2 != (Addr)NULL)
3210 POST_MEM_WRITE( ARG2, RES );
3213 PRE(sys_llistxattr)
3215 *flags |= SfMayBlock;
3216 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3217 ARG1, ARG2, (ULong)ARG3);
3218 PRE_REG_READ3(ssize_t, "llistxattr",
3219 char *, path, char *, list, vki_size_t, size);
3220 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3221 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3223 POST(sys_llistxattr)
3225 if (RES > 0 && ARG2 != (Addr)NULL)
3226 POST_MEM_WRITE( ARG2, RES );
3229 PRE(sys_flistxattr)
3231 *flags |= SfMayBlock;
3232 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3233 SARG1, ARG2, ARG3);
3234 PRE_REG_READ3(ssize_t, "flistxattr",
3235 int, fd, char *, list, vki_size_t, size);
3236 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3238 POST(sys_flistxattr)
3240 if (RES > 0 && ARG2 != (Addr)NULL)
3241 POST_MEM_WRITE( ARG2, RES );
3244 PRE(sys_removexattr)
3246 *flags |= SfMayBlock;
3247 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3248 ARG1, ARG2);
3249 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3250 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3251 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3254 PRE(sys_lremovexattr)
3256 *flags |= SfMayBlock;
3257 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3258 ARG1, ARG2);
3259 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3260 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3261 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3264 PRE(sys_fremovexattr)
3266 *flags |= SfMayBlock;
3267 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3268 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3269 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3272 /* ---------------------------------------------------------------------
3273 sched_* wrappers
3274 ------------------------------------------------------------------ */
3276 PRE(sys_sched_setparam)
3278 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3279 PRE_REG_READ2(long, "sched_setparam",
3280 vki_pid_t, pid, struct sched_param *, p);
3281 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3283 POST(sys_sched_setparam)
3285 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3288 PRE(sys_sched_getparam)
3290 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3291 PRE_REG_READ2(long, "sched_getparam",
3292 vki_pid_t, pid, struct sched_param *, p);
3293 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3295 POST(sys_sched_getparam)
3297 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3300 PRE(sys_sched_getscheduler)
3302 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3303 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3306 PRE(sys_sched_setscheduler)
3308 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3309 SARG1, SARG2, ARG3);
3310 PRE_REG_READ3(long, "sched_setscheduler",
3311 vki_pid_t, pid, int, policy, struct sched_param *, p);
3312 if (ARG3 != 0)
3313 PRE_MEM_READ( "sched_setscheduler(p)",
3314 ARG3, sizeof(struct vki_sched_param));
3317 PRE(sys_sched_yield)
3319 *flags |= SfMayBlock;
3320 PRINT("sched_yield()");
3321 PRE_REG_READ0(long, "sys_sched_yield");
3324 PRE(sys_sched_get_priority_max)
3326 PRINT("sched_get_priority_max ( %ld )", SARG1);
3327 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3330 PRE(sys_sched_get_priority_min)
3332 PRINT("sched_get_priority_min ( %ld )", SARG1);
3333 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3336 PRE(sys_sched_rr_get_interval)
3338 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3339 PRE_REG_READ2(int, "sched_rr_get_interval",
3340 vki_pid_t, pid,
3341 struct vki_timespec *, tp);
3342 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3343 ARG2, sizeof(struct vki_timespec));
3346 POST(sys_sched_rr_get_interval)
3348 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3351 PRE(sys_sched_setaffinity)
3353 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3354 SARG1, ARG2, ARG3);
3355 PRE_REG_READ3(long, "sched_setaffinity",
3356 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3357 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3360 PRE(sys_sched_getaffinity)
3362 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3363 SARG1, ARG2, ARG3);
3364 PRE_REG_READ3(long, "sched_getaffinity",
3365 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3366 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3368 POST(sys_sched_getaffinity)
3370 POST_MEM_WRITE(ARG3, ARG2);
3373 PRE(sys_unshare)
3375 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3376 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3379 /* ---------------------------------------------------------------------
3380 miscellaneous wrappers
3381 ------------------------------------------------------------------ */
3383 PRE(sys_munlockall)
3385 *flags |= SfMayBlock;
3386 PRINT("sys_munlockall ( )");
3387 PRE_REG_READ0(long, "munlockall");
3390 // This has different signatures for different platforms.
3392 // x86: int sys_pipe(unsigned long __user *fildes);
3393 // AMD64: long sys_pipe(int *fildes);
3394 // ppc32: int sys_pipe(int __user *fildes);
3395 // ppc64: int sys_pipe(int __user *fildes);
3397 // The type of the argument is most important, and it is an array of 32 bit
3398 // values in all cases. (The return type differs across platforms, but it
3399 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3400 // was caused by using an array of 'unsigned long's, which didn't work on
3401 // AMD64.
3402 PRE(sys_pipe)
3404 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3405 PRE_REG_READ1(int, "pipe", int *, filedes);
3406 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3408 POST(sys_pipe)
3410 Int *p = (Int *)(Addr)ARG1;
3411 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3412 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3413 VG_(close)(p[0]);
3414 VG_(close)(p[1]);
3415 SET_STATUS_Failure( VKI_EMFILE );
3416 } else {
3417 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3418 if (VG_(clo_track_fds)) {
3419 ML_(record_fd_open_nameless)(tid, p[0]);
3420 ML_(record_fd_open_nameless)(tid, p[1]);
3425 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3426 there's a second arg containing flags to be applied to the new file
3427 descriptors. It hardly seems worth the effort to factor out the
3428 duplicated code, hence: */
3429 PRE(sys_pipe2)
3431 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3432 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3433 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3435 POST(sys_pipe2)
3437 Int *p = (Int *)(Addr)ARG1;
3438 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3439 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3440 VG_(close)(p[0]);
3441 VG_(close)(p[1]);
3442 SET_STATUS_Failure( VKI_EMFILE );
3443 } else {
3444 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3445 if (VG_(clo_track_fds)) {
3446 ML_(record_fd_open_nameless)(tid, p[0]);
3447 ML_(record_fd_open_nameless)(tid, p[1]);
3452 PRE(sys_dup3)
3454 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3455 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3456 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3457 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3458 SET_STATUS_Failure( VKI_EBADF );
3461 POST(sys_dup3)
3463 vg_assert(SUCCESS);
3464 if (VG_(clo_track_fds))
3465 ML_(record_fd_open_named)(tid, RES);
3468 PRE(sys_quotactl)
3470 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3471 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3472 PRE_REG_READ4(long, "quotactl",
3473 unsigned int, cmd, const char *, special, vki_qid_t, id,
3474 void *, addr);
3475 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3478 PRE(sys_waitid)
3480 *flags |= SfMayBlock;
3481 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3482 SARG1, SARG2, ARG3, SARG4, ARG5);
3483 PRE_REG_READ5(int32_t, "sys_waitid",
3484 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3485 int, options, struct vki_rusage *, ru);
3486 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3487 if (ARG5 != 0)
3488 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3490 POST(sys_waitid)
3492 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3493 if (ARG5 != 0)
3494 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3497 PRE(sys_sync_file_range)
3499 *flags |= SfMayBlock;
3500 #if VG_WORDSIZE == 4
3501 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3502 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3503 PRE_REG_READ6(long, "sync_file_range",
3504 int, fd,
3505 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3506 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3507 unsigned int, flags);
3508 #elif VG_WORDSIZE == 8
3509 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3510 SARG1, SARG2, SARG3, ARG4);
3511 PRE_REG_READ4(long, "sync_file_range",
3512 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3513 unsigned int, flags);
3514 #else
3515 # error Unexpected word size
3516 #endif
3517 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3518 SET_STATUS_Failure( VKI_EBADF );
3521 PRE(sys_sync_file_range2)
3523 *flags |= SfMayBlock;
3524 #if VG_WORDSIZE == 4
3525 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3526 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3527 PRE_REG_READ6(long, "sync_file_range2",
3528 int, fd, unsigned int, flags,
3529 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3530 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3531 #elif VG_WORDSIZE == 8
3532 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3533 SARG1, ARG2, SARG3, SARG4);
3534 PRE_REG_READ4(long, "sync_file_range2",
3535 int, fd, unsigned int, flags,
3536 vki_loff_t, offset, vki_loff_t, nbytes);
3537 #else
3538 # error Unexpected word size
3539 #endif
3540 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3541 SET_STATUS_Failure( VKI_EBADF );
3544 PRE(sys_stime)
3546 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
3547 PRE_REG_READ1(int, "stime", vki_time_t*, t);
3548 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3551 PRE(sys_perf_event_open)
3553 struct vki_perf_event_attr *attr;
3554 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
3555 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
3556 PRE_REG_READ5(long, "perf_event_open",
3557 struct vki_perf_event_attr *, attr,
3558 vki_pid_t, pid, int, cpu, int, group_fd,
3559 unsigned long, flags);
3560 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
3561 PRE_MEM_READ( "perf_event_open(attr->size)",
3562 (Addr)&attr->size, sizeof(attr->size) );
3563 PRE_MEM_READ( "perf_event_open(attr)",
3564 (Addr)attr, attr->size );
3567 POST(sys_perf_event_open)
3569 vg_assert(SUCCESS);
3570 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3571 VG_(close)(RES);
3572 SET_STATUS_Failure( VKI_EMFILE );
3573 } else {
3574 if (VG_(clo_track_fds))
3575 ML_(record_fd_open_nameless)(tid, RES);
3579 PRE(sys_getcpu)
3581 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3582 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
3583 PRE_REG_READ3(int, "getcpu",
3584 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3585 if (ARG1 != 0)
3586 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3587 if (ARG2 != 0)
3588 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3589 if (ARG3 != 0)
3590 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3593 POST(sys_getcpu)
3595 if (ARG1 != 0)
3596 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3597 if (ARG2 != 0)
3598 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3599 if (ARG3 != 0)
3600 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3603 PRE(sys_move_pages)
3605 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
3606 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3607 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3608 PRE_REG_READ6(int, "move_pages",
3609 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3610 const int *, nodes, int *, status, int, flags);
3611 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3612 if (ARG4)
3613 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3614 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3617 POST(sys_move_pages)
3619 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3622 PRE(sys_getrandom)
3624 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3625 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
3626 PRE_REG_READ3(int, "getrandom",
3627 char *, buf, vki_size_t, count, unsigned int, flags);
3628 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3631 POST(sys_getrandom)
3633 POST_MEM_WRITE( ARG1, ARG2 );
3636 PRE(sys_memfd_create)
3638 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
3639 ARG1, ARG2);
3640 PRE_REG_READ2(int, "memfd_create",
3641 char *, uname, unsigned int, flags);
3642 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3645 POST(sys_memfd_create)
3647 vg_assert(SUCCESS);
3648 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3649 VG_(close)(RES);
3650 SET_STATUS_Failure( VKI_EMFILE );
3651 } else {
3652 if (VG_(clo_track_fds))
3653 ML_(record_fd_open_nameless)(tid, RES);
3657 PRE(sys_membarrier)
3659 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
3660 PRE_REG_READ1(int, "membarrier", int, flags);
3663 PRE(sys_syncfs)
3665 *flags |= SfMayBlock;
3666 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
3667 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3670 PRE(sys_statx)
3672 FUSE_COMPATIBLE_MAY_BLOCK();
3673 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
3674 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
3675 PRE_REG_READ5(long, "statx",
3676 int, dirfd, char *, file_name, int, flags,
3677 unsigned int, mask, struct statx *, buf);
3678 PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 );
3679 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
3681 POST(sys_statx)
3683 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
3686 /* ---------------------------------------------------------------------
3687 utime wrapper
3688 ------------------------------------------------------------------ */
3690 PRE(sys_utime)
3692 *flags |= SfMayBlock;
3693 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
3694 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3695 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3696 if (ARG2 != 0)
3697 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3700 /* ---------------------------------------------------------------------
3701 lseek wrapper
3702 ------------------------------------------------------------------ */
3704 PRE(sys_lseek)
3706 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
3707 ARG1, SARG2, ARG3);
3708 PRE_REG_READ3(vki_off_t, "lseek",
3709 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3712 /* ---------------------------------------------------------------------
3713 readahead wrapper
3714 ------------------------------------------------------------------ */
3716 PRE(sys_readahead)
3718 *flags |= SfMayBlock;
3719 #if VG_WORDSIZE == 4
3720 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
3721 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3722 PRE_REG_READ4(vki_off_t, "readahead",
3723 int, fd, unsigned, MERGE64_FIRST(offset),
3724 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3725 #elif VG_WORDSIZE == 8
3726 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3727 PRE_REG_READ3(vki_off_t, "readahead",
3728 int, fd, vki_loff_t, offset, vki_size_t, count);
3729 #else
3730 # error Unexpected word size
3731 #endif
3732 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3733 SET_STATUS_Failure( VKI_EBADF );
3736 /* ---------------------------------------------------------------------
3737 sig* wrappers
3738 ------------------------------------------------------------------ */
3740 PRE(sys_sigpending)
3742 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
3743 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3744 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3746 POST(sys_sigpending)
3748 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3751 // This syscall is not used on amd64/Linux -- it only provides
3752 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3753 // This wrapper is only suitable for 32-bit architectures.
3754 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3755 // conditional compilation like this?)
3756 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3757 || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
3758 PRE(sys_sigprocmask)
3760 vki_old_sigset_t* set;
3761 vki_old_sigset_t* oldset;
3762 vki_sigset_t bigger_set;
3763 vki_sigset_t bigger_oldset;
3765 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3766 PRE_REG_READ3(long, "sigprocmask",
3767 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3768 if (ARG2 != 0)
3769 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3770 if (ARG3 != 0)
3771 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3773 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3774 // vki_sigset_t params.
3775 set = (vki_old_sigset_t*)(Addr)ARG2;
3776 oldset = (vki_old_sigset_t*)(Addr)ARG3;
3778 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
3779 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3780 if (set)
3781 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3783 SET_STATUS_from_SysRes(
3784 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3785 set ? &bigger_set : NULL,
3786 oldset ? &bigger_oldset : NULL)
3789 if (oldset)
3790 *oldset = bigger_oldset.sig[0];
3792 if (SUCCESS)
3793 *flags |= SfPollAfter;
3795 POST(sys_sigprocmask)
3797 vg_assert(SUCCESS);
3798 if (RES == 0 && ARG3 != 0)
3799 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3802 /* Convert from non-RT to RT sigset_t's */
3803 static
3804 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3806 VG_(sigemptyset)(set);
3807 set->sig[0] = *oldset;
3809 PRE(sys_sigaction)
3811 vki_sigaction_toK_t new, *newp;
3812 vki_sigaction_fromK_t old, *oldp;
3814 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3815 PRE_REG_READ3(int, "sigaction",
3816 int, signum, const struct old_sigaction *, act,
3817 struct old_sigaction *, oldact);
3819 newp = oldp = NULL;
3821 if (ARG2 != 0) {
3822 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
3823 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3824 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3825 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3826 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3827 && (sa->sa_flags & VKI_SA_RESTORER))
3828 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3831 if (ARG3 != 0) {
3832 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3833 oldp = &old;
3836 /* If the new or old sigaction is not NULL, but the structs
3837 aren't accessible then sigaction returns EFAULT and we cannot
3838 use either struct for our own bookkeeping. Just fail early. */
3839 if (ARG2 != 0
3840 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3841 sizeof(struct vki_old_sigaction))) {
3842 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3843 (void *)(Addr)ARG2);
3844 SET_STATUS_Failure ( VKI_EFAULT );
3845 } else if ((ARG3 != 0
3846 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3847 sizeof(struct vki_old_sigaction)))) {
3848 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3849 (void *)(Addr)ARG3);
3850 SET_STATUS_Failure ( VKI_EFAULT );
3851 } else {
3852 if (ARG2 != 0) {
3853 struct vki_old_sigaction *oldnew =
3854 (struct vki_old_sigaction *)(Addr)ARG2;
3856 new.ksa_handler = oldnew->ksa_handler;
3857 new.sa_flags = oldnew->sa_flags;
3858 new.sa_restorer = oldnew->sa_restorer;
3859 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3860 newp = &new;
3863 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3865 if (ARG3 != 0 && SUCCESS && RES == 0) {
3866 struct vki_old_sigaction *oldold =
3867 (struct vki_old_sigaction *)(Addr)ARG3;
3869 oldold->ksa_handler = oldp->ksa_handler;
3870 oldold->sa_flags = oldp->sa_flags;
3871 oldold->sa_restorer = oldp->sa_restorer;
3872 oldold->sa_mask = oldp->sa_mask.sig[0];
3876 POST(sys_sigaction)
3878 vg_assert(SUCCESS);
3879 if (RES == 0 && ARG3 != 0)
3880 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3882 #endif
3884 PRE(sys_signalfd)
3886 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
3887 (ULong)ARG3);
3888 PRE_REG_READ3(long, "sys_signalfd",
3889 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3890 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3891 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3892 SET_STATUS_Failure( VKI_EBADF );
3894 POST(sys_signalfd)
3896 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3897 VG_(close)(RES);
3898 SET_STATUS_Failure( VKI_EMFILE );
3899 } else {
3900 if (VG_(clo_track_fds))
3901 ML_(record_fd_open_nameless) (tid, RES);
3905 PRE(sys_signalfd4)
3907 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3908 SARG1, ARG2, ARG3, SARG4);
3909 PRE_REG_READ4(long, "sys_signalfd4",
3910 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3911 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3912 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3913 SET_STATUS_Failure( VKI_EBADF );
3915 POST(sys_signalfd4)
3917 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3918 VG_(close)(RES);
3919 SET_STATUS_Failure( VKI_EMFILE );
3920 } else {
3921 if (VG_(clo_track_fds))
3922 ML_(record_fd_open_nameless) (tid, RES);
3927 /* ---------------------------------------------------------------------
3928 rt_sig* wrappers
3929 ------------------------------------------------------------------ */
3931 PRE(sys_rt_sigaction)
3933 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3934 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3935 PRE_REG_READ4(long, "rt_sigaction",
3936 int, signum, const struct sigaction *, act,
3937 struct sigaction *, oldact, vki_size_t, sigsetsize);
3939 if (ARG2 != 0) {
3940 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
3941 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3942 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3943 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3944 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3945 && (sa->sa_flags & VKI_SA_RESTORER))
3946 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3948 if (ARG3 != 0)
3949 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3951 /* If the new or old sigaction is not NULL, but the structs
3952 aren't accessible then sigaction returns EFAULT and we cannot
3953 use either struct for our own bookkeeping. Just fail early. */
3954 if (ARG2 != 0
3955 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3956 sizeof(vki_sigaction_toK_t))) {
3957 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3958 (void *)(Addr)ARG2);
3959 SET_STATUS_Failure ( VKI_EFAULT );
3960 } else if ((ARG3 != 0
3961 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3962 sizeof(vki_sigaction_fromK_t)))) {
3963 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3964 (void *)(Addr)ARG3);
3965 SET_STATUS_Failure ( VKI_EFAULT );
3966 } else {
3968 // XXX: doesn't seem right to be calling do_sys_sigaction for
3969 // sys_rt_sigaction... perhaps this function should be renamed
3970 // VG_(do_sys_rt_sigaction)() --njn
3972 SET_STATUS_from_SysRes(
3973 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
3974 (vki_sigaction_fromK_t *)(Addr)ARG3)
3978 POST(sys_rt_sigaction)
3980 vg_assert(SUCCESS);
3981 if (RES == 0 && ARG3 != 0)
3982 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
3985 PRE(sys_rt_sigprocmask)
3987 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3988 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3989 PRE_REG_READ4(long, "rt_sigprocmask",
3990 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3991 vki_size_t, sigsetsize);
3992 if (ARG2 != 0)
3993 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3994 if (ARG3 != 0)
3995 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3997 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3998 // Since we want to use the set and oldset for bookkeeping we also want
3999 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4000 if (sizeof(vki_sigset_t) != ARG4)
4001 SET_STATUS_Failure( VKI_EINVAL );
4002 else if (ARG2 != 0
4003 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4004 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4005 (void *)(Addr)ARG2);
4006 SET_STATUS_Failure ( VKI_EFAULT );
4008 else if (ARG3 != 0
4009 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4010 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4011 (void *)(Addr)ARG3);
4012 SET_STATUS_Failure ( VKI_EFAULT );
4015 else {
4016 SET_STATUS_from_SysRes(
4017 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4018 (vki_sigset_t*) (Addr)ARG2,
4019 (vki_sigset_t*) (Addr)ARG3 )
4023 if (SUCCESS)
4024 *flags |= SfPollAfter;
4026 POST(sys_rt_sigprocmask)
4028 vg_assert(SUCCESS);
4029 if (RES == 0 && ARG3 != 0)
4030 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4033 PRE(sys_rt_sigpending)
4035 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4036 PRE_REG_READ2(long, "rt_sigpending",
4037 vki_sigset_t *, set, vki_size_t, sigsetsize);
4038 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4040 POST(sys_rt_sigpending)
4042 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4045 PRE(sys_rt_sigtimedwait)
4047 *flags |= SfMayBlock;
4048 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4049 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4050 ARG1, ARG2, ARG3, ARG4);
4051 PRE_REG_READ4(long, "rt_sigtimedwait",
4052 const vki_sigset_t *, set, vki_siginfo_t *, info,
4053 const struct timespec *, timeout, vki_size_t, sigsetsize);
4054 if (ARG1 != 0)
4055 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4056 if (ARG2 != 0)
4057 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4058 if (ARG3 != 0)
4059 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4060 ARG3, sizeof(struct vki_timespec) );
4062 POST(sys_rt_sigtimedwait)
4064 if (ARG2 != 0)
4065 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4068 PRE(sys_rt_sigqueueinfo)
4070 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4071 SARG1, SARG2, ARG3);
4072 PRE_REG_READ3(long, "rt_sigqueueinfo",
4073 int, pid, int, sig, vki_siginfo_t *, uinfo);
4074 if (ARG2 != 0)
4075 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4077 POST(sys_rt_sigqueueinfo)
4079 if (!ML_(client_signal_OK)(ARG2))
4080 SET_STATUS_Failure( VKI_EINVAL );
4083 PRE(sys_rt_tgsigqueueinfo)
4085 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4086 SARG1, SARG2, SARG3, ARG4);
4087 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4088 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4089 if (ARG3 != 0)
4090 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4093 POST(sys_rt_tgsigqueueinfo)
4095 if (!ML_(client_signal_OK)(ARG3))
4096 SET_STATUS_Failure( VKI_EINVAL );
4099 // XXX: x86-specific? The kernel prototypes for the different archs are
4100 // hard to decipher.
4101 PRE(sys_rt_sigsuspend)
4103 /* The C library interface to sigsuspend just takes a pointer to
4104 a signal mask but this system call has two arguments - a pointer
4105 to the mask and the number of bytes used by it. The kernel insists
4106 on the size being equal to sizeof(sigset_t) however and will just
4107 return EINVAL if it isn't.
4109 *flags |= SfMayBlock;
4110 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4111 ARG1, ARG2 );
4112 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4113 if (ARG1 != (Addr)NULL) {
4114 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4115 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4116 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4117 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4118 be killable by VG_(nuke_all_threads_except).
4119 We thus silently ignore the user request to mask this signal.
4120 Note that this is similar to what is done for e.g.
4121 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4122 } else {
4123 SET_STATUS_Failure(VKI_EFAULT);
4128 /* ---------------------------------------------------------------------
4129 linux msg* wrapper helpers
4130 ------------------------------------------------------------------ */
4132 void
4133 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4134 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4136 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4137 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4138 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4139 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4142 void
4143 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4144 UWord arg0, UWord arg1, UWord arg2,
4145 UWord arg3, UWord arg4 )
4147 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4148 long msgtyp, int msgflg); */
4149 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4150 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4151 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4153 void
4154 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4155 UWord res,
4156 UWord arg0, UWord arg1, UWord arg2,
4157 UWord arg3, UWord arg4 )
4159 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4160 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4161 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4164 void
4165 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4166 UWord arg0, UWord arg1, UWord arg2 )
4168 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4169 switch (arg1 /* cmd */) {
4170 case VKI_IPC_INFO:
4171 case VKI_MSG_INFO:
4172 case VKI_IPC_INFO|VKI_IPC_64:
4173 case VKI_MSG_INFO|VKI_IPC_64:
4174 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4175 arg2, sizeof(struct vki_msginfo) );
4176 break;
4177 case VKI_IPC_STAT:
4178 case VKI_MSG_STAT:
4179 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4180 arg2, sizeof(struct vki_msqid_ds) );
4181 break;
4182 case VKI_IPC_STAT|VKI_IPC_64:
4183 case VKI_MSG_STAT|VKI_IPC_64:
4184 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4185 arg2, sizeof(struct vki_msqid64_ds) );
4186 break;
4187 case VKI_IPC_SET:
4188 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4189 arg2, sizeof(struct vki_msqid_ds) );
4190 break;
4191 case VKI_IPC_SET|VKI_IPC_64:
4192 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4193 arg2, sizeof(struct vki_msqid64_ds) );
4194 break;
4197 void
4198 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4199 UWord res,
4200 UWord arg0, UWord arg1, UWord arg2 )
4202 switch (arg1 /* cmd */) {
4203 case VKI_IPC_INFO:
4204 case VKI_MSG_INFO:
4205 case VKI_IPC_INFO|VKI_IPC_64:
4206 case VKI_MSG_INFO|VKI_IPC_64:
4207 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4208 break;
4209 case VKI_IPC_STAT:
4210 case VKI_MSG_STAT:
4211 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4212 break;
4213 case VKI_IPC_STAT|VKI_IPC_64:
4214 case VKI_MSG_STAT|VKI_IPC_64:
4215 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4216 break;
4220 /* ---------------------------------------------------------------------
4221 Generic handler for sys_ipc
4222 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4223 are either direct system calls, or are all implemented via sys_ipc.
4224 ------------------------------------------------------------------ */
4225 #ifdef __NR_ipc
4226 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4228 Addr* a_p = (Addr*)a;
4229 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4230 return *a_p;
4233 static Bool semctl_cmd_has_4args (UWord cmd)
4235 switch (cmd & ~VKI_IPC_64)
4237 case VKI_IPC_INFO:
4238 case VKI_SEM_INFO:
4239 case VKI_IPC_STAT:
4240 case VKI_SEM_STAT:
4241 case VKI_IPC_SET:
4242 case VKI_GETALL:
4243 case VKI_SETALL:
4244 return True;
4245 default:
4246 return False;
4250 PRE(sys_ipc)
4252 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4253 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4255 switch (ARG1 /* call */) {
4256 case VKI_SEMOP:
4257 PRE_REG_READ5(int, "ipc",
4258 vki_uint, call, int, first, int, second, int, third,
4259 void *, ptr);
4260 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4261 *flags |= SfMayBlock;
4262 break;
4263 case VKI_SEMGET:
4264 PRE_REG_READ4(int, "ipc",
4265 vki_uint, call, int, first, int, second, int, third);
4266 break;
4267 case VKI_SEMCTL:
4269 PRE_REG_READ5(int, "ipc",
4270 vki_uint, call, int, first, int, second, int, third,
4271 void *, ptr);
4272 UWord arg;
4273 if (semctl_cmd_has_4args(ARG4))
4274 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4275 else
4276 arg = 0;
4277 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4278 break;
4280 case VKI_SEMTIMEDOP:
4281 PRE_REG_READ6(int, "ipc",
4282 vki_uint, call, int, first, int, second, int, third,
4283 void *, ptr, long, fifth);
4284 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4285 *flags |= SfMayBlock;
4286 break;
4287 case VKI_MSGSND:
4288 PRE_REG_READ5(int, "ipc",
4289 vki_uint, call, int, first, int, second, int, third,
4290 void *, ptr);
4291 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4292 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4293 *flags |= SfMayBlock;
4294 break;
4295 case VKI_MSGRCV:
4297 PRE_REG_READ5(int, "ipc",
4298 vki_uint, call, int, first, int, second, int, third,
4299 void *, ptr);
4300 Addr msgp;
4301 Word msgtyp;
4303 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4304 "msgrcv(msgp)" );
4305 msgtyp = deref_Addr( tid,
4306 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4307 "msgrcv(msgp)" );
4309 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4311 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4312 *flags |= SfMayBlock;
4313 break;
4315 case VKI_MSGGET:
4316 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4317 break;
4318 case VKI_MSGCTL:
4319 PRE_REG_READ5(int, "ipc",
4320 vki_uint, call, int, first, int, second, int, third,
4321 void *, ptr);
4322 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4323 break;
4324 case VKI_SHMAT:
4326 PRE_REG_READ5(int, "ipc",
4327 vki_uint, call, int, first, int, second, int, third,
4328 void *, ptr);
4329 UWord w;
4330 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4331 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4332 if (w == 0)
4333 SET_STATUS_Failure( VKI_EINVAL );
4334 else
4335 ARG5 = w;
4336 break;
4338 case VKI_SHMDT:
4339 PRE_REG_READ5(int, "ipc",
4340 vki_uint, call, int, first, int, second, int, third,
4341 void *, ptr);
4342 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4343 SET_STATUS_Failure( VKI_EINVAL );
4344 break;
4345 case VKI_SHMGET:
4346 PRE_REG_READ4(int, "ipc",
4347 vki_uint, call, int, first, int, second, int, third);
4348 if (ARG4 & VKI_SHM_HUGETLB) {
4349 static Bool warning_given = False;
4350 ARG4 &= ~VKI_SHM_HUGETLB;
4351 if (!warning_given) {
4352 warning_given = True;
4353 VG_(umsg)(
4354 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4357 break;
4358 case VKI_SHMCTL: /* IPCOP_shmctl */
4359 PRE_REG_READ5(int, "ipc",
4360 vki_uint, call, int, first, int, second, int, third,
4361 void *, ptr);
4362 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4363 break;
4364 default:
4365 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4366 VG_(core_panic)("... bye!\n");
4367 break; /*NOTREACHED*/
4371 POST(sys_ipc)
4373 vg_assert(SUCCESS);
4374 switch (ARG1 /* call */) {
4375 case VKI_SEMOP:
4376 case VKI_SEMGET:
4377 break;
4378 case VKI_SEMCTL:
4380 UWord arg;
4381 if (semctl_cmd_has_4args(ARG4))
4382 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4383 else
4384 arg = 0;
4385 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4386 break;
4388 case VKI_SEMTIMEDOP:
4389 case VKI_MSGSND:
4390 break;
4391 case VKI_MSGRCV:
4393 Addr msgp;
4394 Word msgtyp;
4396 msgp = deref_Addr( tid,
4397 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4398 "msgrcv(msgp)" );
4399 msgtyp = deref_Addr( tid,
4400 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4401 "msgrcv(msgp)" );
4403 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4404 break;
4406 case VKI_MSGGET:
4407 break;
4408 case VKI_MSGCTL:
4409 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4410 break;
4411 case VKI_SHMAT:
4413 Addr addr;
4415 /* force readability. before the syscall it is
4416 * indeed uninitialized, as can be seen in
4417 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4418 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4420 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4421 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4422 break;
4424 case VKI_SHMDT:
4425 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4426 break;
4427 case VKI_SHMGET:
4428 break;
4429 case VKI_SHMCTL:
4430 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4431 break;
4432 default:
4433 VG_(message)(Vg_DebugMsg,
4434 "FATAL: unhandled syscall(ipc) %lu\n",
4435 ARG1 );
4436 VG_(core_panic)("... bye!\n");
4437 break; /*NOTREACHED*/
4440 #endif
4442 PRE(sys_semget)
4444 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4445 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4448 PRE(sys_semop)
4450 *flags |= SfMayBlock;
4451 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4452 SARG1, ARG2, ARG3);
4453 PRE_REG_READ3(long, "semop",
4454 int, semid, struct sembuf *, sops, unsigned, nsoops);
4455 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4458 PRE(sys_semctl)
4460 switch (ARG3 & ~VKI_IPC_64) {
4461 case VKI_IPC_INFO:
4462 case VKI_SEM_INFO:
4463 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4464 SARG3, ARG4);
4465 PRE_REG_READ4(long, "semctl",
4466 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4467 break;
4468 case VKI_IPC_STAT:
4469 case VKI_SEM_STAT:
4470 case VKI_IPC_SET:
4471 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4472 SARG3, ARG4);
4473 PRE_REG_READ4(long, "semctl",
4474 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4475 break;
4476 case VKI_GETALL:
4477 case VKI_SETALL:
4478 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4479 SARG3, ARG4);
4480 PRE_REG_READ4(long, "semctl",
4481 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4482 break;
4483 default:
4484 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4485 PRE_REG_READ3(long, "semctl",
4486 int, semid, int, semnum, int, cmd);
4487 break;
4489 #ifdef VGP_amd64_linux
4490 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4491 #else
4492 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4493 #endif
4496 POST(sys_semctl)
4498 #ifdef VGP_amd64_linux
4499 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4500 #else
4501 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4502 #endif
4505 PRE(sys_semtimedop)
4507 *flags |= SfMayBlock;
4508 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
4509 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4510 PRE_REG_READ4(long, "semtimedop",
4511 int, semid, struct sembuf *, sops, unsigned, nsoops,
4512 struct timespec *, timeout);
4513 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4516 PRE(sys_msgget)
4518 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4519 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4522 PRE(sys_msgsnd)
4524 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4525 SARG1, ARG2, ARG3, SARG4);
4526 PRE_REG_READ4(long, "msgsnd",
4527 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4528 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4529 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4530 *flags |= SfMayBlock;
4533 PRE(sys_msgrcv)
4535 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
4536 SARG1, ARG2, ARG3, SARG4, SARG5);
4537 PRE_REG_READ5(long, "msgrcv",
4538 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4539 long, msgytp, int, msgflg);
4540 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4541 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4542 *flags |= SfMayBlock;
4544 POST(sys_msgrcv)
4546 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4549 PRE(sys_msgctl)
4551 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4552 PRE_REG_READ3(long, "msgctl",
4553 int, msqid, int, cmd, struct msqid_ds *, buf);
4554 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4557 POST(sys_msgctl)
4559 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4562 PRE(sys_shmget)
4564 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
4565 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4566 if (ARG3 & VKI_SHM_HUGETLB) {
4567 static Bool warning_given = False;
4568 ARG3 &= ~VKI_SHM_HUGETLB;
4569 if (!warning_given) {
4570 warning_given = True;
4571 VG_(umsg)(
4572 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4577 PRE(sys_shmat)
4579 UWord arg2tmp;
4580 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4581 PRE_REG_READ3(long, "shmat",
4582 int, shmid, const void *, shmaddr, int, shmflg);
4583 #if defined(VGP_arm_linux)
4584 /* Round the attach address down to an VKI_SHMLBA boundary if the
4585 client requested rounding. See #222545. This is necessary only
4586 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4587 other linux targets it is the same as the page size. */
4588 if (ARG3 & VKI_SHM_RND)
4589 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4590 #endif
4591 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4592 if (arg2tmp == 0)
4593 SET_STATUS_Failure( VKI_EINVAL );
4594 else
4595 ARG2 = arg2tmp; // used in POST
4598 POST(sys_shmat)
4600 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4603 PRE(sys_shmdt)
4605 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
4606 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4607 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4608 SET_STATUS_Failure( VKI_EINVAL );
4611 POST(sys_shmdt)
4613 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4616 PRE(sys_shmctl)
4618 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4619 PRE_REG_READ3(long, "shmctl",
4620 int, shmid, int, cmd, struct shmid_ds *, buf);
4621 #ifdef VGP_amd64_linux
4622 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4623 #else
4624 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4625 #endif
4628 POST(sys_shmctl)
4630 #ifdef VGP_amd64_linux
4631 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4632 #else
4633 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4634 #endif
4638 /* ---------------------------------------------------------------------
4639 Generic handler for sys_socketcall
4640 Depending on the platform, some socket related syscalls (e.g. socketpair,
4641 socket, bind, ...)
4642 are either direct system calls, or are all implemented via sys_socketcall.
4643 ------------------------------------------------------------------ */
4644 #ifdef __NR_socketcall
4645 PRE(sys_socketcall)
4647 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4648 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4649 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4650 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4651 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4652 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4654 // call PRE_MEM_READ and check for EFAULT result.
4655 #define PRE_MEM_READ_ef(msg, arg, size) \
4657 PRE_MEM_READ( msg, arg, size); \
4658 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
4659 SET_STATUS_Failure( VKI_EFAULT ); \
4660 break; \
4664 *flags |= SfMayBlock;
4665 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4666 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4668 switch (ARG1 /* request */) {
4670 case VKI_SYS_SOCKETPAIR:
4671 /* int socketpair(int d, int type, int protocol, int sv[2]); */
4672 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4673 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4674 break;
4676 case VKI_SYS_SOCKET:
4677 /* int socket(int domain, int type, int protocol); */
4678 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4679 break;
4681 case VKI_SYS_BIND:
4682 /* int bind(int sockfd, struct sockaddr *my_addr,
4683 int addrlen); */
4684 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4685 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4686 break;
4688 case VKI_SYS_LISTEN:
4689 /* int listen(int s, int backlog); */
4690 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4691 break;
4693 case VKI_SYS_ACCEPT:
4694 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4695 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4696 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4697 break;
4699 case VKI_SYS_ACCEPT4:
4700 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4701 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4702 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4703 break;
4705 case VKI_SYS_SENDTO:
4706 /* int sendto(int s, const void *msg, int len,
4707 unsigned int flags,
4708 const struct sockaddr *to, int tolen); */
4709 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4710 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4711 ARG2_3, ARG2_4, ARG2_5 );
4712 break;
4714 case VKI_SYS_SEND:
4715 /* int send(int s, const void *msg, size_t len, int flags); */
4716 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4717 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4718 break;
4720 case VKI_SYS_RECVFROM:
4721 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4722 struct sockaddr *from, int *fromlen); */
4723 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4724 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4725 ARG2_3, ARG2_4, ARG2_5 );
4726 break;
4728 case VKI_SYS_RECV:
4729 /* int recv(int s, void *buf, int len, unsigned int flags); */
4730 /* man 2 recv says:
4731 The recv call is normally used only on a connected socket
4732 (see connect(2)) and is identical to recvfrom with a NULL
4733 from parameter.
4735 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4736 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4737 break;
4739 case VKI_SYS_CONNECT:
4740 /* int connect(int sockfd,
4741 struct sockaddr *serv_addr, int addrlen ); */
4742 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4743 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4744 break;
4746 case VKI_SYS_SETSOCKOPT:
4747 /* int setsockopt(int s, int level, int optname,
4748 const void *optval, int optlen); */
4749 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4750 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4751 ARG2_3, ARG2_4 );
4752 break;
4754 case VKI_SYS_GETSOCKOPT:
4755 /* int getsockopt(int s, int level, int optname,
4756 void *optval, socklen_t *optlen); */
4757 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4758 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4759 ARG2_3, ARG2_4 );
4760 break;
4762 case VKI_SYS_GETSOCKNAME:
4763 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4764 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4765 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4766 break;
4768 case VKI_SYS_GETPEERNAME:
4769 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4770 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4771 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4772 break;
4774 case VKI_SYS_SHUTDOWN:
4775 /* int shutdown(int s, int how); */
4776 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4777 break;
4779 case VKI_SYS_SENDMSG:
4780 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4781 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4782 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
4783 (struct vki_msghdr *)(Addr)ARG2_1 );
4784 break;
4786 case VKI_SYS_RECVMSG:
4787 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4788 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4789 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
4790 (struct vki_msghdr *)(Addr)ARG2_1 );
4791 break;
4793 case VKI_SYS_RECVMMSG:
4794 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4795 struct timespec *timeout); */
4796 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4797 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4798 ARG2_4 );
4799 break;
4801 case VKI_SYS_SENDMMSG:
4802 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4803 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4804 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4805 break;
4807 default:
4808 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4809 SET_STATUS_Failure( VKI_EINVAL );
4810 break;
4812 # undef ARG2_0
4813 # undef ARG2_1
4814 # undef ARG2_2
4815 # undef ARG2_3
4816 # undef ARG2_4
4817 # undef ARG2_5
4820 POST(sys_socketcall)
4822 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4823 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4824 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4825 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4826 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4827 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4829 SysRes r;
4830 vg_assert(SUCCESS);
4831 switch (ARG1 /* request */) {
4833 case VKI_SYS_SOCKETPAIR:
4834 r = ML_(generic_POST_sys_socketpair)(
4835 tid, VG_(mk_SysRes_Success)(RES),
4836 ARG2_0, ARG2_1, ARG2_2, ARG2_3
4838 SET_STATUS_from_SysRes(r);
4839 break;
4841 case VKI_SYS_SOCKET:
4842 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4843 SET_STATUS_from_SysRes(r);
4844 break;
4846 case VKI_SYS_BIND:
4847 /* int bind(int sockfd, struct sockaddr *my_addr,
4848 int addrlen); */
4849 break;
4851 case VKI_SYS_LISTEN:
4852 /* int listen(int s, int backlog); */
4853 break;
4855 case VKI_SYS_ACCEPT:
4856 case VKI_SYS_ACCEPT4:
4857 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4858 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4859 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4860 ARG2_0, ARG2_1, ARG2_2 );
4861 SET_STATUS_from_SysRes(r);
4862 break;
4864 case VKI_SYS_SENDTO:
4865 break;
4867 case VKI_SYS_SEND:
4868 break;
4870 case VKI_SYS_RECVFROM:
4871 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4872 ARG2_0, ARG2_1, ARG2_2,
4873 ARG2_3, ARG2_4, ARG2_5 );
4874 break;
4876 case VKI_SYS_RECV:
4877 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4878 break;
4880 case VKI_SYS_CONNECT:
4881 break;
4883 case VKI_SYS_SETSOCKOPT:
4884 break;
4886 case VKI_SYS_GETSOCKOPT:
4887 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4888 ARG2_0, ARG2_1,
4889 ARG2_2, ARG2_3, ARG2_4 );
4890 break;
4892 case VKI_SYS_GETSOCKNAME:
4893 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4894 ARG2_0, ARG2_1, ARG2_2 );
4895 break;
4897 case VKI_SYS_GETPEERNAME:
4898 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4899 ARG2_0, ARG2_1, ARG2_2 );
4900 break;
4902 case VKI_SYS_SHUTDOWN:
4903 break;
4905 case VKI_SYS_SENDMSG:
4906 break;
4908 case VKI_SYS_RECVMSG:
4909 ML_(generic_POST_sys_recvmsg)( tid, "msg",
4910 (struct vki_msghdr *)(Addr)ARG2_1, RES );
4911 break;
4913 case VKI_SYS_RECVMMSG:
4914 ML_(linux_POST_sys_recvmmsg)( tid, RES,
4915 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4916 break;
4918 case VKI_SYS_SENDMMSG:
4919 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4920 break;
4922 default:
4923 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4924 VG_(core_panic)("... bye!\n");
4925 break; /*NOTREACHED*/
4927 # undef ARG2_0
4928 # undef ARG2_1
4929 # undef ARG2_2
4930 # undef ARG2_3
4931 # undef ARG2_4
4932 # undef ARG2_5
4934 #endif
4936 PRE(sys_socket)
4938 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4939 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4941 POST(sys_socket)
4943 SysRes r;
4944 vg_assert(SUCCESS);
4945 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4946 SET_STATUS_from_SysRes(r);
4949 PRE(sys_setsockopt)
4951 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
4952 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
4953 PRE_REG_READ5(long, "setsockopt",
4954 int, s, int, level, int, optname,
4955 const void *, optval, unsigned, optlen); // socklen_t
4956 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4959 PRE(sys_getsockopt)
4961 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
4962 SARG1, SARG2, SARG3, ARG4, SARG5);
4963 PRE_REG_READ5(long, "getsockopt",
4964 int, s, int, level, int, optname,
4965 void *, optval, int, *optlen);
4966 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4968 POST(sys_getsockopt)
4970 vg_assert(SUCCESS);
4971 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4972 ARG1,ARG2,ARG3,ARG4,ARG5);
4975 PRE(sys_connect)
4977 *flags |= SfMayBlock;
4978 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4979 PRE_REG_READ3(long, "connect",
4980 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4981 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4984 PRE(sys_accept)
4986 *flags |= SfMayBlock;
4987 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4988 SARG1, ARG2, ARG3);
4989 PRE_REG_READ3(long, "accept",
4990 int, s, struct sockaddr *, addr, int *, addrlen);
4991 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4993 POST(sys_accept)
4995 SysRes r;
4996 vg_assert(SUCCESS);
4997 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4998 ARG1,ARG2,ARG3);
4999 SET_STATUS_from_SysRes(r);
5002 PRE(sys_accept4)
5004 *flags |= SfMayBlock;
5005 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5006 SARG1, ARG2, ARG3, SARG4);
5007 PRE_REG_READ4(long, "accept4",
5008 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5009 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5011 POST(sys_accept4)
5013 SysRes r;
5014 vg_assert(SUCCESS);
5015 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5016 ARG1,ARG2,ARG3);
5017 SET_STATUS_from_SysRes(r);
5020 PRE(sys_send)
5022 *flags |= SfMayBlock;
5023 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5024 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5025 PRE_REG_READ4(long, "send",
5026 int, s, const void *, msg, vki_size_t, len,
5027 int, flags);
5029 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5032 PRE(sys_sendto)
5034 *flags |= SfMayBlock;
5035 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5036 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5037 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5038 PRE_REG_READ6(long, "sendto",
5039 int, s, const void *, msg, vki_size_t, len,
5040 unsigned int, flags,
5041 const struct sockaddr *, to, int, tolen);
5042 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5045 PRE (sys_recv)
5047 *flags |= SfMayBlock;
5048 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5049 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5050 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5051 unsigned int, flags);
5052 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5055 POST (sys_recv)
5057 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5060 PRE(sys_recvfrom)
5062 *flags |= SfMayBlock;
5063 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5064 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5065 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5066 PRE_REG_READ6(long, "recvfrom",
5067 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5068 struct sockaddr *, from, int *, fromlen);
5069 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5071 POST(sys_recvfrom)
5073 vg_assert(SUCCESS);
5074 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5075 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5078 PRE(sys_sendmsg)
5080 *flags |= SfMayBlock;
5081 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5082 SARG1, ARG2, ARG3);
5083 PRE_REG_READ3(long, "sendmsg",
5084 int, s, const struct msghdr *, msg, unsigned int, flags);
5085 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5088 PRE(sys_recvmsg)
5090 *flags |= SfMayBlock;
5091 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5092 SARG1, ARG2, ARG3);
5093 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5094 unsigned int, flags);
5095 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5097 POST(sys_recvmsg)
5099 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5100 RES);
5103 PRE(sys_shutdown)
5105 *flags |= SfMayBlock;
5106 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5107 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5110 PRE(sys_bind)
5112 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5113 PRE_REG_READ3(long, "bind",
5114 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5115 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5118 PRE(sys_listen)
5120 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5121 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5124 PRE(sys_getsockname)
5126 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5127 SARG1, ARG2, ARG3);
5128 PRE_REG_READ3(long, "getsockname",
5129 int, s, struct sockaddr *, name, int *, namelen);
5130 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5132 POST(sys_getsockname)
5134 vg_assert(SUCCESS);
5135 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5136 ARG1,ARG2,ARG3);
5139 PRE(sys_getpeername)
5141 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5142 SARG1, ARG2, ARG3);
5143 PRE_REG_READ3(long, "getpeername",
5144 int, s, struct sockaddr *, name, int *, namelen);
5145 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5147 POST(sys_getpeername)
5149 vg_assert(SUCCESS);
5150 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5151 ARG1,ARG2,ARG3);
5154 PRE(sys_socketpair)
5156 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5157 SARG3, ARG4);
5158 PRE_REG_READ4(long, "socketpair",
5159 int, d, int, type, int, protocol, int*, sv);
5160 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5162 POST(sys_socketpair)
5164 vg_assert(SUCCESS);
5165 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5166 ARG1,ARG2,ARG3,ARG4);
5170 /* ---------------------------------------------------------------------
5171 *at wrappers
5172 ------------------------------------------------------------------ */
5174 PRE(sys_openat)
5176 HChar name[30]; // large enough
5177 SysRes sres;
5179 if (ARG3 & VKI_O_CREAT) {
5180 // 4-arg version
5181 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5182 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5183 PRE_REG_READ4(long, "openat",
5184 int, dfd, const char *, filename, int, flags, int, mode);
5185 } else {
5186 // 3-arg version
5187 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5188 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5189 PRE_REG_READ3(long, "openat",
5190 int, dfd, const char *, filename, int, flags);
5193 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5195 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5196 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5197 be sure only to compare the bottom 32 bits. */
5198 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5199 && *(Char *)(Addr)ARG2 != '/'
5200 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5201 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5202 SET_STATUS_Failure( VKI_EBADF );
5204 /* Handle the case where the open is of /proc/self/cmdline or
5205 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5206 fake file we cooked up at startup (in m_main). Also, seek the
5207 cloned fd back to the start. */
5209 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5210 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5211 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5212 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5213 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5214 SET_STATUS_from_SysRes( sres );
5215 if (!sr_isError(sres)) {
5216 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5217 if (off < 0)
5218 SET_STATUS_Failure( VKI_EMFILE );
5220 return;
5223 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5225 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5226 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5227 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5228 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5229 sres = VG_(dup)( VG_(cl_auxv_fd) );
5230 SET_STATUS_from_SysRes( sres );
5231 if (!sr_isError(sres)) {
5232 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5233 if (off < 0)
5234 SET_STATUS_Failure( VKI_EMFILE );
5236 return;
5239 /* Otherwise handle normally */
5240 *flags |= SfMayBlock;
5243 POST(sys_openat)
5245 vg_assert(SUCCESS);
5246 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5247 VG_(close)(RES);
5248 SET_STATUS_Failure( VKI_EMFILE );
5249 } else {
5250 if (VG_(clo_track_fds))
5251 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5255 PRE(sys_mkdirat)
5257 *flags |= SfMayBlock;
5258 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5259 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5260 PRE_REG_READ3(long, "mkdirat",
5261 int, dfd, const char *, pathname, int, mode);
5262 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5265 PRE(sys_mknodat)
5267 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5268 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5269 PRE_REG_READ4(long, "mknodat",
5270 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5271 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5274 PRE(sys_fchownat)
5276 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5277 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5278 PRE_REG_READ4(long, "fchownat",
5279 int, dfd, const char *, path,
5280 vki_uid_t, owner, vki_gid_t, group);
5281 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5284 PRE(sys_futimesat)
5286 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5287 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5288 PRE_REG_READ3(long, "futimesat",
5289 int, dfd, char *, filename, struct timeval *, tvp);
5290 if (ARG2 != 0)
5291 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5292 if (ARG3 != 0)
5293 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5296 PRE(sys_utimensat)
5298 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5299 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5300 PRE_REG_READ4(long, "utimensat",
5301 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5302 if (ARG2 != 0)
5303 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5304 if (ARG3 != 0) {
5305 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5306 then the tv_sec field is ignored. */
5307 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5308 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5309 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5310 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5311 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5312 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5313 if (times[0].tv_nsec != VKI_UTIME_NOW
5314 && times[0].tv_nsec != VKI_UTIME_OMIT)
5315 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5316 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5317 if (times[1].tv_nsec != VKI_UTIME_NOW
5318 && times[1].tv_nsec != VKI_UTIME_OMIT)
5319 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5320 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5325 PRE(sys_newfstatat)
5327 FUSE_COMPATIBLE_MAY_BLOCK();
5328 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5329 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5330 PRE_REG_READ3(long, "fstatat",
5331 int, dfd, char *, file_name, struct stat *, buf);
5332 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5333 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5336 POST(sys_newfstatat)
5338 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5341 PRE(sys_unlinkat)
5343 *flags |= SfMayBlock;
5344 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5345 (HChar*)(Addr)ARG2);
5346 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5347 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5350 PRE(sys_renameat)
5352 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5353 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5354 ARG4, (HChar*)(Addr)ARG4);
5355 PRE_REG_READ4(long, "renameat",
5356 int, olddfd, const char *, oldpath,
5357 int, newdfd, const char *, newpath);
5358 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5359 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5362 PRE(sys_renameat2)
5364 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5365 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5366 ARG4, (HChar*)(Addr)ARG4, ARG5);
5367 PRE_REG_READ5(long, "renameat2",
5368 int, olddfd, const char *, oldpath,
5369 int, newdfd, const char *, newpath,
5370 unsigned int, flags);
5371 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5372 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5375 PRE(sys_linkat)
5377 *flags |= SfMayBlock;
5378 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5379 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5380 (HChar*)(Addr)ARG4, SARG5);
5381 PRE_REG_READ5(long, "linkat",
5382 int, olddfd, const char *, oldpath,
5383 int, newdfd, const char *, newpath,
5384 int, flags);
5385 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5386 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5389 PRE(sys_symlinkat)
5391 *flags |= SfMayBlock;
5392 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5393 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5394 PRE_REG_READ3(long, "symlinkat",
5395 const char *, oldpath, int, newdfd, const char *, newpath);
5396 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5397 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5400 PRE(sys_readlinkat)
5402 HChar name[30]; // large enough
5403 Word saved = SYSNO;
5405 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5406 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5407 PRE_REG_READ4(long, "readlinkat",
5408 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5409 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5410 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5413 * Handle the case where readlinkat is looking at /proc/self/exe or
5414 * /proc/<pid>/exe.
5416 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5417 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5418 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5419 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5420 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5421 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5422 ARG3, ARG4));
5423 } else {
5424 /* Normal case */
5425 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5428 if (SUCCESS && RES > 0)
5429 POST_MEM_WRITE( ARG3, RES );
5432 PRE(sys_fchmodat)
5434 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5435 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5436 PRE_REG_READ3(long, "fchmodat",
5437 int, dfd, const char *, path, vki_mode_t, mode);
5438 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5441 PRE(sys_faccessat)
5443 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5444 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5445 PRE_REG_READ3(long, "faccessat",
5446 int, dfd, const char *, pathname, int, mode);
5447 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5450 PRE(sys_name_to_handle_at)
5452 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
5453 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
5454 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5455 PRE_REG_READ5(int, "name_to_handle_at",
5456 int, dfd, const char *, name,
5457 struct vki_file_handle *, handle,
5458 int *, mnt_id, int, flag);
5459 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5460 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
5461 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5462 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5463 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5465 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5468 POST(sys_name_to_handle_at)
5470 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5471 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5472 POST_MEM_WRITE( ARG4, sizeof(int) );
5475 PRE(sys_open_by_handle_at)
5477 *flags |= SfMayBlock;
5478 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
5479 ARG2, SARG3);
5480 PRE_REG_READ3(int, "open_by_handle_at",
5481 int, mountdirfd,
5482 struct vki_file_handle *, handle,
5483 int, flags);
5484 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
5485 sizeof(struct vki_file_handle) +
5486 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
5489 POST(sys_open_by_handle_at)
5491 vg_assert(SUCCESS);
5492 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5493 VG_(close)(RES);
5494 SET_STATUS_Failure( VKI_EMFILE );
5495 } else {
5496 if (VG_(clo_track_fds))
5497 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5501 /* ---------------------------------------------------------------------
5502 p{read,write}v wrappers
5503 ------------------------------------------------------------------ */
5505 PRE(sys_preadv)
5507 Int i;
5508 struct vki_iovec * vec;
5509 *flags |= SfMayBlock;
5510 #if VG_WORDSIZE == 4
5511 /* Note that the offset argument here is in lo+hi order on both
5512 big and little endian platforms... */
5513 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5514 "u, %lld )",
5515 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5516 PRE_REG_READ5(ssize_t, "preadv",
5517 unsigned long, fd, const struct iovec *, vector,
5518 unsigned long, count, vki_u32, offset_low,
5519 vki_u32, offset_high);
5520 #elif VG_WORDSIZE == 8
5521 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5522 PRE_REG_READ4(ssize_t, "preadv",
5523 unsigned long, fd, const struct iovec *, vector,
5524 unsigned long, count, Word, offset);
5525 #else
5526 # error Unexpected word size
5527 #endif
5528 if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
5529 SET_STATUS_Failure( VKI_EBADF );
5530 } else {
5531 PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
5533 if (ARG2 != 0) {
5534 /* ToDo: don't do any of the following if the vector is invalid */
5535 vec = (struct vki_iovec *)(Addr)ARG2;
5536 for (i = 0; i < (Int)ARG3; i++)
5537 PRE_MEM_WRITE( "preadv(vector[...])",
5538 (Addr)vec[i].iov_base, vec[i].iov_len );
5543 POST(sys_preadv)
5545 vg_assert(SUCCESS);
5546 if (RES > 0) {
5547 Int i;
5548 struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
5549 Int remains = RES;
5551 /* RES holds the number of bytes read. */
5552 for (i = 0; i < (Int)ARG3; i++) {
5553 Int nReadThisBuf = vec[i].iov_len;
5554 if (nReadThisBuf > remains) nReadThisBuf = remains;
5555 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5556 remains -= nReadThisBuf;
5557 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5562 PRE(sys_pwritev)
5564 Int i;
5565 struct vki_iovec * vec;
5566 *flags |= SfMayBlock;
5567 #if VG_WORDSIZE == 4
5568 /* Note that the offset argument here is in lo+hi order on both
5569 big and little endian platforms... */
5570 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5571 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5572 PRE_REG_READ5(ssize_t, "pwritev",
5573 unsigned long, fd, const struct iovec *, vector,
5574 unsigned long, count, vki_u32, offset_low,
5575 vki_u32, offset_high);
5576 #elif VG_WORDSIZE == 8
5577 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5578 PRE_REG_READ4(ssize_t, "pwritev",
5579 unsigned long, fd, const struct iovec *, vector,
5580 unsigned long, count, Word, offset);
5581 #else
5582 # error Unexpected word size
5583 #endif
5584 if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
5585 SET_STATUS_Failure( VKI_EBADF );
5586 } else {
5587 PRE_MEM_READ( "pwritev(vector)",
5588 ARG2, ARG3 * sizeof(struct vki_iovec) );
5589 if (ARG2 != 0) {
5590 /* ToDo: don't do any of the following if the vector is invalid */
5591 vec = (struct vki_iovec *)(Addr)ARG2;
5592 for (i = 0; i < (Int)ARG3; i++)
5593 PRE_MEM_READ( "pwritev(vector[...])",
5594 (Addr)vec[i].iov_base, vec[i].iov_len );
5599 /* ---------------------------------------------------------------------
5600 process_vm_{read,write}v wrappers
5601 ------------------------------------------------------------------ */
5603 PRE(sys_process_vm_readv)
5605 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5606 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5607 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5608 PRE_REG_READ6(ssize_t, "process_vm_readv",
5609 vki_pid_t, pid,
5610 const struct iovec *, lvec,
5611 unsigned long, liovcnt,
5612 const struct iovec *, rvec,
5613 unsigned long, riovcnt,
5614 unsigned long, flags);
5615 PRE_MEM_READ( "process_vm_readv(lvec)",
5616 ARG2, ARG3 * sizeof(struct vki_iovec) );
5617 PRE_MEM_READ( "process_vm_readv(rvec)",
5618 ARG4, ARG5 * sizeof(struct vki_iovec) );
5619 if (ARG2 != 0
5620 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5621 sizeof(struct vki_iovec) * ARG3)) {
5622 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5623 UInt i;
5624 for (i = 0; i < ARG3; i++)
5625 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5626 (Addr)vec[i].iov_base, vec[i].iov_len );
5630 POST(sys_process_vm_readv)
5632 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5633 UInt remains = RES;
5634 UInt i;
5635 for (i = 0; i < ARG3; i++) {
5636 UInt nReadThisBuf = vec[i].iov_len <= remains ?
5637 vec[i].iov_len : remains;
5638 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5639 remains -= nReadThisBuf;
5643 PRE(sys_process_vm_writev)
5645 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5646 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5647 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5648 PRE_REG_READ6(ssize_t, "process_vm_writev",
5649 vki_pid_t, pid,
5650 const struct iovec *, lvec,
5651 unsigned long, liovcnt,
5652 const struct iovec *, rvec,
5653 unsigned long, riovcnt,
5654 unsigned long, flags);
5655 PRE_MEM_READ( "process_vm_writev(lvec)",
5656 ARG2, ARG3 * sizeof(struct vki_iovec) );
5657 PRE_MEM_READ( "process_vm_writev(rvec)",
5658 ARG4, ARG5 * sizeof(struct vki_iovec) );
5659 if (ARG2 != 0
5660 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5661 sizeof(struct vki_iovec) * ARG3)) {
5662 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5663 UInt i;
5664 for (i = 0; i < ARG3; i++)
5665 PRE_MEM_READ( "process_vm_writev(lvec[...])",
5666 (Addr)vec[i].iov_base, vec[i].iov_len );
5670 /* ---------------------------------------------------------------------
5671 {send,recv}mmsg wrappers
5672 ------------------------------------------------------------------ */
5674 PRE(sys_sendmmsg)
5676 *flags |= SfMayBlock;
5677 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
5678 SARG3, SARG4);
5679 PRE_REG_READ4(long, "sendmmsg",
5680 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5681 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5684 POST(sys_sendmmsg)
5686 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5689 PRE(sys_recvmmsg)
5691 *flags |= SfMayBlock;
5692 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
5693 FMT_REGWORD "x )",
5694 SARG1, ARG2, SARG3, SARG4, ARG5);
5695 PRE_REG_READ5(long, "recvmmsg",
5696 int, s, struct mmsghdr *, mmsg, int, vlen,
5697 int, flags, struct timespec *, timeout);
5698 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5701 POST(sys_recvmmsg)
5703 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5706 /* ---------------------------------------------------------------------
5707 key retention service wrappers
5708 ------------------------------------------------------------------ */
5710 PRE(sys_request_key)
5712 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5713 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
5714 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
5715 PRE_REG_READ4(long, "request_key",
5716 const char *, type, const char *, description,
5717 const char *, callout_info, vki_key_serial_t, keyring);
5718 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5719 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5720 if (ARG3 != (UWord)NULL)
5721 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5724 PRE(sys_add_key)
5726 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5727 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
5728 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5729 PRE_REG_READ5(long, "add_key",
5730 const char *, type, const char *, description,
5731 const void *, payload, vki_size_t, plen,
5732 vki_key_serial_t, keyring);
5733 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5734 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5735 if (ARG3 != (UWord)NULL)
5736 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5739 PRE(sys_keyctl)
5741 switch (ARG1 /* option */) {
5742 case VKI_KEYCTL_GET_KEYRING_ID:
5743 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5744 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5745 int, option, vki_key_serial_t, id, int, create);
5746 break;
5747 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5748 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
5749 "x(%s) )", ARG2,(char*)(Addr)ARG2);
5750 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5751 int, option, const char *, name);
5752 if (ARG2 != (UWord)NULL)
5753 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5754 break;
5755 case VKI_KEYCTL_UPDATE:
5756 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
5757 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5758 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5759 int, option, vki_key_serial_t, key,
5760 const void *, payload, vki_size_t, plen);
5761 if (ARG3 != (UWord)NULL)
5762 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5763 break;
5764 case VKI_KEYCTL_REVOKE:
5765 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5766 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5767 int, option, vki_key_serial_t, id);
5768 break;
5769 case VKI_KEYCTL_CHOWN:
5770 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
5771 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5772 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5773 int, option, vki_key_serial_t, id,
5774 vki_uid_t, uid, vki_gid_t, gid);
5775 break;
5776 case VKI_KEYCTL_SETPERM:
5777 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
5778 SARG2, ARG3);
5779 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5780 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5781 break;
5782 case VKI_KEYCTL_DESCRIBE:
5783 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
5784 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5785 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5786 int, option, vki_key_serial_t, id,
5787 char *, buffer, vki_size_t, buflen);
5788 if (ARG3 != (UWord)NULL)
5789 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5790 break;
5791 case VKI_KEYCTL_CLEAR:
5792 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5793 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5794 int, option, vki_key_serial_t, keyring);
5795 break;
5796 case VKI_KEYCTL_LINK:
5797 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5798 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5799 vki_key_serial_t, keyring, vki_key_serial_t, key);
5800 break;
5801 case VKI_KEYCTL_UNLINK:
5802 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5803 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5804 vki_key_serial_t, keyring, vki_key_serial_t, key);
5805 break;
5806 case VKI_KEYCTL_SEARCH:
5807 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
5808 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
5809 ARG4, (HChar*)(Addr)ARG4, SARG5);
5810 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5811 int, option, vki_key_serial_t, keyring,
5812 const char *, type, const char *, description,
5813 vki_key_serial_t, destring);
5814 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5815 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5816 break;
5817 case VKI_KEYCTL_READ:
5818 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5819 "u )", SARG2, ARG3, ARG4);
5820 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5821 int, option, vki_key_serial_t, keyring,
5822 char *, buffer, vki_size_t, buflen);
5823 if (ARG3 != (UWord)NULL)
5824 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5825 break;
5826 case VKI_KEYCTL_INSTANTIATE:
5827 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
5828 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
5829 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5830 int, option, vki_key_serial_t, key,
5831 char *, payload, vki_size_t, plen,
5832 vki_key_serial_t, keyring);
5833 if (ARG3 != (UWord)NULL)
5834 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5835 break;
5836 case VKI_KEYCTL_NEGATE:
5837 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
5838 SARG2, ARG3, SARG4);
5839 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5840 int, option, vki_key_serial_t, key,
5841 unsigned, timeout, vki_key_serial_t, keyring);
5842 break;
5843 case VKI_KEYCTL_SET_REQKEY_KEYRING:
5844 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5845 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5846 int, option, int, reqkey_defl);
5847 break;
5848 case VKI_KEYCTL_SET_TIMEOUT:
5849 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
5850 SARG2, ARG3);
5851 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5852 int, option, vki_key_serial_t, key, unsigned, timeout);
5853 break;
5854 case VKI_KEYCTL_ASSUME_AUTHORITY:
5855 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5856 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5857 int, option, vki_key_serial_t, key);
5858 break;
5859 default:
5860 PRINT("sys_keyctl ( %ld ) ", SARG1);
5861 PRE_REG_READ1(long, "keyctl", int, option);
5862 break;
5866 POST(sys_keyctl)
5868 vg_assert(SUCCESS);
5869 switch (ARG1 /* option */) {
5870 case VKI_KEYCTL_DESCRIBE:
5871 case VKI_KEYCTL_READ:
5872 if (RES > ARG4)
5873 POST_MEM_WRITE(ARG3, ARG4);
5874 else
5875 POST_MEM_WRITE(ARG3, RES);
5876 break;
5877 default:
5878 break;
5882 /* ---------------------------------------------------------------------
5883 ioprio_ wrappers
5884 ------------------------------------------------------------------ */
5886 PRE(sys_ioprio_set)
5888 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5889 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5892 PRE(sys_ioprio_get)
5894 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
5895 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5898 /* ---------------------------------------------------------------------
5899 _module wrappers
5900 ------------------------------------------------------------------ */
5902 PRE(sys_init_module)
5904 *flags |= SfMayBlock;
5905 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5906 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
5907 PRE_REG_READ3(long, "init_module",
5908 void *, umod, unsigned long, len, const char *, uargs);
5909 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5910 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5913 PRE(sys_finit_module)
5915 *flags |= SfMayBlock;
5917 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
5918 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5919 PRE_REG_READ3(long, "finit_module",
5920 int, fd, const char *, params, int, flags);
5921 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
5924 PRE(sys_delete_module)
5926 *flags |= SfMayBlock;
5927 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
5928 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
5929 PRE_REG_READ2(long, "delete_module",
5930 const char *, name_user, unsigned int, flags);
5931 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5934 /* ---------------------------------------------------------------------
5935 splice wrappers
5936 ------------------------------------------------------------------ */
5938 PRE(sys_splice)
5940 *flags |= SfMayBlock;
5941 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
5942 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5943 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
5944 PRE_REG_READ6(vki_ssize_t, "splice",
5945 int, fd_in, vki_loff_t *, off_in,
5946 int, fd_out, vki_loff_t *, off_out,
5947 vki_size_t, len, unsigned int, flags);
5948 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5949 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5950 SET_STATUS_Failure( VKI_EBADF );
5951 } else {
5952 if (ARG2 != 0)
5953 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5954 if (ARG4 != 0)
5955 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5959 PRE(sys_tee)
5961 *flags |= SfMayBlock;
5962 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
5963 SARG1, SARG2, ARG3, ARG4);
5964 PRE_REG_READ4(vki_ssize_t, "tee",
5965 int, fd_in, int, fd_out,
5966 vki_size_t, len, unsigned int, flags);
5967 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5968 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5969 SET_STATUS_Failure( VKI_EBADF );
5973 PRE(sys_vmsplice)
5975 Int fdfl;
5976 *flags |= SfMayBlock;
5977 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5978 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5979 PRE_REG_READ4(vki_ssize_t, "splice",
5980 int, fd, struct vki_iovec *, iov,
5981 unsigned long, nr_segs, unsigned int, flags);
5982 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5983 SET_STATUS_Failure( VKI_EBADF );
5984 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5985 SET_STATUS_Failure( VKI_EBADF );
5986 } else {
5987 const struct vki_iovec *iov;
5988 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5989 for (iov = (struct vki_iovec *)(Addr)ARG2;
5990 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
5992 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
5993 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
5994 PRE_MEM_WRITE( "vmsplice(iov[...])",
5995 (Addr)iov->iov_base, iov->iov_len );
5996 else
5997 PRE_MEM_READ( "vmsplice(iov[...])",
5998 (Addr)iov->iov_base, iov->iov_len );
6004 POST(sys_vmsplice)
6006 vg_assert(SUCCESS);
6007 if (RES > 0) {
6008 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6009 vg_assert(fdfl >= 0);
6010 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6012 const struct vki_iovec *iov;
6013 for (iov = (struct vki_iovec *)(Addr)ARG2;
6014 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6016 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6022 /* ---------------------------------------------------------------------
6023 oprofile-related wrappers
6024 ------------------------------------------------------------------ */
6026 #if defined(VGP_x86_linux)
6027 PRE(sys_lookup_dcookie)
6029 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6030 MERGE64(ARG1,ARG2), ARG3, ARG4);
6031 PRE_REG_READ4(long, "lookup_dcookie",
6032 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6033 char *, buf, vki_size_t, len);
6034 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6036 POST(sys_lookup_dcookie)
6038 vg_assert(SUCCESS);
6039 if (ARG3 != (Addr)NULL)
6040 POST_MEM_WRITE( ARG3, RES);
6042 #endif
6044 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6045 || defined(VGP_arm64_linux)
6046 PRE(sys_lookup_dcookie)
6048 *flags |= SfMayBlock;
6049 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6050 PRE_REG_READ3(int, "lookup_dcookie",
6051 unsigned long long, cookie, char *, buf, vki_size_t, len);
6053 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6056 POST(sys_lookup_dcookie)
6058 vg_assert(SUCCESS);
6059 if (ARG2 != (Addr)NULL)
6060 POST_MEM_WRITE( ARG2, RES );
6062 #endif
6064 /* ---------------------------------------------------------------------
6065 fcntl wrappers
6066 ------------------------------------------------------------------ */
6068 PRE(sys_fcntl)
6070 switch (ARG2) {
6071 // These ones ignore ARG3.
6072 case VKI_F_GETFD:
6073 case VKI_F_GETFL:
6074 case VKI_F_GETOWN:
6075 case VKI_F_GETSIG:
6076 case VKI_F_GETLEASE:
6077 case VKI_F_GETPIPE_SZ:
6078 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6079 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6080 break;
6082 // These ones use ARG3 as "arg".
6083 case VKI_F_DUPFD:
6084 case VKI_F_DUPFD_CLOEXEC:
6085 case VKI_F_SETFD:
6086 case VKI_F_SETFL:
6087 case VKI_F_SETLEASE:
6088 case VKI_F_NOTIFY:
6089 case VKI_F_SETOWN:
6090 case VKI_F_SETSIG:
6091 case VKI_F_SETPIPE_SZ:
6092 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6093 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6094 PRE_REG_READ3(long, "fcntl",
6095 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6096 break;
6098 // These ones use ARG3 as "lock".
6099 case VKI_F_GETLK:
6100 case VKI_F_SETLK:
6101 case VKI_F_SETLKW:
6102 case VKI_F_OFD_GETLK:
6103 case VKI_F_OFD_SETLK:
6104 case VKI_F_OFD_SETLKW:
6105 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6106 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6107 PRE_REG_READ3(long, "fcntl",
6108 unsigned int, fd, unsigned int, cmd,
6109 struct vki_flock *, lock);
6111 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6112 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6113 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6114 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6115 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6116 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6117 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6120 break;
6122 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6123 case VKI_F_GETLK64:
6124 case VKI_F_SETLK64:
6125 case VKI_F_SETLKW64:
6126 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6127 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6128 PRE_REG_READ3(long, "fcntl",
6129 unsigned int, fd, unsigned int, cmd,
6130 struct flock64 *, lock);
6132 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6133 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6134 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6135 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6136 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6137 if (ARG2 == VKI_F_GETLK64) {
6138 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6141 break;
6142 # endif
6144 case VKI_F_SETOWN_EX:
6145 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6146 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6147 PRE_REG_READ3(long, "fcntl",
6148 unsigned int, fd, unsigned int, cmd,
6149 struct vki_f_owner_ex *, arg);
6150 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6151 break;
6153 case VKI_F_GETOWN_EX:
6154 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6155 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6156 PRE_REG_READ3(long, "fcntl",
6157 unsigned int, fd, unsigned int, cmd,
6158 struct vki_f_owner_ex *, arg);
6159 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6160 break;
6162 default:
6163 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6164 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6165 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6166 ARG2);
6167 SET_STATUS_Failure( VKI_EINVAL );
6168 break;
6171 # if defined(VGP_x86_linux)
6172 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6173 # else
6174 if (ARG2 == VKI_F_SETLKW)
6175 # endif
6176 *flags |= SfMayBlock;
6179 POST(sys_fcntl)
6181 vg_assert(SUCCESS);
6182 if (ARG2 == VKI_F_DUPFD) {
6183 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6184 VG_(close)(RES);
6185 SET_STATUS_Failure( VKI_EMFILE );
6186 } else {
6187 if (VG_(clo_track_fds))
6188 ML_(record_fd_open_named)(tid, RES);
6191 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6192 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6193 VG_(close)(RES);
6194 SET_STATUS_Failure( VKI_EMFILE );
6195 } else {
6196 if (VG_(clo_track_fds))
6197 ML_(record_fd_open_named)(tid, RES);
6199 } else if (ARG2 == VKI_F_GETOWN_EX) {
6200 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6201 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6202 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6203 POST_FIELD_WRITE(lock->l_pid);
6204 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6205 } else if (ARG2 == VKI_F_GETLK64) {
6206 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6207 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6208 # endif
6212 // XXX: wrapper only suitable for 32-bit systems
6213 PRE(sys_fcntl64)
6215 switch (ARG2) {
6216 // These ones ignore ARG3.
6217 case VKI_F_GETFD:
6218 case VKI_F_GETFL:
6219 case VKI_F_GETOWN:
6220 case VKI_F_SETOWN:
6221 case VKI_F_GETSIG:
6222 case VKI_F_SETSIG:
6223 case VKI_F_GETLEASE:
6224 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6225 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6226 break;
6228 // These ones use ARG3 as "arg".
6229 case VKI_F_DUPFD:
6230 case VKI_F_DUPFD_CLOEXEC:
6231 case VKI_F_SETFD:
6232 case VKI_F_SETFL:
6233 case VKI_F_SETLEASE:
6234 case VKI_F_NOTIFY:
6235 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6236 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6237 PRE_REG_READ3(long, "fcntl64",
6238 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6239 break;
6241 // These ones use ARG3 as "lock".
6242 case VKI_F_GETLK:
6243 case VKI_F_SETLK:
6244 case VKI_F_SETLKW:
6245 # if defined(VGP_x86_linux)
6246 case VKI_F_GETLK64:
6247 case VKI_F_SETLK64:
6248 case VKI_F_SETLKW64:
6249 # endif
6250 case VKI_F_OFD_GETLK:
6251 case VKI_F_OFD_SETLK:
6252 case VKI_F_OFD_SETLKW:
6253 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6254 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6255 PRE_REG_READ3(long, "fcntl64",
6256 unsigned int, fd, unsigned int, cmd,
6257 struct flock64 *, lock);
6258 break;
6260 case VKI_F_SETOWN_EX:
6261 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6262 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6263 PRE_REG_READ3(long, "fcntl",
6264 unsigned int, fd, unsigned int, cmd,
6265 struct vki_f_owner_ex *, arg);
6266 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6267 break;
6269 case VKI_F_GETOWN_EX:
6270 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6271 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6272 PRE_REG_READ3(long, "fcntl",
6273 unsigned int, fd, unsigned int, cmd,
6274 struct vki_f_owner_ex *, arg);
6275 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6276 break;
6279 # if defined(VGP_x86_linux)
6280 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6281 # else
6282 if (ARG2 == VKI_F_SETLKW)
6283 # endif
6284 *flags |= SfMayBlock;
6287 POST(sys_fcntl64)
6289 vg_assert(SUCCESS);
6290 if (ARG2 == VKI_F_DUPFD) {
6291 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6292 VG_(close)(RES);
6293 SET_STATUS_Failure( VKI_EMFILE );
6294 } else {
6295 if (VG_(clo_track_fds))
6296 ML_(record_fd_open_named)(tid, RES);
6299 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6300 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6301 VG_(close)(RES);
6302 SET_STATUS_Failure( VKI_EMFILE );
6303 } else {
6304 if (VG_(clo_track_fds))
6305 ML_(record_fd_open_named)(tid, RES);
6307 } else if (ARG2 == VKI_F_GETOWN_EX) {
6308 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6312 /* ---------------------------------------------------------------------
6313 ioctl wrappers
6314 ------------------------------------------------------------------ */
6316 struct vg_drm_version_info {
6317 struct vki_drm_version data;
6318 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6321 PRE(sys_ioctl)
6323 *flags |= SfMayBlock;
6325 ARG2 = (UInt)ARG2;
6327 // We first handle the ones that don't use ARG3 (even as a
6328 // scalar/non-pointer argument).
6329 switch (ARG2 /* request */) {
6331 /* asm-generic/ioctls.h */
6332 case VKI_FIOCLEX:
6333 case VKI_FIONCLEX:
6334 case VKI_TIOCNOTTY:
6336 /* linux perf_event ioctls */
6337 case VKI_PERF_EVENT_IOC_ENABLE:
6338 case VKI_PERF_EVENT_IOC_DISABLE:
6340 /* linux/soundcard interface (ALSA) */
6341 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6342 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6343 case VKI_SNDRV_PCM_IOCTL_PREPARE:
6344 case VKI_SNDRV_PCM_IOCTL_RESET:
6345 case VKI_SNDRV_PCM_IOCTL_START:
6346 case VKI_SNDRV_PCM_IOCTL_DROP:
6347 case VKI_SNDRV_PCM_IOCTL_DRAIN:
6348 case VKI_SNDRV_PCM_IOCTL_RESUME:
6349 case VKI_SNDRV_PCM_IOCTL_XRUN:
6350 case VKI_SNDRV_PCM_IOCTL_UNLINK:
6351 case VKI_SNDRV_TIMER_IOCTL_START:
6352 case VKI_SNDRV_TIMER_IOCTL_STOP:
6353 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6354 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6356 /* SCSI no operand */
6357 case VKI_SCSI_IOCTL_DOORLOCK:
6358 case VKI_SCSI_IOCTL_DOORUNLOCK:
6360 /* CDROM stuff. */
6361 case VKI_CDROM_DISC_STATUS:
6362 case VKI_CDROMSTOP:
6364 /* DVD stuff */
6365 case VKI_DVD_READ_STRUCT:
6367 /* KVM ioctls that don't check for a numeric value as parameter */
6368 case VKI_KVM_S390_ENABLE_SIE:
6369 case VKI_KVM_CREATE_IRQCHIP:
6370 case VKI_KVM_S390_INITIAL_RESET:
6371 case VKI_KVM_KVMCLOCK_CTRL:
6373 /* vhost without parameter */
6374 case VKI_VHOST_SET_OWNER:
6375 case VKI_VHOST_RESET_OWNER:
6377 /* User input device creation */
6378 case VKI_UI_DEV_CREATE:
6379 case VKI_UI_DEV_DESTROY:
6381 /* InfiniBand */
6382 case VKI_IB_USER_MAD_ENABLE_PKEY:
6384 /* Lustre */
6385 case VKI_LL_IOC_GROUP_LOCK:
6386 case VKI_LL_IOC_GROUP_UNLOCK:
6388 /* V4L2 */
6389 case VKI_V4L2_LOG_STATUS:
6391 /* DVB */
6392 case VKI_DMX_STOP:
6393 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
6394 PRE_REG_READ2(long, "ioctl",
6395 unsigned int, fd, unsigned int, request);
6396 return;
6398 default:
6399 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
6400 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6401 PRE_REG_READ3(long, "ioctl",
6402 unsigned int, fd, unsigned int, request, unsigned long, arg);
6403 break;
6406 // We now handle those that do look at ARG3 (and unknown ones fall into
6407 // this category). Nb: some of these may well belong in the
6408 // doesn't-use-ARG3 switch above.
6409 switch (ARG2 /* request */) {
6411 case VKI_ION_IOC_ALLOC: {
6412 struct vki_ion_allocation_data* data
6413 = (struct vki_ion_allocation_data*)(Addr)ARG3;
6414 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
6415 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
6416 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6417 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
6418 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
6419 break;
6421 case VKI_ION_IOC_MAP: {
6422 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6423 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6424 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
6425 break;
6427 case VKI_ION_IOC_IMPORT: {
6428 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6429 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
6430 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6431 break;
6434 case VKI_SYNC_IOC_MERGE: {
6435 struct vki_sync_merge_data* data =
6436 (struct vki_sync_merge_data*)(Addr)ARG3;
6437 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
6438 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
6439 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6440 break;
6443 case VKI_TCSETS:
6444 case VKI_TCSETSW:
6445 case VKI_TCSETSF:
6446 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6447 break;
6448 case VKI_TCGETS:
6449 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6450 break;
6451 case VKI_TCSETA:
6452 case VKI_TCSETAW:
6453 case VKI_TCSETAF:
6454 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6455 break;
6456 case VKI_TCGETA:
6457 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6458 break;
6459 case VKI_TCSBRK:
6460 case VKI_TCXONC:
6461 case VKI_TCSBRKP:
6462 case VKI_TCFLSH:
6463 case VKI_TIOCSIG:
6464 /* These just take an int by value */
6465 break;
6466 case VKI_TIOCGWINSZ:
6467 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6468 break;
6469 case VKI_TIOCSWINSZ:
6470 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
6471 break;
6472 case VKI_TIOCMBIS:
6473 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
6474 break;
6475 case VKI_TIOCMBIC:
6476 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
6477 break;
6478 case VKI_TIOCMSET:
6479 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
6480 break;
6481 case VKI_TIOCMGET:
6482 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
6483 break;
6484 case VKI_TIOCLINUX:
6485 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
6486 if (*(char *)(Addr)ARG3 == 11) {
6487 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6489 break;
6490 case VKI_TIOCGPGRP:
6491 /* Get process group ID for foreground processing group. */
6492 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6493 break;
6494 case VKI_TIOCSPGRP:
6495 /* Set a process group ID? */
6496 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6497 break;
6498 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6499 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6500 break;
6501 case VKI_TIOCSCTTY:
6502 /* Just takes an int value. */
6503 break;
6504 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6505 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6506 break;
6507 case VKI_FIONBIO:
6508 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
6509 break;
6510 case VKI_FIOASYNC:
6511 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
6512 break;
6513 case VKI_FIONREAD: /* identical to SIOCINQ */
6514 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
6515 break;
6516 case VKI_FIOQSIZE:
6517 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
6518 break;
6520 case VKI_TIOCSERGETLSR:
6521 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6522 break;
6523 case VKI_TIOCGICOUNT:
6524 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6525 sizeof(struct vki_serial_icounter_struct) );
6526 break;
6528 case VKI_SG_SET_COMMAND_Q:
6529 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6530 break;
6531 case VKI_SG_IO:
6532 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6534 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
6535 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6536 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6537 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6538 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6541 break;
6542 case VKI_SG_GET_SCSI_ID:
6543 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6544 break;
6545 case VKI_SG_SET_RESERVED_SIZE:
6546 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6547 break;
6548 case VKI_SG_SET_TIMEOUT:
6549 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6550 break;
6551 case VKI_SG_GET_RESERVED_SIZE:
6552 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6553 break;
6554 case VKI_SG_GET_TIMEOUT:
6555 break;
6556 case VKI_SG_GET_VERSION_NUM:
6557 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
6558 break;
6559 case VKI_SG_EMULATED_HOST: /* 0x2203 */
6560 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
6561 break;
6562 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6563 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6564 break;
6566 case VKI_IIOCGETCPS:
6567 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6568 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6569 break;
6570 case VKI_IIOCNETGPN:
6571 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6572 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
6573 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
6574 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6575 sizeof(vki_isdn_net_ioctl_phone) );
6576 break;
6578 /* These all use struct ifreq AFAIK */
6579 case VKI_SIOCGIFINDEX: /* get iface index */
6580 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6581 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6582 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6583 break;
6584 case VKI_SIOCGIFFLAGS: /* get flags */
6585 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6586 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6587 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6588 break;
6589 case VKI_SIOCGIFHWADDR: /* Get hardware address */
6590 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6591 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6592 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6593 break;
6594 case VKI_SIOCGIFMTU: /* get MTU size */
6595 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6596 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6597 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6598 break;
6599 case VKI_SIOCGIFADDR: /* get PA address */
6600 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6601 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6602 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6603 break;
6604 case VKI_SIOCGIFNETMASK: /* get network PA mask */
6605 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6606 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6607 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6608 break;
6609 case VKI_SIOCGIFMETRIC: /* get metric */
6610 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6611 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6612 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6613 break;
6614 case VKI_SIOCGIFMAP: /* Get device parameters */
6615 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6616 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6617 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6618 break;
6619 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
6620 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6621 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6622 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6623 break;
6624 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
6625 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6626 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6627 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6628 break;
6629 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
6630 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6631 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6632 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6633 break;
6634 case VKI_SIOCGIFNAME: /* get iface name */
6635 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6636 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
6637 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
6638 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6639 break;
6640 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
6641 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
6642 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir, sizeof(struct vki_ifreq) );
6643 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_name );
6644 PRE_MEM_READ( "ioctl(SIOCETHTOOL)", (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6645 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6646 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6647 case VKI_ETHTOOL_GSET:
6648 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6649 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6650 break;
6651 case VKI_ETHTOOL_SSET:
6652 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6653 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6654 break;
6655 case VKI_ETHTOOL_GDRVINFO:
6656 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6657 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6658 break;
6659 case VKI_ETHTOOL_GREGS:
6660 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6661 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6662 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6663 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6664 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6665 break;
6666 case VKI_ETHTOOL_GWOL:
6667 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6668 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6669 break;
6670 case VKI_ETHTOOL_SWOL:
6671 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6672 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6673 break;
6674 case VKI_ETHTOOL_GMSGLVL:
6675 case VKI_ETHTOOL_GLINK:
6676 case VKI_ETHTOOL_GRXCSUM:
6677 case VKI_ETHTOOL_GSG:
6678 case VKI_ETHTOOL_GTSO:
6679 case VKI_ETHTOOL_GUFO:
6680 case VKI_ETHTOOL_GGSO:
6681 case VKI_ETHTOOL_GFLAGS:
6682 case VKI_ETHTOOL_GGRO:
6683 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6684 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6685 break;
6686 case VKI_ETHTOOL_SMSGLVL:
6687 case VKI_ETHTOOL_SRXCSUM:
6688 case VKI_ETHTOOL_SSG:
6689 case VKI_ETHTOOL_STSO:
6690 case VKI_ETHTOOL_SUFO:
6691 case VKI_ETHTOOL_SGSO:
6692 case VKI_ETHTOOL_SFLAGS:
6693 case VKI_ETHTOOL_SGRO:
6694 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6695 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6696 break;
6697 case VKI_ETHTOOL_NWAY_RST:
6698 break;
6699 case VKI_ETHTOOL_GRINGPARAM:
6700 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6701 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6702 break;
6703 case VKI_ETHTOOL_SRINGPARAM:
6704 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6705 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6706 break;
6707 case VKI_ETHTOOL_TEST:
6708 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6709 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6710 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6711 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6712 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6713 break;
6714 case VKI_ETHTOOL_PHYS_ID:
6715 break;
6716 case VKI_ETHTOOL_GPERMADDR:
6717 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6718 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6719 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6720 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6721 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6722 break;
6723 case VKI_ETHTOOL_RESET:
6724 break;
6725 case VKI_ETHTOOL_GSSET_INFO:
6726 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6727 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6728 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6729 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6730 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6731 break;
6732 case VKI_ETHTOOL_GFEATURES:
6733 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6734 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6735 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6736 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6737 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6738 break;
6739 case VKI_ETHTOOL_SFEATURES:
6740 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6741 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6742 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6743 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6744 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6745 break;
6746 case VKI_ETHTOOL_GCHANNELS:
6747 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6748 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6749 break;
6750 case VKI_ETHTOOL_SCHANNELS:
6751 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6752 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6753 break;
6754 case VKI_ETHTOOL_GET_TS_INFO:
6755 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6756 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6757 break;
6759 break;
6761 case VKI_SIOCGMIIPHY: /* get hardware entry */
6762 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6763 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6764 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6765 break;
6766 case VKI_SIOCGMIIREG: /* get hardware entry registers */
6767 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6768 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6769 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6770 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6771 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6772 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6773 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6774 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6775 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6776 sizeof(struct vki_ifreq));
6777 break;
6778 case VKI_SIOCGIFCONF: /* get iface list */
6779 /* WAS:
6780 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6781 KERNEL_DO_SYSCALL(tid,RES);
6782 if (!VG_(is_kerror)(RES) && RES == 0)
6783 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6785 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6786 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
6787 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
6788 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6789 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
6790 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
6791 if ( ARG3 ) {
6792 // TODO len must be readable and writable
6793 // buf pointer only needs to be readable
6794 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
6795 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6796 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6798 break;
6799 case VKI_SIOCGSTAMP:
6800 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6801 break;
6802 case VKI_SIOCGSTAMPNS:
6803 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6804 break;
6805 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6806 the number of bytes currently in that socket's send buffer.
6807 It writes this value as an int to the memory location
6808 indicated by the third argument of ioctl(2). */
6809 case VKI_SIOCOUTQ:
6810 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6811 break;
6812 case VKI_SIOCGRARP: /* get RARP table entry */
6813 case VKI_SIOCGARP: /* get ARP table entry */
6814 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6815 break;
6817 case VKI_SIOCSIFFLAGS: /* set flags */
6818 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6819 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6820 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6821 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6822 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6823 break;
6824 case VKI_SIOCSIFMAP: /* Set device parameters */
6825 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6826 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6827 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6828 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
6829 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
6830 break;
6831 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
6832 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
6833 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6834 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
6835 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
6836 sizeof(struct vki_hwtstamp_config) );
6837 break;
6838 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
6839 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
6840 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6841 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
6842 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
6843 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
6844 break;
6845 case VKI_SIOCSIFADDR: /* set PA address */
6846 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
6847 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
6848 case VKI_SIOCSIFNETMASK: /* set network PA mask */
6849 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
6850 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6851 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
6852 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
6853 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
6854 break;
6855 case VKI_SIOCSIFMETRIC: /* set metric */
6856 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
6857 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6858 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
6859 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
6860 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
6861 break;
6862 case VKI_SIOCSIFMTU: /* set MTU size */
6863 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
6864 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6865 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
6866 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
6867 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
6868 break;
6869 case VKI_SIOCSIFHWADDR: /* set hardware address */
6870 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
6871 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6872 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
6873 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
6874 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
6875 break;
6876 case VKI_SIOCSMIIREG: /* set hardware entry registers */
6877 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
6878 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6879 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6880 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6881 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6882 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6883 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6884 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6885 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
6886 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
6887 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
6888 break;
6889 /* Routing table calls. */
6890 case VKI_SIOCADDRT: /* add routing table entry */
6891 case VKI_SIOCDELRT: /* delete routing table entry */
6892 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
6893 sizeof(struct vki_rtentry));
6894 break;
6896 /* tun/tap related ioctls */
6897 case VKI_TUNSETNOCSUM:
6898 case VKI_TUNSETDEBUG:
6899 break;
6900 case VKI_TUNSETIFF:
6901 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
6902 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6903 PRE_MEM_READ( "ioctl(TUNSETIFF)",
6904 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6905 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6906 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
6907 break;
6908 case VKI_TUNSETPERSIST:
6909 case VKI_TUNSETOWNER:
6910 case VKI_TUNSETLINK:
6911 case VKI_TUNSETGROUP:
6912 break;
6913 case VKI_TUNGETFEATURES:
6914 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
6915 break;
6916 case VKI_TUNSETOFFLOAD:
6917 break;
6918 case VKI_TUNGETIFF:
6919 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
6920 break;
6921 case VKI_TUNGETSNDBUF:
6922 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
6923 break;
6924 case VKI_TUNSETSNDBUF:
6925 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
6926 break;
6927 case VKI_TUNGETVNETHDRSZ:
6928 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
6929 break;
6930 case VKI_TUNSETVNETHDRSZ:
6931 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
6932 break;
6933 case VKI_TUNSETQUEUE:
6934 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
6935 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6936 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6937 break;
6938 case VKI_TUNSETIFINDEX:
6939 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
6940 break;
6942 /* RARP cache control calls. */
6943 case VKI_SIOCDRARP: /* delete RARP table entry */
6944 case VKI_SIOCSRARP: /* set RARP table entry */
6945 /* ARP cache control calls. */
6946 case VKI_SIOCSARP: /* set ARP table entry */
6947 case VKI_SIOCDARP: /* delete ARP table entry */
6948 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6949 break;
6951 case VKI_SIOCGPGRP:
6952 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6953 break;
6954 case VKI_SIOCSPGRP:
6955 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6956 //tst->sys_flags &= ~SfMayBlock;
6957 break;
6959 case VKI_SIOCATMARK:
6960 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
6961 break;
6963 /* linux/soundcard interface (OSS) */
6964 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6965 case VKI_SNDCTL_SEQ_GETINCOUNT:
6966 case VKI_SNDCTL_SEQ_PERCMODE:
6967 case VKI_SNDCTL_SEQ_TESTMIDI:
6968 case VKI_SNDCTL_SEQ_RESETSAMPLES:
6969 case VKI_SNDCTL_SEQ_NRSYNTHS:
6970 case VKI_SNDCTL_SEQ_NRMIDIS:
6971 case VKI_SNDCTL_SEQ_GETTIME:
6972 case VKI_SNDCTL_DSP_GETBLKSIZE:
6973 case VKI_SNDCTL_DSP_GETFMTS:
6974 case VKI_SNDCTL_DSP_GETTRIGGER:
6975 case VKI_SNDCTL_DSP_GETODELAY:
6976 case VKI_SNDCTL_DSP_GETSPDIF:
6977 case VKI_SNDCTL_DSP_GETCAPS:
6978 case VKI_SOUND_PCM_READ_RATE:
6979 case VKI_SOUND_PCM_READ_CHANNELS:
6980 case VKI_SOUND_PCM_READ_BITS:
6981 case VKI_SOUND_PCM_READ_FILTER:
6982 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6983 ARG3, sizeof(int));
6984 break;
6985 case VKI_SNDCTL_SEQ_CTRLRATE:
6986 case VKI_SNDCTL_DSP_SPEED:
6987 case VKI_SNDCTL_DSP_STEREO:
6988 case VKI_SNDCTL_DSP_CHANNELS:
6989 case VKI_SOUND_PCM_WRITE_FILTER:
6990 case VKI_SNDCTL_DSP_SUBDIVIDE:
6991 case VKI_SNDCTL_DSP_SETFRAGMENT:
6992 case VKI_SNDCTL_DSP_SETFMT:
6993 case VKI_SNDCTL_DSP_GETCHANNELMASK:
6994 case VKI_SNDCTL_DSP_BIND_CHANNEL:
6995 case VKI_SNDCTL_TMR_TIMEBASE:
6996 case VKI_SNDCTL_TMR_TEMPO:
6997 case VKI_SNDCTL_TMR_SOURCE:
6998 case VKI_SNDCTL_MIDI_PRETIME:
6999 case VKI_SNDCTL_MIDI_MPUMODE:
7000 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7001 ARG3, sizeof(int));
7002 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7003 ARG3, sizeof(int));
7004 break;
7005 case VKI_SNDCTL_DSP_GETOSPACE:
7006 case VKI_SNDCTL_DSP_GETISPACE:
7007 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7008 ARG3, sizeof(vki_audio_buf_info));
7009 break;
7010 case VKI_SNDCTL_DSP_NONBLOCK:
7011 break;
7012 case VKI_SNDCTL_DSP_SETTRIGGER:
7013 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7014 ARG3, sizeof(int));
7015 break;
7017 case VKI_SNDCTL_DSP_POST:
7018 case VKI_SNDCTL_DSP_RESET:
7019 case VKI_SNDCTL_DSP_SYNC:
7020 case VKI_SNDCTL_DSP_SETSYNCRO:
7021 case VKI_SNDCTL_DSP_SETDUPLEX:
7022 break;
7024 /* linux/soundcard interface (ALSA) */
7025 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7026 case VKI_SNDRV_PCM_IOCTL_LINK:
7027 /* these just take an int by value */
7028 break;
7029 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7030 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7031 break;
7032 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7033 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7034 break;
7035 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7036 struct vki_snd_ctl_elem_list *data =
7037 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7038 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7039 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7040 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7041 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7042 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7043 if (data->pids) {
7044 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7046 break;
7048 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7049 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7050 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7051 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7052 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7053 break;
7055 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7056 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7057 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7058 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7059 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7060 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7061 break;
7064 /* Real Time Clock (/dev/rtc) ioctls */
7065 case VKI_RTC_UIE_ON:
7066 case VKI_RTC_UIE_OFF:
7067 case VKI_RTC_AIE_ON:
7068 case VKI_RTC_AIE_OFF:
7069 case VKI_RTC_PIE_ON:
7070 case VKI_RTC_PIE_OFF:
7071 case VKI_RTC_IRQP_SET:
7072 break;
7073 case VKI_RTC_RD_TIME:
7074 case VKI_RTC_ALM_READ:
7075 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7076 ARG3, sizeof(struct vki_rtc_time));
7077 break;
7078 case VKI_RTC_ALM_SET:
7079 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7080 break;
7081 case VKI_RTC_IRQP_READ:
7082 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7083 break;
7085 /* Block devices */
7086 case VKI_BLKROSET:
7087 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7088 break;
7089 case VKI_BLKROGET:
7090 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7091 break;
7092 case VKI_BLKGETSIZE:
7093 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7094 break;
7095 case VKI_BLKFLSBUF:
7096 break;
7097 case VKI_BLKRASET:
7098 break;
7099 case VKI_BLKRAGET:
7100 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7101 break;
7102 case VKI_BLKFRASET:
7103 break;
7104 case VKI_BLKFRAGET:
7105 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7106 break;
7107 case VKI_BLKSECTGET:
7108 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7109 break;
7110 case VKI_BLKSSZGET:
7111 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7112 break;
7113 case VKI_BLKBSZGET:
7114 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7115 break;
7116 case VKI_BLKBSZSET:
7117 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7118 break;
7119 case VKI_BLKGETSIZE64:
7120 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7121 break;
7122 case VKI_BLKPBSZGET:
7123 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7124 break;
7125 case VKI_BLKDISCARDZEROES:
7126 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7127 break;
7128 case VKI_BLKREPORTZONE:
7129 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7130 sizeof(struct vki_blk_zone_report));
7131 break;
7132 case VKI_BLKRESETZONE:
7133 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7134 sizeof(struct vki_blk_zone_range));
7135 break;
7137 /* Hard disks */
7138 case VKI_HDIO_GETGEO: /* 0x0301 */
7139 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7140 break;
7141 case VKI_HDIO_GET_DMA: /* 0x030b */
7142 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7143 break;
7144 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7145 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7146 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7147 break;
7149 /* SCSI */
7150 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7151 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7152 break;
7153 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7154 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7155 break;
7157 /* CD ROM stuff (??) */
7158 case VKI_CDROM_GET_MCN:
7159 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7160 sizeof(struct vki_cdrom_mcn) );
7161 break;
7162 case VKI_CDROM_SEND_PACKET:
7163 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7164 sizeof(struct vki_cdrom_generic_command));
7165 break;
7166 case VKI_CDROMSUBCHNL:
7167 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7168 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7169 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7170 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7171 sizeof(struct vki_cdrom_subchnl));
7172 break;
7173 case VKI_CDROMREADMODE1: /*0x530d*/
7174 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7175 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7176 break;
7177 case VKI_CDROMREADMODE2: /*0x530c*/
7178 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7179 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7180 break;
7181 case VKI_CDROMREADTOCHDR:
7182 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7183 sizeof(struct vki_cdrom_tochdr));
7184 break;
7185 case VKI_CDROMREADTOCENTRY:
7186 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7187 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7188 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7189 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7190 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7191 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7192 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7193 sizeof(struct vki_cdrom_tocentry));
7194 break;
7195 case VKI_CDROMMULTISESSION: /* 0x5310 */
7196 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7197 sizeof(struct vki_cdrom_multisession));
7198 break;
7199 case VKI_CDROMVOLREAD: /* 0x5313 */
7200 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7201 sizeof(struct vki_cdrom_volctrl));
7202 break;
7203 case VKI_CDROMREADRAW: /* 0x5314 */
7204 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7205 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7206 break;
7207 case VKI_CDROMREADAUDIO: /* 0x530e */
7208 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7209 sizeof (struct vki_cdrom_read_audio));
7210 if ( ARG3 ) {
7211 /* ToDo: don't do any of the following if the structure is invalid */
7212 struct vki_cdrom_read_audio *cra =
7213 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7214 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7215 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7217 break;
7218 case VKI_CDROMPLAYMSF:
7219 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7220 break;
7221 /* The following two are probably bogus (should check args
7222 for readability). JRS 20021117 */
7223 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7224 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7225 break;
7226 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7227 break;
7229 case VKI_FIGETBSZ:
7230 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7231 break;
7232 case VKI_FIBMAP:
7233 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7234 break;
7236 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7237 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7238 sizeof(struct vki_fb_var_screeninfo));
7239 break;
7240 case VKI_FBIOPUT_VSCREENINFO:
7241 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7242 sizeof(struct vki_fb_var_screeninfo));
7243 break;
7244 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7245 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7246 sizeof(struct vki_fb_fix_screeninfo));
7247 break;
7248 case VKI_FBIOPAN_DISPLAY:
7249 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7250 sizeof(struct vki_fb_var_screeninfo));
7252 break;
7253 case VKI_PPCLAIM:
7254 case VKI_PPEXCL:
7255 case VKI_PPYIELD:
7256 case VKI_PPRELEASE:
7257 break;
7258 case VKI_PPSETMODE:
7259 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7260 break;
7261 case VKI_PPGETMODE:
7262 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7263 break;
7264 case VKI_PPSETPHASE:
7265 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7266 break;
7267 case VKI_PPGETPHASE:
7268 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7269 break;
7270 case VKI_PPGETMODES:
7271 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7272 break;
7273 case VKI_PPSETFLAGS:
7274 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7275 break;
7276 case VKI_PPGETFLAGS:
7277 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7278 break;
7279 case VKI_PPRSTATUS:
7280 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
7281 break;
7282 case VKI_PPRDATA:
7283 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
7284 break;
7285 case VKI_PPRCONTROL:
7286 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7287 break;
7288 case VKI_PPWDATA:
7289 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
7290 break;
7291 case VKI_PPWCONTROL:
7292 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7293 break;
7294 case VKI_PPFCONTROL:
7295 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7296 break;
7297 case VKI_PPDATADIR:
7298 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
7299 break;
7300 case VKI_PPNEGOT:
7301 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
7302 break;
7303 case VKI_PPWCTLONIRQ:
7304 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7305 break;
7306 case VKI_PPCLRIRQ:
7307 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
7308 break;
7309 case VKI_PPSETTIME:
7310 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
7311 break;
7312 case VKI_PPGETTIME:
7313 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
7314 break;
7316 case VKI_GIO_FONT:
7317 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7318 break;
7319 case VKI_PIO_FONT:
7320 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7321 break;
7323 case VKI_GIO_FONTX:
7324 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7325 if ( ARG3 ) {
7326 /* ToDo: don't do any of the following if the structure is invalid */
7327 struct vki_consolefontdesc *cfd =
7328 (struct vki_consolefontdesc *)(Addr)ARG3;
7329 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7330 32 * cfd->charcount );
7332 break;
7333 case VKI_PIO_FONTX:
7334 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7335 if ( ARG3 ) {
7336 /* ToDo: don't do any of the following if the structure is invalid */
7337 struct vki_consolefontdesc *cfd =
7338 (struct vki_consolefontdesc *)(Addr)ARG3;
7339 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7340 32 * cfd->charcount );
7342 break;
7344 case VKI_PIO_FONTRESET:
7345 break;
7347 case VKI_GIO_CMAP:
7348 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7349 break;
7350 case VKI_PIO_CMAP:
7351 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7352 break;
7354 case VKI_KIOCSOUND:
7355 case VKI_KDMKTONE:
7356 break;
7358 case VKI_KDGETLED:
7359 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7360 break;
7361 case VKI_KDSETLED:
7362 break;
7364 case VKI_KDGKBTYPE:
7365 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7366 break;
7368 case VKI_KDADDIO:
7369 case VKI_KDDELIO:
7370 case VKI_KDENABIO:
7371 case VKI_KDDISABIO:
7372 break;
7374 case VKI_KDSETMODE:
7375 break;
7376 case VKI_KDGETMODE:
7377 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7378 break;
7380 case VKI_KDMAPDISP:
7381 case VKI_KDUNMAPDISP:
7382 break;
7384 case VKI_GIO_SCRNMAP:
7385 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7386 break;
7387 case VKI_PIO_SCRNMAP:
7388 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7389 break;
7390 case VKI_GIO_UNISCRNMAP:
7391 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7392 VKI_E_TABSZ * sizeof(unsigned short) );
7393 break;
7394 case VKI_PIO_UNISCRNMAP:
7395 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7396 VKI_E_TABSZ * sizeof(unsigned short) );
7397 break;
7399 case VKI_GIO_UNIMAP:
7400 if ( ARG3 ) {
7401 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7402 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7403 sizeof(unsigned short));
7404 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7405 sizeof(struct vki_unipair *));
7406 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7407 desc->entry_ct * sizeof(struct vki_unipair));
7409 break;
7410 case VKI_PIO_UNIMAP:
7411 if ( ARG3 ) {
7412 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7413 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7414 sizeof(unsigned short) );
7415 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7416 sizeof(struct vki_unipair *) );
7417 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7418 desc->entry_ct * sizeof(struct vki_unipair) );
7420 break;
7421 case VKI_PIO_UNIMAPCLR:
7422 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7423 break;
7425 case VKI_KDGKBMODE:
7426 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7427 break;
7428 case VKI_KDSKBMODE:
7429 break;
7431 case VKI_KDGKBMETA:
7432 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7433 break;
7434 case VKI_KDSKBMETA:
7435 break;
7437 case VKI_KDGKBLED:
7438 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7439 break;
7440 case VKI_KDSKBLED:
7441 break;
7443 case VKI_KDGKBENT:
7444 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7445 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7446 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7447 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7448 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7449 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7450 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7451 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7452 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7453 break;
7454 case VKI_KDSKBENT:
7455 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7456 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7457 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7458 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7459 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7460 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7461 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7462 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7463 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7464 break;
7466 case VKI_KDGKBSENT:
7467 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7468 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7469 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7470 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7471 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
7472 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
7473 break;
7474 case VKI_KDSKBSENT:
7475 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7476 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7477 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7478 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7479 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
7480 break;
7482 case VKI_KDGKBDIACR:
7483 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7484 break;
7485 case VKI_KDSKBDIACR:
7486 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7487 break;
7489 case VKI_KDGETKEYCODE:
7490 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7491 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7492 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7493 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7494 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7495 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7496 break;
7497 case VKI_KDSETKEYCODE:
7498 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7499 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7500 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7501 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7502 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7503 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7504 break;
7506 case VKI_KDSIGACCEPT:
7507 break;
7509 case VKI_KDKBDREP:
7510 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7511 break;
7513 case VKI_KDFONTOP:
7514 if ( ARG3 ) {
7515 struct vki_console_font_op *op =
7516 (struct vki_console_font_op *) (Addr)ARG3;
7517 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7518 sizeof(struct vki_console_font_op) );
7519 switch ( op->op ) {
7520 case VKI_KD_FONT_OP_SET:
7521 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7522 (Addr)op->data,
7523 (op->width + 7) / 8 * 32 * op->charcount );
7524 break;
7525 case VKI_KD_FONT_OP_GET:
7526 if ( op->data )
7527 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7528 (Addr)op->data,
7529 (op->width + 7) / 8 * 32 * op->charcount );
7530 break;
7531 case VKI_KD_FONT_OP_SET_DEFAULT:
7532 if ( op->data )
7533 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7534 (Addr)op->data );
7535 break;
7536 case VKI_KD_FONT_OP_COPY:
7537 break;
7540 break;
7542 case VKI_VT_OPENQRY:
7543 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7544 break;
7545 case VKI_VT_GETMODE:
7546 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7547 break;
7548 case VKI_VT_SETMODE:
7549 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7550 break;
7551 case VKI_VT_GETSTATE:
7552 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7553 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
7554 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
7555 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7556 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
7557 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
7558 break;
7559 case VKI_VT_RELDISP:
7560 case VKI_VT_ACTIVATE:
7561 case VKI_VT_WAITACTIVE:
7562 case VKI_VT_DISALLOCATE:
7563 break;
7564 case VKI_VT_RESIZE:
7565 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7566 break;
7567 case VKI_VT_RESIZEX:
7568 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7569 break;
7570 case VKI_VT_LOCKSWITCH:
7571 case VKI_VT_UNLOCKSWITCH:
7572 break;
7574 case VKI_USBDEVFS_CONTROL:
7575 if ( ARG3 ) {
7576 struct vki_usbdevfs_ctrltransfer *vkuc =
7577 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
7578 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7579 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7580 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7581 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7582 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7583 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7584 if (vkuc->bRequestType & 0x80)
7585 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7586 else
7587 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7589 break;
7590 case VKI_USBDEVFS_BULK:
7591 if ( ARG3 ) {
7592 struct vki_usbdevfs_bulktransfer *vkub =
7593 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
7594 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7595 if (vkub->ep & 0x80)
7596 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7597 else
7598 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7600 break;
7601 case VKI_USBDEVFS_GETDRIVER:
7602 if ( ARG3 ) {
7603 struct vki_usbdevfs_getdriver *vkugd =
7604 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
7605 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7607 break;
7608 case VKI_USBDEVFS_SUBMITURB:
7609 if ( ARG3 ) {
7610 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
7612 /* Not the whole struct needs to be initialized */
7613 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7614 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7615 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7616 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7617 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7618 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7619 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7620 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7621 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7622 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7623 if (vkusp->bRequestType & 0x80)
7624 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7625 else
7626 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7627 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7628 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7629 int total_length = 0;
7630 int i;
7631 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7632 for(i=0; i<vkuu->number_of_packets; i++) {
7633 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7634 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));
7635 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7636 total_length += vkuu->iso_frame_desc[i].length;
7638 if (vkuu->endpoint & 0x80)
7639 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7640 else
7641 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7642 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7643 } else {
7644 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7645 if (vkuu->endpoint & 0x80)
7646 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7647 else
7648 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7649 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7652 break;
7653 case VKI_USBDEVFS_DISCARDURB:
7654 break;
7655 case VKI_USBDEVFS_REAPURB:
7656 if ( ARG3 ) {
7657 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7659 break;
7660 case VKI_USBDEVFS_REAPURBNDELAY:
7661 if ( ARG3 ) {
7662 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7664 break;
7665 case VKI_USBDEVFS_CONNECTINFO:
7666 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7667 break;
7668 case VKI_USBDEVFS_IOCTL:
7669 if ( ARG3 ) {
7670 struct vki_usbdevfs_ioctl *vkui =
7671 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
7672 UInt dir2, size2;
7673 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7674 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
7675 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7676 if (size2 > 0) {
7677 if (dir2 & _VKI_IOC_WRITE)
7678 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7679 else if (dir2 & _VKI_IOC_READ)
7680 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7683 break;
7684 case VKI_USBDEVFS_RESET:
7685 break;
7687 /* I2C (/dev/i2c-*) ioctls */
7688 case VKI_I2C_SLAVE:
7689 case VKI_I2C_SLAVE_FORCE:
7690 case VKI_I2C_TENBIT:
7691 case VKI_I2C_PEC:
7692 break;
7693 case VKI_I2C_FUNCS:
7694 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7695 break;
7696 case VKI_I2C_RDWR:
7697 if ( ARG3 ) {
7698 struct vki_i2c_rdwr_ioctl_data *vkui =
7699 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
7700 UInt i;
7701 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7702 for (i=0; i < vkui->nmsgs; i++) {
7703 struct vki_i2c_msg *msg = vkui->msgs + i;
7704 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7705 if (msg->flags & VKI_I2C_M_RD)
7706 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7707 else
7708 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7711 break;
7712 case VKI_I2C_SMBUS:
7713 if ( ARG3 ) {
7714 struct vki_i2c_smbus_ioctl_data *vkis
7715 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
7716 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7717 (Addr)&vkis->read_write, sizeof(vkis->read_write));
7718 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7719 (Addr)&vkis->size, sizeof(vkis->size));
7720 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7721 (Addr)&vkis->command, sizeof(vkis->command));
7722 /* i2c_smbus_write_quick hides its value in read_write, so
7723 this variable can have a different meaning */
7724 /* to make matters worse i2c_smbus_write_byte stores its
7725 value in command */
7726 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7727 ((vkis->size == VKI_I2C_SMBUS_BYTE)
7728 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
7729 /* the rest uses the byte array to store the data,
7730 some the first byte for size */
7731 UInt size;
7732 switch(vkis->size) {
7733 case VKI_I2C_SMBUS_BYTE_DATA:
7734 size = 1;
7735 break;
7736 case VKI_I2C_SMBUS_WORD_DATA:
7737 case VKI_I2C_SMBUS_PROC_CALL:
7738 size = 2;
7739 break;
7740 case VKI_I2C_SMBUS_BLOCK_DATA:
7741 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7742 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7743 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7744 size = 1 + vkis->data->block[0];
7745 break;
7746 default:
7747 size = 0;
7750 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7751 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7752 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7753 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7754 ".i2c_smbus_ioctl_data.data",
7755 (Addr)&vkis->data->block[0], size);
7756 else
7757 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7758 "i2c_smbus_ioctl_data.data",
7759 (Addr)&vkis->data->block[0], size);
7762 break;
7764 /* Wireless extensions ioctls */
7765 case VKI_SIOCSIWCOMMIT:
7766 case VKI_SIOCSIWNWID:
7767 case VKI_SIOCSIWFREQ:
7768 case VKI_SIOCSIWMODE:
7769 case VKI_SIOCSIWSENS:
7770 case VKI_SIOCSIWRANGE:
7771 case VKI_SIOCSIWPRIV:
7772 case VKI_SIOCSIWSTATS:
7773 case VKI_SIOCSIWSPY:
7774 case VKI_SIOCSIWTHRSPY:
7775 case VKI_SIOCSIWAP:
7776 case VKI_SIOCSIWSCAN:
7777 case VKI_SIOCSIWESSID:
7778 case VKI_SIOCSIWRATE:
7779 case VKI_SIOCSIWNICKN:
7780 case VKI_SIOCSIWRTS:
7781 case VKI_SIOCSIWFRAG:
7782 case VKI_SIOCSIWTXPOW:
7783 case VKI_SIOCSIWRETRY:
7784 case VKI_SIOCSIWENCODE:
7785 case VKI_SIOCSIWPOWER:
7786 case VKI_SIOCSIWGENIE:
7787 case VKI_SIOCSIWMLME:
7788 case VKI_SIOCSIWAUTH:
7789 case VKI_SIOCSIWENCODEEXT:
7790 case VKI_SIOCSIWPMKSA:
7791 break;
7792 case VKI_SIOCGIWNAME:
7793 if (ARG3) {
7794 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7795 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
7796 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
7798 break;
7799 case VKI_SIOCGIWNWID:
7800 case VKI_SIOCGIWSENS:
7801 case VKI_SIOCGIWRATE:
7802 case VKI_SIOCGIWRTS:
7803 case VKI_SIOCGIWFRAG:
7804 case VKI_SIOCGIWTXPOW:
7805 case VKI_SIOCGIWRETRY:
7806 case VKI_SIOCGIWPOWER:
7807 case VKI_SIOCGIWAUTH:
7808 if (ARG3) {
7809 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7810 "RETRY|PARAM|AUTH])",
7811 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
7812 sizeof(struct vki_iw_param));
7814 break;
7815 case VKI_SIOCGIWFREQ:
7816 if (ARG3) {
7817 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7818 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
7819 sizeof(struct vki_iw_freq));
7821 break;
7822 case VKI_SIOCGIWMODE:
7823 if (ARG3) {
7824 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
7825 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
7826 sizeof(__vki_u32));
7828 break;
7829 case VKI_SIOCGIWRANGE:
7830 case VKI_SIOCGIWPRIV:
7831 case VKI_SIOCGIWSTATS:
7832 case VKI_SIOCGIWSPY:
7833 case VKI_SIOCGIWTHRSPY:
7834 case VKI_SIOCGIWAPLIST:
7835 case VKI_SIOCGIWSCAN:
7836 case VKI_SIOCGIWESSID:
7837 case VKI_SIOCGIWNICKN:
7838 case VKI_SIOCGIWENCODE:
7839 case VKI_SIOCGIWGENIE:
7840 case VKI_SIOCGIWENCODEEXT:
7841 if (ARG3) {
7842 struct vki_iw_point* point;
7843 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
7844 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
7845 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
7846 (Addr)point->pointer, point->length);
7848 break;
7849 case VKI_SIOCGIWAP:
7850 if (ARG3) {
7851 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
7852 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
7853 sizeof(struct vki_sockaddr));
7855 break;
7857 /* User input device creation */
7858 case VKI_UI_SET_EVBIT:
7859 case VKI_UI_SET_KEYBIT:
7860 case VKI_UI_SET_RELBIT:
7861 case VKI_UI_SET_ABSBIT:
7862 case VKI_UI_SET_MSCBIT:
7863 case VKI_UI_SET_LEDBIT:
7864 case VKI_UI_SET_SNDBIT:
7865 case VKI_UI_SET_FFBIT:
7866 case VKI_UI_SET_SWBIT:
7867 case VKI_UI_SET_PROPBIT:
7868 /* These just take an int by value */
7869 break;
7871 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7872 || defined(VGPV_mips32_linux_android) \
7873 || defined(VGPV_arm64_linux_android)
7874 /* ashmem */
7875 case VKI_ASHMEM_GET_SIZE:
7876 case VKI_ASHMEM_SET_SIZE:
7877 case VKI_ASHMEM_GET_PROT_MASK:
7878 case VKI_ASHMEM_SET_PROT_MASK:
7879 case VKI_ASHMEM_GET_PIN_STATUS:
7880 case VKI_ASHMEM_PURGE_ALL_CACHES:
7881 break;
7882 case VKI_ASHMEM_GET_NAME:
7883 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
7884 break;
7885 case VKI_ASHMEM_SET_NAME:
7886 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
7887 break;
7888 case VKI_ASHMEM_PIN:
7889 case VKI_ASHMEM_UNPIN:
7890 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
7891 ARG3, sizeof(struct vki_ashmem_pin) );
7892 break;
7894 /* binder */
7895 case VKI_BINDER_WRITE_READ:
7896 if (ARG3) {
7897 struct vki_binder_write_read* bwr
7898 = (struct vki_binder_write_read*)(Addr)ARG3;
7900 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
7901 bwr->write_buffer);
7902 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
7903 bwr->write_size);
7904 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
7905 bwr->write_consumed);
7906 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
7907 bwr->read_buffer);
7908 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
7909 bwr->read_size);
7910 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
7911 bwr->read_consumed);
7913 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
7914 bwr->write_consumed);
7915 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
7916 bwr->read_consumed);
7918 if (bwr->read_size)
7919 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
7920 (Addr)bwr->read_buffer, bwr->read_size);
7921 if (bwr->write_size)
7922 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
7923 (Addr)bwr->write_buffer, bwr->write_size);
7925 break;
7927 case VKI_BINDER_SET_IDLE_TIMEOUT:
7928 case VKI_BINDER_SET_MAX_THREADS:
7929 case VKI_BINDER_SET_IDLE_PRIORITY:
7930 case VKI_BINDER_SET_CONTEXT_MGR:
7931 case VKI_BINDER_THREAD_EXIT:
7932 break;
7933 case VKI_BINDER_VERSION:
7934 if (ARG3) {
7935 struct vki_binder_version* bv =
7936 (struct vki_binder_version*)(Addr)ARG3;
7937 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
7939 break;
7940 # endif /* defined(VGPV_*_linux_android) */
7942 case VKI_HCIGETDEVLIST:
7943 if (ARG3) {
7944 struct vki_hci_dev_list_req* dlr =
7945 (struct vki_hci_dev_list_req*)(Addr)ARG3;
7946 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
7947 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
7948 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
7949 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
7950 dlr->dev_num * sizeof(struct vki_hci_dev_req));
7952 break;
7954 case VKI_HCIINQUIRY:
7955 if (ARG3) {
7956 struct vki_hci_inquiry_req* ir =
7957 (struct vki_hci_inquiry_req*)(Addr)ARG3;
7958 PRE_MEM_READ("ioctl(HCIINQUIRY)",
7959 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
7960 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
7961 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7962 ir->num_rsp * sizeof(struct vki_inquiry_info));
7964 break;
7966 case VKI_DRM_IOCTL_VERSION:
7967 if (ARG3) {
7968 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
7969 struct vg_drm_version_info* info;
7970 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
7971 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
7972 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
7973 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
7974 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
7975 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
7976 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
7977 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
7978 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
7979 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
7980 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
7981 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
7982 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
7983 // To ensure we VG_(free) info even when syscall fails:
7984 *flags |= SfPostOnFail;
7985 info->data = *data;
7986 info->orig = data;
7987 ARG3 = (Addr)&info->data;
7989 break;
7990 case VKI_DRM_IOCTL_GET_UNIQUE:
7991 if (ARG3) {
7992 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
7993 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
7994 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
7995 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
7997 break;
7998 case VKI_DRM_IOCTL_GET_MAGIC:
7999 if (ARG3) {
8000 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8001 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8003 break;
8004 case VKI_DRM_IOCTL_WAIT_VBLANK:
8005 if (ARG3) {
8006 union vki_drm_wait_vblank *data =
8007 (union vki_drm_wait_vblank *)(Addr)ARG3;
8008 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8009 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8010 /* XXX: It seems request.signal isn't used */
8011 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8013 break;
8014 case VKI_DRM_IOCTL_GEM_CLOSE:
8015 if (ARG3) {
8016 struct vki_drm_gem_close *data =
8017 (struct vki_drm_gem_close *)(Addr)ARG3;
8018 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8020 break;
8021 case VKI_DRM_IOCTL_GEM_FLINK:
8022 if (ARG3) {
8023 struct vki_drm_gem_flink *data =
8024 (struct vki_drm_gem_flink *)(Addr)ARG3;
8025 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8026 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8028 break;
8029 case VKI_DRM_IOCTL_GEM_OPEN:
8030 if (ARG3) {
8031 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8032 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8033 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8034 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8036 break;
8037 case VKI_DRM_IOCTL_I915_GETPARAM:
8038 if (ARG3) {
8039 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8040 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8041 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8043 break;
8044 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8045 if (ARG3) {
8046 struct vki_drm_i915_gem_busy *data =
8047 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8048 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8049 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8051 break;
8052 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8053 if (ARG3) {
8054 struct vki_drm_i915_gem_create *data =
8055 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8056 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8057 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8059 break;
8060 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8061 if (ARG3) {
8062 struct vki_drm_i915_gem_pread *data =
8063 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8064 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8065 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8066 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8067 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8068 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8070 break;
8071 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8072 if (ARG3) {
8073 struct vki_drm_i915_gem_pwrite *data =
8074 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8075 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8076 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8077 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8078 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8079 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8080 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8081 * interleaved vertex attributes may have a wide stride with uninitialized data between
8082 * consecutive vertices) */
8084 break;
8085 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8086 if (ARG3) {
8087 struct vki_drm_i915_gem_mmap_gtt *data =
8088 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8089 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8090 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8092 break;
8093 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8094 if (ARG3) {
8095 struct vki_drm_i915_gem_set_domain *data =
8096 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8097 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8098 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8099 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8101 break;
8102 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8103 if (ARG3) {
8104 struct vki_drm_i915_gem_set_tiling *data =
8105 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8106 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8107 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8108 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8109 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8111 break;
8112 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8113 if (ARG3) {
8114 struct vki_drm_i915_gem_get_tiling *data =
8115 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8116 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8117 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8118 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8120 break;
8121 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8122 if (ARG3) {
8123 struct vki_drm_i915_gem_get_aperture *data =
8124 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8125 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8126 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8128 break;
8130 /* KVM ioctls that check for a numeric value as parameter */
8131 case VKI_KVM_GET_API_VERSION:
8132 case VKI_KVM_CREATE_VM:
8133 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8134 case VKI_KVM_CHECK_EXTENSION:
8135 case VKI_KVM_SET_TSS_ADDR:
8136 case VKI_KVM_CREATE_VCPU:
8137 case VKI_KVM_RUN:
8138 break;
8140 case VKI_KVM_S390_MEM_OP: {
8141 struct vki_kvm_s390_mem_op *args =
8142 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8143 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8144 sizeof(struct vki_kvm_s390_mem_op));
8145 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8146 break;
8147 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8148 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8149 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8150 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8152 break;
8155 #ifdef ENABLE_XEN
8156 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8157 SyscallArgs harrghs;
8158 struct vki_xen_privcmd_hypercall *args =
8159 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8161 if (!args)
8162 break;
8164 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8165 harrghs.sysno = args->op;
8166 harrghs.arg1 = args->arg[0];
8167 harrghs.arg2 = args->arg[1];
8168 harrghs.arg3 = args->arg[2];
8169 harrghs.arg4 = args->arg[3];
8170 harrghs.arg5 = args->arg[4];
8171 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8173 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8175 /* HACK. arg8 is used to return the number of hypercall
8176 * arguments actually consumed! */
8177 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8178 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8180 break;
8183 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8184 struct vki_xen_privcmd_mmap *args =
8185 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8186 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8187 (Addr)&args->num, sizeof(args->num));
8188 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8189 (Addr)&args->dom, sizeof(args->dom));
8190 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8191 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8192 break;
8194 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8195 struct vki_xen_privcmd_mmapbatch *args =
8196 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8197 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8198 (Addr)&args->num, sizeof(args->num));
8199 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8200 (Addr)&args->dom, sizeof(args->dom));
8201 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8202 (Addr)&args->addr, sizeof(args->addr));
8203 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8204 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8205 break;
8207 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8208 struct vki_xen_privcmd_mmapbatch_v2 *args =
8209 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8210 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8211 (Addr)&args->num, sizeof(args->num));
8212 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8213 (Addr)&args->dom, sizeof(args->dom));
8214 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8215 (Addr)&args->addr, sizeof(args->addr));
8216 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8217 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8218 break;
8221 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8222 struct vki_xen_ioctl_evtchn_bind_virq *args =
8223 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8224 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8225 (Addr)&args->virq, sizeof(args->virq));
8227 break;
8228 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8229 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8230 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8231 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8232 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8233 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8234 (Addr)&args->remote_port, sizeof(args->remote_port));
8236 break;
8237 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8238 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8239 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8240 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8241 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8243 break;
8244 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8245 struct vki_xen_ioctl_evtchn_unbind *args =
8246 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8247 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8248 (Addr)&args->port, sizeof(args->port));
8250 break;
8251 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8252 struct vki_xen_ioctl_evtchn_notify *args =
8253 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
8254 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8255 (Addr)&args->port, sizeof(args->port));
8257 break;
8258 case VKI_XEN_IOCTL_EVTCHN_RESET:
8259 /* No input*/
8260 break;
8261 #endif
8263 /* Lustre */
8264 case VKI_OBD_IOC_FID2PATH: {
8265 struct vki_getinfo_fid2path *gf =
8266 (struct vki_getinfo_fid2path *)(Addr)ARG3;
8267 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8268 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8269 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8270 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8271 break;
8274 case VKI_LL_IOC_PATH2FID:
8275 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8276 break;
8278 case VKI_LL_IOC_GETPARENT: {
8279 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
8280 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8281 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8282 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8283 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8284 break;
8287 /* V4L2 */
8288 case VKI_V4L2_QUERYCAP: {
8289 struct vki_v4l2_capability *data =
8290 (struct vki_v4l2_capability *)(Addr)ARG3;
8291 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8292 break;
8294 case VKI_V4L2_ENUM_FMT: {
8295 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
8296 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8297 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8298 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8299 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8300 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8301 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8302 break;
8304 case VKI_V4L2_G_FMT: {
8305 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8306 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8307 switch (data->type) {
8308 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8309 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8310 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8311 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8312 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8313 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8314 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8315 break;
8316 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8317 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8318 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8319 break;
8320 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8321 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8322 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8323 break;
8324 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8325 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8326 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8327 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8328 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8329 if (data->fmt.win.clipcount && data->fmt.win.clips)
8330 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8331 (Addr)data->fmt.win.clips,
8332 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8333 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8334 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8335 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8336 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8337 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8338 break;
8339 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8340 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8341 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8342 break;
8343 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8344 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8345 break;
8347 break;
8349 case VKI_V4L2_S_FMT: {
8350 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8351 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8352 switch (data->type) {
8353 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8354 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8355 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8356 (Addr)&data->type + sizeof(data->type),
8357 sizeof(*data) - sizeof(data->type));
8358 break;
8359 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8360 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8361 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8362 break;
8363 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8364 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8365 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8366 break;
8367 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8368 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8369 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8370 if (data->fmt.win.clipcount && data->fmt.win.clips)
8371 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8372 (Addr)data->fmt.win.clips,
8373 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8374 if (data->fmt.win.bitmap)
8375 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8376 (Addr)data->fmt.win.bitmap,
8377 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8378 break;
8379 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8380 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8381 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8382 break;
8383 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8384 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8385 break;
8387 break;
8389 case VKI_V4L2_TRY_FMT: {
8390 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8391 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8392 switch (data->type) {
8393 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8394 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8395 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8396 (Addr)&data->type + sizeof(data->type),
8397 sizeof(*data) - sizeof(data->type));
8398 break;
8399 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8400 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8401 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8402 break;
8403 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8404 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8405 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8406 break;
8407 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8408 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8409 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8410 if (data->fmt.win.clipcount && data->fmt.win.clips)
8411 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8412 (Addr)data->fmt.win.clips,
8413 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8414 if (data->fmt.win.bitmap)
8415 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8416 (Addr)data->fmt.win.bitmap,
8417 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8418 break;
8419 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8420 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8421 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8422 break;
8423 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8424 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8425 break;
8427 break;
8429 case VKI_V4L2_REQBUFS: {
8430 struct vki_v4l2_requestbuffers *data =
8431 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
8432 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8433 break;
8435 case VKI_V4L2_QUERYBUF: {
8436 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8437 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8438 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8439 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8440 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8441 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8442 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8443 unsigned i;
8445 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8446 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8447 for (i = 0; i < data->length; i++) {
8448 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8449 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8450 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8451 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8452 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8454 } else {
8455 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8456 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8458 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8459 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8460 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8461 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8462 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8463 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8464 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8465 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8466 break;
8468 case VKI_V4L2_G_FBUF: {
8469 struct vki_v4l2_framebuffer *data =
8470 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8471 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8472 break;
8474 case VKI_V4L2_S_FBUF: {
8475 struct vki_v4l2_framebuffer *data =
8476 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8477 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8478 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8479 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8480 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8481 break;
8483 case VKI_V4L2_OVERLAY: {
8484 int *data = (int *)(Addr)ARG3;
8485 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8486 break;
8488 case VKI_V4L2_QBUF: {
8489 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8490 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8491 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8492 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8493 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8495 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8496 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8497 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8498 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8499 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8500 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8501 if (is_output) {
8502 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8503 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8505 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8506 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8507 unsigned i;
8509 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8510 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8511 for (i = 0; i < data->length; i++) {
8512 if (is_output) {
8513 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8514 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8516 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8517 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8518 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8519 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8520 else
8521 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8522 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8524 } else {
8525 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8526 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8527 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8528 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8529 else
8530 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8531 if (is_output) {
8532 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8533 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8536 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8537 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8538 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8540 break;
8542 case VKI_V4L2_EXPBUF: {
8543 struct vki_v4l2_exportbuffer *data =
8544 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
8545 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8546 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8547 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8548 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8549 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8550 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8551 break;
8553 case VKI_V4L2_DQBUF: {
8554 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8555 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8556 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8557 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8558 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8559 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8560 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8561 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8562 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8563 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8564 unsigned i;
8566 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8567 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8568 for (i = 0; i < data->length; i++) {
8569 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8570 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8571 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8572 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8573 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8575 } else {
8576 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8577 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8578 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8579 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8581 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8582 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8583 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8584 break;
8586 case VKI_V4L2_STREAMON: {
8587 int *data = (int *)(Addr)ARG3;
8588 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8589 break;
8591 case VKI_V4L2_STREAMOFF: {
8592 int *data = (int *)(Addr)ARG3;
8593 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8594 break;
8596 case VKI_V4L2_G_PARM: {
8597 struct vki_v4l2_streamparm *data =
8598 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8599 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8600 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8601 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8602 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8604 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8605 if (is_output) {
8606 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8607 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8608 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8609 } else {
8610 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8611 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8612 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8614 break;
8616 case VKI_V4L2_S_PARM: {
8617 struct vki_v4l2_streamparm *data =
8618 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8619 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8620 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8621 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8622 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8624 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8625 if (is_output)
8626 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8627 else
8628 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8629 break;
8631 case VKI_V4L2_G_STD: {
8632 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8633 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8634 break;
8636 case VKI_V4L2_S_STD: {
8637 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8638 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8639 break;
8641 case VKI_V4L2_ENUMSTD: {
8642 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
8643 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8644 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8645 break;
8647 case VKI_V4L2_ENUMINPUT: {
8648 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
8649 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8650 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8651 break;
8653 case VKI_V4L2_G_CTRL: {
8654 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8655 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8656 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8657 break;
8659 case VKI_V4L2_S_CTRL: {
8660 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8661 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8662 break;
8664 case VKI_V4L2_G_TUNER: {
8665 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8666 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8667 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8668 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8669 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8670 break;
8672 case VKI_V4L2_S_TUNER: {
8673 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8674 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8675 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8676 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8677 break;
8679 case VKI_V4L2_G_AUDIO: {
8680 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8681 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8682 sizeof(*data) - sizeof(data->reserved));
8683 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8684 break;
8686 case VKI_V4L2_S_AUDIO: {
8687 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8688 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8689 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8690 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8691 break;
8693 case VKI_V4L2_QUERYCTRL: {
8694 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
8695 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8696 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8697 sizeof(*data) - sizeof(data->id));
8698 break;
8700 case VKI_V4L2_QUERYMENU: {
8701 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
8702 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8703 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8704 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8705 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8706 break;
8708 case VKI_V4L2_G_INPUT: {
8709 int *data = (int *)(Addr)ARG3;
8710 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8711 break;
8713 case VKI_V4L2_S_INPUT: {
8714 int *data = (int *)(Addr)ARG3;
8715 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8716 break;
8718 case VKI_V4L2_G_EDID: {
8719 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8720 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8721 if (data->blocks && data->edid)
8722 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8723 break;
8725 case VKI_V4L2_S_EDID: {
8726 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8727 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8728 if (data->blocks && data->edid)
8729 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8730 break;
8732 case VKI_V4L2_G_OUTPUT: {
8733 int *data = (int *)(Addr)ARG3;
8734 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8735 break;
8737 case VKI_V4L2_S_OUTPUT: {
8738 int *data = (int *)(Addr)ARG3;
8739 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8740 break;
8742 case VKI_V4L2_ENUMOUTPUT: {
8743 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
8744 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8745 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8746 break;
8748 case VKI_V4L2_G_AUDOUT: {
8749 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8750 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8751 sizeof(*data) - sizeof(data->reserved));
8752 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8753 break;
8755 case VKI_V4L2_S_AUDOUT: {
8756 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8757 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8758 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8759 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8760 break;
8762 case VKI_V4L2_G_MODULATOR: {
8763 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8764 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8765 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8766 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8767 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8768 break;
8770 case VKI_V4L2_S_MODULATOR: {
8771 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8772 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8773 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8774 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8775 break;
8777 case VKI_V4L2_G_FREQUENCY: {
8778 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8779 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8780 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8781 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8782 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8783 break;
8785 case VKI_V4L2_S_FREQUENCY: {
8786 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8787 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8788 break;
8790 case VKI_V4L2_CROPCAP: {
8791 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
8792 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8793 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8794 break;
8796 case VKI_V4L2_G_CROP: {
8797 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8798 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8799 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8800 break;
8802 case VKI_V4L2_S_CROP: {
8803 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8804 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
8805 break;
8807 case VKI_V4L2_G_JPEGCOMP: {
8808 struct vki_v4l2_jpegcompression *data =
8809 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8810 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
8811 break;
8813 case VKI_V4L2_S_JPEGCOMP: {
8814 struct vki_v4l2_jpegcompression *data =
8815 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
8816 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
8817 break;
8819 case VKI_V4L2_QUERYSTD: {
8820 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8821 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
8822 break;
8824 case VKI_V4L2_ENUMAUDIO: {
8825 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8826 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
8827 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
8828 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
8829 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8830 break;
8832 case VKI_V4L2_ENUMAUDOUT: {
8833 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8834 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
8835 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
8836 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
8837 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8838 break;
8840 case VKI_V4L2_G_PRIORITY: {
8841 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8842 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
8843 break;
8845 case VKI_V4L2_S_PRIORITY: {
8846 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
8847 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
8848 break;
8850 case VKI_V4L2_G_SLICED_VBI_CAP: {
8851 struct vki_v4l2_sliced_vbi_cap *data =
8852 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
8853 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
8854 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
8855 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
8856 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
8857 break;
8859 case VKI_V4L2_G_EXT_CTRLS: {
8860 struct vki_v4l2_ext_controls *data =
8861 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8862 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
8863 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
8864 if (data->count) {
8865 unsigned i;
8867 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
8868 for (i = 0; i < data->count; i++) {
8869 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
8870 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
8871 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
8872 if (data->controls[i].size) {
8873 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
8874 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
8875 (Addr)data->controls[i].ptr, data->controls[i].size);
8876 } else {
8877 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
8878 data->controls[i].value64);
8882 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
8883 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
8884 break;
8886 case VKI_V4L2_S_EXT_CTRLS: {
8887 struct vki_v4l2_ext_controls *data =
8888 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8889 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
8890 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
8891 if (data->count) {
8892 unsigned i;
8894 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
8895 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
8896 data->count * sizeof(data->controls[0]));
8897 for (i = 0; i < data->count; i++) {
8898 if (data->controls[i].size) {
8899 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
8900 (Addr)data->controls[i].ptr, data->controls[i].size);
8904 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
8905 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
8906 break;
8908 case VKI_V4L2_TRY_EXT_CTRLS: {
8909 struct vki_v4l2_ext_controls *data =
8910 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
8911 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
8912 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
8913 if (data->count) {
8914 unsigned i;
8916 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
8917 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
8918 data->count * sizeof(data->controls[0]));
8919 for (i = 0; i < data->count; i++) {
8920 if (data->controls[i].size) {
8921 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
8922 (Addr)data->controls[i].ptr, data->controls[i].size);
8926 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
8927 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
8928 break;
8930 case VKI_V4L2_ENUM_FRAMESIZES: {
8931 struct vki_v4l2_frmsizeenum *data =
8932 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
8933 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
8934 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
8935 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
8936 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
8937 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
8938 break;
8940 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
8941 struct vki_v4l2_frmivalenum *data =
8942 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
8943 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
8944 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
8945 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
8946 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
8947 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
8948 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
8949 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
8950 break;
8952 case VKI_V4L2_G_ENC_INDEX: {
8953 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
8954 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
8955 break;
8957 case VKI_V4L2_ENCODER_CMD: {
8958 struct vki_v4l2_encoder_cmd *data =
8959 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8960 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
8961 break;
8963 case VKI_V4L2_TRY_ENCODER_CMD: {
8964 struct vki_v4l2_encoder_cmd *data =
8965 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
8966 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
8967 break;
8969 case VKI_V4L2_DBG_S_REGISTER: {
8970 struct vki_v4l2_dbg_register *data =
8971 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8972 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
8973 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
8974 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
8975 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
8976 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
8977 break;
8979 case VKI_V4L2_DBG_G_REGISTER: {
8980 struct vki_v4l2_dbg_register *data =
8981 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
8982 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
8983 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
8984 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
8985 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
8986 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
8987 break;
8989 case VKI_V4L2_S_HW_FREQ_SEEK: {
8990 struct vki_v4l2_hw_freq_seek *data =
8991 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
8992 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
8993 break;
8995 case VKI_V4L2_S_DV_TIMINGS: {
8996 struct vki_v4l2_dv_timings *data =
8997 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
8998 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
8999 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9000 break;
9002 case VKI_V4L2_G_DV_TIMINGS: {
9003 struct vki_v4l2_dv_timings *data =
9004 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9005 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9006 break;
9008 case VKI_V4L2_DQEVENT: {
9009 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9010 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9011 break;
9013 case VKI_V4L2_SUBSCRIBE_EVENT: {
9014 struct vki_v4l2_event_subscription *data =
9015 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9016 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9017 break;
9019 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9020 struct vki_v4l2_event_subscription *data =
9021 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9022 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9023 break;
9025 case VKI_V4L2_CREATE_BUFS: {
9026 struct vki_v4l2_create_buffers *data =
9027 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9028 struct vki_v4l2_format *fmt = &data->format;
9029 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9030 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9031 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9032 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9033 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9034 switch (fmt->type) {
9035 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9036 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9037 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9038 break;
9039 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9040 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9041 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9042 break;
9043 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9044 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9045 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9046 break;
9047 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9048 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9049 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9050 break;
9051 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9052 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9053 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9054 break;
9055 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9056 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9057 break;
9059 break;
9061 case VKI_V4L2_PREPARE_BUF: {
9062 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9063 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9064 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9065 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9066 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9067 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9068 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9069 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9070 unsigned i;
9072 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9073 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9074 for (i = 0; i < data->length; i++) {
9075 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9078 break;
9080 case VKI_V4L2_G_SELECTION: {
9081 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9082 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9083 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9084 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9085 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9086 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9087 break;
9089 case VKI_V4L2_S_SELECTION: {
9090 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9091 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9092 break;
9094 case VKI_V4L2_DECODER_CMD: {
9095 struct vki_v4l2_decoder_cmd *data =
9096 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9097 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9098 break;
9100 case VKI_V4L2_TRY_DECODER_CMD: {
9101 struct vki_v4l2_decoder_cmd *data =
9102 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9103 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9104 break;
9106 case VKI_V4L2_ENUM_DV_TIMINGS: {
9107 struct vki_v4l2_enum_dv_timings *data =
9108 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9109 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9110 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9111 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9112 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9113 break;
9115 case VKI_V4L2_QUERY_DV_TIMINGS: {
9116 struct vki_v4l2_dv_timings *data =
9117 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9118 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9119 break;
9121 case VKI_V4L2_DV_TIMINGS_CAP: {
9122 struct vki_v4l2_dv_timings_cap *data =
9123 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9124 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9125 break;
9127 case VKI_V4L2_ENUM_FREQ_BANDS: {
9128 struct vki_v4l2_frequency_band *data =
9129 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9130 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9131 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9132 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9133 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9134 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9135 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9136 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9137 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9138 break;
9140 case VKI_V4L2_DBG_G_CHIP_INFO: {
9141 struct vki_v4l2_dbg_chip_info *data =
9142 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9143 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9144 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9145 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9146 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9147 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9148 break;
9150 case VKI_V4L2_QUERY_EXT_CTRL: {
9151 struct vki_v4l2_query_ext_ctrl *data =
9152 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9153 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9154 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9155 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9156 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9157 break;
9159 case VKI_V4L2_SUBDEV_G_FMT: {
9160 struct vki_v4l2_subdev_format *data =
9161 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9162 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9163 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9164 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9165 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9166 break;
9168 case VKI_V4L2_SUBDEV_S_FMT: {
9169 struct vki_v4l2_subdev_format *data =
9170 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9171 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9172 break;
9174 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9175 struct vki_v4l2_subdev_frame_interval *data =
9176 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9177 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9178 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9179 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9180 break;
9182 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9183 struct vki_v4l2_subdev_frame_interval *data =
9184 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9185 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9186 break;
9188 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9189 struct vki_v4l2_subdev_mbus_code_enum *data =
9190 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9191 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9192 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9193 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9194 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9195 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9196 break;
9198 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9199 struct vki_v4l2_subdev_frame_size_enum *data =
9200 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9201 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9202 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9203 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9204 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9205 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9206 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9207 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9208 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9209 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9210 break;
9212 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9213 struct vki_v4l2_subdev_frame_interval_enum *data =
9214 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9215 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9216 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9217 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9218 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9219 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9220 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9221 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9222 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9223 break;
9225 case VKI_V4L2_SUBDEV_G_CROP: {
9226 struct vki_v4l2_subdev_crop *data =
9227 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9228 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9229 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9231 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9232 break;
9234 case VKI_V4L2_SUBDEV_S_CROP: {
9235 struct vki_v4l2_subdev_crop *data =
9236 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9237 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9238 break;
9240 case VKI_V4L2_SUBDEV_G_SELECTION: {
9241 struct vki_v4l2_subdev_selection *data =
9242 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9243 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9244 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9245 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9246 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9247 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9248 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9249 break;
9251 case VKI_V4L2_SUBDEV_S_SELECTION: {
9252 struct vki_v4l2_subdev_selection *data =
9253 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9254 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
9255 break;
9257 case VKI_MEDIA_IOC_DEVICE_INFO: {
9258 struct vki_media_device_info *data =
9259 (struct vki_media_device_info *)(Addr)ARG3;
9260 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
9261 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
9262 (Addr)data, sizeof(*data) - sizeof(data->reserved));
9263 break;
9265 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
9266 struct vki_media_entity_desc *data =
9267 (struct vki_media_entity_desc *)(Addr)ARG3;
9268 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
9269 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
9270 (Addr)data->name, sizeof(*data) - sizeof(data->id));
9271 break;
9273 case VKI_MEDIA_IOC_ENUM_LINKS: {
9274 struct vki_media_links_enum *data =
9275 (struct vki_media_links_enum *)(Addr)ARG3;
9276 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
9277 break;
9279 case VKI_MEDIA_IOC_SETUP_LINK: {
9280 struct vki_media_link_desc *data =
9281 (struct vki_media_link_desc *)(Addr)ARG3;
9282 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
9283 break;
9286 /* Serial */
9287 case VKI_TIOCGSERIAL: {
9288 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9289 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9290 break;
9292 case VKI_TIOCSSERIAL: {
9293 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9294 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9295 break;
9298 case VKI_PERF_EVENT_IOC_RESET:
9299 case VKI_PERF_EVENT_IOC_REFRESH:
9300 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9301 case VKI_PERF_EVENT_IOC_SET_BPF:
9302 /* These take scalar arguments, so already handled above */
9303 break;
9305 case VKI_PERF_EVENT_IOC_PERIOD:
9306 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9307 break;
9309 case VKI_PERF_EVENT_IOC_SET_FILTER:
9310 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9311 break;
9313 case VKI_PERF_EVENT_IOC_ID:
9314 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9315 break;
9317 default:
9318 /* EVIOC* are variable length and return size written on success */
9319 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9320 case VKI_EVIOCGNAME(0):
9321 case VKI_EVIOCGPHYS(0):
9322 case VKI_EVIOCGUNIQ(0):
9323 case VKI_EVIOCGKEY(0):
9324 case VKI_EVIOCGLED(0):
9325 case VKI_EVIOCGSND(0):
9326 case VKI_EVIOCGSW(0):
9327 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9328 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9329 case VKI_EVIOCGBIT(VKI_EV_REL,0):
9330 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9331 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9332 case VKI_EVIOCGBIT(VKI_EV_SW,0):
9333 case VKI_EVIOCGBIT(VKI_EV_LED,0):
9334 case VKI_EVIOCGBIT(VKI_EV_SND,0):
9335 case VKI_EVIOCGBIT(VKI_EV_REP,0):
9336 case VKI_EVIOCGBIT(VKI_EV_FF,0):
9337 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9338 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9339 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9340 break;
9341 default:
9342 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9343 break;
9345 break;
9349 POST(sys_ioctl)
9351 ARG2 = (UInt)ARG2;
9353 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9355 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9357 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9358 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9359 VG_(clo_kernel_variant))) {
9361 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9362 /* What's going on here: there appear to be a bunch of ioctls
9363 of the form 0xC01C67xx which are undocumented, and if
9364 unhandled give rise to a vast number of false positives in
9365 Memcheck.
9367 The "normal" interpretation of an ioctl of this form would
9368 be that the 3rd arg is a pointer to an area of size 0x1C
9369 (28 bytes) which is filled in by the kernel. Hence you
9370 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9371 But it doesn't.
9373 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9374 One interpretation of this is that ARG3 really does point
9375 to a 28 byte struct, but inside that are pointers to other
9376 areas also filled in by the kernel. If these happen to be
9377 allocated just back up the stack then the 256 byte paint
9378 might cover them too, somewhat indiscriminately.
9380 By printing out ARG3 and also the 28 bytes that it points
9381 at, it's possible to guess that the 7 word structure has
9382 this form
9384 0 1 2 3 4 5 6
9385 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9387 Unfortunately that doesn't seem to work for some reason,
9388 so stay with the blunt-instrument approach for the time
9389 being.
9391 if (1) {
9392 /* blunt-instrument approach */
9393 POST_MEM_WRITE(ARG3, 256);
9394 } else {
9395 /* be a bit more sophisticated */
9396 POST_MEM_WRITE(ARG3, 28);
9397 UInt* word = (UInt*)(Addr)ARG3;
9398 if (word && word[2] && word[3] < 0x200/*stay sane*/)
9399 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9400 if (word && word[4] && word[5] < 0x200/*stay sane*/)
9401 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9403 goto post_sys_ioctl__out;
9406 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9408 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9409 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9410 VG_(clo_kernel_variant))) {
9411 if (ARG2 == 0xC00C0902) {
9412 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9413 goto post_sys_ioctl__out;
9416 /* END undocumented ioctls for Qualcomm Adreno 3xx */
9418 /* --- END special IOCTL handlers for specific Android hardware --- */
9420 /* --- normal handling --- */
9421 switch (ARG2 /* request */) {
9423 /* The Linux kernel "ion" memory allocator, used on Android. Note:
9424 this is pretty poor given that there's no pre-handling to check
9425 that writable areas are addressable. */
9426 case VKI_ION_IOC_ALLOC: {
9427 struct vki_ion_allocation_data* data
9428 = (struct vki_ion_allocation_data*)(Addr)ARG3;
9429 POST_FIELD_WRITE(data->handle);
9430 break;
9432 case VKI_ION_IOC_MAP: {
9433 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9434 POST_FIELD_WRITE(data->fd);
9435 break;
9437 case VKI_ION_IOC_FREE: // is this necessary?
9438 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9439 break;
9440 case VKI_ION_IOC_SHARE:
9441 break;
9442 case VKI_ION_IOC_IMPORT: {
9443 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9444 POST_FIELD_WRITE(data->handle);
9445 break;
9447 case VKI_ION_IOC_SYNC:
9448 break;
9449 case VKI_ION_IOC_CUSTOM: // is this necessary?
9450 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9451 break;
9453 case VKI_SYNC_IOC_MERGE: {
9454 struct vki_sync_merge_data* data =
9455 (struct vki_sync_merge_data*)(Addr)ARG3;
9456 POST_FIELD_WRITE(data->fence);
9457 break;
9460 case VKI_TCSETS:
9461 case VKI_TCSETSW:
9462 case VKI_TCSETSF:
9463 case VKI_IB_USER_MAD_ENABLE_PKEY:
9464 break;
9465 case VKI_TCGETS:
9466 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9467 break;
9468 case VKI_TCSETA:
9469 case VKI_TCSETAW:
9470 case VKI_TCSETAF:
9471 break;
9472 case VKI_TCGETA:
9473 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9474 break;
9475 case VKI_TCSBRK:
9476 case VKI_TCXONC:
9477 case VKI_TCSBRKP:
9478 case VKI_TCFLSH:
9479 case VKI_TIOCSIG:
9480 break;
9481 case VKI_TIOCGWINSZ:
9482 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9483 break;
9484 case VKI_TIOCSWINSZ:
9485 case VKI_TIOCMBIS:
9486 case VKI_TIOCMBIC:
9487 case VKI_TIOCMSET:
9488 break;
9489 case VKI_TIOCMGET:
9490 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9491 break;
9492 case VKI_TIOCLINUX:
9493 POST_MEM_WRITE( ARG3, sizeof(char *) );
9494 break;
9495 case VKI_TIOCGPGRP:
9496 /* Get process group ID for foreground processing group. */
9497 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9498 break;
9499 case VKI_TIOCSPGRP:
9500 /* Set a process group ID? */
9501 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9502 break;
9503 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9504 POST_MEM_WRITE( ARG3, sizeof(int));
9505 break;
9506 case VKI_TIOCSCTTY:
9507 break;
9508 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9509 break;
9510 case VKI_FIONBIO:
9511 break;
9512 case VKI_FIONCLEX:
9513 break;
9514 case VKI_FIOCLEX:
9515 break;
9516 case VKI_TIOCNOTTY:
9517 break;
9518 case VKI_FIOASYNC:
9519 break;
9520 case VKI_FIONREAD: /* identical to SIOCINQ */
9521 POST_MEM_WRITE( ARG3, sizeof(int) );
9522 break;
9523 case VKI_FIOQSIZE:
9524 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9525 break;
9527 case VKI_TIOCSERGETLSR:
9528 POST_MEM_WRITE( ARG3, sizeof(int) );
9529 break;
9530 case VKI_TIOCGICOUNT:
9531 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9532 break;
9534 case VKI_SG_SET_COMMAND_Q:
9535 break;
9536 case VKI_SG_IO:
9538 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
9539 if ( sgio->sbp ) {
9540 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9542 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9543 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9544 int transferred = sgio->dxfer_len - sgio->resid;
9545 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9548 break;
9549 case VKI_SG_GET_SCSI_ID:
9550 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9551 break;
9552 case VKI_SG_SET_RESERVED_SIZE:
9553 break;
9554 case VKI_SG_SET_TIMEOUT:
9555 break;
9556 case VKI_SG_GET_RESERVED_SIZE:
9557 POST_MEM_WRITE(ARG3, sizeof(int));
9558 break;
9559 case VKI_SG_GET_TIMEOUT:
9560 break;
9561 case VKI_SG_GET_VERSION_NUM:
9562 POST_MEM_WRITE(ARG3, sizeof(int));
9563 break;
9564 case VKI_SG_EMULATED_HOST:
9565 POST_MEM_WRITE(ARG3, sizeof(int));
9566 break;
9567 case VKI_SG_GET_SG_TABLESIZE:
9568 POST_MEM_WRITE(ARG3, sizeof(int));
9569 break;
9571 case VKI_IIOCGETCPS:
9572 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9573 break;
9574 case VKI_IIOCNETGPN:
9575 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9576 break;
9578 /* These all use struct ifreq AFAIK */
9579 case VKI_SIOCGIFINDEX: /* get iface index */
9580 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
9581 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
9582 break;
9583 case VKI_SIOCGIFFLAGS: /* get flags */
9584 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9585 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
9586 break;
9587 case VKI_SIOCGIFHWADDR: /* Get hardware address */
9588 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
9589 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
9590 break;
9591 case VKI_SIOCGIFMTU: /* get MTU size */
9592 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
9593 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
9594 break;
9595 case VKI_SIOCGIFADDR: /* get PA address */
9596 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
9597 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
9598 case VKI_SIOCGIFNETMASK: /* get network PA mask */
9599 POST_MEM_WRITE(
9600 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
9601 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
9602 break;
9603 case VKI_SIOCGIFMETRIC: /* get metric */
9604 POST_MEM_WRITE(
9605 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
9606 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
9607 break;
9608 case VKI_SIOCGIFMAP: /* Get device parameters */
9609 POST_MEM_WRITE(
9610 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
9611 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
9612 break;
9613 break;
9614 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
9615 POST_MEM_WRITE(
9616 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
9617 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
9618 break;
9619 case VKI_SIOCGIFNAME: /* get iface name */
9620 POST_MEM_WRITE(
9621 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9622 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9623 break;
9624 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
9625 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
9626 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9627 case VKI_ETHTOOL_GSET:
9628 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9629 break;
9630 case VKI_ETHTOOL_SSET:
9631 break;
9632 case VKI_ETHTOOL_GDRVINFO:
9633 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9634 break;
9635 case VKI_ETHTOOL_GREGS:
9636 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9637 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9638 break;
9639 case VKI_ETHTOOL_GWOL:
9640 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9641 break;
9642 case VKI_ETHTOOL_SWOL:
9643 break;
9644 case VKI_ETHTOOL_GMSGLVL:
9645 case VKI_ETHTOOL_GLINK:
9646 case VKI_ETHTOOL_GRXCSUM:
9647 case VKI_ETHTOOL_GSG:
9648 case VKI_ETHTOOL_GTSO:
9649 case VKI_ETHTOOL_GUFO:
9650 case VKI_ETHTOOL_GGSO:
9651 case VKI_ETHTOOL_GFLAGS:
9652 case VKI_ETHTOOL_GGRO:
9653 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9654 break;
9655 case VKI_ETHTOOL_SMSGLVL:
9656 case VKI_ETHTOOL_SRXCSUM:
9657 case VKI_ETHTOOL_SSG:
9658 case VKI_ETHTOOL_STSO:
9659 case VKI_ETHTOOL_SUFO:
9660 case VKI_ETHTOOL_SGSO:
9661 case VKI_ETHTOOL_SFLAGS:
9662 case VKI_ETHTOOL_SGRO:
9663 break;
9664 case VKI_ETHTOOL_NWAY_RST:
9665 break;
9666 case VKI_ETHTOOL_GRINGPARAM:
9667 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9668 break;
9669 case VKI_ETHTOOL_SRINGPARAM:
9670 break;
9671 case VKI_ETHTOOL_TEST:
9672 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9673 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9674 break;
9675 case VKI_ETHTOOL_PHYS_ID:
9676 break;
9677 case VKI_ETHTOOL_GPERMADDR:
9678 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9679 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9680 break;
9681 case VKI_ETHTOOL_RESET:
9682 break;
9683 case VKI_ETHTOOL_GSSET_INFO:
9684 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9685 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9686 break;
9687 case VKI_ETHTOOL_GFEATURES:
9688 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9689 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9690 break;
9691 case VKI_ETHTOOL_SFEATURES:
9692 break;
9693 case VKI_ETHTOOL_GCHANNELS:
9694 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9695 break;
9696 case VKI_ETHTOOL_SCHANNELS:
9697 break;
9698 case VKI_ETHTOOL_GET_TS_INFO:
9699 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9700 break;
9702 break;
9704 case VKI_SIOCGMIIPHY: /* get hardware entry */
9705 POST_MEM_WRITE(
9706 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
9707 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
9708 break;
9709 case VKI_SIOCGMIIREG: /* get hardware entry registers */
9710 POST_MEM_WRITE(
9711 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
9712 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
9713 break;
9715 /* tun/tap related ioctls */
9716 case VKI_TUNSETIFF:
9717 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9718 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9719 break;
9720 case VKI_TUNGETFEATURES:
9721 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9722 break;
9723 case VKI_TUNGETIFF:
9724 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9725 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9726 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9727 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
9728 break;
9729 case VKI_TUNGETSNDBUF:
9730 POST_MEM_WRITE( ARG3, sizeof(int) );
9731 break;
9732 case VKI_TUNGETVNETHDRSZ:
9733 POST_MEM_WRITE( ARG3, sizeof(int) );
9734 break;
9736 case VKI_SIOCGIFCONF: /* get iface list */
9737 /* WAS:
9738 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
9739 KERNEL_DO_SYSCALL(tid,RES);
9740 if (!VG_(is_kerror)(RES) && RES == 0)
9741 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
9743 if (RES == 0 && ARG3 ) {
9744 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
9745 if (ifc->vki_ifc_buf != NULL)
9746 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
9748 break;
9749 case VKI_SIOCGSTAMP:
9750 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
9751 break;
9752 case VKI_SIOCGSTAMPNS:
9753 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
9754 break;
9755 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
9756 the number of bytes currently in that socket's send buffer.
9757 It writes this value as an int to the memory location
9758 indicated by the third argument of ioctl(2). */
9759 case VKI_SIOCOUTQ:
9760 POST_MEM_WRITE(ARG3, sizeof(int));
9761 break;
9762 case VKI_SIOCGRARP: /* get RARP table entry */
9763 case VKI_SIOCGARP: /* get ARP table entry */
9764 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
9765 break;
9767 case VKI_SIOCSIFFLAGS: /* set flags */
9768 case VKI_SIOCSIFMAP: /* Set device parameters */
9769 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
9770 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
9771 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
9772 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
9773 case VKI_SIOCSIFNETMASK: /* set network PA mask */
9774 case VKI_SIOCSIFMETRIC: /* set metric */
9775 case VKI_SIOCSIFADDR: /* set PA address */
9776 case VKI_SIOCSIFMTU: /* set MTU size */
9777 case VKI_SIOCSIFHWADDR: /* set hardware address */
9778 case VKI_SIOCSMIIREG: /* set hardware entry registers */
9779 break;
9780 /* Routing table calls. */
9781 case VKI_SIOCADDRT: /* add routing table entry */
9782 case VKI_SIOCDELRT: /* delete routing table entry */
9783 break;
9785 /* RARP cache control calls. */
9786 case VKI_SIOCDRARP: /* delete RARP table entry */
9787 case VKI_SIOCSRARP: /* set RARP table entry */
9788 /* ARP cache control calls. */
9789 case VKI_SIOCSARP: /* set ARP table entry */
9790 case VKI_SIOCDARP: /* delete ARP table entry */
9791 break;
9793 case VKI_SIOCGPGRP:
9794 POST_MEM_WRITE(ARG3, sizeof(int));
9795 break;
9796 case VKI_SIOCSPGRP:
9797 break;
9799 case VKI_SIOCATMARK:
9800 POST_MEM_WRITE(ARG3, sizeof(int));
9801 break;
9803 /* linux/soundcard interface (OSS) */
9804 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
9805 case VKI_SNDCTL_SEQ_GETINCOUNT:
9806 case VKI_SNDCTL_SEQ_PERCMODE:
9807 case VKI_SNDCTL_SEQ_TESTMIDI:
9808 case VKI_SNDCTL_SEQ_RESETSAMPLES:
9809 case VKI_SNDCTL_SEQ_NRSYNTHS:
9810 case VKI_SNDCTL_SEQ_NRMIDIS:
9811 case VKI_SNDCTL_SEQ_GETTIME:
9812 case VKI_SNDCTL_DSP_GETBLKSIZE:
9813 case VKI_SNDCTL_DSP_GETFMTS:
9814 case VKI_SNDCTL_DSP_SETFMT:
9815 case VKI_SNDCTL_DSP_GETTRIGGER:
9816 case VKI_SNDCTL_DSP_GETODELAY:
9817 case VKI_SNDCTL_DSP_GETSPDIF:
9818 case VKI_SNDCTL_DSP_GETCAPS:
9819 case VKI_SOUND_PCM_READ_RATE:
9820 case VKI_SOUND_PCM_READ_CHANNELS:
9821 case VKI_SOUND_PCM_READ_BITS:
9822 case VKI_SOUND_PCM_READ_FILTER:
9823 POST_MEM_WRITE(ARG3, sizeof(int));
9824 break;
9825 case VKI_SNDCTL_SEQ_CTRLRATE:
9826 case VKI_SNDCTL_DSP_SPEED:
9827 case VKI_SNDCTL_DSP_STEREO:
9828 case VKI_SNDCTL_DSP_CHANNELS:
9829 case VKI_SOUND_PCM_WRITE_FILTER:
9830 case VKI_SNDCTL_DSP_SUBDIVIDE:
9831 case VKI_SNDCTL_DSP_SETFRAGMENT:
9832 case VKI_SNDCTL_DSP_GETCHANNELMASK:
9833 case VKI_SNDCTL_DSP_BIND_CHANNEL:
9834 case VKI_SNDCTL_TMR_TIMEBASE:
9835 case VKI_SNDCTL_TMR_TEMPO:
9836 case VKI_SNDCTL_TMR_SOURCE:
9837 case VKI_SNDCTL_MIDI_PRETIME:
9838 case VKI_SNDCTL_MIDI_MPUMODE:
9839 break;
9840 case VKI_SNDCTL_DSP_GETOSPACE:
9841 case VKI_SNDCTL_DSP_GETISPACE:
9842 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
9843 break;
9844 case VKI_SNDCTL_DSP_NONBLOCK:
9845 break;
9846 case VKI_SNDCTL_DSP_SETTRIGGER:
9847 break;
9849 case VKI_SNDCTL_DSP_POST:
9850 case VKI_SNDCTL_DSP_RESET:
9851 case VKI_SNDCTL_DSP_SYNC:
9852 case VKI_SNDCTL_DSP_SETSYNCRO:
9853 case VKI_SNDCTL_DSP_SETDUPLEX:
9854 break;
9856 /* linux/soundcard interface (ALSA) */
9857 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
9858 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
9859 case VKI_SNDRV_PCM_IOCTL_PREPARE:
9860 case VKI_SNDRV_PCM_IOCTL_RESET:
9861 case VKI_SNDRV_PCM_IOCTL_START:
9862 case VKI_SNDRV_PCM_IOCTL_DROP:
9863 case VKI_SNDRV_PCM_IOCTL_DRAIN:
9864 case VKI_SNDRV_PCM_IOCTL_RESUME:
9865 case VKI_SNDRV_PCM_IOCTL_XRUN:
9866 case VKI_SNDRV_PCM_IOCTL_UNLINK:
9867 case VKI_SNDRV_TIMER_IOCTL_START:
9868 case VKI_SNDRV_TIMER_IOCTL_STOP:
9869 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
9870 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
9871 break;
9873 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
9874 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
9875 break;
9877 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
9878 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
9879 break;
9880 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
9881 struct vki_snd_ctl_elem_list *data =
9882 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
9883 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
9884 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
9885 if (data->pids) {
9886 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
9888 break;
9890 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
9891 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
9892 POST_MEM_WRITE( (Addr)data->tlv, data->length );
9893 break;
9895 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
9896 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
9897 break;
9899 /* SCSI no operand */
9900 case VKI_SCSI_IOCTL_DOORLOCK:
9901 case VKI_SCSI_IOCTL_DOORUNLOCK:
9902 break;
9904 /* Real Time Clock (/dev/rtc) ioctls */
9905 case VKI_RTC_UIE_ON:
9906 case VKI_RTC_UIE_OFF:
9907 case VKI_RTC_AIE_ON:
9908 case VKI_RTC_AIE_OFF:
9909 case VKI_RTC_PIE_ON:
9910 case VKI_RTC_PIE_OFF:
9911 case VKI_RTC_IRQP_SET:
9912 break;
9913 case VKI_RTC_RD_TIME:
9914 case VKI_RTC_ALM_READ:
9915 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
9916 break;
9917 case VKI_RTC_ALM_SET:
9918 break;
9919 case VKI_RTC_IRQP_READ:
9920 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9921 break;
9923 /* Block devices */
9924 case VKI_BLKROSET:
9925 break;
9926 case VKI_BLKROGET:
9927 POST_MEM_WRITE(ARG3, sizeof(int));
9928 break;
9929 case VKI_BLKGETSIZE:
9930 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
9931 break;
9932 case VKI_BLKFLSBUF:
9933 break;
9934 case VKI_BLKRASET:
9935 break;
9936 case VKI_BLKRAGET:
9937 POST_MEM_WRITE(ARG3, sizeof(long));
9938 break;
9939 case VKI_BLKFRASET:
9940 break;
9941 case VKI_BLKFRAGET:
9942 POST_MEM_WRITE(ARG3, sizeof(long));
9943 break;
9944 case VKI_BLKSECTGET:
9945 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
9946 break;
9947 case VKI_BLKSSZGET:
9948 POST_MEM_WRITE(ARG3, sizeof(int));
9949 break;
9950 case VKI_BLKBSZGET:
9951 POST_MEM_WRITE(ARG3, sizeof(int));
9952 break;
9953 case VKI_BLKBSZSET:
9954 break;
9955 case VKI_BLKGETSIZE64:
9956 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
9957 break;
9958 case VKI_BLKPBSZGET:
9959 POST_MEM_WRITE(ARG3, sizeof(int));
9960 break;
9961 case VKI_BLKDISCARDZEROES:
9962 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
9963 break;
9964 case VKI_BLKREPORTZONE: {
9965 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
9967 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
9968 break;
9970 case VKI_BLKRESETZONE:
9971 break;
9973 /* Hard disks */
9974 case VKI_HDIO_GETGEO: /* 0x0301 */
9975 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
9976 break;
9977 case VKI_HDIO_GET_DMA: /* 0x030b */
9978 POST_MEM_WRITE(ARG3, sizeof(long));
9979 break;
9980 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
9981 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
9982 break;
9984 /* SCSI */
9985 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
9986 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
9987 break;
9988 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
9989 POST_MEM_WRITE(ARG3, sizeof(int));
9990 break;
9992 /* CD ROM stuff (??) */
9993 case VKI_CDROM_DISC_STATUS:
9994 case VKI_CDROMSTOP:
9995 break;
9996 case VKI_CDROMSUBCHNL:
9997 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
9998 break;
9999 case VKI_CDROMREADTOCHDR:
10000 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10001 break;
10002 case VKI_CDROMREADTOCENTRY:
10003 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10004 break;
10005 case VKI_CDROMMULTISESSION:
10006 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10007 break;
10008 case VKI_CDROMVOLREAD:
10009 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10010 break;
10011 case VKI_CDROMREADMODE1:
10012 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10013 break;
10014 case VKI_CDROMREADMODE2:
10015 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10016 break;
10017 case VKI_CDROMREADRAW:
10018 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10019 break;
10020 case VKI_CDROMREADAUDIO:
10022 struct vki_cdrom_read_audio *cra =
10023 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10024 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10025 break;
10028 case VKI_CDROMPLAYMSF:
10029 break;
10030 /* The following two are probably bogus (should check args
10031 for readability). JRS 20021117 */
10032 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10033 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10034 break;
10035 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10036 break;
10038 /* DVD stuff */
10039 case VKI_DVD_READ_STRUCT:
10040 break;
10042 case VKI_FIGETBSZ:
10043 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10044 break;
10045 case VKI_FIBMAP:
10046 POST_MEM_WRITE(ARG3, sizeof(int));
10047 break;
10049 case VKI_FBIOGET_VSCREENINFO: //0x4600
10050 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10051 break;
10052 case VKI_FBIOGET_FSCREENINFO: //0x4602
10053 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10054 break;
10056 case VKI_PPCLAIM:
10057 case VKI_PPEXCL:
10058 case VKI_PPYIELD:
10059 case VKI_PPRELEASE:
10060 case VKI_PPSETMODE:
10061 case VKI_PPSETPHASE:
10062 case VKI_PPSETFLAGS:
10063 case VKI_PPWDATA:
10064 case VKI_PPWCONTROL:
10065 case VKI_PPFCONTROL:
10066 case VKI_PPDATADIR:
10067 case VKI_PPNEGOT:
10068 case VKI_PPWCTLONIRQ:
10069 case VKI_PPSETTIME:
10070 break;
10071 case VKI_PPGETMODE:
10072 POST_MEM_WRITE( ARG3, sizeof(int) );
10073 break;
10074 case VKI_PPGETPHASE:
10075 POST_MEM_WRITE( ARG3, sizeof(int) );
10076 break;
10077 case VKI_PPGETMODES:
10078 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10079 break;
10080 case VKI_PPGETFLAGS:
10081 POST_MEM_WRITE( ARG3, sizeof(int) );
10082 break;
10083 case VKI_PPRSTATUS:
10084 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10085 break;
10086 case VKI_PPRDATA:
10087 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10088 break;
10089 case VKI_PPRCONTROL:
10090 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10091 break;
10092 case VKI_PPCLRIRQ:
10093 POST_MEM_WRITE( ARG3, sizeof(int) );
10094 break;
10095 case VKI_PPGETTIME:
10096 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10097 break;
10099 case VKI_GIO_FONT:
10100 POST_MEM_WRITE( ARG3, 32 * 256 );
10101 break;
10102 case VKI_PIO_FONT:
10103 break;
10105 case VKI_GIO_FONTX:
10106 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10107 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10108 break;
10109 case VKI_PIO_FONTX:
10110 break;
10112 case VKI_PIO_FONTRESET:
10113 break;
10115 case VKI_GIO_CMAP:
10116 POST_MEM_WRITE( ARG3, 16 * 3 );
10117 break;
10118 case VKI_PIO_CMAP:
10119 break;
10121 case VKI_KIOCSOUND:
10122 case VKI_KDMKTONE:
10123 break;
10125 case VKI_KDGETLED:
10126 POST_MEM_WRITE( ARG3, sizeof(char) );
10127 break;
10128 case VKI_KDSETLED:
10129 break;
10131 case VKI_KDGKBTYPE:
10132 POST_MEM_WRITE( ARG3, sizeof(char) );
10133 break;
10135 case VKI_KDADDIO:
10136 case VKI_KDDELIO:
10137 case VKI_KDENABIO:
10138 case VKI_KDDISABIO:
10139 break;
10141 case VKI_KDSETMODE:
10142 break;
10143 case VKI_KDGETMODE:
10144 POST_MEM_WRITE( ARG3, sizeof(int) );
10145 break;
10147 case VKI_KDMAPDISP:
10148 case VKI_KDUNMAPDISP:
10149 break;
10151 case VKI_GIO_SCRNMAP:
10152 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
10153 break;
10154 case VKI_PIO_SCRNMAP:
10155 break;
10156 case VKI_GIO_UNISCRNMAP:
10157 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
10158 break;
10159 case VKI_PIO_UNISCRNMAP:
10160 break;
10162 case VKI_GIO_UNIMAP:
10163 if ( ARG3 ) {
10164 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
10165 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
10166 POST_MEM_WRITE( (Addr)desc->entries,
10167 desc->entry_ct * sizeof(struct vki_unipair) );
10169 break;
10170 case VKI_PIO_UNIMAP:
10171 break;
10172 case VKI_PIO_UNIMAPCLR:
10173 break;
10175 case VKI_KDGKBMODE:
10176 POST_MEM_WRITE( ARG3, sizeof(int) );
10177 break;
10178 case VKI_KDSKBMODE:
10179 break;
10181 case VKI_KDGKBMETA:
10182 POST_MEM_WRITE( ARG3, sizeof(int) );
10183 break;
10184 case VKI_KDSKBMETA:
10185 break;
10187 case VKI_KDGKBLED:
10188 POST_MEM_WRITE( ARG3, sizeof(char) );
10189 break;
10190 case VKI_KDSKBLED:
10191 break;
10193 case VKI_KDGKBENT:
10194 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
10195 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
10196 break;
10197 case VKI_KDSKBENT:
10198 break;
10200 case VKI_KDGKBSENT:
10201 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
10202 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
10203 break;
10204 case VKI_KDSKBSENT:
10205 break;
10207 case VKI_KDGKBDIACR:
10208 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
10209 break;
10210 case VKI_KDSKBDIACR:
10211 break;
10213 case VKI_KDGETKEYCODE:
10214 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
10215 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
10216 break;
10217 case VKI_KDSETKEYCODE:
10218 break;
10220 case VKI_KDSIGACCEPT:
10221 break;
10223 case VKI_KDKBDREP:
10224 break;
10226 case VKI_KDFONTOP:
10227 if ( ARG3 ) {
10228 struct vki_console_font_op *op =
10229 (struct vki_console_font_op *) (Addr)ARG3;
10230 switch ( op->op ) {
10231 case VKI_KD_FONT_OP_SET:
10232 break;
10233 case VKI_KD_FONT_OP_GET:
10234 if ( op->data )
10235 POST_MEM_WRITE( (Addr) op->data,
10236 (op->width + 7) / 8 * 32 * op->charcount );
10237 break;
10238 case VKI_KD_FONT_OP_SET_DEFAULT:
10239 break;
10240 case VKI_KD_FONT_OP_COPY:
10241 break;
10243 POST_MEM_WRITE( (Addr) op, sizeof(*op));
10245 break;
10247 case VKI_VT_OPENQRY:
10248 POST_MEM_WRITE( ARG3, sizeof(int) );
10249 break;
10250 case VKI_VT_GETMODE:
10251 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
10252 break;
10253 case VKI_VT_SETMODE:
10254 break;
10255 case VKI_VT_GETSTATE:
10256 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
10257 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
10258 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
10259 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
10260 break;
10261 case VKI_VT_RELDISP:
10262 case VKI_VT_ACTIVATE:
10263 case VKI_VT_WAITACTIVE:
10264 case VKI_VT_DISALLOCATE:
10265 break;
10266 case VKI_VT_RESIZE:
10267 break;
10268 case VKI_VT_RESIZEX:
10269 break;
10270 case VKI_VT_LOCKSWITCH:
10271 case VKI_VT_UNLOCKSWITCH:
10272 break;
10274 case VKI_USBDEVFS_CONTROL:
10275 if ( ARG3 ) {
10276 struct vki_usbdevfs_ctrltransfer *vkuc =
10277 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
10278 if (vkuc->bRequestType & 0x80)
10279 POST_MEM_WRITE((Addr)vkuc->data, RES);
10281 break;
10282 case VKI_USBDEVFS_BULK:
10283 if ( ARG3 ) {
10284 struct vki_usbdevfs_bulktransfer *vkub =
10285 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
10286 if (vkub->ep & 0x80)
10287 POST_MEM_WRITE((Addr)vkub->data, RES);
10289 break;
10290 case VKI_USBDEVFS_GETDRIVER:
10291 if ( ARG3 ) {
10292 struct vki_usbdevfs_getdriver *vkugd =
10293 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
10294 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
10296 break;
10297 case VKI_USBDEVFS_REAPURB:
10298 case VKI_USBDEVFS_REAPURBNDELAY:
10299 if ( ARG3 ) {
10300 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
10301 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
10302 if (!*vkuu)
10303 break;
10304 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
10305 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10306 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10307 if (vkusp->bRequestType & 0x80)
10308 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10309 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10310 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10311 char *bp = (*vkuu)->buffer;
10312 int i;
10313 for(i=0; i<(*vkuu)->number_of_packets; i++) {
10314 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10315 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10316 if ((*vkuu)->endpoint & 0x80)
10317 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10318 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10320 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10321 } else {
10322 if ((*vkuu)->endpoint & 0x80)
10323 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10324 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10327 break;
10328 case VKI_USBDEVFS_CONNECTINFO:
10329 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10330 break;
10331 case VKI_USBDEVFS_IOCTL:
10332 if ( ARG3 ) {
10333 struct vki_usbdevfs_ioctl *vkui =
10334 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
10335 UInt dir2, size2;
10336 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
10337 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10338 if (size2 > 0) {
10339 if (dir2 & _VKI_IOC_READ)
10340 POST_MEM_WRITE((Addr)vkui->data, size2);
10343 break;
10345 /* I2C (/dev/i2c-*) ioctls */
10346 case VKI_I2C_SLAVE:
10347 case VKI_I2C_SLAVE_FORCE:
10348 case VKI_I2C_TENBIT:
10349 case VKI_I2C_PEC:
10350 break;
10351 case VKI_I2C_FUNCS:
10352 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10353 break;
10354 case VKI_I2C_RDWR:
10355 if ( ARG3 ) {
10356 struct vki_i2c_rdwr_ioctl_data *vkui =
10357 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
10358 UInt i;
10359 for (i=0; i < vkui->nmsgs; i++) {
10360 struct vki_i2c_msg *msg = vkui->msgs + i;
10361 if (msg->flags & VKI_I2C_M_RD)
10362 POST_MEM_WRITE((Addr)msg->buf, msg->len);
10365 break;
10366 case VKI_I2C_SMBUS:
10367 if ( ARG3 ) {
10368 struct vki_i2c_smbus_ioctl_data *vkis
10369 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
10370 /* i2c_smbus_write_quick hides its value in read_write, so
10371 this variable can have a different meaning */
10372 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10373 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10374 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10375 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10376 UInt size;
10377 switch(vkis->size) {
10378 case VKI_I2C_SMBUS_BYTE:
10379 case VKI_I2C_SMBUS_BYTE_DATA:
10380 size = 1;
10381 break;
10382 case VKI_I2C_SMBUS_WORD_DATA:
10383 case VKI_I2C_SMBUS_PROC_CALL:
10384 size = 2;
10385 break;
10386 case VKI_I2C_SMBUS_BLOCK_DATA:
10387 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10388 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10389 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10390 size = 1 + vkis->data->block[0];
10391 break;
10392 default:
10393 size = 0;
10395 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10399 break;
10401 /* Wireless extensions ioctls */
10402 case VKI_SIOCSIWCOMMIT:
10403 case VKI_SIOCSIWNWID:
10404 case VKI_SIOCSIWFREQ:
10405 case VKI_SIOCSIWMODE:
10406 case VKI_SIOCSIWSENS:
10407 case VKI_SIOCSIWRANGE:
10408 case VKI_SIOCSIWPRIV:
10409 case VKI_SIOCSIWSTATS:
10410 case VKI_SIOCSIWSPY:
10411 case VKI_SIOCSIWTHRSPY:
10412 case VKI_SIOCSIWAP:
10413 case VKI_SIOCSIWSCAN:
10414 case VKI_SIOCSIWESSID:
10415 case VKI_SIOCSIWRATE:
10416 case VKI_SIOCSIWNICKN:
10417 case VKI_SIOCSIWRTS:
10418 case VKI_SIOCSIWFRAG:
10419 case VKI_SIOCSIWTXPOW:
10420 case VKI_SIOCSIWRETRY:
10421 case VKI_SIOCSIWENCODE:
10422 case VKI_SIOCSIWPOWER:
10423 case VKI_SIOCSIWGENIE:
10424 case VKI_SIOCSIWMLME:
10425 case VKI_SIOCSIWAUTH:
10426 case VKI_SIOCSIWENCODEEXT:
10427 case VKI_SIOCSIWPMKSA:
10428 break;
10429 case VKI_SIOCGIWNAME:
10430 if (ARG3) {
10431 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
10432 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
10434 break;
10435 case VKI_SIOCGIWNWID:
10436 case VKI_SIOCGIWSENS:
10437 case VKI_SIOCGIWRATE:
10438 case VKI_SIOCGIWRTS:
10439 case VKI_SIOCGIWFRAG:
10440 case VKI_SIOCGIWTXPOW:
10441 case VKI_SIOCGIWRETRY:
10442 case VKI_SIOCGIWPOWER:
10443 case VKI_SIOCGIWAUTH:
10444 if (ARG3) {
10445 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
10446 sizeof(struct vki_iw_param));
10448 break;
10449 case VKI_SIOCGIWFREQ:
10450 if (ARG3) {
10451 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
10452 sizeof(struct vki_iw_freq));
10454 break;
10455 case VKI_SIOCGIWMODE:
10456 if (ARG3) {
10457 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
10458 sizeof(__vki_u32));
10460 break;
10461 case VKI_SIOCGIWRANGE:
10462 case VKI_SIOCGIWPRIV:
10463 case VKI_SIOCGIWSTATS:
10464 case VKI_SIOCGIWSPY:
10465 case VKI_SIOCGIWTHRSPY:
10466 case VKI_SIOCGIWAPLIST:
10467 case VKI_SIOCGIWSCAN:
10468 case VKI_SIOCGIWESSID:
10469 case VKI_SIOCGIWNICKN:
10470 case VKI_SIOCGIWENCODE:
10471 case VKI_SIOCGIWGENIE:
10472 case VKI_SIOCGIWENCODEEXT:
10473 if (ARG3) {
10474 struct vki_iw_point* point;
10475 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
10476 POST_MEM_WRITE((Addr)point->pointer, point->length);
10478 break;
10479 case VKI_SIOCGIWAP:
10480 if (ARG3) {
10481 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
10482 sizeof(struct vki_sockaddr));
10484 break;
10486 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10487 || defined(VGPV_mips32_linux_android) \
10488 || defined(VGPV_arm64_linux_android)
10489 /* ashmem */
10490 case VKI_ASHMEM_GET_SIZE:
10491 case VKI_ASHMEM_SET_SIZE:
10492 case VKI_ASHMEM_GET_PROT_MASK:
10493 case VKI_ASHMEM_SET_PROT_MASK:
10494 case VKI_ASHMEM_GET_PIN_STATUS:
10495 case VKI_ASHMEM_PURGE_ALL_CACHES:
10496 case VKI_ASHMEM_SET_NAME:
10497 case VKI_ASHMEM_PIN:
10498 case VKI_ASHMEM_UNPIN:
10499 break;
10500 case VKI_ASHMEM_GET_NAME:
10501 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10502 break;
10504 /* binder */
10505 case VKI_BINDER_WRITE_READ:
10506 if (ARG3) {
10507 struct vki_binder_write_read* bwr
10508 = (struct vki_binder_write_read*)(Addr)ARG3;
10509 POST_FIELD_WRITE(bwr->write_consumed);
10510 POST_FIELD_WRITE(bwr->read_consumed);
10512 if (bwr->read_size)
10513 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10515 break;
10517 case VKI_BINDER_SET_IDLE_TIMEOUT:
10518 case VKI_BINDER_SET_MAX_THREADS:
10519 case VKI_BINDER_SET_IDLE_PRIORITY:
10520 case VKI_BINDER_SET_CONTEXT_MGR:
10521 case VKI_BINDER_THREAD_EXIT:
10522 break;
10523 case VKI_BINDER_VERSION:
10524 if (ARG3) {
10525 struct vki_binder_version* bv =
10526 (struct vki_binder_version*)(Addr)ARG3;
10527 POST_FIELD_WRITE(bv->protocol_version);
10529 break;
10530 # endif /* defined(VGPV_*_linux_android) */
10532 case VKI_HCIGETDEVLIST:
10533 if (ARG3) {
10534 struct vki_hci_dev_list_req* dlr =
10535 (struct vki_hci_dev_list_req*)(Addr)ARG3;
10536 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10537 dlr->dev_num * sizeof(struct vki_hci_dev_req));
10539 break;
10541 case VKI_HCIINQUIRY:
10542 if (ARG3) {
10543 struct vki_hci_inquiry_req* ir =
10544 (struct vki_hci_inquiry_req*)(Addr)ARG3;
10545 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10546 ir->num_rsp * sizeof(struct vki_inquiry_info));
10548 break;
10550 case VKI_DRM_IOCTL_VERSION:
10551 if (ARG3) {
10552 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
10553 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10554 const vki_size_t orig_name_len = info->orig->name_len;
10555 const vki_size_t orig_date_len = info->orig->date_len;
10556 const vki_size_t orig_desc_len = info->orig->desc_len;
10557 *info->orig = info->data;
10558 ARG3 = (Addr)info->orig;
10559 data = info->orig;
10560 VG_(free)(info);
10561 if (SUCCESS) {
10562 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10563 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10564 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10565 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10566 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10567 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10568 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10569 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10570 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10573 break;
10574 case VKI_DRM_IOCTL_GET_UNIQUE:
10575 if (ARG3) {
10576 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
10577 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10579 break;
10580 case VKI_DRM_IOCTL_GET_MAGIC:
10581 if (ARG3) {
10582 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
10583 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10585 break;
10586 case VKI_DRM_IOCTL_WAIT_VBLANK:
10587 if (ARG3) {
10588 union vki_drm_wait_vblank *data =
10589 (union vki_drm_wait_vblank *)(Addr)ARG3;
10590 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10592 break;
10593 case VKI_DRM_IOCTL_GEM_FLINK:
10594 if (ARG3) {
10595 struct vki_drm_gem_flink *data =
10596 (struct vki_drm_gem_flink *)(Addr)ARG3;
10597 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10599 break;
10600 case VKI_DRM_IOCTL_GEM_OPEN:
10601 if (ARG3) {
10602 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
10603 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10604 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10606 break;
10607 case VKI_DRM_IOCTL_I915_GETPARAM:
10608 if (ARG3) {
10609 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
10610 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10612 break;
10613 case VKI_DRM_IOCTL_I915_GEM_BUSY:
10614 if (ARG3) {
10615 struct vki_drm_i915_gem_busy *data =
10616 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
10617 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10619 break;
10620 case VKI_DRM_IOCTL_I915_GEM_CREATE:
10621 if (ARG3) {
10622 struct vki_drm_i915_gem_create *data =
10623 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
10624 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10626 break;
10627 case VKI_DRM_IOCTL_I915_GEM_PREAD:
10628 if (ARG3) {
10629 struct vki_drm_i915_gem_pread *data =
10630 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
10631 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10633 break;
10634 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10635 if (ARG3) {
10636 struct vki_drm_i915_gem_mmap_gtt *data =
10637 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
10638 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10640 break;
10641 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10642 if (ARG3) {
10643 struct vki_drm_i915_gem_set_tiling *data =
10644 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
10645 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10646 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10647 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10649 break;
10650 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10651 if (ARG3) {
10652 struct vki_drm_i915_gem_get_tiling *data =
10653 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
10654 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10655 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10657 break;
10658 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10659 if (ARG3) {
10660 struct vki_drm_i915_gem_get_aperture *data =
10661 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
10662 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10663 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10665 break;
10667 /* KVM ioctls that only write the system call return value */
10668 case VKI_KVM_GET_API_VERSION:
10669 case VKI_KVM_CREATE_VM:
10670 case VKI_KVM_CHECK_EXTENSION:
10671 case VKI_KVM_GET_VCPU_MMAP_SIZE:
10672 case VKI_KVM_S390_ENABLE_SIE:
10673 case VKI_KVM_CREATE_VCPU:
10674 case VKI_KVM_SET_TSS_ADDR:
10675 case VKI_KVM_CREATE_IRQCHIP:
10676 case VKI_KVM_RUN:
10677 case VKI_KVM_S390_INITIAL_RESET:
10678 case VKI_KVM_KVMCLOCK_CTRL:
10679 break;
10681 case VKI_KVM_S390_MEM_OP: {
10682 struct vki_kvm_s390_mem_op *args =
10683 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
10684 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
10685 break;
10686 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
10687 POST_MEM_WRITE((Addr)args->buf, args->size);
10689 break;
10691 #ifdef ENABLE_XEN
10692 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
10693 SyscallArgs harrghs;
10694 struct vki_xen_privcmd_hypercall *args =
10695 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
10697 if (!args)
10698 break;
10700 VG_(memset)(&harrghs, 0, sizeof(harrghs));
10701 harrghs.sysno = args->op;
10702 harrghs.arg1 = args->arg[0];
10703 harrghs.arg2 = args->arg[1];
10704 harrghs.arg3 = args->arg[2];
10705 harrghs.arg4 = args->arg[3];
10706 harrghs.arg5 = args->arg[4];
10707 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
10709 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
10711 break;
10713 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
10714 break;
10715 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
10716 struct vki_xen_privcmd_mmapbatch *args =
10717 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
10718 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
10720 break;
10721 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
10722 struct vki_xen_privcmd_mmapbatch_v2 *args =
10723 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
10724 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
10726 break;
10728 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
10729 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
10730 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
10731 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
10732 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
10733 case VKI_XEN_IOCTL_EVTCHN_RESET:
10734 /* No output */
10735 break;
10736 #endif
10738 /* Lustre */
10739 case VKI_OBD_IOC_FID2PATH: {
10740 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
10741 POST_FIELD_WRITE(args->gf_recno);
10742 POST_FIELD_WRITE(args->gf_linkno);
10743 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
10744 break;
10747 case VKI_LL_IOC_PATH2FID:
10748 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
10749 break;
10751 case VKI_LL_IOC_GETPARENT: {
10752 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
10753 POST_FIELD_WRITE(gp->gp_fid);
10754 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
10755 break;
10758 /* V4L2 */
10759 case VKI_V4L2_S_FMT:
10760 case VKI_V4L2_TRY_FMT:
10761 case VKI_V4L2_REQBUFS:
10762 case VKI_V4L2_OVERLAY:
10763 case VKI_V4L2_STREAMON:
10764 case VKI_V4L2_STREAMOFF:
10765 case VKI_V4L2_S_PARM:
10766 case VKI_V4L2_S_STD:
10767 case VKI_V4L2_S_FREQUENCY:
10768 case VKI_V4L2_S_CTRL:
10769 case VKI_V4L2_S_TUNER:
10770 case VKI_V4L2_S_AUDIO:
10771 case VKI_V4L2_S_INPUT:
10772 case VKI_V4L2_S_EDID:
10773 case VKI_V4L2_S_OUTPUT:
10774 case VKI_V4L2_S_AUDOUT:
10775 case VKI_V4L2_S_MODULATOR:
10776 case VKI_V4L2_S_JPEGCOMP:
10777 case VKI_V4L2_S_CROP:
10778 case VKI_V4L2_S_PRIORITY:
10779 case VKI_V4L2_S_HW_FREQ_SEEK:
10780 case VKI_V4L2_S_DV_TIMINGS:
10781 case VKI_V4L2_SUBSCRIBE_EVENT:
10782 case VKI_V4L2_UNSUBSCRIBE_EVENT:
10783 case VKI_V4L2_PREPARE_BUF:
10784 break;
10785 case VKI_V4L2_QUERYCAP: {
10786 struct vki_v4l2_capability *data =
10787 (struct vki_v4l2_capability *)(Addr)ARG3;
10788 POST_MEM_WRITE((Addr)data, sizeof(*data));
10789 break;
10791 case VKI_V4L2_ENUM_FMT: {
10792 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
10793 POST_FIELD_WRITE(data->flags);
10794 POST_FIELD_WRITE(data->description);
10795 POST_FIELD_WRITE(data->pixelformat);
10796 POST_FIELD_WRITE(data->reserved);
10797 break;
10799 case VKI_V4L2_G_FMT: {
10800 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
10801 switch (data->type) {
10802 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
10803 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
10804 POST_FIELD_WRITE(data->fmt.pix);
10805 break;
10806 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
10807 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
10808 POST_FIELD_WRITE(data->fmt.vbi);
10809 break;
10810 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
10811 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
10812 POST_FIELD_WRITE(data->fmt.sliced);
10813 break;
10814 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
10815 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
10816 POST_FIELD_WRITE(data->fmt.win);
10817 break;
10818 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
10819 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
10820 POST_FIELD_WRITE(data->fmt.pix_mp);
10821 break;
10822 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
10823 POST_FIELD_WRITE(data->fmt.sdr);
10824 break;
10826 break;
10828 case VKI_V4L2_QUERYBUF: {
10829 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10830 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10831 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10832 unsigned i;
10834 for (i = 0; i < data->length; i++) {
10835 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10836 POST_FIELD_WRITE(data->m.planes[i].length);
10837 POST_FIELD_WRITE(data->m.planes[i].m);
10838 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10839 POST_FIELD_WRITE(data->m.planes[i].reserved);
10841 } else {
10842 POST_FIELD_WRITE(data->m);
10843 POST_FIELD_WRITE(data->length);
10845 POST_FIELD_WRITE(data->bytesused);
10846 POST_FIELD_WRITE(data->flags);
10847 POST_FIELD_WRITE(data->field);
10848 POST_FIELD_WRITE(data->timestamp);
10849 POST_FIELD_WRITE(data->timecode);
10850 POST_FIELD_WRITE(data->sequence);
10851 POST_FIELD_WRITE(data->memory);
10852 POST_FIELD_WRITE(data->sequence);
10853 break;
10855 case VKI_V4L2_G_FBUF: {
10856 struct vki_v4l2_framebuffer *data =
10857 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10858 POST_MEM_WRITE((Addr)data, sizeof(*data));
10859 break;
10861 case VKI_V4L2_S_FBUF: {
10862 struct vki_v4l2_framebuffer *data =
10863 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
10864 POST_FIELD_WRITE(data->capability);
10865 POST_FIELD_WRITE(data->flags);
10866 POST_FIELD_WRITE(data->fmt);
10867 break;
10869 case VKI_V4L2_QBUF: {
10870 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
10872 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10873 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10874 unsigned i;
10876 for (i = 0; i < data->length; i++) {
10877 POST_FIELD_WRITE(data->m.planes[i].length);
10878 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10879 POST_FIELD_WRITE(data->m.planes[i].m);
10881 } else {
10882 if (data->memory == VKI_V4L2_MEMORY_MMAP)
10883 POST_FIELD_WRITE(data->m);
10884 POST_FIELD_WRITE(data->length);
10886 break;
10888 case VKI_V4L2_EXPBUF: {
10889 struct vki_v4l2_exportbuffer *data =
10890 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
10891 POST_FIELD_WRITE(data->fd);
10892 break;
10894 case VKI_V4L2_DQBUF: {
10895 struct vki_v4l2_buffer *data =
10896 (struct vki_v4l2_buffer *)(Addr)ARG3;
10897 POST_FIELD_WRITE(data->index);
10898 POST_FIELD_WRITE(data->bytesused);
10899 POST_FIELD_WRITE(data->field);
10900 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
10901 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
10902 unsigned i;
10904 for (i = 0; i < data->length; i++) {
10905 POST_FIELD_WRITE(data->m.planes[i].bytesused);
10906 POST_FIELD_WRITE(data->m.planes[i].data_offset);
10907 POST_FIELD_WRITE(data->m.planes[i].length);
10908 POST_FIELD_WRITE(data->m.planes[i].m);
10910 } else {
10911 POST_FIELD_WRITE(data->m);
10912 POST_FIELD_WRITE(data->length);
10913 POST_FIELD_WRITE(data->bytesused);
10914 POST_FIELD_WRITE(data->field);
10916 POST_FIELD_WRITE(data->timestamp);
10917 POST_FIELD_WRITE(data->timecode);
10918 POST_FIELD_WRITE(data->sequence);
10919 break;
10921 case VKI_V4L2_G_PARM: {
10922 struct vki_v4l2_streamparm *data =
10923 (struct vki_v4l2_streamparm *)(Addr)ARG3;
10924 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
10925 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
10926 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
10927 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
10929 if (is_output)
10930 POST_MEM_WRITE((Addr)&data->parm.output,
10931 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
10932 else
10933 POST_MEM_WRITE((Addr)&data->parm.capture,
10934 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
10935 break;
10937 case VKI_V4L2_G_STD: {
10938 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
10939 POST_MEM_WRITE((Addr)data, sizeof(*data));
10940 break;
10942 case VKI_V4L2_ENUMSTD: {
10943 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
10944 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
10945 break;
10947 case VKI_V4L2_ENUMINPUT: {
10948 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
10949 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
10950 break;
10952 case VKI_V4L2_G_CTRL: {
10953 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
10954 POST_FIELD_WRITE(data->value);
10955 break;
10957 case VKI_V4L2_G_TUNER: {
10958 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
10959 POST_MEM_WRITE((Addr)data->name,
10960 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
10961 break;
10963 case VKI_V4L2_G_AUDIO: {
10964 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
10965 POST_MEM_WRITE((Addr)data,
10966 sizeof(*data) - sizeof(data->reserved));
10967 break;
10969 case VKI_V4L2_QUERYCTRL: {
10970 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
10971 POST_MEM_WRITE((Addr)&data->type,
10972 sizeof(*data) - sizeof(data->id));
10973 break;
10975 case VKI_V4L2_QUERYMENU: {
10976 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
10977 POST_MEM_WRITE((Addr)data->name,
10978 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
10979 break;
10981 case VKI_V4L2_G_INPUT: {
10982 int *data = (int *)(Addr)ARG3;
10983 POST_MEM_WRITE((Addr)data, sizeof(*data));
10984 break;
10986 case VKI_V4L2_G_EDID: {
10987 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
10988 if (data->blocks && data->edid)
10989 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
10990 break;
10992 case VKI_V4L2_G_OUTPUT: {
10993 int *data = (int *)(Addr)ARG3;
10994 POST_MEM_WRITE((Addr)data, sizeof(*data));
10995 break;
10997 case VKI_V4L2_ENUMOUTPUT: {
10998 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
10999 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11000 break;
11002 case VKI_V4L2_G_AUDOUT: {
11003 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11004 POST_MEM_WRITE((Addr)data,
11005 sizeof(*data) - sizeof(data->reserved));
11006 break;
11008 case VKI_V4L2_G_MODULATOR: {
11009 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11010 POST_MEM_WRITE((Addr)data->name,
11011 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11012 break;
11014 case VKI_V4L2_G_FREQUENCY: {
11015 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11016 POST_FIELD_WRITE(data->type);
11017 POST_FIELD_WRITE(data->frequency);
11018 break;
11020 case VKI_V4L2_CROPCAP: {
11021 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11022 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11023 break;
11025 case VKI_V4L2_G_CROP: {
11026 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11027 POST_FIELD_WRITE(data->c);
11028 break;
11030 case VKI_V4L2_G_JPEGCOMP: {
11031 struct vki_v4l2_jpegcompression *data =
11032 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11033 POST_MEM_WRITE((Addr)data, sizeof(*data));
11034 break;
11036 case VKI_V4L2_QUERYSTD: {
11037 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11038 POST_MEM_WRITE((Addr)data, sizeof(*data));
11039 break;
11041 case VKI_V4L2_ENUMAUDIO: {
11042 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11043 POST_MEM_WRITE((Addr)data->name,
11044 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11045 break;
11047 case VKI_V4L2_ENUMAUDOUT: {
11048 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11049 POST_MEM_WRITE((Addr)data->name,
11050 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11051 break;
11053 case VKI_V4L2_G_PRIORITY: {
11054 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11055 POST_MEM_WRITE((Addr)data, sizeof(*data));
11056 break;
11058 case VKI_V4L2_G_SLICED_VBI_CAP: {
11059 struct vki_v4l2_sliced_vbi_cap *data =
11060 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11061 POST_MEM_WRITE((Addr)data,
11062 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11063 break;
11065 case VKI_V4L2_G_EXT_CTRLS: {
11066 struct vki_v4l2_ext_controls *data =
11067 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11068 if (data->count) {
11069 unsigned i;
11071 for (i = 0; i < data->count; i++) {
11072 if (data->controls[i].size)
11073 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11074 else
11075 POST_FIELD_WRITE(data->controls[i].value64);
11078 POST_FIELD_WRITE(data->error_idx);
11079 break;
11081 case VKI_V4L2_S_EXT_CTRLS: {
11082 struct vki_v4l2_ext_controls *data =
11083 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11084 POST_FIELD_WRITE(data->error_idx);
11085 break;
11087 case VKI_V4L2_TRY_EXT_CTRLS: {
11088 struct vki_v4l2_ext_controls *data =
11089 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11090 POST_FIELD_WRITE(data->error_idx);
11091 break;
11093 case VKI_V4L2_ENUM_FRAMESIZES: {
11094 struct vki_v4l2_frmsizeenum *data =
11095 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11096 POST_FIELD_WRITE(data->type);
11097 POST_FIELD_WRITE(data->stepwise);
11098 break;
11100 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11101 struct vki_v4l2_frmivalenum *data =
11102 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11103 POST_FIELD_WRITE(data->type);
11104 POST_FIELD_WRITE(data->stepwise);
11105 break;
11107 case VKI_V4L2_G_ENC_INDEX: {
11108 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11109 POST_MEM_WRITE((Addr)data, sizeof(*data));
11110 break;
11112 case VKI_V4L2_ENCODER_CMD: {
11113 struct vki_v4l2_encoder_cmd *data =
11114 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11115 POST_FIELD_WRITE(data->flags);
11116 break;
11118 case VKI_V4L2_TRY_ENCODER_CMD: {
11119 struct vki_v4l2_encoder_cmd *data =
11120 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11121 POST_FIELD_WRITE(data->flags);
11122 break;
11124 case VKI_V4L2_DBG_S_REGISTER: {
11125 struct vki_v4l2_dbg_register *data =
11126 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11127 POST_FIELD_WRITE(data->size);
11128 break;
11130 case VKI_V4L2_DBG_G_REGISTER: {
11131 struct vki_v4l2_dbg_register *data =
11132 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11133 POST_FIELD_WRITE(data->val);
11134 POST_FIELD_WRITE(data->size);
11135 break;
11137 case VKI_V4L2_G_DV_TIMINGS: {
11138 struct vki_v4l2_dv_timings *data =
11139 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11140 POST_MEM_WRITE((Addr)data, sizeof(*data));
11141 break;
11143 case VKI_V4L2_DQEVENT: {
11144 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
11145 POST_MEM_WRITE((Addr)data, sizeof(*data));
11146 break;
11148 case VKI_V4L2_CREATE_BUFS: {
11149 struct vki_v4l2_create_buffers *data =
11150 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
11151 POST_FIELD_WRITE(data->index);
11152 break;
11154 case VKI_V4L2_G_SELECTION: {
11155 struct vki_v4l2_selection *data =
11156 (struct vki_v4l2_selection *)(Addr)ARG3;
11157 POST_FIELD_WRITE(data->r);
11158 break;
11160 case VKI_V4L2_S_SELECTION: {
11161 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
11162 POST_FIELD_WRITE(data->r);
11163 break;
11165 case VKI_V4L2_DECODER_CMD: {
11166 struct vki_v4l2_decoder_cmd *data =
11167 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11168 POST_FIELD_WRITE(data->flags);
11169 break;
11171 case VKI_V4L2_TRY_DECODER_CMD: {
11172 struct vki_v4l2_decoder_cmd *data =
11173 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11174 POST_FIELD_WRITE(data->flags);
11175 break;
11177 case VKI_V4L2_ENUM_DV_TIMINGS: {
11178 struct vki_v4l2_enum_dv_timings *data =
11179 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
11180 POST_FIELD_WRITE(data->timings);
11181 break;
11183 case VKI_V4L2_QUERY_DV_TIMINGS: {
11184 struct vki_v4l2_dv_timings *data =
11185 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11186 POST_MEM_WRITE((Addr)data, sizeof(*data));
11187 break;
11189 case VKI_V4L2_DV_TIMINGS_CAP: {
11190 struct vki_v4l2_dv_timings_cap *data =
11191 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
11192 POST_MEM_WRITE((Addr)data, sizeof(*data));
11193 break;
11195 case VKI_V4L2_ENUM_FREQ_BANDS: {
11196 struct vki_v4l2_frequency_band *data =
11197 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
11198 POST_FIELD_WRITE(data->capability);
11199 POST_FIELD_WRITE(data->rangelow);
11200 POST_FIELD_WRITE(data->rangehigh);
11201 POST_FIELD_WRITE(data->modulation);
11202 break;
11204 case VKI_V4L2_DBG_G_CHIP_INFO: {
11205 struct vki_v4l2_dbg_chip_info *data =
11206 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
11207 POST_FIELD_WRITE(data->name);
11208 POST_FIELD_WRITE(data->flags);
11209 break;
11211 case VKI_V4L2_QUERY_EXT_CTRL: {
11212 struct vki_v4l2_query_ext_ctrl *data =
11213 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
11214 POST_MEM_WRITE((Addr)&data->type,
11215 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
11216 break;
11219 case VKI_V4L2_SUBDEV_S_FMT:
11220 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
11221 case VKI_V4L2_SUBDEV_S_CROP:
11222 case VKI_V4L2_SUBDEV_S_SELECTION:
11223 break;
11225 case VKI_V4L2_SUBDEV_G_FMT: {
11226 struct vki_v4l2_subdev_format *data =
11227 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
11228 POST_FIELD_WRITE(data->format);
11229 break;
11231 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
11232 struct vki_v4l2_subdev_frame_interval *data =
11233 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
11234 POST_FIELD_WRITE(data->interval);
11235 break;
11237 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
11238 struct vki_v4l2_subdev_mbus_code_enum *data =
11239 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
11240 POST_FIELD_WRITE(data->code);
11241 break;
11243 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
11244 struct vki_v4l2_subdev_frame_size_enum *data =
11245 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
11246 POST_FIELD_WRITE(data->min_width);
11247 POST_FIELD_WRITE(data->min_height);
11248 POST_FIELD_WRITE(data->max_width);
11249 POST_FIELD_WRITE(data->max_height);
11250 break;
11252 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
11253 struct vki_v4l2_subdev_frame_interval_enum *data =
11254 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
11255 POST_FIELD_WRITE(data->interval);
11256 break;
11258 case VKI_V4L2_SUBDEV_G_CROP: {
11259 struct vki_v4l2_subdev_crop *data =
11260 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
11261 POST_FIELD_WRITE(data->rect);
11262 break;
11264 case VKI_V4L2_SUBDEV_G_SELECTION: {
11265 struct vki_v4l2_subdev_selection *data =
11266 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
11267 POST_FIELD_WRITE(data->r);
11268 break;
11270 case VKI_MEDIA_IOC_DEVICE_INFO: {
11271 struct vki_media_device_info *data =
11272 (struct vki_media_device_info *)(Addr)ARG3;
11273 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
11274 break;
11276 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
11277 struct vki_media_entity_desc *data =
11278 (struct vki_media_entity_desc *)(Addr)ARG3;
11279 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
11280 break;
11282 case VKI_MEDIA_IOC_ENUM_LINKS:
11284 * This ioctl does write to the provided pointers, but it's not
11285 * possible to deduce the size of the array those pointers point to.
11287 break;
11288 case VKI_MEDIA_IOC_SETUP_LINK:
11289 break;
11291 /* Serial */
11292 case VKI_TIOCGSERIAL: {
11293 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
11294 POST_MEM_WRITE((Addr)data, sizeof(*data));
11295 break;
11297 case VKI_TIOCSSERIAL:
11298 break;
11300 case VKI_PERF_EVENT_IOC_ENABLE:
11301 case VKI_PERF_EVENT_IOC_DISABLE:
11302 case VKI_PERF_EVENT_IOC_REFRESH:
11303 case VKI_PERF_EVENT_IOC_RESET:
11304 case VKI_PERF_EVENT_IOC_PERIOD:
11305 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
11306 case VKI_PERF_EVENT_IOC_SET_FILTER:
11307 case VKI_PERF_EVENT_IOC_SET_BPF:
11308 break;
11310 case VKI_PERF_EVENT_IOC_ID:
11311 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
11312 break;
11314 default:
11315 /* EVIOC* are variable length and return size written on success */
11316 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
11317 case VKI_EVIOCGNAME(0):
11318 case VKI_EVIOCGPHYS(0):
11319 case VKI_EVIOCGUNIQ(0):
11320 case VKI_EVIOCGKEY(0):
11321 case VKI_EVIOCGLED(0):
11322 case VKI_EVIOCGSND(0):
11323 case VKI_EVIOCGSW(0):
11324 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
11325 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
11326 case VKI_EVIOCGBIT(VKI_EV_REL,0):
11327 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
11328 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
11329 case VKI_EVIOCGBIT(VKI_EV_SW,0):
11330 case VKI_EVIOCGBIT(VKI_EV_LED,0):
11331 case VKI_EVIOCGBIT(VKI_EV_SND,0):
11332 case VKI_EVIOCGBIT(VKI_EV_REP,0):
11333 case VKI_EVIOCGBIT(VKI_EV_FF,0):
11334 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
11335 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
11336 if (RES > 0)
11337 POST_MEM_WRITE(ARG3, RES);
11338 break;
11339 default:
11340 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
11341 break;
11343 break;
11346 post_sys_ioctl__out:
11347 {} /* keep C compilers happy */
11350 /* ---------------------------------------------------------------------
11351 socketcall wrapper helpers
11352 ------------------------------------------------------------------ */
11354 void
11355 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
11356 UWord arg0, UWord arg1, UWord arg2,
11357 UWord arg3, UWord arg4 )
11359 /* int getsockopt(int s, int level, int optname,
11360 void *optval, socklen_t *optlen); */
11361 Addr optval_p = arg3;
11362 Addr optlen_p = arg4;
11363 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11364 if (optval_p != (Addr)NULL) {
11365 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11366 "socketcall.getsockopt(optval)",
11367 "socketcall.getsockopt(optlen)" );
11368 if (arg1 == VKI_SOL_SCTP &&
11369 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11370 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11372 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11373 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11374 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11375 (Addr)ga->addrs, address_bytes );
11380 void
11381 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11382 SysRes res,
11383 UWord arg0, UWord arg1, UWord arg2,
11384 UWord arg3, UWord arg4 )
11386 Addr optval_p = arg3;
11387 Addr optlen_p = arg4;
11388 vg_assert(!sr_isError(res)); /* guaranteed by caller */
11389 if (optval_p != (Addr)NULL) {
11390 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11391 "socketcall.getsockopt(optlen_out)" );
11392 if (arg1 == VKI_SOL_SCTP &&
11393 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11394 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11396 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11397 struct vki_sockaddr *a = ga->addrs;
11398 int i;
11399 for (i = 0; i < ga->addr_num; i++) {
11400 int sl = 0;
11401 if (a->sa_family == VKI_AF_INET)
11402 sl = sizeof(struct vki_sockaddr_in);
11403 else if (a->sa_family == VKI_AF_INET6)
11404 sl = sizeof(struct vki_sockaddr_in6);
11405 else {
11406 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11407 "address type %d\n", a->sa_family);
11409 a = (struct vki_sockaddr*)((char*)a + sl);
11411 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11416 void
11417 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11418 UWord arg0, UWord arg1, UWord arg2,
11419 UWord arg3, UWord arg4 )
11421 /* int setsockopt(int s, int level, int optname,
11422 const void *optval, socklen_t optlen); */
11423 Addr optval_p = arg3;
11424 if (optval_p != (Addr)NULL) {
11426 * OK, let's handle at least some setsockopt levels and options
11427 * ourselves, so we don't get false claims of references to
11428 * uninitialized memory (such as padding in structures) and *do*
11429 * check what pointers in the argument point to.
11431 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11433 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11436 * struct sock_fprog has a 16-bit count of instructions,
11437 * followed by a pointer to an array of those instructions.
11438 * There's padding between those two elements.
11440 * So that we don't bogusly complain about the padding bytes,
11441 * we just report that we read len and and filter.
11443 * We then make sure that what filter points to is valid.
11445 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11446 (Addr)&fp->len, sizeof(fp->len) );
11447 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11448 (Addr)&fp->filter, sizeof(fp->filter) );
11450 /* len * sizeof (*filter) */
11451 if (fp->filter != NULL)
11453 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11454 (Addr)(fp->filter),
11455 fp->len * sizeof(*fp->filter) );
11458 else
11460 PRE_MEM_READ( "socketcall.setsockopt(optval)",
11461 arg3, /* optval */
11462 arg4 /* optlen */ );
11467 void
11468 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11469 UWord arg1, UWord arg2, UWord arg3,
11470 UWord arg4, UWord arg5 )
11472 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11473 HChar name[40]; // large enough
11474 UInt i;
11475 for (i = 0; i < arg3; i++) {
11476 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11477 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11478 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11479 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11481 if (arg5)
11482 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11485 void
11486 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11487 UWord arg1, UWord arg2, UWord arg3,
11488 UWord arg4, UWord arg5 )
11490 if (res > 0) {
11491 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11492 HChar name[32]; // large enough
11493 UInt i;
11494 for (i = 0; i < res; i++) {
11495 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11496 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11497 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11502 void
11503 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11504 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11506 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11507 HChar name[40]; // large enough
11508 UInt i;
11509 for (i = 0; i < arg3; i++) {
11510 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11511 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11512 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11513 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11517 void
11518 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11519 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11521 if (res > 0) {
11522 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11523 UInt i;
11524 for (i = 0; i < res; i++) {
11525 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11530 /* ---------------------------------------------------------------------
11531 ptrace wrapper helpers
11532 ------------------------------------------------------------------ */
11534 void
11535 ML_(linux_POST_traceme) ( ThreadId tid )
11537 ThreadState *tst = VG_(get_ThreadState)(tid);
11538 tst->ptrace = VKI_PT_PTRACED;
11541 void
11542 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11544 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11546 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11547 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11548 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11549 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11550 (Addr) iov->iov_base, iov->iov_len);
11554 void
11555 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11557 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11559 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11560 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11561 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11562 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11563 (Addr) iov->iov_base, iov->iov_len);
11567 void
11568 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11570 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11572 /* XXX: The actual amount of data written by the kernel might be
11573 less than iov_len, depending on the regset (arg3). */
11574 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11577 PRE(sys_kcmp)
11579 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
11580 SARG1, SARG2, SARG3, ARG4, ARG5);
11581 switch (ARG3) {
11582 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11583 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11584 /* Most of the comparison types don't look at |idx1| or
11585 |idx2|. */
11586 PRE_REG_READ3(long, "kcmp",
11587 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11588 break;
11589 case VKI_KCMP_FILE:
11590 default:
11591 PRE_REG_READ5(long, "kcmp",
11592 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11593 unsigned long, idx1, unsigned long, idx2);
11594 break;
11598 /* ---------------------------------------------------------------------
11599 bpf wrappers
11600 ------------------------------------------------------------------ */
11602 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
11604 HChar path[32], buf[1024]; /* large enough */
11605 SysRes sres;
11606 HChar *comp;
11607 Int proc_fd;
11609 *key_size = 0;
11610 *value_size = 0;
11612 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
11613 sres = VG_(open)(path, VKI_O_RDONLY, 0);
11614 if (sr_isError(sres))
11615 return False;
11616 proc_fd = sr_Res(sres);
11618 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
11619 return False;
11620 VG_(close)(proc_fd);
11622 comp = VG_(strstr)(buf, "key_size:");
11623 if (comp)
11624 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
11626 comp = VG_(strstr)(buf, "value_size:");
11627 if (comp)
11628 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
11630 return (*key_size && *value_size);
11634 * From a file descriptor for an eBPF object, try to determine the size of the
11635 * struct that will be written, i.e. determine if object is a map or a program.
11636 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
11637 * search for strings "prog_type" or "map_type".
11639 static UInt bpf_obj_get_info_size(Int fd)
11641 HChar path[32], buf[1024]; /* large enough */
11642 SysRes sres;
11643 Int proc_fd;
11645 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
11646 sres = VG_(open)(path, VKI_O_RDONLY, 0);
11647 if (sr_isError(sres))
11648 return 0;
11649 proc_fd = sr_Res(sres);
11651 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
11652 return 0;
11653 VG_(close)(proc_fd);
11655 if (VG_(strstr)(buf, "prog_type:"))
11656 return sizeof(struct vki_bpf_prog_info);
11658 if (VG_(strstr)(buf, "map_type:"))
11659 return sizeof(struct vki_bpf_map_info);
11661 return 0;
11664 PRE(sys_bpf)
11666 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
11667 UInt res, key_size, value_size;
11669 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
11670 (Word)ARG1, ARG2, ARG3);
11671 PRE_REG_READ3(long, "bpf",
11672 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
11673 switch (ARG1) {
11674 case VKI_BPF_PROG_GET_NEXT_ID:
11675 case VKI_BPF_MAP_GET_NEXT_ID:
11676 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
11677 break;
11678 case VKI_BPF_PROG_GET_FD_BY_ID:
11679 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
11680 break;
11681 case VKI_BPF_MAP_GET_FD_BY_ID:
11682 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
11683 break;
11684 case VKI_BPF_BTF_GET_FD_BY_ID:
11685 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
11686 break;
11687 case VKI_BPF_MAP_CREATE:
11688 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
11689 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
11690 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
11691 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
11692 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
11693 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
11694 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
11695 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
11696 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
11697 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
11698 switch (attr->map_type) {
11699 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
11700 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
11701 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
11702 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
11703 SET_STATUS_Failure(VKI_EBADF);
11704 break;
11705 case VKI_BPF_MAP_TYPE_ARRAY:
11706 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
11707 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
11708 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
11709 if (attr->btf_key_type_id && attr->btf_value_type_id) {
11710 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
11711 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
11712 SET_STATUS_Failure(VKI_EBADF);
11713 break;
11717 break;
11718 case VKI_BPF_MAP_TYPE_UNSPEC:
11719 case VKI_BPF_MAP_TYPE_HASH:
11720 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
11721 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
11722 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
11723 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
11724 case VKI_BPF_MAP_TYPE_STACK_TRACE:
11725 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
11726 case VKI_BPF_MAP_TYPE_LRU_HASH:
11727 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
11728 case VKI_BPF_MAP_TYPE_LPM_TRIE:
11729 case VKI_BPF_MAP_TYPE_DEVMAP:
11730 case VKI_BPF_MAP_TYPE_SOCKMAP:
11731 case VKI_BPF_MAP_TYPE_CPUMAP:
11732 case VKI_BPF_MAP_TYPE_XSKMAP:
11733 case VKI_BPF_MAP_TYPE_SOCKHASH:
11734 default:
11735 break;
11737 break;
11738 case VKI_BPF_MAP_LOOKUP_ELEM:
11739 /* Perform a lookup on an eBPF map. Read key, write value. */
11740 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11741 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
11742 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11743 if (ML_(safe_to_deref)(attr, ARG3)) {
11744 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11745 SET_STATUS_Failure(VKI_EBADF);
11746 break;
11748 /* Get size of key and value for this map. */
11749 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11750 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11751 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
11754 break;
11755 case VKI_BPF_MAP_UPDATE_ELEM:
11756 /* Add or update a map element in kernel. Read key, read value. */
11757 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11758 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
11759 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11760 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
11761 if (ML_(safe_to_deref)(attr, ARG3)) {
11762 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11763 SET_STATUS_Failure(VKI_EBADF);
11764 break;
11766 /* Get size of key and value for this map. */
11767 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11768 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11769 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
11772 break;
11773 case VKI_BPF_MAP_DELETE_ELEM:
11774 /* Delete a map element in kernel. Read key from user space. */
11775 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11776 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11777 if (ML_(safe_to_deref)(attr, ARG3)) {
11778 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11779 SET_STATUS_Failure(VKI_EBADF);
11780 break;
11782 /* Get size of key for this map. */
11783 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
11784 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11786 break;
11787 case VKI_BPF_MAP_GET_NEXT_KEY:
11788 /* From a key, get next key for the map. Read key, write next key. */
11789 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
11790 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
11791 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
11792 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
11793 if (ML_(safe_to_deref)(attr, ARG3)) {
11794 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
11795 SET_STATUS_Failure(VKI_EBADF);
11796 break;
11798 /* Get size of key for this map. */
11799 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
11800 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
11801 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
11804 break;
11805 case VKI_BPF_PROG_LOAD:
11806 /* Load a program into the kernel from an array of instructions. */
11807 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
11808 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
11809 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
11810 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
11811 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
11812 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
11813 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
11814 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
11815 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
11816 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
11817 if (ML_(safe_to_deref)(attr, ARG3)) {
11818 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
11819 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
11820 /* Read instructions, license, program name. */
11821 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
11822 attr->insn_cnt * sizeof(struct vki_bpf_insn));
11823 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
11824 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
11825 /* Possibly write up to log_len into user space log buffer. */
11826 if (attr->log_level || attr->log_size || attr->log_buf)
11827 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
11829 break;
11830 case VKI_BPF_OBJ_PIN:
11831 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
11832 /* fall through */
11833 case VKI_BPF_OBJ_GET:
11834 /* Get pinned eBPF program or map. Read path name. */
11835 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
11836 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
11837 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
11838 if (ML_(safe_to_deref)(attr, ARG3)) {
11839 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
11840 SET_STATUS_Failure(VKI_EBADF);
11841 break;
11843 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
11845 break;
11846 case VKI_BPF_PROG_ATTACH:
11847 case VKI_BPF_PROG_DETACH:
11848 /* Detach eBPF program from kernel attach point. */
11849 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
11850 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
11851 if (ML_(safe_to_deref)(attr, ARG3)) {
11852 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
11853 SET_STATUS_Failure(VKI_EBADF);
11854 if (ARG1 == VKI_BPF_PROG_ATTACH ||
11855 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
11856 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
11857 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
11858 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
11859 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
11860 SET_STATUS_Failure(VKI_EBADF);
11863 break;
11864 case VKI_BPF_PROG_TEST_RUN:
11865 /* Test prog. Read data_in, write up to data_size_out to data_out. */
11866 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
11867 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
11868 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
11869 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
11870 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
11871 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
11872 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
11873 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
11874 if (ML_(safe_to_deref)(attr, ARG3)) {
11875 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
11876 SET_STATUS_Failure(VKI_EBADF);
11877 break;
11879 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
11880 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
11881 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
11883 break;
11884 case VKI_BPF_OBJ_GET_INFO_BY_FD:
11885 /* Get info for eBPF map or program. Write info. */
11886 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
11887 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
11888 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
11889 if (ML_(safe_to_deref)(attr, ARG3)) {
11890 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
11891 SET_STATUS_Failure(VKI_EBADF);
11892 break;
11894 /* Get size of struct to write: is object a program or a map? */
11895 res = bpf_obj_get_info_size(attr->info.bpf_fd);
11896 if (res)
11897 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
11898 VG_MIN(attr->info.info_len, res));
11899 else
11900 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
11901 VG_MIN(attr->info.info_len,
11902 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
11903 sizeof(struct vki_bpf_map_info)),
11904 sizeof(struct vki_bpf_btf_info))));
11906 break;
11907 case VKI_BPF_PROG_QUERY:
11909 * Query list of eBPF program attached to cgroup.
11910 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
11912 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
11913 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
11914 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
11915 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
11916 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
11917 if (ML_(safe_to_deref)(attr, ARG3)) {
11918 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
11919 SET_STATUS_Failure(VKI_EBADF);
11920 break;
11922 if (attr->query.prog_cnt > 0) {
11923 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
11924 if (attr->query.prog_ids) {
11925 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
11926 attr->query.prog_cnt * sizeof(__vki_u32));
11930 break;
11931 case VKI_BPF_RAW_TRACEPOINT_OPEN:
11932 /* Open raw tracepoint. Read tracepoint name. */
11933 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
11934 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
11935 if (ML_(safe_to_deref)(attr, ARG3)) {
11936 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
11937 "bpf", tid, False)) {
11938 SET_STATUS_Failure(VKI_EBADF);
11939 break;
11941 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
11942 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
11943 "bpf(attr->raw_tracepoint.name)");
11945 break;
11946 case VKI_BPF_BTF_LOAD:
11947 /* Load BTF information about a program into the kernel. */
11948 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
11949 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
11950 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
11951 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
11952 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
11953 if (ML_(safe_to_deref)(attr, ARG3)) {
11954 /* Read BTF data. */
11955 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
11956 /* Possibly write up to btf_log_len into user space log buffer. */
11957 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
11958 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
11959 attr->btf_log_buf, attr->btf_log_size);
11961 break;
11962 case VKI_BPF_TASK_FD_QUERY:
11963 /* Get info about the task. Write collected info. */
11964 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
11965 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
11966 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
11967 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
11968 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
11969 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
11970 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
11971 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
11972 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
11973 if (ML_(safe_to_deref)(attr, ARG3)) {
11974 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
11975 SET_STATUS_Failure(VKI_EBADF);
11976 break;
11978 if (attr->task_fd_query.buf_len > 0) {
11979 /* Write task or perf event name. */
11980 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
11981 attr->task_fd_query.buf,
11982 attr->task_fd_query.buf_len);
11985 break;
11986 default:
11987 VG_(message)(Vg_DebugMsg,
11988 "FATAL: unhandled eBPF command %lu\n", ARG1);
11989 VG_(core_panic)("... bye!\n");
11990 break;
11994 POST(sys_bpf)
11996 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
11997 UInt key_size, value_size;
11999 vg_assert(SUCCESS);
12001 switch (ARG1) {
12002 case VKI_BPF_PROG_GET_NEXT_ID:
12003 case VKI_BPF_MAP_GET_NEXT_ID:
12004 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12005 break;
12006 case VKI_BPF_MAP_UPDATE_ELEM:
12007 case VKI_BPF_MAP_DELETE_ELEM:
12008 case VKI_BPF_OBJ_PIN:
12009 case VKI_BPF_PROG_ATTACH:
12010 case VKI_BPF_PROG_DETACH:
12011 break;
12012 /* Following commands have bpf() return a file descriptor. */
12013 case VKI_BPF_MAP_CREATE:
12014 case VKI_BPF_OBJ_GET:
12015 case VKI_BPF_PROG_GET_FD_BY_ID:
12016 case VKI_BPF_MAP_GET_FD_BY_ID:
12017 case VKI_BPF_BTF_GET_FD_BY_ID:
12018 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12019 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12020 VG_(close)(RES);
12021 SET_STATUS_Failure(VKI_EMFILE);
12022 } else {
12023 if (VG_(clo_track_fds))
12024 ML_(record_fd_open_nameless)(tid, RES);
12026 break;
12028 * TODO: Is there a way to pass information between PRE and POST hooks?
12029 * To avoid querying again for the size of keys and values.
12031 case VKI_BPF_MAP_LOOKUP_ELEM:
12032 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12033 POST_MEM_WRITE(attr->value, value_size);
12034 break;
12035 case VKI_BPF_MAP_GET_NEXT_KEY:
12036 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12037 POST_MEM_WRITE(attr->next_key, key_size);
12038 break;
12039 case VKI_BPF_PROG_LOAD:
12040 /* Return a file descriptor for loaded program, write into log_buf. */
12041 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12042 VG_(close)(RES);
12043 SET_STATUS_Failure(VKI_EMFILE);
12044 } else {
12045 if (VG_(clo_track_fds))
12046 ML_(record_fd_open_nameless)(tid, RES);
12048 if (attr->log_level || attr->log_size || attr->log_buf)
12049 POST_MEM_WRITE(attr->log_buf, attr->log_size);
12050 break;
12051 case VKI_BPF_PROG_TEST_RUN:
12052 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
12053 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12054 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
12055 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
12056 break;
12057 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12058 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
12059 break;
12060 case VKI_BPF_PROG_QUERY:
12061 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12062 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12063 if (attr->query.prog_ids)
12064 POST_MEM_WRITE(attr->query.prog_ids,
12065 attr->query.prog_cnt * sizeof(__vki_u32));
12066 break;
12067 case VKI_BPF_BTF_LOAD:
12068 /* Return a file descriptor for BTF data, write into btf_log_buf. */
12069 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12070 VG_(close)(RES);
12071 SET_STATUS_Failure(VKI_EMFILE);
12072 } else {
12073 if (VG_(clo_track_fds))
12074 ML_(record_fd_open_nameless)(tid, RES);
12076 if (attr->btf_log_level)
12077 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
12078 break;
12079 case VKI_BPF_TASK_FD_QUERY:
12080 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
12081 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12082 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12083 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12084 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12085 break;
12086 default:
12087 VG_(message)(Vg_DebugMsg,
12088 "FATAL: unhandled eBPF command %lu\n", ARG1);
12089 VG_(core_panic)("... bye!\n");
12090 break;
12094 PRE(sys_copy_file_range)
12096 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
12097 ARG4, ARG5, ARG6);
12099 PRE_REG_READ6(vki_size_t, "copy_file_range",
12100 int, "fd_in",
12101 vki_loff_t *, "off_in",
12102 int, "fd_out",
12103 vki_loff_t *, "off_out",
12104 vki_size_t, "len",
12105 unsigned int, "flags");
12107 /* File descriptors are "specially" tracked by valgrind.
12108 valgrind itself uses some, so make sure someone didn't
12109 put in one of our own... */
12110 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
12111 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
12112 SET_STATUS_Failure( VKI_EBADF );
12113 } else {
12114 /* Now see if the offsets are defined. PRE_MEM_READ will
12115 double check it can dereference them. */
12116 if (ARG2 != 0)
12117 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
12118 if (ARG4 != 0)
12119 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
12123 PRE(sys_pkey_alloc)
12125 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
12127 PRE_REG_READ2(long, "pkey_alloc",
12128 unsigned long, "flags",
12129 unsigned long, "access_rights");
12131 /* The kernel says: pkey_alloc() is always safe to call regardless of
12132 whether or not the operating system supports protection keys. It can be
12133 used in lieu of any other mechanism for detecting pkey support and will
12134 simply fail with the error ENOSPC if the operating system has no pkey
12135 support.
12137 So we simply always return ENOSPC to signal memory protection keys are
12138 not supported under valgrind, unless there are unknown flags, then we
12139 return EINVAL. */
12140 unsigned long pkey_flags = ARG1;
12141 if (pkey_flags != 0)
12142 SET_STATUS_Failure( VKI_EINVAL );
12143 else
12144 SET_STATUS_Failure( VKI_ENOSPC );
12147 PRE(sys_pkey_free)
12149 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
12151 PRE_REG_READ1(long, "pkey_free",
12152 unsigned long, "pkey");
12154 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
12155 always an error. */
12156 SET_STATUS_Failure( VKI_EINVAL );
12159 PRE(sys_pkey_mprotect)
12161 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12162 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
12163 PRE_REG_READ4(long, "pkey_mprotect",
12164 unsigned long, addr, vki_size_t, len, unsigned long, prot,
12165 unsigned long, pkey);
12167 Addr addr = ARG1;
12168 SizeT len = ARG2;
12169 Int prot = ARG3;
12170 Int pkey = ARG4;
12172 /* Since pkey_alloc () can never succeed, see above, any pkey is
12173 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
12174 if (pkey != -1)
12175 SET_STATUS_Failure( VKI_EINVAL );
12176 else
12177 handle_sys_mprotect (tid, status, &addr, &len, &prot);
12179 ARG1 = addr;
12180 ARG2 = len;
12181 ARG3 = prot;
12184 POST(sys_pkey_mprotect)
12186 Addr addr = ARG1;
12187 SizeT len = ARG2;
12188 Int prot = ARG3;
12190 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
12193 PRE(sys_io_uring_setup)
12195 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12196 ARG1, ARG2);
12197 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
12198 struct vki_io_uring_params *, p);
12199 if (ARG2)
12200 PRE_MEM_READ("io_uring_setup(p)", ARG2,
12201 offsetof(struct vki_io_uring_params, sq_off));
12204 POST(sys_io_uring_setup)
12206 vg_assert(SUCCESS);
12207 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
12208 VG_(close)(RES);
12209 SET_STATUS_Failure( VKI_EMFILE );
12210 } else {
12211 if (VG_(clo_track_fds))
12212 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
12213 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
12214 sizeof(struct vki_io_sqring_offsets) +
12215 sizeof(struct vki_io_cqring_offsets));
12219 PRE(sys_io_uring_enter)
12221 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12222 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
12223 FMT_REGWORD "u )",
12224 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
12225 PRE_REG_READ6(long, "io_uring_enter",
12226 unsigned int, fd, unsigned int, to_submit,
12227 unsigned int, min_complete, unsigned int, flags,
12228 const void *, sig, unsigned long, sigsz);
12229 if (ARG5)
12230 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
12233 POST(sys_io_uring_enter)
12237 PRE(sys_io_uring_register)
12239 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12240 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
12241 PRE_REG_READ4(long, "io_uring_register",
12242 unsigned int, fd, unsigned int, opcode,
12243 void *, arg, unsigned int, nr_args);
12244 switch (ARG2) {
12245 case VKI_IORING_REGISTER_BUFFERS:
12246 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
12247 break;
12248 case VKI_IORING_UNREGISTER_BUFFERS:
12249 break;
12250 case VKI_IORING_REGISTER_FILES:
12251 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
12252 break;
12253 case VKI_IORING_UNREGISTER_FILES:
12254 break;
12255 case VKI_IORING_REGISTER_EVENTFD:
12256 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
12257 break;
12258 case VKI_IORING_UNREGISTER_EVENTFD:
12259 break;
12263 POST(sys_io_uring_register)
12267 #undef PRE
12268 #undef POST
12270 #endif // defined(VGO_linux)
12272 /*--------------------------------------------------------------------*/
12273 /*--- end ---*/
12274 /*--------------------------------------------------------------------*/