Update bug status.
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob1190a57d655906347f1b04fcab97e27b9c9924db
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 #elif defined(VGP_nanomips_linux)
303 asm volatile (
304 "sw %1, %0 \n\t" /* set tst->status = VgTs_Empty */
305 "li $t4, %2 \n\t" /* set t4 = __NR_exit */
306 "lw $a0, %3 \n\t" /* set a0 = tst->os_state.exitcode */
307 "syscall[32] \n\t" /* exit(tst->os_state.exitcode) */
308 : "=m" (tst->status)
309 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
310 : "memory" , "$t4", "$a0"
312 #else
313 # error Unknown platform
314 #endif
316 VG_(core_panic)("Thread exit failed?\n");
319 /*NOTREACHED*/
320 vg_assert(0);
323 Word ML_(start_thread_NORETURN) ( void* arg )
325 ThreadState* tst = (ThreadState*)arg;
326 ThreadId tid = tst->tid;
328 run_a_thread_NORETURN ( (Word)tid );
329 /*NOTREACHED*/
330 vg_assert(0);
333 /* Allocate a stack for this thread, if it doesn't already have one.
334 They're allocated lazily, and never freed. Returns the initial stack
335 pointer value to use, or 0 if allocation failed. */
336 Addr ML_(allocstack)(ThreadId tid)
338 ThreadState* tst = VG_(get_ThreadState)(tid);
339 VgStack* stack;
340 Addr initial_SP;
342 /* Either the stack_base and stack_init_SP are both zero (in which
343 case a stack hasn't been allocated) or they are both non-zero,
344 in which case it has. */
346 if (tst->os_state.valgrind_stack_base == 0)
347 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
349 if (tst->os_state.valgrind_stack_base != 0)
350 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
352 /* If no stack is present, allocate one. */
354 if (tst->os_state.valgrind_stack_base == 0) {
355 stack = VG_(am_alloc_VgStack)( &initial_SP );
356 if (stack) {
357 tst->os_state.valgrind_stack_base = (Addr)stack;
358 tst->os_state.valgrind_stack_init_SP = initial_SP;
362 if (0)
363 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
364 tid,
365 (void*)tst->os_state.valgrind_stack_base,
366 (void*)tst->os_state.valgrind_stack_init_SP );
368 return tst->os_state.valgrind_stack_init_SP;
371 /* Allocate a stack for the main thread, and run it all the way to the
372 end. Although we already have a working VgStack
373 (VG_(interim_stack)) it's better to allocate a new one, so that
374 overflow detection works uniformly for all threads.
376 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
378 Addr sp;
379 VG_(debugLog)(1, "syswrap-linux",
380 "entering VG_(main_thread_wrapper_NORETURN)\n");
382 sp = ML_(allocstack)(tid);
383 #if defined(ENABLE_INNER_CLIENT_REQUEST)
385 // we must register the main thread stack before the call
386 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
387 // reports 'write error' on the non registered stack.
388 ThreadState* tst = VG_(get_ThreadState)(tid);
389 INNER_REQUEST
390 ((void)
391 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
392 tst->os_state.valgrind_stack_init_SP));
394 #endif
396 #if defined(VGP_ppc32_linux)
397 /* make a stack frame */
398 sp -= 16;
399 sp &= ~0xF;
400 *(UWord *)sp = 0;
401 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
402 /* make a stack frame */
403 sp -= 112;
404 sp &= ~((Addr)0xF);
405 *(UWord *)sp = 0;
406 #elif defined(VGP_s390x_linux)
407 /* make a stack frame */
408 sp -= 160;
409 sp &= ~((Addr)0xF);
410 *(UWord *)sp = 0;
411 #endif
413 /* If we can't even allocate the first thread's stack, we're hosed.
414 Give up. */
415 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
417 /* shouldn't be any other threads around yet */
418 vg_assert( VG_(count_living_threads)() == 1 );
420 ML_(call_on_new_stack_0_1)(
421 (Addr)sp, /* stack */
422 0, /* bogus return address */
423 run_a_thread_NORETURN, /* fn to call */
424 (Word)tid /* arg to give it */
427 /*NOTREACHED*/
428 vg_assert(0);
431 /* Clone a new thread. Note that in the clone syscalls, we hard-code
432 tlsaddr argument as NULL : the guest TLS is emulated via guest
433 registers, and Valgrind itself has no thread local storage. */
434 static SysRes clone_new_thread ( Word (*fn)(void *),
435 void* stack,
436 Word flags,
437 ThreadState* ctst,
438 Int* child_tidptr,
439 Int* parent_tidptr)
441 SysRes res;
442 /* Note that in all the below, we make sys_clone appear to have returned
443 Success(0) in the child, by assigning the relevant child guest
444 register(s) just before the clone syscall. */
445 #if defined(VGP_x86_linux)
446 Int eax;
447 ctst->arch.vex.guest_EAX = 0;
448 eax = do_syscall_clone_x86_linux
449 (ML_(start_thread_NORETURN), stack, flags, ctst,
450 child_tidptr, parent_tidptr, NULL);
451 res = VG_(mk_SysRes_x86_linux)( eax );
452 #elif defined(VGP_amd64_linux)
453 Long rax;
454 ctst->arch.vex.guest_RAX = 0;
455 rax = do_syscall_clone_amd64_linux
456 (ML_(start_thread_NORETURN), stack, flags, ctst,
457 child_tidptr, parent_tidptr, NULL);
458 res = VG_(mk_SysRes_amd64_linux)( rax );
459 #elif defined(VGP_ppc32_linux)
460 ULong word64;
461 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
462 /* %r3 = 0 */
463 ctst->arch.vex.guest_GPR3 = 0;
464 /* %cr0.so = 0 */
465 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
466 word64 = do_syscall_clone_ppc32_linux
467 (ML_(start_thread_NORETURN), stack, flags, ctst,
468 child_tidptr, parent_tidptr, NULL);
469 /* High half word64 is syscall return value. Low half is
470 the entire CR, from which we need to extract CR0.SO. */
471 /* VG_(printf)("word64 = 0x%llx\n", word64); */
472 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
473 /*errflag*/ (((UInt)word64) >> 28) & 1);
474 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
475 ULong word64;
476 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
477 /* %r3 = 0 */
478 ctst->arch.vex.guest_GPR3 = 0;
479 /* %cr0.so = 0 */
480 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
481 word64 = do_syscall_clone_ppc64_linux
482 (ML_(start_thread_NORETURN), stack, flags, ctst,
483 child_tidptr, parent_tidptr, NULL);
484 /* Low half word64 is syscall return value. Hi half is
485 the entire CR, from which we need to extract CR0.SO. */
486 /* VG_(printf)("word64 = 0x%llx\n", word64); */
487 res = VG_(mk_SysRes_ppc64_linux)
488 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
489 /*errflag*/ (UInt)((word64 >> (32+28)) & 1));
490 #elif defined(VGP_s390x_linux)
491 ULong r2;
492 ctst->arch.vex.guest_r2 = 0;
493 r2 = do_syscall_clone_s390x_linux
494 (stack, flags, parent_tidptr, child_tidptr, NULL,
495 ML_(start_thread_NORETURN), ctst);
496 res = VG_(mk_SysRes_s390x_linux)( r2 );
497 #elif defined(VGP_arm64_linux)
498 ULong x0;
499 ctst->arch.vex.guest_X0 = 0;
500 x0 = do_syscall_clone_arm64_linux
501 (ML_(start_thread_NORETURN), stack, flags, ctst,
502 child_tidptr, parent_tidptr, NULL);
503 res = VG_(mk_SysRes_arm64_linux)( x0 );
504 #elif defined(VGP_arm_linux)
505 UInt r0;
506 ctst->arch.vex.guest_R0 = 0;
507 r0 = do_syscall_clone_arm_linux
508 (ML_(start_thread_NORETURN), stack, flags, ctst,
509 child_tidptr, parent_tidptr, NULL);
510 res = VG_(mk_SysRes_arm_linux)( r0 );
511 #elif defined(VGP_mips64_linux)
512 UInt ret = 0;
513 ctst->arch.vex.guest_r2 = 0;
514 ctst->arch.vex.guest_r7 = 0;
515 ret = do_syscall_clone_mips64_linux
516 (ML_(start_thread_NORETURN), stack, flags, ctst,
517 parent_tidptr, NULL, child_tidptr);
518 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
519 #elif defined(VGP_mips32_linux)
520 UInt ret = 0;
521 ctst->arch.vex.guest_r2 = 0;
522 ctst->arch.vex.guest_r7 = 0;
523 ret = do_syscall_clone_mips_linux
524 (ML_(start_thread_NORETURN), stack, flags, ctst,
525 child_tidptr, parent_tidptr, NULL);
526 /* High half word64 is syscall return value. Low half is
527 the entire CR, from which we need to extract CR0.SO. */
528 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
529 #elif defined(VGP_nanomips_linux)
530 UInt ret = 0;
531 ctst->arch.vex.guest_r4 = 0;
532 ret = do_syscall_clone_nanomips_linux
533 (ML_(start_thread_NORETURN), stack, flags, ctst,
534 child_tidptr, parent_tidptr, NULL);
535 res = VG_ (mk_SysRes_nanomips_linux) (ret);
536 #else
537 # error Unknown platform
538 #endif
539 return res;
542 static void setup_child ( /*OUT*/ ThreadArchState *child,
543 /*IN*/ ThreadArchState *parent )
545 /* We inherit our parent's guest state. */
546 child->vex = parent->vex;
547 child->vex_shadow1 = parent->vex_shadow1;
548 child->vex_shadow2 = parent->vex_shadow2;
550 #if defined(VGP_x86_linux)
551 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
552 /*IN*/ ThreadArchState *parent );
553 ML_(x86_setup_LDT_GDT)(child, parent);
554 #endif
557 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
559 static const Bool debug = False;
560 ThreadState* ctst = VG_(get_ThreadState)(ctid);
561 // res is succesful by default, overriden if a real syscall is needed/done.
562 SysRes res = VG_(mk_SysRes_Success)(0);
564 if (debug)
565 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
567 #if defined(VGP_x86_linux)
568 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
569 if (debug)
570 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
571 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
572 tlsinfo, tlsinfo->entry_number,
573 tlsinfo->base_addr, tlsinfo->limit,
574 ctst->arch.vex.guest_ESP,
575 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
576 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
577 #elif defined(VGP_amd64_linux)
578 ctst->arch.vex.guest_FS_CONST = tlsaddr;
579 #elif defined(VGP_ppc32_linux)
580 ctst->arch.vex.guest_GPR2 = tlsaddr;
581 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
582 ctst->arch.vex.guest_GPR13 = tlsaddr;
583 #elif defined(VGP_s390x_linux)
584 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
585 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
586 #elif defined(VGP_arm64_linux)
587 /* Just assign the tls pointer in the guest TPIDR_EL0. */
588 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
589 #elif defined(VGP_arm_linux)
590 /* Just assign the tls pointer in the guest TPIDRURO. */
591 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
592 #elif defined(VGP_mips64_linux)
593 ctst->arch.vex.guest_ULR = tlsaddr;
594 ctst->arch.vex.guest_r27 = tlsaddr;
595 #elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
596 ctst->arch.vex.guest_ULR = tlsaddr;
597 ctst->arch.vex.guest_r27 = tlsaddr;
598 #else
599 # error Unknown platform
600 #endif
601 return res;
605 When a client clones, we need to keep track of the new thread. This means:
606 1. allocate a ThreadId+ThreadState+stack for the thread
608 2. initialize the thread's new VCPU state
610 3. create the thread using the same args as the client requested,
611 but using the scheduler entrypoint for EIP, and a separate stack
612 for ESP.
614 static SysRes do_clone ( ThreadId ptid,
615 UWord flags, Addr sp,
616 Int* parent_tidptr,
617 Int* child_tidptr,
618 Addr tlsaddr)
620 ThreadId ctid = VG_(alloc_ThreadState)();
621 ThreadState* ptst = VG_(get_ThreadState)(ptid);
622 ThreadState* ctst = VG_(get_ThreadState)(ctid);
623 UWord* stack;
624 SysRes res;
625 vki_sigset_t blockall, savedmask;
627 VG_(sigfillset)(&blockall);
629 vg_assert(VG_(is_running_thread)(ptid));
630 vg_assert(VG_(is_valid_tid)(ctid));
632 stack = (UWord*)ML_(allocstack)(ctid);
633 if (stack == NULL) {
634 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
635 goto out;
638 /* Copy register state
640 Both parent and child return to the same place, and the code
641 following the clone syscall works out which is which, so we
642 don't need to worry about it.
644 The parent gets the child's new tid returned from clone, but the
645 child gets 0.
647 If the clone call specifies a NULL sp for the new thread, then
648 it actually gets a copy of the parent's sp.
650 setup_child( &ctst->arch, &ptst->arch );
652 if (sp != 0)
653 VG_(set_SP)(ctid, sp);
655 ctst->os_state.parent = ptid;
657 /* inherit signal mask */
658 ctst->sig_mask = ptst->sig_mask;
659 ctst->tmp_sig_mask = ptst->sig_mask;
661 /* Start the child with its threadgroup being the same as the
662 parent's. This is so that any exit_group calls that happen
663 after the child is created but before it sets its
664 os_state.threadgroup field for real (in thread_wrapper in
665 syswrap-linux.c), really kill the new thread. a.k.a this avoids
666 a race condition in which the thread is unkillable (via
667 exit_group) because its threadgroup is not set. The race window
668 is probably only a few hundred or a few thousand cycles long.
669 See #226116. */
670 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
672 ML_(guess_and_register_stack) (sp, ctst);
674 /* Assume the clone will succeed, and tell any tool that wants to
675 know that this thread has come into existence. We cannot defer
676 it beyond this point because setup_tls, just below,
677 causes checks to assert by making references to the new ThreadId
678 if we don't state the new thread exists prior to that point.
679 If the clone fails, we'll send out a ll_exit notification for it
680 at the out: label below, to clean up. */
681 vg_assert(VG_(owns_BigLock_LL)(ptid));
682 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
684 if (flags & VKI_CLONE_SETTLS) {
685 res = setup_child_tls(ctid, tlsaddr);
686 if (sr_isError(res))
687 goto out;
689 flags &= ~VKI_CLONE_SETTLS;
691 /* start the thread with everything blocked */
692 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
694 /* Create the new thread */
695 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
696 child_tidptr, parent_tidptr);
698 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
700 out:
701 if (sr_isError(res)) {
702 /* clone failed */
703 VG_(cleanup_thread)(&ctst->arch);
704 ctst->status = VgTs_Empty;
705 /* oops. Better tell the tool the thread exited in a hurry :-) */
706 VG_TRACK( pre_thread_ll_exit, ctid );
709 return res;
712 /* Do a clone which is really a fork().
713 ML_(do_fork_clone) uses the clone syscall to fork a child process.
714 Note that this should not be called for a thread creation.
715 Also, some flags combinations are not supported, and such combinations
716 are handled either by masking the non supported flags or by asserting.
718 The CLONE_VFORK flag is accepted, as this just tells that the parent is
719 suspended till the child exits or calls execve. We better keep this flag,
720 just in case the guests parent/client code depends on this synchronisation.
722 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
723 instructions in the child process, that will mess up the parent host
724 memory. So, we hope for the best and assumes that the guest application does
725 not (really) depends on sharing the memory between parent and child in the
726 interval between clone and exits/execve.
728 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
729 clone syscall, before child guest instructions are executed. */
730 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
731 Int* parent_tidptr, Int* child_tidptr,
732 Addr child_sp)
734 vki_sigset_t fork_saved_mask;
735 vki_sigset_t mask;
736 SysRes res;
738 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
739 | VKI_CLONE_FILES))
740 return VG_(mk_SysRes_Error)( VKI_EINVAL );
742 /* Block all signals during fork, so that we can fix things up in
743 the child without being interrupted. */
744 VG_(sigfillset)(&mask);
745 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
747 VG_(do_atfork_pre)(tid);
749 /* Since this is the fork() form of clone, we don't need all that
750 VG_(clone) stuff */
751 #if defined(VGP_x86_linux) \
752 || defined(VGP_ppc32_linux) \
753 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
754 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
755 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
756 || defined(VGP_nanomips_linux)
757 res = VG_(do_syscall5)( __NR_clone, flags,
758 (UWord)NULL, (UWord)parent_tidptr,
759 (UWord)NULL, (UWord)child_tidptr );
760 #elif defined(VGP_amd64_linux)
761 /* note that the last two arguments are the opposite way round to x86 and
762 ppc32 as the amd64 kernel expects the arguments in a different order */
763 res = VG_(do_syscall5)( __NR_clone, flags,
764 (UWord)NULL, (UWord)parent_tidptr,
765 (UWord)child_tidptr, (UWord)NULL );
766 #elif defined(VGP_s390x_linux)
767 /* Note that s390 has the stack first and then the flags */
768 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
769 (UWord)parent_tidptr, (UWord)child_tidptr);
770 #else
771 # error Unknown platform
772 #endif
774 if (!sr_isError(res) && sr_Res(res) == 0) {
775 /* child */
776 if (child_sp != 0)
777 VG_(set_SP)(tid, child_sp);
778 VG_(do_atfork_child)(tid);
780 /* restore signal mask */
781 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
783 else
784 if (!sr_isError(res) && sr_Res(res) > 0) {
785 /* parent */
786 VG_(do_atfork_parent)(tid);
788 if (VG_(clo_trace_syscalls))
789 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
790 VG_(getpid)(), (RegWord)sr_Res(res));
792 /* restore signal mask */
793 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
796 return res;
799 /* ---------------------------------------------------------------------
800 PRE/POST wrappers for arch-generic, Linux-specific syscalls
801 ------------------------------------------------------------------ */
803 // Nb: See the comment above the generic PRE/POST wrappers in
804 // m_syswrap/syswrap-generic.c for notes about how they work.
806 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
807 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
809 PRE(sys_clone)
811 UInt cloneflags;
812 Bool badarg = False;
814 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
815 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
816 ARG4, ARG5);
818 // Order of arguments differs between platforms.
819 #if defined(VGP_x86_linux) \
820 || defined(VGP_ppc32_linux) \
821 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
822 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
823 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
824 || defined(VGP_nanomips_linux)
825 #define ARG_CHILD_TIDPTR ARG5
826 #define PRA_CHILD_TIDPTR PRA5
827 #define ARG_TLS ARG4
828 #define PRA_TLS PRA4
829 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
830 #define ARG_CHILD_TIDPTR ARG4
831 #define PRA_CHILD_TIDPTR PRA4
832 #define ARG_TLS ARG5
833 #define PRA_TLS PRA5
834 #else
835 # error Unknown platform
836 #endif
837 // And s390x is even more special, and inverts flags and child stack args
838 #if defined(VGP_s390x_linux)
839 #define ARG_FLAGS ARG2
840 #define PRA_FLAGS PRA2
841 #define ARG_CHILD_STACK ARG1
842 #define PRA_CHILD_STACK PRA1
843 #else
844 #define ARG_FLAGS ARG1
845 #define PRA_FLAGS PRA1
846 #define ARG_CHILD_STACK ARG2
847 #define PRA_CHILD_STACK PRA2
848 #endif
850 if (VG_(tdict).track_pre_reg_read) {
851 PRA_FLAGS("clone", unsigned long, flags);
852 PRA_CHILD_STACK("clone", void *, child_stack);
855 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD)) {
856 if (VG_(tdict).track_pre_reg_read) {
857 PRA3("clone", int *, parent_tidptr);
859 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
860 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
861 VKI_PROT_WRITE)) {
862 badarg = True;
865 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
866 if (VG_(tdict).track_pre_reg_read) {
867 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
869 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
870 dummy type (that we define as a char). We only dereference/check the
871 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
872 if (sizeof(vki_modify_ldt_t) > 1) {
873 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
874 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
875 VKI_PROT_READ)) {
876 badarg = True;
880 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
881 if (VG_(tdict).track_pre_reg_read) {
882 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
884 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
885 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
886 VKI_PROT_WRITE)) {
887 badarg = True;
891 if (badarg) {
892 SET_STATUS_Failure( VKI_EFAULT );
893 return;
896 cloneflags = ARG_FLAGS;
898 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
899 SET_STATUS_Failure( VKI_EINVAL );
900 return;
903 /* Only look at the flags we really care about */
904 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
905 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
906 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
907 /* thread creation */
908 SET_STATUS_from_SysRes(
909 do_clone(tid,
910 ARG_FLAGS, /* flags */
911 (Addr)ARG_CHILD_STACK, /* child ESP */
912 (Int*)(Addr)ARG3, /* parent_tidptr */
913 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
914 (Addr)ARG_TLS)); /* set_tls */
915 break;
917 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
918 case VKI_CLONE_VFORK: /* vfork without memory sharing */
919 cloneflags &= ~VKI_CLONE_VM;
920 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
922 case 0: /* plain fork */
923 SET_STATUS_from_SysRes(
924 ML_(do_fork_clone)(tid,
925 cloneflags, /* flags */
926 (Int*)(Addr)ARG3, /* parent_tidptr */
927 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
928 (Addr)ARG_CHILD_STACK));
929 break;
931 default:
932 /* should we just ENOSYS? */
933 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
934 "x\n", ARG_FLAGS);
935 VG_(message)(Vg_UserMsg, "\n");
936 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
937 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
938 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
939 VG_(unimplemented)
940 ("Valgrind does not support general clone().");
943 if (SUCCESS) {
944 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD))
945 POST_MEM_WRITE(ARG3, sizeof(Int));
946 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
947 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
948 if (ARG_FLAGS & VKI_CLONE_PIDFD) {
949 Int fd = *(Int*)(Addr)ARG3;
950 if (!ML_(fd_allowed)(fd, "clone", tid, True)) {
951 VG_(close)(fd);
952 SET_STATUS_Failure( VKI_EMFILE );
953 } else {
954 if (VG_(clo_track_fds))
955 ML_(record_fd_open_nameless) (tid, fd);
959 /* Thread creation was successful; let the child have the chance
960 to run */
961 *flags |= SfYieldAfter;
964 #undef ARG_CHILD_TIDPTR
965 #undef PRA_CHILD_TIDPTR
966 #undef ARG_TLS
967 #undef PRA_TLS
968 #undef ARG_FLAGS
969 #undef PRA_FLAGS
970 #undef ARG_CHILD_STACK
971 #undef PRA_CHILD_STACK
974 /* ---------------------------------------------------------------------
975 *mount wrappers
976 ------------------------------------------------------------------ */
978 PRE(sys_mount)
980 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
981 // We are conservative and check everything, except the memory pointed to
982 // by 'data'.
983 *flags |= SfMayBlock;
984 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
985 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
986 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
987 (HChar*)(Addr)ARG3, ARG4, ARG5);
988 PRE_REG_READ5(long, "mount",
989 char *, source, char *, target, char *, type,
990 unsigned long, flags, void *, data);
991 if (ARG1)
992 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
993 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
994 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
997 PRE(sys_oldumount)
999 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
1000 PRE_REG_READ1(long, "umount", char *, path);
1001 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
1004 PRE(sys_umount)
1006 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
1007 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
1008 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1011 /* Not actually wrapped by GLibc but does things with the system
1012 * mounts so it is put here.
1014 PRE(sys_pivot_root)
1016 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1017 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1018 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1019 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1023 /* ---------------------------------------------------------------------
1024 16- and 32-bit uid/gid wrappers
1025 ------------------------------------------------------------------ */
1027 PRE(sys_setfsuid16)
1029 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1030 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1033 PRE(sys_setfsuid)
1035 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1036 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1039 PRE(sys_setfsgid16)
1041 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1042 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1045 PRE(sys_setfsgid)
1047 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1048 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1051 PRE(sys_setresuid16)
1053 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1054 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1055 PRE_REG_READ3(long, "setresuid16",
1056 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1059 PRE(sys_setresuid)
1061 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1062 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1063 PRE_REG_READ3(long, "setresuid",
1064 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1067 PRE(sys_getresuid16)
1069 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1070 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1071 PRE_REG_READ3(long, "getresuid16",
1072 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1073 vki_old_uid_t *, suid);
1074 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1075 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1076 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1078 POST(sys_getresuid16)
1080 vg_assert(SUCCESS);
1081 if (RES == 0) {
1082 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1083 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1084 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1088 PRE(sys_getresuid)
1090 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1091 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1092 PRE_REG_READ3(long, "getresuid",
1093 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1094 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1095 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1096 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1098 POST(sys_getresuid)
1100 vg_assert(SUCCESS);
1101 if (RES == 0) {
1102 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1103 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1104 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1108 PRE(sys_setresgid16)
1110 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1111 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1112 PRE_REG_READ3(long, "setresgid16",
1113 vki_old_gid_t, rgid,
1114 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1117 PRE(sys_setresgid)
1119 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1120 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1121 PRE_REG_READ3(long, "setresgid",
1122 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1125 PRE(sys_getresgid16)
1127 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1128 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1129 PRE_REG_READ3(long, "getresgid16",
1130 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1131 vki_old_gid_t *, sgid);
1132 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1133 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1134 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1136 POST(sys_getresgid16)
1138 vg_assert(SUCCESS);
1139 if (RES == 0) {
1140 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1141 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1142 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1146 PRE(sys_getresgid)
1148 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1149 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1150 PRE_REG_READ3(long, "getresgid",
1151 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1152 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1153 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1154 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1156 POST(sys_getresgid)
1158 vg_assert(SUCCESS);
1159 if (RES == 0) {
1160 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1161 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1162 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1166 /* ---------------------------------------------------------------------
1167 miscellaneous wrappers
1168 ------------------------------------------------------------------ */
1170 PRE(sys_exit_group)
1172 ThreadId t;
1173 ThreadState* tst;
1175 PRINT("exit_group( %ld )", SARG1);
1176 PRE_REG_READ1(void, "exit_group", int, status);
1178 tst = VG_(get_ThreadState)(tid);
1179 /* A little complex; find all the threads with the same threadgroup
1180 as this one (including this one), and mark them to exit */
1181 /* It is unclear how one can get a threadgroup in this process which
1182 is not the threadgroup of the calling thread:
1183 The assignments to threadgroups are:
1184 = 0; /// scheduler.c os_state_clear
1185 = getpid(); /// scheduler.c in child after fork
1186 = getpid(); /// this file, in thread_wrapper
1187 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1188 copying the thread group of the thread doing clone
1189 So, the only case where the threadgroup might be different to the getpid
1190 value is in the child, just after fork. But then the fork syscall is
1191 still going on, the forked thread has had no chance yet to make this
1192 syscall. */
1193 for (t = 1; t < VG_N_THREADS; t++) {
1194 if ( /* not alive */
1195 VG_(threads)[t].status == VgTs_Empty
1197 /* not our group */
1198 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1200 continue;
1201 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1202 the exitreason. */
1203 VG_(threads)[t].os_state.exitcode = ARG1;
1206 /* Indicate in all other threads that the process is exiting.
1207 Then wait using VG_(reap_threads) for these threads to disappear.
1209 Can this give a deadlock if another thread is calling exit in parallel
1210 and would then wait for this thread to disappear ?
1211 The answer is no:
1212 Other threads are either blocked in a syscall or have yielded the CPU.
1214 A thread that has yielded the CPU is trying to get the big lock in
1215 VG_(scheduler). This thread will get the CPU thanks to the call
1216 to VG_(reap_threads). The scheduler will then check for signals,
1217 kill the process if this is a fatal signal, and otherwise prepare
1218 the thread for handling this signal. After this preparation, if
1219 the thread status is VG_(is_exiting), the scheduler exits the thread.
1220 So, a thread that has yielded the CPU does not have a chance to
1221 call exit => no deadlock for this thread.
1223 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1224 to all threads blocked in a syscall.
1225 The syscall will be interrupted, and the control will go to the
1226 scheduler. The scheduler will then return, as the thread is in
1227 exiting state. */
1229 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1230 VG_(reap_threads)(tid);
1231 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1232 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1233 is the thread calling exit_group and so its registers must be considered
1234 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1236 /* We have to claim the syscall already succeeded. */
1237 SET_STATUS_Success(0);
1240 PRE(sys_llseek)
1242 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1243 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1244 ARG1, ARG2, ARG3, ARG4, ARG5);
1245 PRE_REG_READ5(long, "llseek",
1246 unsigned int, fd, unsigned long, offset_high,
1247 unsigned long, offset_low, vki_loff_t *, result,
1248 unsigned int, whence);
1249 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1250 SET_STATUS_Failure( VKI_EBADF );
1251 else
1252 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1254 POST(sys_llseek)
1256 vg_assert(SUCCESS);
1257 if (RES == 0)
1258 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1261 PRE(sys_adjtimex)
1263 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1264 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1265 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1267 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1268 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1270 #define ADJX(bits,field) \
1271 if (tx->modes & (bits)) \
1272 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1273 (Addr)&tx->field, sizeof(tx->field))
1275 if (tx->modes & VKI_ADJ_ADJTIME) {
1276 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1277 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1278 } else {
1279 ADJX(VKI_ADJ_OFFSET, offset);
1280 ADJX(VKI_ADJ_FREQUENCY, freq);
1281 ADJX(VKI_ADJ_MAXERROR, maxerror);
1282 ADJX(VKI_ADJ_ESTERROR, esterror);
1283 ADJX(VKI_ADJ_STATUS, status);
1284 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1285 ADJX(VKI_ADJ_TICK, tick);
1287 #undef ADJX
1290 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1293 POST(sys_adjtimex)
1295 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1298 PRE(sys_clock_adjtime)
1300 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1301 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1302 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1303 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1305 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1306 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1308 #define ADJX(bits,field) \
1309 if (tx->modes & (bits)) \
1310 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1311 (Addr)&tx->field, sizeof(tx->field))
1313 if (tx->modes & VKI_ADJ_ADJTIME) {
1314 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1315 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1316 } else {
1317 ADJX(VKI_ADJ_OFFSET, offset);
1318 ADJX(VKI_ADJ_FREQUENCY, freq);
1319 ADJX(VKI_ADJ_MAXERROR, maxerror);
1320 ADJX(VKI_ADJ_ESTERROR, esterror);
1321 ADJX(VKI_ADJ_STATUS, status);
1322 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1323 ADJX(VKI_ADJ_TICK, tick);
1325 #undef ADJX
1328 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1331 POST(sys_clock_adjtime)
1333 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1336 PRE(sys_ioperm)
1338 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1339 ARG1, ARG2, SARG3 );
1340 PRE_REG_READ3(long, "ioperm",
1341 unsigned long, from, unsigned long, num, int, turn_on);
1344 PRE(sys_syslog)
1346 *flags |= SfMayBlock;
1347 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1348 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1349 switch (ARG1) {
1350 // The kernel uses magic numbers here, rather than named constants,
1351 // therefore so do we.
1352 case 2: case 3: case 4:
1353 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1354 break;
1355 default:
1356 break;
1359 POST(sys_syslog)
1361 switch (ARG1) {
1362 case 2: case 3: case 4:
1363 POST_MEM_WRITE( ARG2, ARG3 );
1364 break;
1365 default:
1366 break;
1370 PRE(sys_vhangup)
1372 PRINT("sys_vhangup ( )");
1373 PRE_REG_READ0(long, "vhangup");
1376 PRE(sys_sysinfo)
1378 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1379 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1380 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1382 POST(sys_sysinfo)
1384 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1387 PRE(sys_personality)
1389 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1390 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1393 PRE(sys_sysctl)
1395 struct __vki_sysctl_args *args;
1396 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1397 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1398 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1399 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1400 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1401 VKI_PROT_READ)) {
1402 SET_STATUS_Failure( VKI_EFAULT );
1403 return;
1406 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1407 if (args->newval != NULL)
1408 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1409 if (args->oldlenp != NULL) {
1410 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1411 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1414 POST(sys_sysctl)
1416 struct __vki_sysctl_args *args;
1417 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1418 if (args->oldlenp != NULL) {
1419 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1420 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1424 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1425 const char *attr_name)
1427 const HChar *step_str = (const HChar *)str;
1428 SizeT len;
1429 UInt i;
1432 * The name can be up to maxlen bytes long, including the terminating null
1433 * byte. So do not check more than maxlen bytes.
1435 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1436 len = VG_(strnlen)((const HChar *)str, maxlen);
1437 if (len < maxlen)
1438 PRE_MEM_RASCIIZ(attr_name, str);
1439 else
1440 PRE_MEM_READ(attr_name, str, maxlen);
1441 } else {
1443 * Do it the slow way, one byte at a time, while checking for terminating
1444 * '\0'.
1446 for (i = 0; i < maxlen; i++) {
1447 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1448 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1449 break;
1454 PRE(sys_prctl)
1456 *flags |= SfMayBlock;
1457 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1458 switch (ARG1) {
1459 case VKI_PR_SET_PDEATHSIG:
1460 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1461 break;
1462 case VKI_PR_GET_PDEATHSIG:
1463 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1464 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1465 break;
1466 case VKI_PR_GET_DUMPABLE:
1467 PRE_REG_READ1(int, "prctl", int, option);
1468 break;
1469 case VKI_PR_SET_DUMPABLE:
1470 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1471 break;
1472 case VKI_PR_GET_UNALIGN:
1473 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1474 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1475 break;
1476 case VKI_PR_SET_UNALIGN:
1477 PRE_REG_READ2(int, "prctl", int, option, int, value);
1478 break;
1479 case VKI_PR_GET_KEEPCAPS:
1480 PRE_REG_READ1(int, "prctl", int, option);
1481 break;
1482 case VKI_PR_SET_KEEPCAPS:
1483 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1484 break;
1485 case VKI_PR_GET_FPEMU:
1486 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1487 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1488 break;
1489 case VKI_PR_SET_FPEMU:
1490 PRE_REG_READ2(int, "prctl", int, option, int, value);
1491 break;
1492 case VKI_PR_GET_FPEXC:
1493 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1494 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1495 break;
1496 case VKI_PR_SET_FPEXC:
1497 PRE_REG_READ2(int, "prctl", int, option, int, value);
1498 break;
1499 case VKI_PR_GET_TIMING:
1500 PRE_REG_READ1(int, "prctl", int, option);
1501 break;
1502 case VKI_PR_SET_TIMING:
1503 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1504 break;
1505 case VKI_PR_SET_NAME:
1506 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1507 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1508 break;
1509 case VKI_PR_GET_NAME:
1510 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1511 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1512 break;
1513 case VKI_PR_GET_ENDIAN:
1514 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1515 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1516 break;
1517 case VKI_PR_SET_ENDIAN:
1518 PRE_REG_READ2(int, "prctl", int, option, int, value);
1519 break;
1520 case VKI_PR_SET_PTRACER:
1521 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1522 break;
1523 case VKI_PR_SET_SECCOMP:
1524 /* This is a bit feeble in that it uses |option| before checking
1525 it, but at least both sides of the conditional check it. */
1526 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1527 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1528 if (ARG3) {
1529 /* Should check that ARG3 points at a valid struct sock_fprog.
1530 Sounds complex; hence be lame. */
1531 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1532 ARG3, 1 );
1534 } else {
1535 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1537 break;
1538 case VKI_PR_CAPBSET_READ:
1539 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1540 break;
1541 case VKI_PR_CAPBSET_DROP:
1542 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1543 break;
1544 default:
1545 PRE_REG_READ5(long, "prctl",
1546 int, option, unsigned long, arg2, unsigned long, arg3,
1547 unsigned long, arg4, unsigned long, arg5);
1548 break;
1551 POST(sys_prctl)
1553 switch (ARG1) {
1554 case VKI_PR_GET_PDEATHSIG:
1555 POST_MEM_WRITE(ARG2, sizeof(Int));
1556 break;
1557 case VKI_PR_GET_UNALIGN:
1558 POST_MEM_WRITE(ARG2, sizeof(Int));
1559 break;
1560 case VKI_PR_GET_FPEMU:
1561 POST_MEM_WRITE(ARG2, sizeof(Int));
1562 break;
1563 case VKI_PR_GET_FPEXC:
1564 POST_MEM_WRITE(ARG2, sizeof(Int));
1565 break;
1566 case VKI_PR_GET_NAME:
1567 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1568 break;
1569 case VKI_PR_GET_ENDIAN:
1570 POST_MEM_WRITE(ARG2, sizeof(Int));
1571 break;
1572 case VKI_PR_SET_NAME:
1574 const HChar* new_name = (const HChar*) (Addr)ARG2;
1575 if (new_name) { // Paranoia
1576 ThreadState* tst = VG_(get_ThreadState)(tid);
1577 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1579 /* Don't bother reusing the memory. This is a rare event. */
1580 tst->thread_name =
1581 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1582 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1585 break;
1589 PRE(sys_sendfile)
1591 *flags |= SfMayBlock;
1592 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1593 SARG1, SARG2, ARG3, ARG4);
1594 PRE_REG_READ4(ssize_t, "sendfile",
1595 int, out_fd, int, in_fd, vki_off_t *, offset,
1596 vki_size_t, count);
1597 if (ARG3 != 0)
1598 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1600 POST(sys_sendfile)
1602 if (ARG3 != 0 ) {
1603 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1607 PRE(sys_sendfile64)
1609 *flags |= SfMayBlock;
1610 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1611 SARG1, SARG2, ARG3, ARG4);
1612 PRE_REG_READ4(ssize_t, "sendfile64",
1613 int, out_fd, int, in_fd, vki_loff_t *, offset,
1614 vki_size_t, count);
1615 if (ARG3 != 0)
1616 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1618 POST(sys_sendfile64)
1620 if (ARG3 != 0 ) {
1621 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1625 static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
1627 struct vki_timespec64 *ts64 = (void *)(Addr)arg;
1628 PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
1629 PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
1632 static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
1634 struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
1635 pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
1636 pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
1639 static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1640 SyscallArgs* arrghs, SyscallStatus* status,
1641 UWord* flags, Bool is_time64 )
1644 arg param used by ops
1646 ARG1 - u32 *futex all
1647 ARG2 - int op
1648 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1649 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1650 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1651 ARG6 - int val3 CMP_REQUEUE
1654 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1655 case VKI_FUTEX_CMP_REQUEUE:
1656 case VKI_FUTEX_WAKE_OP:
1657 case VKI_FUTEX_CMP_REQUEUE_PI:
1658 if (is_time64) {
1659 PRE_REG_READ6(long, "futex_time64",
1660 vki_u32 *, futex, int, op, int, val,
1661 struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
1662 } else {
1663 PRE_REG_READ6(long, "futex",
1664 vki_u32 *, futex, int, op, int, val,
1665 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1667 break;
1668 case VKI_FUTEX_REQUEUE:
1669 case VKI_FUTEX_WAIT_REQUEUE_PI:
1670 if (is_time64) {
1671 PRE_REG_READ5(long, "futex_time64",
1672 vki_u32 *, futex, int, op, int, val,
1673 struct timespec64 *, utime, vki_u32 *, uaddr2);
1674 } else {
1675 PRE_REG_READ5(long, "futex",
1676 vki_u32 *, futex, int, op, int, val,
1677 struct timespec *, utime, vki_u32 *, uaddr2);
1679 break;
1680 case VKI_FUTEX_WAIT_BITSET:
1681 /* Check that the address at least begins in client-accessible area. */
1682 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1683 SET_STATUS_Failure( VKI_EFAULT );
1684 return;
1686 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1687 if (is_time64) {
1688 PRE_REG_READ4(long, "futex_time64",
1689 vki_u32 *, futex, int, op, int, val,
1690 struct timespec64 *, utime);
1691 } else {
1692 PRE_REG_READ4(long, "futex",
1693 vki_u32 *, futex, int, op, int, val,
1694 struct timespec64 *, utime);
1696 } else {
1697 /* Note argument 5 is unused, but argument 6 is used.
1698 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1699 if (is_time64) {
1700 PRE_REG_READ4(long, "futex_time64",
1701 vki_u32 *, futex, int, op, int, val,
1702 struct timespec64 *, utime);
1703 } else {
1704 PRE_REG_READ4(long, "futex",
1705 vki_u32 *, futex, int, op, int, val,
1706 struct timespec *, utime);
1708 if (VG_(tdict).track_pre_reg_read)
1709 PRA6("futex",int,val3);
1711 break;
1712 case VKI_FUTEX_WAKE_BITSET:
1713 PRE_REG_READ3(long, "futex",
1714 vki_u32 *, futex, int, op, int, val);
1715 if (VG_(tdict).track_pre_reg_read) {
1716 PRA6("futex", int, val3);
1718 break;
1719 case VKI_FUTEX_WAIT:
1720 case VKI_FUTEX_LOCK_PI:
1721 if (is_time64) {
1722 PRE_REG_READ4(long, "futex_time64",
1723 vki_u32 *, futex, int, op, int, val,
1724 struct timespec64 *, utime);
1725 } else {
1726 PRE_REG_READ4(long, "futex",
1727 vki_u32 *, futex, int, op, int, val,
1728 struct timespec *, utime);
1730 break;
1731 case VKI_FUTEX_WAKE:
1732 case VKI_FUTEX_FD:
1733 PRE_REG_READ3(long, "futex",
1734 vki_u32 *, futex, int, op, int, val);
1735 break;
1736 case VKI_FUTEX_TRYLOCK_PI:
1737 case VKI_FUTEX_UNLOCK_PI:
1738 default:
1739 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1740 break;
1743 *flags |= SfMayBlock;
1745 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1746 case VKI_FUTEX_WAIT:
1747 case VKI_FUTEX_LOCK_PI:
1748 case VKI_FUTEX_WAIT_BITSET:
1749 case VKI_FUTEX_WAIT_REQUEUE_PI:
1750 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1751 if (ARG4 != 0) {
1752 if (is_time64) {
1753 pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
1754 } else {
1755 PRE_MEM_READ( "futex(timeout)", ARG4,
1756 sizeof(struct vki_timespec) );
1759 break;
1761 case VKI_FUTEX_REQUEUE:
1762 case VKI_FUTEX_CMP_REQUEUE:
1763 case VKI_FUTEX_CMP_REQUEUE_PI:
1764 case VKI_FUTEX_WAKE_OP:
1765 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1766 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1767 break;
1769 case VKI_FUTEX_FD:
1770 case VKI_FUTEX_TRYLOCK_PI:
1771 case VKI_FUTEX_UNLOCK_PI:
1772 case VKI_FUTEX_WAKE:
1773 case VKI_FUTEX_WAKE_BITSET:
1774 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1775 break;
1777 default:
1778 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1779 break;
1783 static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
1784 SyscallStatus* status )
1786 vg_assert(SUCCESS);
1787 POST_MEM_WRITE( ARG1, sizeof(int) );
1788 if (ARG2 == VKI_FUTEX_FD) {
1789 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1790 VG_(close)(RES);
1791 SET_STATUS_Failure( VKI_EMFILE );
1792 } else {
1793 if (VG_(clo_track_fds))
1794 ML_(record_fd_open_nameless)(tid, RES);
1799 PRE(sys_futex)
1801 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1802 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1803 futex_pre_helper (tid, layout, arrghs, status, flags, False);
1806 POST(sys_futex)
1808 futex_post_helper (tid, arrghs, status);
1811 PRE(sys_futex_time64)
1813 PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1814 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1815 futex_pre_helper (tid, layout, arrghs, status, flags, True);
1818 POST(sys_futex_time64)
1820 futex_post_helper (tid, arrghs, status);
1823 PRE(sys_set_robust_list)
1825 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1826 FMT_REGWORD "u )", ARG1, ARG2);
1827 PRE_REG_READ2(long, "set_robust_list",
1828 struct vki_robust_list_head *, head, vki_size_t, len);
1830 /* Just check the robust_list_head structure is readable - don't
1831 try and chase the list as the kernel will only read it when
1832 the thread exits so the current contents is irrelevant. */
1833 if (ARG1 != 0)
1834 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1837 PRE(sys_get_robust_list)
1839 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1840 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1841 PRE_REG_READ3(long, "get_robust_list",
1842 int, pid,
1843 struct vki_robust_list_head **, head_ptr,
1844 vki_size_t *, len_ptr);
1845 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1846 ARG2, sizeof(struct vki_robust_list_head *));
1847 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1848 ARG3, sizeof(struct vki_size_t *));
1850 POST(sys_get_robust_list)
1852 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1853 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1856 struct pselect_sized_sigset {
1857 const vki_sigset_t *ss;
1858 vki_size_t ss_len;
1860 struct pselect_adjusted_sigset {
1861 struct pselect_sized_sigset ss; /* The actual syscall arg */
1862 vki_sigset_t adjusted_ss;
1865 static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1866 SyscallArgs* arrghs, SyscallStatus* status,
1867 UWord* flags, Bool is_time64 )
1869 *flags |= SfMayBlock | SfPostOnFail;
1870 if (is_time64) {
1871 PRE_REG_READ6(long, "pselect6_time64",
1872 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1873 vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
1874 void *, sig);
1875 } else {
1876 PRE_REG_READ6(long, "pselect6",
1877 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1878 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
1879 void *, sig);
1881 // XXX: this possibly understates how much memory is read.
1882 if (ARG2 != 0)
1883 PRE_MEM_READ( "pselect6(readfds)",
1884 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1885 if (ARG3 != 0)
1886 PRE_MEM_READ( "pselect6(writefds)",
1887 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1888 if (ARG4 != 0)
1889 PRE_MEM_READ( "pselect6(exceptfds)",
1890 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1891 if (ARG5 != 0) {
1892 if (is_time64) {
1893 pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
1894 } else {
1895 PRE_MEM_READ( "pselect6(timeout)", ARG5,
1896 sizeof(struct vki_timespec) );
1899 if (ARG6 != 0) {
1900 const struct pselect_sized_sigset *pss =
1901 (struct pselect_sized_sigset *)(Addr)ARG6;
1902 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1903 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1904 ARG6 = 1; /* Something recognisable to POST() hook. */
1905 } else {
1906 struct pselect_adjusted_sigset *pas;
1907 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1908 ARG6 = (Addr)pas;
1909 pas->ss.ss = (void *)1;
1910 pas->ss.ss_len = pss->ss_len;
1911 if (pss->ss_len == sizeof(*pss->ss)) {
1912 if (pss->ss == NULL) {
1913 pas->ss.ss = NULL;
1914 } else {
1915 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1916 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1917 pas->adjusted_ss = *pss->ss;
1918 pas->ss.ss = &pas->adjusted_ss;
1919 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1927 PRE(sys_pselect6)
1929 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1930 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1931 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1932 pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
1935 POST(sys_pselect6)
1937 if (ARG6 != 0 && ARG6 != 1) {
1938 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1942 PRE(sys_pselect6_time64)
1944 PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1945 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1946 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1947 pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
1950 POST(sys_pselect6_time64)
1952 if (ARG6 != 0 && ARG6 != 1) {
1953 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1957 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1958 SyscallArgs* arrghs, SyscallStatus* status,
1959 UWord* flags, Bool is_time64 )
1961 UInt i;
1962 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1963 *flags |= SfMayBlock | SfPostOnFail;
1964 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1965 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1966 ARG1, ARG2, ARG3, ARG4, ARG5);
1967 if (is_time64) {
1968 PRE_REG_READ5(long, "ppoll_time64",
1969 struct vki_pollfd *, ufds, unsigned int, nfds,
1970 struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
1971 vki_size_t, sigsetsize);
1972 } else {
1973 PRE_REG_READ5(long, "ppoll",
1974 struct vki_pollfd *, ufds, unsigned int, nfds,
1975 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1976 vki_size_t, sigsetsize);
1979 for (i = 0; i < ARG2; i++) {
1980 PRE_MEM_READ( "ppoll(ufds.fd)",
1981 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1982 PRE_MEM_READ( "ppoll(ufds.events)",
1983 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1984 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1985 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1988 if (ARG3) {
1989 if (is_time64) {
1990 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
1991 } else {
1992 PRE_MEM_READ( "ppoll(tsp)", ARG3,
1993 sizeof(struct vki_timespec) );
1996 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1997 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1998 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1999 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
2000 ARG4 = 1; /* Something recognisable to POST() hook. */
2001 } else {
2002 vki_sigset_t *vg_sigmask =
2003 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
2004 ARG4 = (Addr)vg_sigmask;
2005 *vg_sigmask = *guest_sigmask;
2006 VG_(sanitize_client_sigmask)(vg_sigmask);
2011 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2012 SyscallStatus* status )
2014 vg_assert(SUCCESS || FAILURE);
2015 if (SUCCESS && (RES >= 0)) {
2016 UInt i;
2017 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2018 for (i = 0; i < ARG2; i++)
2019 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2021 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
2022 VG_(free)((vki_sigset_t *) (Addr)ARG4);
2026 PRE(sys_ppoll)
2028 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2029 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2030 ARG1, ARG2, ARG3, ARG4, ARG5);
2031 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2034 POST(sys_ppoll)
2036 ppoll_post_helper (tid, arrghs, status);
2039 PRE(sys_ppoll_time64)
2041 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2042 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2043 ARG1, ARG2, ARG3, ARG4, ARG5);
2044 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2047 POST(sys_ppoll_time64)
2049 ppoll_post_helper (tid, arrghs, status);
2053 /* ---------------------------------------------------------------------
2054 epoll_* wrappers
2055 ------------------------------------------------------------------ */
2057 PRE(sys_epoll_create)
2059 PRINT("sys_epoll_create ( %ld )", SARG1);
2060 PRE_REG_READ1(long, "epoll_create", int, size);
2062 POST(sys_epoll_create)
2064 vg_assert(SUCCESS);
2065 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2066 VG_(close)(RES);
2067 SET_STATUS_Failure( VKI_EMFILE );
2068 } else {
2069 if (VG_(clo_track_fds))
2070 ML_(record_fd_open_nameless) (tid, RES);
2074 PRE(sys_epoll_create1)
2076 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2077 PRE_REG_READ1(long, "epoll_create1", int, flags);
2079 POST(sys_epoll_create1)
2081 vg_assert(SUCCESS);
2082 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2083 VG_(close)(RES);
2084 SET_STATUS_Failure( VKI_EMFILE );
2085 } else {
2086 if (VG_(clo_track_fds))
2087 ML_(record_fd_open_nameless) (tid, RES);
2091 PRE(sys_epoll_ctl)
2093 static const HChar* epoll_ctl_s[3] = {
2094 "EPOLL_CTL_ADD",
2095 "EPOLL_CTL_DEL",
2096 "EPOLL_CTL_MOD"
2098 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2099 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2100 PRE_REG_READ4(long, "epoll_ctl",
2101 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2102 if (ARG2 != VKI_EPOLL_CTL_DEL)
2103 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
2106 PRE(sys_epoll_wait)
2108 *flags |= SfMayBlock;
2109 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2110 SARG1, ARG2, SARG3, SARG4);
2111 PRE_REG_READ4(long, "epoll_wait",
2112 int, epfd, struct vki_epoll_event *, events,
2113 int, maxevents, int, timeout);
2114 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2116 POST(sys_epoll_wait)
2118 vg_assert(SUCCESS);
2119 if (RES > 0)
2120 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
2123 PRE(sys_epoll_pwait)
2125 *flags |= SfMayBlock;
2126 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2127 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2128 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2129 PRE_REG_READ6(long, "epoll_pwait",
2130 int, epfd, struct vki_epoll_event *, events,
2131 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2132 vki_size_t, sigsetsize);
2133 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2134 if (ARG5)
2135 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2137 POST(sys_epoll_pwait)
2139 vg_assert(SUCCESS);
2140 if (RES > 0)
2141 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
2144 PRE(sys_eventfd)
2146 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2147 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2149 POST(sys_eventfd)
2151 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2152 VG_(close)(RES);
2153 SET_STATUS_Failure( VKI_EMFILE );
2154 } else {
2155 if (VG_(clo_track_fds))
2156 ML_(record_fd_open_nameless) (tid, RES);
2160 PRE(sys_eventfd2)
2162 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2163 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2165 POST(sys_eventfd2)
2167 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2168 VG_(close)(RES);
2169 SET_STATUS_Failure( VKI_EMFILE );
2170 } else {
2171 if (VG_(clo_track_fds))
2172 ML_(record_fd_open_nameless) (tid, RES);
2176 PRE(sys_fallocate)
2178 *flags |= SfMayBlock;
2179 #if VG_WORDSIZE == 4
2180 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2181 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2182 PRE_REG_READ6(long, "fallocate",
2183 int, fd, int, mode,
2184 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2185 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2186 #elif VG_WORDSIZE == 8
2187 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2188 SARG1, SARG2, SARG3, SARG4);
2189 PRE_REG_READ4(long, "fallocate",
2190 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2191 #else
2192 # error Unexpected word size
2193 #endif
2194 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2195 SET_STATUS_Failure( VKI_EBADF );
2198 PRE(sys_prlimit64)
2200 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2201 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2202 PRE_REG_READ4(long, "prlimit64",
2203 vki_pid_t, pid, unsigned int, resource,
2204 const struct rlimit64 *, new_rlim,
2205 struct rlimit64 *, old_rlim);
2206 if (ARG3)
2207 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2208 if (ARG4)
2209 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2211 if (ARG3 &&
2212 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2213 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2214 SET_STATUS_Failure( VKI_EINVAL );
2216 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2217 switch (ARG2) {
2218 case VKI_RLIMIT_NOFILE:
2219 SET_STATUS_Success( 0 );
2220 if (ARG4) {
2221 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2222 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2224 if (ARG3) {
2225 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2226 > VG_(fd_hard_limit) ||
2227 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2228 != VG_(fd_hard_limit)) {
2229 SET_STATUS_Failure( VKI_EPERM );
2231 else {
2232 VG_(fd_soft_limit) =
2233 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2236 break;
2238 case VKI_RLIMIT_DATA:
2239 SET_STATUS_Success( 0 );
2240 if (ARG4) {
2241 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2242 VG_(client_rlimit_data).rlim_cur;
2243 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2244 VG_(client_rlimit_data).rlim_max;
2246 if (ARG3) {
2247 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2248 > VG_(client_rlimit_data).rlim_max ||
2249 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2250 > VG_(client_rlimit_data).rlim_max) {
2251 SET_STATUS_Failure( VKI_EPERM );
2253 else {
2254 VG_(client_rlimit_data).rlim_cur =
2255 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2256 VG_(client_rlimit_data).rlim_max =
2257 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2260 break;
2262 case VKI_RLIMIT_STACK:
2263 SET_STATUS_Success( 0 );
2264 if (ARG4) {
2265 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2266 VG_(client_rlimit_stack).rlim_cur;
2267 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2268 VG_(client_rlimit_stack).rlim_max;
2270 if (ARG3) {
2271 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2272 > VG_(client_rlimit_stack).rlim_max ||
2273 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2274 > VG_(client_rlimit_stack).rlim_max) {
2275 SET_STATUS_Failure( VKI_EPERM );
2277 else {
2278 VG_(threads)[tid].client_stack_szB =
2279 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2280 VG_(client_rlimit_stack).rlim_cur =
2281 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2282 VG_(client_rlimit_stack).rlim_max =
2283 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2286 break;
2291 POST(sys_prlimit64)
2293 if (ARG4)
2294 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2297 /* ---------------------------------------------------------------------
2298 tid-related wrappers
2299 ------------------------------------------------------------------ */
2301 PRE(sys_gettid)
2303 PRINT("sys_gettid ()");
2304 PRE_REG_READ0(long, "gettid");
2307 PRE(sys_set_tid_address)
2309 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2310 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2313 PRE(sys_tkill)
2315 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2316 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2317 if (!ML_(client_signal_OK)(ARG2)) {
2318 SET_STATUS_Failure( VKI_EINVAL );
2319 return;
2322 /* Check to see if this kill gave us a pending signal */
2323 *flags |= SfPollAfter;
2325 if (VG_(clo_trace_signals))
2326 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2327 SARG2, SARG1);
2329 /* If we're sending SIGKILL, check to see if the target is one of
2330 our threads and handle it specially. */
2331 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2332 SET_STATUS_Success(0);
2333 return;
2336 /* Ask to handle this syscall via the slow route, since that's the
2337 only one that sets tst->status to VgTs_WaitSys. If the result
2338 of doing the syscall is an immediate run of
2339 async_signalhandler() in m_signals, then we need the thread to
2340 be properly tidied away. I have the impression the previous
2341 version of this wrapper worked on x86/amd64 only because the
2342 kernel did not immediately deliver the async signal to this
2343 thread (on ppc it did, which broke the assertion re tst->status
2344 at the top of async_signalhandler()). */
2345 *flags |= SfMayBlock;
2347 POST(sys_tkill)
2349 if (VG_(clo_trace_signals))
2350 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2351 SARG2, SARG1);
2354 PRE(sys_tgkill)
2356 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2357 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2358 if (!ML_(client_signal_OK)(ARG3)) {
2359 SET_STATUS_Failure( VKI_EINVAL );
2360 return;
2363 /* Check to see if this kill gave us a pending signal */
2364 *flags |= SfPollAfter;
2366 if (VG_(clo_trace_signals))
2367 VG_(message)(Vg_DebugMsg,
2368 "tgkill: sending signal %ld to pid %ld/%ld\n",
2369 SARG3, SARG1, SARG2);
2371 /* If we're sending SIGKILL, check to see if the target is one of
2372 our threads and handle it specially. */
2373 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2374 SET_STATUS_Success(0);
2375 return;
2378 /* Ask to handle this syscall via the slow route, since that's the
2379 only one that sets tst->status to VgTs_WaitSys. If the result
2380 of doing the syscall is an immediate run of
2381 async_signalhandler() in m_signals, then we need the thread to
2382 be properly tidied away. I have the impression the previous
2383 version of this wrapper worked on x86/amd64 only because the
2384 kernel did not immediately deliver the async signal to this
2385 thread (on ppc it did, which broke the assertion re tst->status
2386 at the top of async_signalhandler()). */
2387 *flags |= SfMayBlock;
2389 POST(sys_tgkill)
2391 if (VG_(clo_trace_signals))
2392 VG_(message)(Vg_DebugMsg,
2393 "tgkill: sent signal %ld to pid %ld/%ld\n",
2394 SARG3, SARG1, SARG2);
2397 /* ---------------------------------------------------------------------
2398 fadvise64* wrappers
2399 ------------------------------------------------------------------ */
2401 PRE(sys_fadvise64)
2403 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2404 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2405 PRE_REG_READ5(long, "fadvise64",
2406 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2407 vki_size_t, len, int, advice);
2410 PRE(sys_fadvise64_64)
2412 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2413 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2414 PRE_REG_READ6(long, "fadvise64_64",
2415 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2416 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2419 /* ---------------------------------------------------------------------
2420 io_* wrappers
2421 ------------------------------------------------------------------ */
2423 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2424 // and this allows us to control exactly the code that gets run while
2425 // the padding is in place.
2427 PRE(sys_io_setup)
2429 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2430 PRE_REG_READ2(long, "io_setup",
2431 unsigned, nr_events, vki_aio_context_t *, ctxp);
2432 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2435 POST(sys_io_setup)
2437 SizeT size;
2438 struct vki_aio_ring *r;
2440 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2441 ARG1*sizeof(struct vki_io_event));
2442 r = *(struct vki_aio_ring **)(Addr)ARG2;
2443 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2445 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2446 VKI_PROT_READ | VKI_PROT_WRITE,
2447 VKI_MAP_ANONYMOUS, -1, 0 );
2449 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2452 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2453 // after the syscall. We must get 'size' from the aio_ring structure,
2454 // before the syscall, while the aio_ring structure still exists. (And we
2455 // know that we must look at the aio_ring structure because Tom inspected the
2456 // kernel and glibc sources to see what they do, yuk.)
2458 // XXX This segment can be implicitly unmapped when aio
2459 // file-descriptors are closed...
2460 PRE(sys_io_destroy)
2462 SizeT size = 0;
2464 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2465 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2467 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2468 // possible...
2469 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2470 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2471 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2472 r->nr*sizeof(struct vki_io_event));
2475 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2477 if (SUCCESS && RES == 0) {
2478 Bool d = VG_(am_notify_munmap)( ARG1, size );
2479 VG_TRACK( die_mem_munmap, ARG1, size );
2480 if (d)
2481 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2482 "PRE(sys_io_destroy)" );
2486 PRE(sys_io_getevents)
2488 *flags |= SfMayBlock;
2489 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2490 FMT_REGWORD "x )",
2491 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2492 PRE_REG_READ5(long, "io_getevents",
2493 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2494 struct io_event *, events,
2495 struct timespec *, timeout);
2496 if (ARG3 > 0)
2497 PRE_MEM_WRITE( "io_getevents(events)",
2498 ARG4, sizeof(struct vki_io_event)*ARG3 );
2499 if (ARG5 != 0)
2500 PRE_MEM_READ( "io_getevents(timeout)",
2501 ARG5, sizeof(struct vki_timespec));
2503 POST(sys_io_getevents)
2505 Int i;
2506 vg_assert(SUCCESS);
2507 if (RES > 0) {
2508 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2509 for (i = 0; i < RES; i++) {
2510 const struct vki_io_event *vev =
2511 ((struct vki_io_event *)(Addr)ARG4) + i;
2512 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2514 switch (cb->aio_lio_opcode) {
2515 case VKI_IOCB_CMD_PREAD:
2516 if (vev->result > 0)
2517 POST_MEM_WRITE( cb->aio_buf, vev->result );
2518 break;
2520 case VKI_IOCB_CMD_PWRITE:
2521 break;
2523 case VKI_IOCB_CMD_FSYNC:
2524 break;
2526 case VKI_IOCB_CMD_FDSYNC:
2527 break;
2529 case VKI_IOCB_CMD_PREADV:
2530 if (vev->result > 0) {
2531 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2532 Int remains = vev->result;
2533 Int j;
2535 for (j = 0; j < cb->aio_nbytes; j++) {
2536 Int nReadThisBuf = vec[j].iov_len;
2537 if (nReadThisBuf > remains) nReadThisBuf = remains;
2538 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2539 remains -= nReadThisBuf;
2540 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2543 break;
2545 case VKI_IOCB_CMD_PWRITEV:
2546 break;
2548 default:
2549 VG_(message)(Vg_DebugMsg,
2550 "Warning: unhandled io_getevents opcode: %u\n",
2551 cb->aio_lio_opcode);
2552 break;
2558 PRE(sys_io_submit)
2560 Int i, j;
2562 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2563 ARG1, SARG2, ARG3);
2564 PRE_REG_READ3(long, "io_submit",
2565 vki_aio_context_t, ctx_id, long, nr,
2566 struct iocb **, iocbpp);
2567 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2568 if (ARG3 != 0) {
2569 for (i = 0; i < ARG2; i++) {
2570 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2571 struct vki_iovec *iov;
2573 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2574 switch (cb->aio_lio_opcode) {
2575 case VKI_IOCB_CMD_PREAD:
2576 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2577 break;
2579 case VKI_IOCB_CMD_PWRITE:
2580 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2581 break;
2583 case VKI_IOCB_CMD_FSYNC:
2584 break;
2586 case VKI_IOCB_CMD_FDSYNC:
2587 break;
2589 case VKI_IOCB_CMD_PREADV:
2590 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2591 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2592 for (j = 0; j < cb->aio_nbytes; j++)
2593 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2594 break;
2596 case VKI_IOCB_CMD_PWRITEV:
2597 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2598 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2599 for (j = 0; j < cb->aio_nbytes; j++)
2600 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2601 break;
2603 default:
2604 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2605 cb->aio_lio_opcode);
2606 break;
2612 PRE(sys_io_cancel)
2614 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2615 (ULong)ARG1, ARG2, ARG3);
2616 PRE_REG_READ3(long, "io_cancel",
2617 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2618 struct io_event *, result);
2619 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2620 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2622 POST(sys_io_cancel)
2624 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2627 /* ---------------------------------------------------------------------
2628 *_mempolicy wrappers
2629 ------------------------------------------------------------------ */
2631 PRE(sys_mbind)
2633 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2634 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2635 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2636 PRE_REG_READ6(long, "mbind",
2637 unsigned long, start, unsigned long, len,
2638 unsigned long, policy, unsigned long *, nodemask,
2639 unsigned long, maxnode, unsigned, flags);
2640 if (ARG1 != 0)
2641 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2642 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2645 PRE(sys_set_mempolicy)
2647 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2648 SARG1, ARG2, ARG3);
2649 PRE_REG_READ3(long, "set_mempolicy",
2650 int, policy, unsigned long *, nodemask,
2651 unsigned long, maxnode);
2652 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2653 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2656 PRE(sys_get_mempolicy)
2658 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2659 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2660 ARG1, ARG2, ARG3, ARG4, ARG5);
2661 PRE_REG_READ5(long, "get_mempolicy",
2662 int *, policy, unsigned long *, nodemask,
2663 unsigned long, maxnode, unsigned long, addr,
2664 unsigned long, flags);
2665 if (ARG1 != 0)
2666 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2667 if (ARG2 != 0)
2668 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2669 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2671 POST(sys_get_mempolicy)
2673 if (ARG1 != 0)
2674 POST_MEM_WRITE( ARG1, sizeof(Int) );
2675 if (ARG2 != 0)
2676 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2679 /* ---------------------------------------------------------------------
2680 fanotify_* wrappers
2681 ------------------------------------------------------------------ */
2683 PRE(sys_fanotify_init)
2685 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2686 ARG1, ARG2);
2687 PRE_REG_READ2(long, "fanotify_init",
2688 unsigned int, flags, unsigned int, event_f_flags);
2691 POST(sys_fanotify_init)
2693 vg_assert(SUCCESS);
2694 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2695 VG_(close)(RES);
2696 SET_STATUS_Failure( VKI_EMFILE );
2697 } else {
2698 if (VG_(clo_track_fds))
2699 ML_(record_fd_open_nameless) (tid, RES);
2703 PRE(sys_fanotify_mark)
2705 #if VG_WORDSIZE == 4
2706 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2707 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2708 (HChar *)(Addr)ARG6);
2709 PRE_REG_READ6(long, "sys_fanotify_mark",
2710 int, fanotify_fd, unsigned int, flags,
2711 __vki_u32, mask0, __vki_u32, mask1,
2712 int, dfd, const char *, pathname);
2713 if (ARG6)
2714 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2715 #elif VG_WORDSIZE == 8
2716 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2717 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2718 PRE_REG_READ5(long, "sys_fanotify_mark",
2719 int, fanotify_fd, unsigned int, flags,
2720 __vki_u64, mask,
2721 int, dfd, const char *, pathname);
2722 if (ARG5)
2723 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2724 #else
2725 # error Unexpected word size
2726 #endif
2729 /* ---------------------------------------------------------------------
2730 inotify_* wrappers
2731 ------------------------------------------------------------------ */
2733 PRE(sys_inotify_init)
2735 PRINT("sys_inotify_init ( )");
2736 PRE_REG_READ0(long, "inotify_init");
2738 POST(sys_inotify_init)
2740 vg_assert(SUCCESS);
2741 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2742 VG_(close)(RES);
2743 SET_STATUS_Failure( VKI_EMFILE );
2744 } else {
2745 if (VG_(clo_track_fds))
2746 ML_(record_fd_open_nameless) (tid, RES);
2750 PRE(sys_inotify_init1)
2752 PRINT("sys_inotify_init ( %ld )", SARG1);
2753 PRE_REG_READ1(long, "inotify_init", int, flag);
2756 POST(sys_inotify_init1)
2758 vg_assert(SUCCESS);
2759 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2760 VG_(close)(RES);
2761 SET_STATUS_Failure( VKI_EMFILE );
2762 } else {
2763 if (VG_(clo_track_fds))
2764 ML_(record_fd_open_nameless) (tid, RES);
2768 PRE(sys_inotify_add_watch)
2770 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2771 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2772 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2773 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2776 PRE(sys_inotify_rm_watch)
2778 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2779 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2782 /* ---------------------------------------------------------------------
2783 mq_* wrappers
2784 ------------------------------------------------------------------ */
2786 PRE(sys_mq_open)
2788 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2789 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2790 PRE_REG_READ4(long, "mq_open",
2791 const char *, name, int, oflag, vki_mode_t, mode,
2792 struct mq_attr *, attr);
2793 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2794 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2795 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2796 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2797 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2798 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2799 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2802 POST(sys_mq_open)
2804 vg_assert(SUCCESS);
2805 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2806 VG_(close)(RES);
2807 SET_STATUS_Failure( VKI_EMFILE );
2808 } else {
2809 if (VG_(clo_track_fds))
2810 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2814 PRE(sys_mq_unlink)
2816 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2817 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2818 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2821 PRE(sys_mq_timedsend)
2823 *flags |= SfMayBlock;
2824 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2825 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2826 SARG1,ARG2,ARG3,ARG4,ARG5);
2827 PRE_REG_READ5(long, "mq_timedsend",
2828 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2829 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2830 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2831 SET_STATUS_Failure( VKI_EBADF );
2832 } else {
2833 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2834 if (ARG5 != 0)
2835 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2836 sizeof(struct vki_timespec) );
2840 PRE(sys_mq_timedsend_time64)
2842 *flags |= SfMayBlock;
2843 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2844 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2845 SARG1,ARG2,ARG3,ARG4,ARG5);
2846 PRE_REG_READ5(long, "mq_timedsend_time64",
2847 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2848 unsigned int, msg_prio,
2849 const struct vki_timespec64 *, abs_timeout);
2850 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2851 SET_STATUS_Failure( VKI_EBADF );
2852 } else {
2853 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2854 if (ARG5 != 0)
2855 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2859 PRE(sys_mq_timedreceive)
2861 *flags |= SfMayBlock;
2862 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2863 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2864 SARG1,ARG2,ARG3,ARG4,ARG5);
2865 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2866 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2867 unsigned int *, msg_prio,
2868 const struct timespec *, abs_timeout);
2869 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2870 SET_STATUS_Failure( VKI_EBADF );
2871 } else {
2872 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2873 if (ARG4 != 0)
2874 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2875 ARG4, sizeof(unsigned int) );
2876 if (ARG5 != 0)
2877 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2878 ARG5, sizeof(struct vki_timespec) );
2881 POST(sys_mq_timedreceive)
2883 POST_MEM_WRITE( ARG2, RES );
2884 if (ARG4 != 0)
2885 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2888 PRE(sys_mq_timedreceive_time64)
2890 *flags |= SfMayBlock;
2891 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2892 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2893 SARG1,ARG2,ARG3,ARG4,ARG5);
2894 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2895 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2896 unsigned int *, msg_prio,
2897 const struct vki_timespec64 *, abs_timeout);
2898 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2899 SET_STATUS_Failure( VKI_EBADF );
2900 } else {
2901 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2902 if (ARG4 != 0)
2903 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2904 ARG4, sizeof(unsigned int) );
2905 if (ARG5 != 0)
2906 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2910 POST(sys_mq_timedreceive_time64)
2912 POST_MEM_WRITE( ARG2, RES );
2913 if (ARG4 != 0)
2914 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2917 PRE(sys_mq_notify)
2919 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2920 PRE_REG_READ2(long, "mq_notify",
2921 vki_mqd_t, mqdes, const struct sigevent *, notification);
2922 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2923 SET_STATUS_Failure( VKI_EBADF );
2924 else if (ARG2 != 0)
2925 PRE_MEM_READ( "mq_notify(notification)",
2926 ARG2, sizeof(struct vki_sigevent) );
2929 PRE(sys_mq_getsetattr)
2931 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2932 SARG1, ARG2, ARG3 );
2933 PRE_REG_READ3(long, "mq_getsetattr",
2934 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2935 struct mq_attr *, omqstat);
2936 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2937 SET_STATUS_Failure( VKI_EBADF );
2938 } else {
2939 if (ARG2 != 0) {
2940 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2941 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2942 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2944 if (ARG3 != 0)
2945 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2946 sizeof(struct vki_mq_attr) );
2949 POST(sys_mq_getsetattr)
2951 if (ARG3 != 0)
2952 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2955 /* ---------------------------------------------------------------------
2956 clock_* wrappers
2957 ------------------------------------------------------------------ */
2959 PRE(sys_clock_settime)
2961 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2962 PRE_REG_READ2(long, "clock_settime",
2963 vki_clockid_t, clk_id, const struct timespec *, tp);
2964 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2967 PRE(sys_clock_settime64)
2969 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2970 PRE_REG_READ2(long, "clock_settime64",
2971 vki_clockid_t, clk_id, const struct timespec64 *, tp);
2972 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
2975 PRE(sys_clock_gettime)
2977 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2978 PRE_REG_READ2(long, "clock_gettime",
2979 vki_clockid_t, clk_id, struct timespec *, tp);
2980 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2982 POST(sys_clock_gettime)
2984 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2987 PRE(sys_clock_gettime64)
2989 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2990 PRE_REG_READ2(long, "clock_gettime64",
2991 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
2992 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
2993 sizeof(struct vki_timespec64) );
2995 POST(sys_clock_gettime64)
2997 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3000 PRE(sys_clock_getres)
3002 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3003 // Nb: we can't use "RES" as the param name because that's a macro
3004 // defined above!
3005 PRE_REG_READ2(long, "clock_getres",
3006 vki_clockid_t, clk_id, struct timespec *, res);
3007 if (ARG2 != 0)
3008 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3010 POST(sys_clock_getres)
3012 if (ARG2 != 0)
3013 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3016 PRE(sys_clock_getres_time64)
3018 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3019 // Nb: we can't use "RES" as the param name because that's a macro
3020 // defined above!
3021 PRE_REG_READ2(long, "clock_getres_time64",
3022 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3023 if (ARG2 != 0)
3024 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3025 sizeof(struct vki_timespec64) );
3027 POST(sys_clock_getres_time64)
3029 if (ARG2 != 0)
3030 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3033 PRE(sys_clock_nanosleep)
3035 *flags |= SfMayBlock|SfPostOnFail;
3036 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3037 FMT_REGWORD "x )",
3038 SARG1, SARG2, ARG3, ARG4);
3039 PRE_REG_READ4(int32_t, "clock_nanosleep",
3040 vki_clockid_t, clkid, int, flags,
3041 const struct timespec *, rqtp, struct timespec *, rmtp);
3042 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3043 if (ARG4 != 0)
3044 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3046 POST(sys_clock_nanosleep)
3048 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3049 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3052 PRE(sys_clock_nanosleep_time64)
3054 *flags |= SfMayBlock|SfPostOnFail;
3055 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3056 FMT_REGWORD "x )",
3057 SARG1, SARG2, ARG3, ARG4);
3058 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3059 vki_clockid_t, clkid, int, flags,
3060 const struct vki_timespec64 *, rqtp,
3061 struct vki_timespec64 *, rmtp);
3062 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3063 if (ARG4 != 0)
3064 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3065 sizeof(struct vki_timespec64) );
3067 POST(sys_clock_nanosleep_time64)
3069 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3070 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3073 /* ---------------------------------------------------------------------
3074 timer_* wrappers
3075 ------------------------------------------------------------------ */
3077 PRE(sys_timer_create)
3079 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3080 SARG1, ARG2, ARG3);
3081 PRE_REG_READ3(long, "timer_create",
3082 vki_clockid_t, clockid, struct sigevent *, evp,
3083 vki_timer_t *, timerid);
3084 if (ARG2 != 0) {
3085 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3086 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3087 sizeof(vki_sigval_t) );
3088 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3089 sizeof(int) );
3090 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3091 sizeof(int) );
3092 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3093 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3094 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3095 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3097 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3099 POST(sys_timer_create)
3101 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3104 PRE(sys_timer_settime)
3106 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3107 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3108 PRE_REG_READ4(long, "timer_settime",
3109 vki_timer_t, timerid, int, flags,
3110 const struct itimerspec *, value,
3111 struct itimerspec *, ovalue);
3112 PRE_MEM_READ( "timer_settime(value)", ARG3,
3113 sizeof(struct vki_itimerspec) );
3114 if (ARG4 != 0)
3115 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3116 sizeof(struct vki_itimerspec) );
3118 POST(sys_timer_settime)
3120 if (ARG4 != 0)
3121 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3124 PRE(sys_timer_settime64)
3126 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3127 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3128 PRE_REG_READ4(long, "timer_settime64",
3129 vki_timer_t, timerid, int, flags,
3130 const struct vki_itimerspec64 *, value,
3131 struct vki_itimerspec64 *, ovalue);
3132 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3133 sizeof(struct vki_itimerspec64) );
3134 if (ARG4 != 0)
3135 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3136 sizeof(struct vki_itimerspec64) );
3138 POST(sys_timer_settime64)
3140 if (ARG4 != 0)
3141 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3144 PRE(sys_timer_gettime)
3146 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3147 PRE_REG_READ2(long, "timer_gettime",
3148 vki_timer_t, timerid, struct itimerspec *, value);
3149 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3150 sizeof(struct vki_itimerspec));
3152 POST(sys_timer_gettime)
3154 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3157 PRE(sys_timer_gettime64)
3159 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3160 PRE_REG_READ2(long, "timer_gettime64",
3161 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3162 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3163 sizeof(struct vki_itimerspec64));
3165 POST(sys_timer_gettime64)
3167 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3170 PRE(sys_timer_getoverrun)
3172 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3173 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3176 PRE(sys_timer_delete)
3178 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3179 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3182 /* ---------------------------------------------------------------------
3183 timerfd* wrappers
3184 See also http://lwn.net/Articles/260172/ for an overview.
3185 See also /usr/src/linux/fs/timerfd.c for the implementation.
3186 ------------------------------------------------------------------ */
3188 /* Returns True if running on 2.6.22, else False (or False if
3189 cannot be determined). */
3190 static Bool linux_kernel_2_6_22(void)
3192 static Int result = -1;
3193 Int fd, read;
3194 HChar release[64]; // large enough
3195 SysRes res;
3197 if (result == -1) {
3198 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3199 if (sr_isError(res))
3200 return False;
3201 fd = sr_Res(res);
3202 read = VG_(read)(fd, release, sizeof(release) - 1);
3203 if (read < 0)
3204 return False;
3205 release[read] = 0;
3206 VG_(close)(fd);
3207 //VG_(printf)("kernel release = %s\n", release);
3208 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3209 && ! VG_(isdigit)(release[6]);
3211 vg_assert(result == 0 || result == 1);
3212 return result == 1;
3215 PRE(sys_timerfd_create)
3217 if (linux_kernel_2_6_22()) {
3218 /* 2.6.22 kernel: timerfd system call. */
3219 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3220 PRE_REG_READ3(long, "sys_timerfd",
3221 int, fd, int, clockid, const struct itimerspec *, tmr);
3222 PRE_MEM_READ("timerfd(tmr)", ARG3,
3223 sizeof(struct vki_itimerspec) );
3224 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3225 SET_STATUS_Failure( VKI_EBADF );
3226 } else {
3227 /* 2.6.24 and later kernels: timerfd_create system call. */
3228 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3229 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3232 POST(sys_timerfd_create)
3234 if (linux_kernel_2_6_22())
3236 /* 2.6.22 kernel: timerfd system call. */
3237 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3238 VG_(close)(RES);
3239 SET_STATUS_Failure( VKI_EMFILE );
3240 } else {
3241 if (VG_(clo_track_fds))
3242 ML_(record_fd_open_nameless) (tid, RES);
3245 else
3247 /* 2.6.24 and later kernels: timerfd_create system call. */
3248 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3249 VG_(close)(RES);
3250 SET_STATUS_Failure( VKI_EMFILE );
3251 } else {
3252 if (VG_(clo_track_fds))
3253 ML_(record_fd_open_nameless) (tid, RES);
3258 PRE(sys_timerfd_gettime)
3260 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3261 PRE_REG_READ2(long, "timerfd_gettime",
3262 int, ufd,
3263 struct vki_itimerspec*, otmr);
3264 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3265 SET_STATUS_Failure(VKI_EBADF);
3266 else
3267 PRE_MEM_WRITE("timerfd_gettime(result)",
3268 ARG2, sizeof(struct vki_itimerspec));
3270 POST(sys_timerfd_gettime)
3272 if (RES == 0)
3273 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3276 PRE(sys_timerfd_gettime64)
3278 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3279 PRE_REG_READ2(long, "timerfd_gettime64",
3280 int, ufd,
3281 struct vki_itimerspec64*, otmr);
3282 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3283 SET_STATUS_Failure(VKI_EBADF);
3284 else
3285 PRE_MEM_WRITE("timerfd_gettime64(result)",
3286 ARG2, sizeof(struct vki_itimerspec64));
3288 POST(sys_timerfd_gettime64)
3290 if (RES == 0)
3291 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3294 PRE(sys_timerfd_settime)
3296 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3297 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3298 PRE_REG_READ4(long, "timerfd_settime",
3299 int, ufd,
3300 int, flags,
3301 const struct vki_itimerspec*, utmr,
3302 struct vki_itimerspec*, otmr);
3303 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3304 SET_STATUS_Failure(VKI_EBADF);
3305 else
3307 PRE_MEM_READ("timerfd_settime(result)",
3308 ARG3, sizeof(struct vki_itimerspec));
3309 if (ARG4)
3311 PRE_MEM_WRITE("timerfd_settime(result)",
3312 ARG4, sizeof(struct vki_itimerspec));
3316 POST(sys_timerfd_settime)
3318 if (RES == 0 && ARG4 != 0)
3319 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3322 PRE(sys_timerfd_settime64)
3324 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3325 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3326 PRE_REG_READ4(long, "timerfd_settime64",
3327 int, ufd,
3328 int, flags,
3329 const struct vki_itimerspec64*, utmr,
3330 struct vki_itimerspec64*, otmr);
3331 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3332 SET_STATUS_Failure(VKI_EBADF);
3333 else
3335 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3336 if (ARG4)
3338 PRE_MEM_WRITE("timerfd_settime64(result)",
3339 ARG4, sizeof(struct vki_itimerspec64));
3343 POST(sys_timerfd_settime64)
3345 if (RES == 0 && ARG4 != 0)
3346 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3349 /* ---------------------------------------------------------------------
3350 capabilities wrappers
3351 ------------------------------------------------------------------ */
3353 PRE(sys_capget)
3355 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3356 PRE_REG_READ2(long, "capget",
3357 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3358 PRE_MEM_READ( "capget(header)", ARG1,
3359 sizeof(struct __vki_user_cap_header_struct) );
3360 if (ARG2 != (Addr)NULL)
3361 PRE_MEM_WRITE( "capget(data)", ARG2,
3362 sizeof(struct __vki_user_cap_data_struct) );
3364 POST(sys_capget)
3366 if (ARG2 != (Addr)NULL)
3367 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3370 PRE(sys_capset)
3372 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3373 PRE_REG_READ2(long, "capset",
3374 vki_cap_user_header_t, header,
3375 const vki_cap_user_data_t, data);
3376 PRE_MEM_READ( "capset(header)",
3377 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3378 PRE_MEM_READ( "capset(data)",
3379 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3382 /* ---------------------------------------------------------------------
3383 16-bit uid/gid/groups wrappers
3384 ------------------------------------------------------------------ */
3386 PRE(sys_getuid16)
3388 PRINT("sys_getuid16 ( )");
3389 PRE_REG_READ0(long, "getuid16");
3392 PRE(sys_setuid16)
3394 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3395 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3398 PRE(sys_getgid16)
3400 PRINT("sys_getgid16 ( )");
3401 PRE_REG_READ0(long, "getgid16");
3404 PRE(sys_setgid16)
3406 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3407 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3410 PRE(sys_geteuid16)
3412 PRINT("sys_geteuid16 ( )");
3413 PRE_REG_READ0(long, "geteuid16");
3416 PRE(sys_getegid16)
3418 PRINT("sys_getegid16 ( )");
3419 PRE_REG_READ0(long, "getegid16");
3422 PRE(sys_setreuid16)
3424 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3425 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3428 PRE(sys_setregid16)
3430 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3431 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3434 PRE(sys_getgroups16)
3436 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3437 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3438 if (ARG1 > 0)
3439 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3441 POST(sys_getgroups16)
3443 vg_assert(SUCCESS);
3444 if (ARG1 > 0 && RES > 0)
3445 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3448 PRE(sys_setgroups16)
3450 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3451 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3452 if (ARG1 > 0)
3453 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3456 /* ---------------------------------------------------------------------
3457 *chown16 wrappers
3458 ------------------------------------------------------------------ */
3460 PRE(sys_chown16)
3462 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3463 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3464 PRE_REG_READ3(long, "chown16",
3465 const char *, path,
3466 vki_old_uid_t, owner, vki_old_gid_t, group);
3467 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3470 PRE(sys_fchown16)
3472 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3473 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3474 PRE_REG_READ3(long, "fchown16",
3475 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3478 /* ---------------------------------------------------------------------
3479 *xattr wrappers
3480 ------------------------------------------------------------------ */
3482 PRE(sys_setxattr)
3484 *flags |= SfMayBlock;
3485 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3486 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3487 ARG4, SARG5);
3488 PRE_REG_READ5(long, "setxattr",
3489 char *, path, char *, name,
3490 void *, value, vki_size_t, size, int, flags);
3491 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3492 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3493 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3496 PRE(sys_lsetxattr)
3498 *flags |= SfMayBlock;
3499 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3500 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3501 ARG1, ARG2, ARG3, ARG4, SARG5);
3502 PRE_REG_READ5(long, "lsetxattr",
3503 char *, path, char *, name,
3504 void *, value, vki_size_t, size, int, flags);
3505 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3506 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3507 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3510 PRE(sys_fsetxattr)
3512 *flags |= SfMayBlock;
3513 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3514 FMT_REGWORD "u, %ld )",
3515 SARG1, ARG2, ARG3, ARG4, SARG5);
3516 PRE_REG_READ5(long, "fsetxattr",
3517 int, fd, char *, name, void *, value,
3518 vki_size_t, size, int, flags);
3519 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3520 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3523 PRE(sys_getxattr)
3525 *flags |= SfMayBlock;
3526 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3527 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3528 PRE_REG_READ4(ssize_t, "getxattr",
3529 char *, path, char *, name, void *, value, vki_size_t, size);
3530 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3531 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3532 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3534 POST(sys_getxattr)
3536 vg_assert(SUCCESS);
3537 if (RES > 0 && ARG3 != (Addr)NULL) {
3538 POST_MEM_WRITE( ARG3, RES );
3542 PRE(sys_lgetxattr)
3544 *flags |= SfMayBlock;
3545 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3546 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3547 PRE_REG_READ4(ssize_t, "lgetxattr",
3548 char *, path, char *, name, void *, value, vki_size_t, size);
3549 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3550 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3551 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3553 POST(sys_lgetxattr)
3555 vg_assert(SUCCESS);
3556 if (RES > 0 && ARG3 != (Addr)NULL) {
3557 POST_MEM_WRITE( ARG3, RES );
3561 PRE(sys_fgetxattr)
3563 *flags |= SfMayBlock;
3564 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3565 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3566 PRE_REG_READ4(ssize_t, "fgetxattr",
3567 int, fd, char *, name, void *, value, vki_size_t, size);
3568 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3569 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3571 POST(sys_fgetxattr)
3573 if (RES > 0 && ARG3 != (Addr)NULL)
3574 POST_MEM_WRITE( ARG3, RES );
3577 PRE(sys_listxattr)
3579 *flags |= SfMayBlock;
3580 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3581 ARG1, ARG2, (ULong)ARG3);
3582 PRE_REG_READ3(ssize_t, "listxattr",
3583 char *, path, char *, list, vki_size_t, size);
3584 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3585 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3587 POST(sys_listxattr)
3589 if (RES > 0 && ARG2 != (Addr)NULL)
3590 POST_MEM_WRITE( ARG2, RES );
3593 PRE(sys_llistxattr)
3595 *flags |= SfMayBlock;
3596 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3597 ARG1, ARG2, (ULong)ARG3);
3598 PRE_REG_READ3(ssize_t, "llistxattr",
3599 char *, path, char *, list, vki_size_t, size);
3600 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3601 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3603 POST(sys_llistxattr)
3605 if (RES > 0 && ARG2 != (Addr)NULL)
3606 POST_MEM_WRITE( ARG2, RES );
3609 PRE(sys_flistxattr)
3611 *flags |= SfMayBlock;
3612 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3613 SARG1, ARG2, ARG3);
3614 PRE_REG_READ3(ssize_t, "flistxattr",
3615 int, fd, char *, list, vki_size_t, size);
3616 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3618 POST(sys_flistxattr)
3620 if (RES > 0 && ARG2 != (Addr)NULL)
3621 POST_MEM_WRITE( ARG2, RES );
3624 PRE(sys_removexattr)
3626 *flags |= SfMayBlock;
3627 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3628 ARG1, ARG2);
3629 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3630 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3631 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3634 PRE(sys_lremovexattr)
3636 *flags |= SfMayBlock;
3637 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3638 ARG1, ARG2);
3639 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3640 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3641 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3644 PRE(sys_fremovexattr)
3646 *flags |= SfMayBlock;
3647 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3648 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3649 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3652 /* ---------------------------------------------------------------------
3653 sched_* wrappers
3654 ------------------------------------------------------------------ */
3656 PRE(sys_sched_setparam)
3658 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3659 PRE_REG_READ2(long, "sched_setparam",
3660 vki_pid_t, pid, struct sched_param *, p);
3661 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3663 POST(sys_sched_setparam)
3665 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3668 PRE(sys_sched_getparam)
3670 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3671 PRE_REG_READ2(long, "sched_getparam",
3672 vki_pid_t, pid, struct sched_param *, p);
3673 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3675 POST(sys_sched_getparam)
3677 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3680 PRE(sys_sched_getscheduler)
3682 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3683 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3686 PRE(sys_sched_setscheduler)
3688 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3689 SARG1, SARG2, ARG3);
3690 PRE_REG_READ3(long, "sched_setscheduler",
3691 vki_pid_t, pid, int, policy, struct sched_param *, p);
3692 if (ARG3 != 0)
3693 PRE_MEM_READ( "sched_setscheduler(p)",
3694 ARG3, sizeof(struct vki_sched_param));
3697 PRE(sys_sched_yield)
3699 *flags |= SfMayBlock;
3700 PRINT("sched_yield()");
3701 PRE_REG_READ0(long, "sys_sched_yield");
3704 PRE(sys_sched_get_priority_max)
3706 PRINT("sched_get_priority_max ( %ld )", SARG1);
3707 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3710 PRE(sys_sched_get_priority_min)
3712 PRINT("sched_get_priority_min ( %ld )", SARG1);
3713 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3716 PRE(sys_sched_rr_get_interval)
3718 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3719 PRE_REG_READ2(int, "sched_rr_get_interval",
3720 vki_pid_t, pid,
3721 struct vki_timespec *, tp);
3722 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3723 ARG2, sizeof(struct vki_timespec));
3726 POST(sys_sched_rr_get_interval)
3728 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3731 PRE(sys_sched_rr_get_interval_time64)
3733 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3734 SARG1, ARG2);
3735 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3736 vki_pid_t, pid,
3737 struct vki_timespec *, tp);
3738 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3739 ARG2, sizeof(struct vki_timespec64));
3742 POST(sys_sched_rr_get_interval_time64)
3744 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3747 PRE(sys_sched_setaffinity)
3749 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3750 SARG1, ARG2, ARG3);
3751 PRE_REG_READ3(long, "sched_setaffinity",
3752 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3753 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3756 PRE(sys_sched_getaffinity)
3758 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3759 SARG1, ARG2, ARG3);
3760 PRE_REG_READ3(long, "sched_getaffinity",
3761 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3762 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3764 POST(sys_sched_getaffinity)
3766 POST_MEM_WRITE(ARG3, ARG2);
3769 PRE(sys_unshare)
3771 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3772 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3775 /* ---------------------------------------------------------------------
3776 miscellaneous wrappers
3777 ------------------------------------------------------------------ */
3779 PRE(sys_munlockall)
3781 *flags |= SfMayBlock;
3782 PRINT("sys_munlockall ( )");
3783 PRE_REG_READ0(long, "munlockall");
3786 // This has different signatures for different platforms.
3788 // x86: int sys_pipe(unsigned long __user *fildes);
3789 // AMD64: long sys_pipe(int *fildes);
3790 // ppc32: int sys_pipe(int __user *fildes);
3791 // ppc64: int sys_pipe(int __user *fildes);
3793 // The type of the argument is most important, and it is an array of 32 bit
3794 // values in all cases. (The return type differs across platforms, but it
3795 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3796 // was caused by using an array of 'unsigned long's, which didn't work on
3797 // AMD64.
3798 PRE(sys_pipe)
3800 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3801 PRE_REG_READ1(int, "pipe", int *, filedes);
3802 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3804 POST(sys_pipe)
3806 Int *p = (Int *)(Addr)ARG1;
3807 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3808 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3809 VG_(close)(p[0]);
3810 VG_(close)(p[1]);
3811 SET_STATUS_Failure( VKI_EMFILE );
3812 } else {
3813 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3814 if (VG_(clo_track_fds)) {
3815 ML_(record_fd_open_nameless)(tid, p[0]);
3816 ML_(record_fd_open_nameless)(tid, p[1]);
3821 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3822 there's a second arg containing flags to be applied to the new file
3823 descriptors. It hardly seems worth the effort to factor out the
3824 duplicated code, hence: */
3825 PRE(sys_pipe2)
3827 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3828 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3829 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3831 POST(sys_pipe2)
3833 Int *p = (Int *)(Addr)ARG1;
3834 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3835 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3836 VG_(close)(p[0]);
3837 VG_(close)(p[1]);
3838 SET_STATUS_Failure( VKI_EMFILE );
3839 } else {
3840 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3841 if (VG_(clo_track_fds)) {
3842 ML_(record_fd_open_nameless)(tid, p[0]);
3843 ML_(record_fd_open_nameless)(tid, p[1]);
3848 PRE(sys_dup3)
3850 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3851 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3852 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3853 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3854 SET_STATUS_Failure( VKI_EBADF );
3857 POST(sys_dup3)
3859 vg_assert(SUCCESS);
3860 if (VG_(clo_track_fds))
3861 ML_(record_fd_open_named)(tid, RES);
3864 PRE(sys_quotactl)
3866 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3867 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3868 PRE_REG_READ4(long, "quotactl",
3869 unsigned int, cmd, const char *, special, vki_qid_t, id,
3870 void *, addr);
3871 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3874 PRE(sys_waitid)
3876 *flags |= SfMayBlock;
3877 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3878 SARG1, SARG2, ARG3, SARG4, ARG5);
3879 PRE_REG_READ5(int32_t, "sys_waitid",
3880 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3881 int, options, struct vki_rusage *, ru);
3882 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3883 if (ARG5 != 0)
3884 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3886 POST(sys_waitid)
3888 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3889 if (ARG5 != 0)
3890 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3893 PRE(sys_sync_file_range)
3895 *flags |= SfMayBlock;
3896 #if VG_WORDSIZE == 4
3897 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3898 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3899 PRE_REG_READ6(long, "sync_file_range",
3900 int, fd,
3901 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3902 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3903 unsigned int, flags);
3904 #elif VG_WORDSIZE == 8
3905 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3906 SARG1, SARG2, SARG3, ARG4);
3907 PRE_REG_READ4(long, "sync_file_range",
3908 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3909 unsigned int, flags);
3910 #else
3911 # error Unexpected word size
3912 #endif
3913 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3914 SET_STATUS_Failure( VKI_EBADF );
3917 PRE(sys_sync_file_range2)
3919 *flags |= SfMayBlock;
3920 #if VG_WORDSIZE == 4
3921 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3922 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3923 PRE_REG_READ6(long, "sync_file_range2",
3924 int, fd, unsigned int, flags,
3925 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3926 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3927 #elif VG_WORDSIZE == 8
3928 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3929 SARG1, ARG2, SARG3, SARG4);
3930 PRE_REG_READ4(long, "sync_file_range2",
3931 int, fd, unsigned int, flags,
3932 vki_loff_t, offset, vki_loff_t, nbytes);
3933 #else
3934 # error Unexpected word size
3935 #endif
3936 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3937 SET_STATUS_Failure( VKI_EBADF );
3940 PRE(sys_stime)
3942 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
3943 PRE_REG_READ1(int, "stime", vki_time_t*, t);
3944 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3947 PRE(sys_perf_event_open)
3949 struct vki_perf_event_attr *attr;
3950 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
3951 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
3952 PRE_REG_READ5(long, "perf_event_open",
3953 struct vki_perf_event_attr *, attr,
3954 vki_pid_t, pid, int, cpu, int, group_fd,
3955 unsigned long, flags);
3956 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
3957 PRE_MEM_READ( "perf_event_open(attr->size)",
3958 (Addr)&attr->size, sizeof(attr->size) );
3959 PRE_MEM_READ( "perf_event_open(attr)",
3960 (Addr)attr, attr->size );
3963 POST(sys_perf_event_open)
3965 vg_assert(SUCCESS);
3966 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3967 VG_(close)(RES);
3968 SET_STATUS_Failure( VKI_EMFILE );
3969 } else {
3970 if (VG_(clo_track_fds))
3971 ML_(record_fd_open_nameless)(tid, RES);
3975 PRE(sys_getcpu)
3977 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3978 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
3979 PRE_REG_READ3(int, "getcpu",
3980 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3981 if (ARG1 != 0)
3982 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3983 if (ARG2 != 0)
3984 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3985 if (ARG3 != 0)
3986 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3989 POST(sys_getcpu)
3991 if (ARG1 != 0)
3992 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3993 if (ARG2 != 0)
3994 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3995 if (ARG3 != 0)
3996 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3999 PRE(sys_move_pages)
4001 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4002 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4003 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4004 PRE_REG_READ6(int, "move_pages",
4005 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4006 const int *, nodes, int *, status, int, flags);
4007 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4008 if (ARG4)
4009 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4010 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4013 POST(sys_move_pages)
4015 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4018 PRE(sys_getrandom)
4020 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4021 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4022 PRE_REG_READ3(int, "getrandom",
4023 char *, buf, vki_size_t, count, unsigned int, flags);
4024 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4027 POST(sys_getrandom)
4029 POST_MEM_WRITE( ARG1, ARG2 );
4032 PRE(sys_memfd_create)
4034 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4035 ARG1, ARG2);
4036 PRE_REG_READ2(int, "memfd_create",
4037 char *, uname, unsigned int, flags);
4038 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4041 POST(sys_memfd_create)
4043 vg_assert(SUCCESS);
4044 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4045 VG_(close)(RES);
4046 SET_STATUS_Failure( VKI_EMFILE );
4047 } else {
4048 if (VG_(clo_track_fds))
4049 ML_(record_fd_open_nameless)(tid, RES);
4053 PRE(sys_membarrier)
4055 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4056 PRE_REG_READ1(int, "membarrier", int, flags);
4059 PRE(sys_syncfs)
4061 *flags |= SfMayBlock;
4062 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4063 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4066 PRE(sys_statx)
4068 FUSE_COMPATIBLE_MAY_BLOCK();
4069 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4070 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4071 PRE_REG_READ5(long, "statx",
4072 int, dirfd, char *, filename, int, flags,
4073 unsigned int, mask, struct statx *, buf);
4074 // Work around Rust's dubious use of statx, as described here:
4075 // https://github.com/rust-lang/rust/blob/
4076 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4077 // src/libstd/sys/unix/fs.rs#L128-L142
4078 // in which it passes NULL for both filename and buf, and then looks at the
4079 // return value, so as to determine whether or not this syscall is supported.
4080 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4081 if (!both_filename_and_buf_are_null) {
4082 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4083 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4086 POST(sys_statx)
4088 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4091 /* ---------------------------------------------------------------------
4092 utime wrapper
4093 ------------------------------------------------------------------ */
4095 PRE(sys_utime)
4097 *flags |= SfMayBlock;
4098 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4099 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4100 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4101 if (ARG2 != 0)
4102 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4105 /* ---------------------------------------------------------------------
4106 lseek wrapper
4107 ------------------------------------------------------------------ */
4109 PRE(sys_lseek)
4111 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4112 ARG1, SARG2, ARG3);
4113 PRE_REG_READ3(vki_off_t, "lseek",
4114 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4117 /* ---------------------------------------------------------------------
4118 readahead wrapper
4119 ------------------------------------------------------------------ */
4121 PRE(sys_readahead)
4123 *flags |= SfMayBlock;
4124 #if VG_WORDSIZE == 4
4125 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4126 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4127 PRE_REG_READ4(vki_off_t, "readahead",
4128 int, fd, unsigned, MERGE64_FIRST(offset),
4129 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4130 #elif VG_WORDSIZE == 8
4131 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4132 PRE_REG_READ3(vki_off_t, "readahead",
4133 int, fd, vki_loff_t, offset, vki_size_t, count);
4134 #else
4135 # error Unexpected word size
4136 #endif
4137 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4138 SET_STATUS_Failure( VKI_EBADF );
4141 /* ---------------------------------------------------------------------
4142 sig* wrappers
4143 ------------------------------------------------------------------ */
4145 PRE(sys_sigpending)
4147 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4148 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4149 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4151 POST(sys_sigpending)
4153 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4156 // This syscall is not used on amd64/Linux -- it only provides
4157 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4158 // This wrapper is only suitable for 32-bit architectures.
4159 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4160 // conditional compilation like this?)
4161 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4162 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4163 || defined(VGP_nanomips_linux)
4164 PRE(sys_sigprocmask)
4166 vki_old_sigset_t* set;
4167 vki_old_sigset_t* oldset;
4168 vki_sigset_t bigger_set;
4169 vki_sigset_t bigger_oldset;
4171 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4172 PRE_REG_READ3(long, "sigprocmask",
4173 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4174 if (ARG2 != 0)
4175 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4176 if (ARG3 != 0)
4177 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4179 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4180 // vki_sigset_t params.
4181 set = (vki_old_sigset_t*)(Addr)ARG2;
4182 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4184 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4185 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4186 if (set)
4187 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4189 SET_STATUS_from_SysRes(
4190 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4191 set ? &bigger_set : NULL,
4192 oldset ? &bigger_oldset : NULL)
4195 if (oldset)
4196 *oldset = bigger_oldset.sig[0];
4198 if (SUCCESS)
4199 *flags |= SfPollAfter;
4201 POST(sys_sigprocmask)
4203 vg_assert(SUCCESS);
4204 if (RES == 0 && ARG3 != 0)
4205 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4208 /* Convert from non-RT to RT sigset_t's */
4209 static
4210 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4212 VG_(sigemptyset)(set);
4213 set->sig[0] = *oldset;
4215 PRE(sys_sigaction)
4217 vki_sigaction_toK_t new, *newp;
4218 vki_sigaction_fromK_t old, *oldp;
4220 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4221 PRE_REG_READ3(int, "sigaction",
4222 int, signum, const struct old_sigaction *, act,
4223 struct old_sigaction *, oldact);
4225 newp = oldp = NULL;
4227 if (ARG2 != 0) {
4228 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4229 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4230 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4231 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4232 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4233 && (sa->sa_flags & VKI_SA_RESTORER))
4234 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4237 if (ARG3 != 0) {
4238 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4239 oldp = &old;
4242 /* If the new or old sigaction is not NULL, but the structs
4243 aren't accessible then sigaction returns EFAULT and we cannot
4244 use either struct for our own bookkeeping. Just fail early. */
4245 if (ARG2 != 0
4246 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4247 sizeof(struct vki_old_sigaction))) {
4248 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4249 (void *)(Addr)ARG2);
4250 SET_STATUS_Failure ( VKI_EFAULT );
4251 } else if ((ARG3 != 0
4252 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4253 sizeof(struct vki_old_sigaction)))) {
4254 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4255 (void *)(Addr)ARG3);
4256 SET_STATUS_Failure ( VKI_EFAULT );
4257 } else {
4258 if (ARG2 != 0) {
4259 struct vki_old_sigaction *oldnew =
4260 (struct vki_old_sigaction *)(Addr)ARG2;
4262 new.ksa_handler = oldnew->ksa_handler;
4263 new.sa_flags = oldnew->sa_flags;
4264 new.sa_restorer = oldnew->sa_restorer;
4265 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4266 newp = &new;
4269 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4271 if (ARG3 != 0 && SUCCESS && RES == 0) {
4272 struct vki_old_sigaction *oldold =
4273 (struct vki_old_sigaction *)(Addr)ARG3;
4275 oldold->ksa_handler = oldp->ksa_handler;
4276 oldold->sa_flags = oldp->sa_flags;
4277 oldold->sa_restorer = oldp->sa_restorer;
4278 oldold->sa_mask = oldp->sa_mask.sig[0];
4282 POST(sys_sigaction)
4284 vg_assert(SUCCESS);
4285 if (RES == 0 && ARG3 != 0)
4286 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4288 #endif
4290 PRE(sys_signalfd)
4292 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4293 (ULong)ARG3);
4294 PRE_REG_READ3(long, "sys_signalfd",
4295 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4296 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4297 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4298 SET_STATUS_Failure( VKI_EBADF );
4300 POST(sys_signalfd)
4302 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4303 VG_(close)(RES);
4304 SET_STATUS_Failure( VKI_EMFILE );
4305 } else {
4306 if (VG_(clo_track_fds))
4307 ML_(record_fd_open_nameless) (tid, RES);
4311 PRE(sys_signalfd4)
4313 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4314 SARG1, ARG2, ARG3, SARG4);
4315 PRE_REG_READ4(long, "sys_signalfd4",
4316 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4317 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4318 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4319 SET_STATUS_Failure( VKI_EBADF );
4321 POST(sys_signalfd4)
4323 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4324 VG_(close)(RES);
4325 SET_STATUS_Failure( VKI_EMFILE );
4326 } else {
4327 if (VG_(clo_track_fds))
4328 ML_(record_fd_open_nameless) (tid, RES);
4333 /* ---------------------------------------------------------------------
4334 rt_sig* wrappers
4335 ------------------------------------------------------------------ */
4337 PRE(sys_rt_sigaction)
4339 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4340 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4341 PRE_REG_READ4(long, "rt_sigaction",
4342 int, signum, const struct sigaction *, act,
4343 struct sigaction *, oldact, vki_size_t, sigsetsize);
4345 if (ARG2 != 0) {
4346 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4347 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4348 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4349 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4350 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4351 && (sa->sa_flags & VKI_SA_RESTORER))
4352 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4354 if (ARG3 != 0)
4355 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4357 /* If the new or old sigaction is not NULL, but the structs
4358 aren't accessible then sigaction returns EFAULT and we cannot
4359 use either struct for our own bookkeeping. Just fail early. */
4360 if (ARG2 != 0
4361 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4362 sizeof(vki_sigaction_toK_t))) {
4363 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4364 (void *)(Addr)ARG2);
4365 SET_STATUS_Failure ( VKI_EFAULT );
4366 } else if ((ARG3 != 0
4367 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4368 sizeof(vki_sigaction_fromK_t)))) {
4369 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4370 (void *)(Addr)ARG3);
4371 SET_STATUS_Failure ( VKI_EFAULT );
4372 } else {
4374 // XXX: doesn't seem right to be calling do_sys_sigaction for
4375 // sys_rt_sigaction... perhaps this function should be renamed
4376 // VG_(do_sys_rt_sigaction)() --njn
4378 SET_STATUS_from_SysRes(
4379 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4380 (vki_sigaction_fromK_t *)(Addr)ARG3)
4384 POST(sys_rt_sigaction)
4386 vg_assert(SUCCESS);
4387 if (RES == 0 && ARG3 != 0)
4388 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4391 PRE(sys_rt_sigprocmask)
4393 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4394 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4395 PRE_REG_READ4(long, "rt_sigprocmask",
4396 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4397 vki_size_t, sigsetsize);
4398 if (ARG2 != 0)
4399 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4400 if (ARG3 != 0)
4401 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4403 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4404 // Since we want to use the set and oldset for bookkeeping we also want
4405 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4406 if (sizeof(vki_sigset_t) != ARG4)
4407 SET_STATUS_Failure( VKI_EINVAL );
4408 else if (ARG2 != 0
4409 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4410 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4411 (void *)(Addr)ARG2);
4412 SET_STATUS_Failure ( VKI_EFAULT );
4414 else if (ARG3 != 0
4415 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4416 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4417 (void *)(Addr)ARG3);
4418 SET_STATUS_Failure ( VKI_EFAULT );
4421 else {
4422 SET_STATUS_from_SysRes(
4423 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4424 (vki_sigset_t*) (Addr)ARG2,
4425 (vki_sigset_t*) (Addr)ARG3 )
4429 if (SUCCESS)
4430 *flags |= SfPollAfter;
4432 POST(sys_rt_sigprocmask)
4434 vg_assert(SUCCESS);
4435 if (RES == 0 && ARG3 != 0)
4436 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4439 PRE(sys_rt_sigpending)
4441 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4442 PRE_REG_READ2(long, "rt_sigpending",
4443 vki_sigset_t *, set, vki_size_t, sigsetsize);
4444 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4446 POST(sys_rt_sigpending)
4448 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4451 PRE(sys_rt_sigtimedwait)
4453 *flags |= SfMayBlock;
4454 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4455 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4456 ARG1, ARG2, ARG3, ARG4);
4457 PRE_REG_READ4(long, "rt_sigtimedwait",
4458 const vki_sigset_t *, set, vki_siginfo_t *, info,
4459 const struct timespec *, timeout, vki_size_t, sigsetsize);
4460 if (ARG1 != 0)
4461 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4462 if (ARG2 != 0)
4463 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4464 if (ARG3 != 0)
4465 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4466 ARG3, sizeof(struct vki_timespec) );
4468 POST(sys_rt_sigtimedwait)
4470 if (ARG2 != 0)
4471 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4474 PRE(sys_rt_sigtimedwait_time64)
4476 *flags |= SfMayBlock;
4477 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4478 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4479 ARG1, ARG2, ARG3, ARG4);
4480 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4481 const vki_sigset_t *, set, vki_siginfo_t *, info,
4482 const struct vki_timespec64 *, timeout,
4483 vki_size_t, sigsetsize);
4484 if (ARG1 != 0)
4485 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4486 if (ARG2 != 0)
4487 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4488 sizeof(vki_siginfo_t) );
4489 if (ARG3 != 0)
4490 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4492 POST(sys_rt_sigtimedwait_time64)
4494 if (ARG2 != 0)
4495 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4498 PRE(sys_rt_sigqueueinfo)
4500 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4501 SARG1, SARG2, ARG3);
4502 PRE_REG_READ3(long, "rt_sigqueueinfo",
4503 int, pid, int, sig, vki_siginfo_t *, uinfo);
4504 if (ARG2 != 0)
4505 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4507 POST(sys_rt_sigqueueinfo)
4509 if (!ML_(client_signal_OK)(ARG2))
4510 SET_STATUS_Failure( VKI_EINVAL );
4513 PRE(sys_rt_tgsigqueueinfo)
4515 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4516 SARG1, SARG2, SARG3, ARG4);
4517 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4518 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4519 if (ARG3 != 0)
4520 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4523 POST(sys_rt_tgsigqueueinfo)
4525 if (!ML_(client_signal_OK)(ARG3))
4526 SET_STATUS_Failure( VKI_EINVAL );
4529 // XXX: x86-specific? The kernel prototypes for the different archs are
4530 // hard to decipher.
4531 PRE(sys_rt_sigsuspend)
4533 /* The C library interface to sigsuspend just takes a pointer to
4534 a signal mask but this system call has two arguments - a pointer
4535 to the mask and the number of bytes used by it. The kernel insists
4536 on the size being equal to sizeof(sigset_t) however and will just
4537 return EINVAL if it isn't.
4539 *flags |= SfMayBlock;
4540 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4541 ARG1, ARG2 );
4542 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4543 if (ARG1 != (Addr)NULL) {
4544 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4545 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4546 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4547 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4548 be killable by VG_(nuke_all_threads_except).
4549 We thus silently ignore the user request to mask this signal.
4550 Note that this is similar to what is done for e.g.
4551 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4552 } else {
4553 SET_STATUS_Failure(VKI_EFAULT);
4558 /* ---------------------------------------------------------------------
4559 linux msg* wrapper helpers
4560 ------------------------------------------------------------------ */
4562 void
4563 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4564 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4566 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4567 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4568 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4569 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4572 void
4573 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4574 UWord arg0, UWord arg1, UWord arg2,
4575 UWord arg3, UWord arg4 )
4577 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4578 long msgtyp, int msgflg); */
4579 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4580 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4581 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4583 void
4584 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4585 UWord res,
4586 UWord arg0, UWord arg1, UWord arg2,
4587 UWord arg3, UWord arg4 )
4589 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4590 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4591 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4594 void
4595 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4596 UWord arg0, UWord arg1, UWord arg2 )
4598 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4599 switch (arg1 /* cmd */) {
4600 case VKI_IPC_INFO:
4601 case VKI_MSG_INFO:
4602 case VKI_IPC_INFO|VKI_IPC_64:
4603 case VKI_MSG_INFO|VKI_IPC_64:
4604 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4605 arg2, sizeof(struct vki_msginfo) );
4606 break;
4607 case VKI_IPC_STAT:
4608 case VKI_MSG_STAT:
4609 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4610 arg2, sizeof(struct vki_msqid_ds) );
4611 break;
4612 case VKI_IPC_STAT|VKI_IPC_64:
4613 case VKI_MSG_STAT|VKI_IPC_64:
4614 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4615 arg2, sizeof(struct vki_msqid64_ds) );
4616 break;
4617 case VKI_IPC_SET:
4618 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4619 arg2, sizeof(struct vki_msqid_ds) );
4620 break;
4621 case VKI_IPC_SET|VKI_IPC_64:
4622 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4623 arg2, sizeof(struct vki_msqid64_ds) );
4624 break;
4627 void
4628 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4629 UWord res,
4630 UWord arg0, UWord arg1, UWord arg2 )
4632 switch (arg1 /* cmd */) {
4633 case VKI_IPC_INFO:
4634 case VKI_MSG_INFO:
4635 case VKI_IPC_INFO|VKI_IPC_64:
4636 case VKI_MSG_INFO|VKI_IPC_64:
4637 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4638 break;
4639 case VKI_IPC_STAT:
4640 case VKI_MSG_STAT:
4641 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4642 break;
4643 case VKI_IPC_STAT|VKI_IPC_64:
4644 case VKI_MSG_STAT|VKI_IPC_64:
4645 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4646 break;
4650 /* ---------------------------------------------------------------------
4651 Generic handler for sys_ipc
4652 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4653 are either direct system calls, or are all implemented via sys_ipc.
4654 ------------------------------------------------------------------ */
4655 #ifdef __NR_ipc
4656 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4658 Addr* a_p = (Addr*)a;
4659 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4660 return *a_p;
4663 static Bool semctl_cmd_has_4args (UWord cmd)
4665 switch (cmd & ~VKI_IPC_64)
4667 case VKI_IPC_INFO:
4668 case VKI_SEM_INFO:
4669 case VKI_IPC_STAT:
4670 case VKI_SEM_STAT:
4671 case VKI_IPC_SET:
4672 case VKI_GETALL:
4673 case VKI_SETALL:
4674 return True;
4675 default:
4676 return False;
4680 PRE(sys_ipc)
4682 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4683 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4685 switch (ARG1 /* call */) {
4686 case VKI_SEMOP:
4687 PRE_REG_READ5(int, "ipc",
4688 vki_uint, call, int, first, int, second, int, third,
4689 void *, ptr);
4690 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4691 *flags |= SfMayBlock;
4692 break;
4693 case VKI_SEMGET:
4694 PRE_REG_READ4(int, "ipc",
4695 vki_uint, call, int, first, int, second, int, third);
4696 break;
4697 case VKI_SEMCTL:
4699 PRE_REG_READ5(int, "ipc",
4700 vki_uint, call, int, first, int, second, int, third,
4701 void *, ptr);
4702 UWord arg;
4703 if (semctl_cmd_has_4args(ARG4))
4704 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4705 else
4706 arg = 0;
4707 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4708 break;
4710 case VKI_SEMTIMEDOP:
4711 PRE_REG_READ6(int, "ipc",
4712 vki_uint, call, int, first, int, second, int, third,
4713 void *, ptr, long, fifth);
4714 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4715 *flags |= SfMayBlock;
4716 break;
4717 case VKI_MSGSND:
4718 PRE_REG_READ5(int, "ipc",
4719 vki_uint, call, int, first, int, second, int, third,
4720 void *, ptr);
4721 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4722 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4723 *flags |= SfMayBlock;
4724 break;
4725 case VKI_MSGRCV:
4727 PRE_REG_READ5(int, "ipc",
4728 vki_uint, call, int, first, int, second, int, third,
4729 void *, ptr);
4730 Addr msgp;
4731 Word msgtyp;
4733 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4734 "msgrcv(msgp)" );
4735 msgtyp = deref_Addr( tid,
4736 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4737 "msgrcv(msgp)" );
4739 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4741 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4742 *flags |= SfMayBlock;
4743 break;
4745 case VKI_MSGGET:
4746 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4747 break;
4748 case VKI_MSGCTL:
4749 PRE_REG_READ5(int, "ipc",
4750 vki_uint, call, int, first, int, second, int, third,
4751 void *, ptr);
4752 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4753 break;
4754 case VKI_SHMAT:
4756 PRE_REG_READ5(int, "ipc",
4757 vki_uint, call, int, first, int, second, int, third,
4758 void *, ptr);
4759 UWord w;
4760 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4761 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4762 if (w == 0)
4763 SET_STATUS_Failure( VKI_EINVAL );
4764 else
4765 ARG5 = w;
4766 break;
4768 case VKI_SHMDT:
4769 PRE_REG_READ5(int, "ipc",
4770 vki_uint, call, int, first, int, second, int, third,
4771 void *, ptr);
4772 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4773 SET_STATUS_Failure( VKI_EINVAL );
4774 break;
4775 case VKI_SHMGET:
4776 PRE_REG_READ4(int, "ipc",
4777 vki_uint, call, int, first, int, second, int, third);
4778 if (ARG4 & VKI_SHM_HUGETLB) {
4779 static Bool warning_given = False;
4780 ARG4 &= ~VKI_SHM_HUGETLB;
4781 if (!warning_given) {
4782 warning_given = True;
4783 VG_(umsg)(
4784 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4787 break;
4788 case VKI_SHMCTL: /* IPCOP_shmctl */
4789 PRE_REG_READ5(int, "ipc",
4790 vki_uint, call, int, first, int, second, int, third,
4791 void *, ptr);
4792 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4793 break;
4794 default:
4795 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4796 VG_(core_panic)("... bye!\n");
4797 break; /*NOTREACHED*/
4801 POST(sys_ipc)
4803 vg_assert(SUCCESS);
4804 switch (ARG1 /* call */) {
4805 case VKI_SEMOP:
4806 case VKI_SEMGET:
4807 break;
4808 case VKI_SEMCTL:
4810 UWord arg;
4811 if (semctl_cmd_has_4args(ARG4))
4812 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4813 else
4814 arg = 0;
4815 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4816 break;
4818 case VKI_SEMTIMEDOP:
4819 case VKI_MSGSND:
4820 break;
4821 case VKI_MSGRCV:
4823 Addr msgp;
4824 Word msgtyp;
4826 msgp = deref_Addr( tid,
4827 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4828 "msgrcv(msgp)" );
4829 msgtyp = deref_Addr( tid,
4830 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4831 "msgrcv(msgp)" );
4833 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4834 break;
4836 case VKI_MSGGET:
4837 break;
4838 case VKI_MSGCTL:
4839 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4840 break;
4841 case VKI_SHMAT:
4843 Addr addr;
4845 /* force readability. before the syscall it is
4846 * indeed uninitialized, as can be seen in
4847 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4848 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4850 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4851 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4852 break;
4854 case VKI_SHMDT:
4855 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4856 break;
4857 case VKI_SHMGET:
4858 break;
4859 case VKI_SHMCTL:
4860 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4861 break;
4862 default:
4863 VG_(message)(Vg_DebugMsg,
4864 "FATAL: unhandled syscall(ipc) %lu\n",
4865 ARG1 );
4866 VG_(core_panic)("... bye!\n");
4867 break; /*NOTREACHED*/
4870 #endif
4872 PRE(sys_semget)
4874 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4875 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4878 PRE(sys_semop)
4880 *flags |= SfMayBlock;
4881 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4882 SARG1, ARG2, ARG3);
4883 PRE_REG_READ3(long, "semop",
4884 int, semid, struct sembuf *, sops, unsigned, nsoops);
4885 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4888 PRE(sys_semctl)
4890 switch (ARG3 & ~VKI_IPC_64) {
4891 case VKI_IPC_INFO:
4892 case VKI_SEM_INFO:
4893 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4894 SARG3, ARG4);
4895 PRE_REG_READ4(long, "semctl",
4896 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4897 break;
4898 case VKI_IPC_STAT:
4899 case VKI_SEM_STAT:
4900 case VKI_IPC_SET:
4901 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4902 SARG3, ARG4);
4903 PRE_REG_READ4(long, "semctl",
4904 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4905 break;
4906 case VKI_GETALL:
4907 case VKI_SETALL:
4908 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4909 SARG3, ARG4);
4910 PRE_REG_READ4(long, "semctl",
4911 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4912 break;
4913 default:
4914 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4915 PRE_REG_READ3(long, "semctl",
4916 int, semid, int, semnum, int, cmd);
4917 break;
4919 #ifdef VGP_amd64_linux
4920 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4921 #else
4922 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4923 #endif
4926 POST(sys_semctl)
4928 #ifdef VGP_amd64_linux
4929 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4930 #else
4931 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4932 #endif
4935 PRE(sys_semtimedop)
4937 *flags |= SfMayBlock;
4938 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
4939 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4940 PRE_REG_READ4(long, "semtimedop",
4941 int, semid, struct sembuf *, sops, unsigned, nsoops,
4942 struct timespec *, timeout);
4943 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4946 PRE(sys_semtimedop_time64)
4948 *flags |= SfMayBlock;
4949 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
4950 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4951 PRE_REG_READ4(long, "semtimedop_time64",
4952 int, semid, struct sembuf *, sops, unsigned, nsoops,
4953 struct vki_timespec64 *, timeout);
4954 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
4955 ARG2 * sizeof(struct vki_sembuf) );
4956 if (ARG3 != 0)
4957 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
4960 PRE(sys_msgget)
4962 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4963 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4966 PRE(sys_msgsnd)
4968 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4969 SARG1, ARG2, ARG3, SARG4);
4970 PRE_REG_READ4(long, "msgsnd",
4971 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4972 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4973 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4974 *flags |= SfMayBlock;
4977 PRE(sys_msgrcv)
4979 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
4980 SARG1, ARG2, ARG3, SARG4, SARG5);
4981 PRE_REG_READ5(long, "msgrcv",
4982 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4983 long, msgytp, int, msgflg);
4984 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4985 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4986 *flags |= SfMayBlock;
4988 POST(sys_msgrcv)
4990 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4993 PRE(sys_msgctl)
4995 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4996 PRE_REG_READ3(long, "msgctl",
4997 int, msqid, int, cmd, struct msqid_ds *, buf);
4998 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5001 POST(sys_msgctl)
5003 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5006 PRE(sys_shmget)
5008 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5009 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5010 if (ARG3 & VKI_SHM_HUGETLB) {
5011 static Bool warning_given = False;
5012 ARG3 &= ~VKI_SHM_HUGETLB;
5013 if (!warning_given) {
5014 warning_given = True;
5015 VG_(umsg)(
5016 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5021 PRE(sys_shmat)
5023 UWord arg2tmp;
5024 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5025 PRE_REG_READ3(long, "shmat",
5026 int, shmid, const void *, shmaddr, int, shmflg);
5027 #if defined(VGP_arm_linux)
5028 /* Round the attach address down to an VKI_SHMLBA boundary if the
5029 client requested rounding. See #222545. This is necessary only
5030 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5031 other linux targets it is the same as the page size. */
5032 if (ARG3 & VKI_SHM_RND)
5033 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5034 #endif
5035 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5036 if (arg2tmp == 0)
5037 SET_STATUS_Failure( VKI_EINVAL );
5038 else
5039 ARG2 = arg2tmp; // used in POST
5042 POST(sys_shmat)
5044 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5047 PRE(sys_shmdt)
5049 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5050 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5051 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5052 SET_STATUS_Failure( VKI_EINVAL );
5055 POST(sys_shmdt)
5057 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5060 PRE(sys_shmctl)
5062 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5063 PRE_REG_READ3(long, "shmctl",
5064 int, shmid, int, cmd, struct shmid_ds *, buf);
5065 #ifdef VGP_amd64_linux
5066 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5067 #else
5068 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5069 #endif
5072 POST(sys_shmctl)
5074 #ifdef VGP_amd64_linux
5075 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5076 #else
5077 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5078 #endif
5082 /* ---------------------------------------------------------------------
5083 Generic handler for sys_socketcall
5084 Depending on the platform, some socket related syscalls (e.g. socketpair,
5085 socket, bind, ...)
5086 are either direct system calls, or are all implemented via sys_socketcall.
5087 ------------------------------------------------------------------ */
5088 #ifdef __NR_socketcall
5089 PRE(sys_socketcall)
5091 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5092 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5093 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5094 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5095 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5096 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5098 // call PRE_MEM_READ and check for EFAULT result.
5099 #define PRE_MEM_READ_ef(msg, arg, size) \
5101 PRE_MEM_READ( msg, arg, size); \
5102 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5103 SET_STATUS_Failure( VKI_EFAULT ); \
5104 break; \
5108 *flags |= SfMayBlock;
5109 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5110 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5112 switch (ARG1 /* request */) {
5114 case VKI_SYS_SOCKETPAIR:
5115 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5116 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5117 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5118 break;
5120 case VKI_SYS_SOCKET:
5121 /* int socket(int domain, int type, int protocol); */
5122 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5123 break;
5125 case VKI_SYS_BIND:
5126 /* int bind(int sockfd, struct sockaddr *my_addr,
5127 int addrlen); */
5128 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5129 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5130 break;
5132 case VKI_SYS_LISTEN:
5133 /* int listen(int s, int backlog); */
5134 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5135 break;
5137 case VKI_SYS_ACCEPT:
5138 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5139 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5140 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5141 break;
5143 case VKI_SYS_ACCEPT4:
5144 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5145 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5146 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5147 break;
5149 case VKI_SYS_SENDTO:
5150 /* int sendto(int s, const void *msg, int len,
5151 unsigned int flags,
5152 const struct sockaddr *to, int tolen); */
5153 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5154 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5155 ARG2_3, ARG2_4, ARG2_5 );
5156 break;
5158 case VKI_SYS_SEND:
5159 /* int send(int s, const void *msg, size_t len, int flags); */
5160 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5161 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5162 break;
5164 case VKI_SYS_RECVFROM:
5165 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5166 struct sockaddr *from, int *fromlen); */
5167 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5168 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5169 ARG2_3, ARG2_4, ARG2_5 );
5170 break;
5172 case VKI_SYS_RECV:
5173 /* int recv(int s, void *buf, int len, unsigned int flags); */
5174 /* man 2 recv says:
5175 The recv call is normally used only on a connected socket
5176 (see connect(2)) and is identical to recvfrom with a NULL
5177 from parameter.
5179 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5180 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5181 break;
5183 case VKI_SYS_CONNECT:
5184 /* int connect(int sockfd,
5185 struct sockaddr *serv_addr, int addrlen ); */
5186 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5187 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5188 break;
5190 case VKI_SYS_SETSOCKOPT:
5191 /* int setsockopt(int s, int level, int optname,
5192 const void *optval, int optlen); */
5193 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5194 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5195 ARG2_3, ARG2_4 );
5196 break;
5198 case VKI_SYS_GETSOCKOPT:
5199 /* int getsockopt(int s, int level, int optname,
5200 void *optval, socklen_t *optlen); */
5201 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5202 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5203 ARG2_3, ARG2_4 );
5204 break;
5206 case VKI_SYS_GETSOCKNAME:
5207 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5208 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5209 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5210 break;
5212 case VKI_SYS_GETPEERNAME:
5213 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5214 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5215 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5216 break;
5218 case VKI_SYS_SHUTDOWN:
5219 /* int shutdown(int s, int how); */
5220 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5221 break;
5223 case VKI_SYS_SENDMSG:
5224 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5225 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5226 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5227 (struct vki_msghdr *)(Addr)ARG2_1 );
5228 break;
5230 case VKI_SYS_RECVMSG:
5231 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5232 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5233 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5234 (struct vki_msghdr *)(Addr)ARG2_1 );
5235 break;
5237 case VKI_SYS_RECVMMSG:
5238 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5239 struct timespec *timeout); */
5240 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5241 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5242 ARG2_4 );
5243 break;
5245 case VKI_SYS_SENDMMSG:
5246 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5247 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5248 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5249 break;
5251 default:
5252 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5253 SET_STATUS_Failure( VKI_EINVAL );
5254 break;
5256 # undef ARG2_0
5257 # undef ARG2_1
5258 # undef ARG2_2
5259 # undef ARG2_3
5260 # undef ARG2_4
5261 # undef ARG2_5
5264 POST(sys_socketcall)
5266 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5267 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5268 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5269 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5270 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5271 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5273 SysRes r;
5274 vg_assert(SUCCESS);
5275 switch (ARG1 /* request */) {
5277 case VKI_SYS_SOCKETPAIR:
5278 r = ML_(generic_POST_sys_socketpair)(
5279 tid, VG_(mk_SysRes_Success)(RES),
5280 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5282 SET_STATUS_from_SysRes(r);
5283 break;
5285 case VKI_SYS_SOCKET:
5286 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5287 SET_STATUS_from_SysRes(r);
5288 break;
5290 case VKI_SYS_BIND:
5291 /* int bind(int sockfd, struct sockaddr *my_addr,
5292 int addrlen); */
5293 break;
5295 case VKI_SYS_LISTEN:
5296 /* int listen(int s, int backlog); */
5297 break;
5299 case VKI_SYS_ACCEPT:
5300 case VKI_SYS_ACCEPT4:
5301 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5302 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5303 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5304 ARG2_0, ARG2_1, ARG2_2 );
5305 SET_STATUS_from_SysRes(r);
5306 break;
5308 case VKI_SYS_SENDTO:
5309 break;
5311 case VKI_SYS_SEND:
5312 break;
5314 case VKI_SYS_RECVFROM:
5315 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5316 ARG2_0, ARG2_1, ARG2_2,
5317 ARG2_3, ARG2_4, ARG2_5 );
5318 break;
5320 case VKI_SYS_RECV:
5321 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5322 break;
5324 case VKI_SYS_CONNECT:
5325 break;
5327 case VKI_SYS_SETSOCKOPT:
5328 break;
5330 case VKI_SYS_GETSOCKOPT:
5331 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5332 ARG2_0, ARG2_1,
5333 ARG2_2, ARG2_3, ARG2_4 );
5334 break;
5336 case VKI_SYS_GETSOCKNAME:
5337 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5338 ARG2_0, ARG2_1, ARG2_2 );
5339 break;
5341 case VKI_SYS_GETPEERNAME:
5342 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5343 ARG2_0, ARG2_1, ARG2_2 );
5344 break;
5346 case VKI_SYS_SHUTDOWN:
5347 break;
5349 case VKI_SYS_SENDMSG:
5350 break;
5352 case VKI_SYS_RECVMSG:
5353 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5354 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5355 break;
5357 case VKI_SYS_RECVMMSG:
5358 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5359 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5360 break;
5362 case VKI_SYS_SENDMMSG:
5363 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5364 break;
5366 default:
5367 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5368 VG_(core_panic)("... bye!\n");
5369 break; /*NOTREACHED*/
5371 # undef ARG2_0
5372 # undef ARG2_1
5373 # undef ARG2_2
5374 # undef ARG2_3
5375 # undef ARG2_4
5376 # undef ARG2_5
5378 #endif
5380 PRE(sys_socket)
5382 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5383 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5385 POST(sys_socket)
5387 SysRes r;
5388 vg_assert(SUCCESS);
5389 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5390 SET_STATUS_from_SysRes(r);
5393 PRE(sys_setsockopt)
5395 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5396 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5397 PRE_REG_READ5(long, "setsockopt",
5398 int, s, int, level, int, optname,
5399 const void *, optval, unsigned, optlen); // socklen_t
5400 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5403 PRE(sys_getsockopt)
5405 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5406 SARG1, SARG2, SARG3, ARG4, SARG5);
5407 PRE_REG_READ5(long, "getsockopt",
5408 int, s, int, level, int, optname,
5409 void *, optval, int, *optlen);
5410 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5412 POST(sys_getsockopt)
5414 vg_assert(SUCCESS);
5415 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5416 ARG1,ARG2,ARG3,ARG4,ARG5);
5419 PRE(sys_connect)
5421 *flags |= SfMayBlock;
5422 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5423 PRE_REG_READ3(long, "connect",
5424 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5425 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5428 PRE(sys_accept)
5430 *flags |= SfMayBlock;
5431 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5432 SARG1, ARG2, ARG3);
5433 PRE_REG_READ3(long, "accept",
5434 int, s, struct sockaddr *, addr, int *, addrlen);
5435 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5437 POST(sys_accept)
5439 SysRes r;
5440 vg_assert(SUCCESS);
5441 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5442 ARG1,ARG2,ARG3);
5443 SET_STATUS_from_SysRes(r);
5446 PRE(sys_accept4)
5448 *flags |= SfMayBlock;
5449 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5450 SARG1, ARG2, ARG3, SARG4);
5451 PRE_REG_READ4(long, "accept4",
5452 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5453 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5455 POST(sys_accept4)
5457 SysRes r;
5458 vg_assert(SUCCESS);
5459 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5460 ARG1,ARG2,ARG3);
5461 SET_STATUS_from_SysRes(r);
5464 PRE(sys_send)
5466 *flags |= SfMayBlock;
5467 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5468 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5469 PRE_REG_READ4(long, "send",
5470 int, s, const void *, msg, vki_size_t, len,
5471 int, flags);
5473 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5476 PRE(sys_sendto)
5478 *flags |= SfMayBlock;
5479 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5480 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5481 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5482 PRE_REG_READ6(long, "sendto",
5483 int, s, const void *, msg, vki_size_t, len,
5484 unsigned int, flags,
5485 const struct sockaddr *, to, int, tolen);
5486 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5489 PRE (sys_recv)
5491 *flags |= SfMayBlock;
5492 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5493 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5494 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5495 unsigned int, flags);
5496 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5499 POST (sys_recv)
5501 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5504 PRE(sys_recvfrom)
5506 *flags |= SfMayBlock;
5507 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5508 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5509 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5510 PRE_REG_READ6(long, "recvfrom",
5511 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5512 struct sockaddr *, from, int *, fromlen);
5513 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5515 POST(sys_recvfrom)
5517 vg_assert(SUCCESS);
5518 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5519 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5522 PRE(sys_sendmsg)
5524 *flags |= SfMayBlock;
5525 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5526 SARG1, ARG2, ARG3);
5527 PRE_REG_READ3(long, "sendmsg",
5528 int, s, const struct msghdr *, msg, unsigned int, flags);
5529 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5532 PRE(sys_recvmsg)
5534 *flags |= SfMayBlock;
5535 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5536 SARG1, ARG2, ARG3);
5537 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5538 unsigned int, flags);
5539 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5541 POST(sys_recvmsg)
5543 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5544 RES);
5547 PRE(sys_shutdown)
5549 *flags |= SfMayBlock;
5550 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5551 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5554 PRE(sys_bind)
5556 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5557 PRE_REG_READ3(long, "bind",
5558 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5559 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5562 PRE(sys_listen)
5564 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5565 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5568 PRE(sys_getsockname)
5570 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5571 SARG1, ARG2, ARG3);
5572 PRE_REG_READ3(long, "getsockname",
5573 int, s, struct sockaddr *, name, int *, namelen);
5574 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5576 POST(sys_getsockname)
5578 vg_assert(SUCCESS);
5579 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5580 ARG1,ARG2,ARG3);
5583 PRE(sys_getpeername)
5585 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5586 SARG1, ARG2, ARG3);
5587 PRE_REG_READ3(long, "getpeername",
5588 int, s, struct sockaddr *, name, int *, namelen);
5589 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5591 POST(sys_getpeername)
5593 vg_assert(SUCCESS);
5594 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5595 ARG1,ARG2,ARG3);
5598 PRE(sys_socketpair)
5600 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5601 SARG3, ARG4);
5602 PRE_REG_READ4(long, "socketpair",
5603 int, d, int, type, int, protocol, int*, sv);
5604 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5606 POST(sys_socketpair)
5608 vg_assert(SUCCESS);
5609 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5610 ARG1,ARG2,ARG3,ARG4);
5614 /* ---------------------------------------------------------------------
5615 *at wrappers
5616 ------------------------------------------------------------------ */
5618 PRE(sys_openat)
5620 HChar name[30]; // large enough
5621 SysRes sres;
5623 if (ARG3 & VKI_O_CREAT) {
5624 // 4-arg version
5625 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5626 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5627 PRE_REG_READ4(long, "openat",
5628 int, dfd, const char *, filename, int, flags, int, mode);
5629 } else {
5630 // 3-arg version
5631 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5632 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5633 PRE_REG_READ3(long, "openat",
5634 int, dfd, const char *, filename, int, flags);
5637 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5639 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5640 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5641 be sure only to compare the bottom 32 bits. */
5642 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5643 && *(Char *)(Addr)ARG2 != '/'
5644 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5645 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5646 SET_STATUS_Failure( VKI_EBADF );
5648 /* Handle the case where the open is of /proc/self/cmdline or
5649 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5650 fake file we cooked up at startup (in m_main). Also, seek the
5651 cloned fd back to the start. */
5653 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5654 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5655 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5656 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5657 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5658 SET_STATUS_from_SysRes( sres );
5659 if (!sr_isError(sres)) {
5660 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5661 if (off < 0)
5662 SET_STATUS_Failure( VKI_EMFILE );
5664 return;
5667 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5669 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5670 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5671 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5672 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5673 sres = VG_(dup)( VG_(cl_auxv_fd) );
5674 SET_STATUS_from_SysRes( sres );
5675 if (!sr_isError(sres)) {
5676 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5677 if (off < 0)
5678 SET_STATUS_Failure( VKI_EMFILE );
5680 return;
5683 /* Otherwise handle normally */
5684 *flags |= SfMayBlock;
5687 POST(sys_openat)
5689 vg_assert(SUCCESS);
5690 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5691 VG_(close)(RES);
5692 SET_STATUS_Failure( VKI_EMFILE );
5693 } else {
5694 if (VG_(clo_track_fds))
5695 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5699 PRE(sys_mkdirat)
5701 *flags |= SfMayBlock;
5702 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5703 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5704 PRE_REG_READ3(long, "mkdirat",
5705 int, dfd, const char *, pathname, int, mode);
5706 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5709 PRE(sys_mknodat)
5711 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5712 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5713 PRE_REG_READ4(long, "mknodat",
5714 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5715 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5718 PRE(sys_fchownat)
5720 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5721 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5722 PRE_REG_READ4(long, "fchownat",
5723 int, dfd, const char *, path,
5724 vki_uid_t, owner, vki_gid_t, group);
5725 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5728 PRE(sys_futimesat)
5730 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5731 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5732 PRE_REG_READ3(long, "futimesat",
5733 int, dfd, char *, filename, struct timeval *, tvp);
5734 if (ARG2 != 0)
5735 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5736 if (ARG3 != 0)
5737 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5740 PRE(sys_utimensat)
5742 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5743 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5744 PRE_REG_READ4(long, "utimensat",
5745 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5746 if (ARG2 != 0)
5747 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5748 if (ARG3 != 0) {
5749 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5750 then the tv_sec field is ignored. */
5751 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5752 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5753 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5754 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5755 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5756 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5757 if (times[0].tv_nsec != VKI_UTIME_NOW
5758 && times[0].tv_nsec != VKI_UTIME_OMIT)
5759 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5760 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5761 if (times[1].tv_nsec != VKI_UTIME_NOW
5762 && times[1].tv_nsec != VKI_UTIME_OMIT)
5763 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5764 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5769 PRE(sys_utimensat_time64)
5771 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5772 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5773 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5774 PRE_REG_READ4(long, "utimensat_time64",
5775 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5776 if (ARG2 != 0)
5777 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5778 if (ARG3 != 0) {
5779 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5780 then the tv_sec field is ignored. */
5781 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5782 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5783 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5784 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5785 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5786 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5787 if (times[0].tv_nsec != VKI_UTIME_NOW
5788 && times[0].tv_nsec != VKI_UTIME_OMIT)
5789 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5790 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5791 if (times[1].tv_nsec != VKI_UTIME_NOW
5792 && times[1].tv_nsec != VKI_UTIME_OMIT)
5793 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5794 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5799 #if !defined(VGP_nanomips_linux)
5800 PRE(sys_newfstatat)
5802 FUSE_COMPATIBLE_MAY_BLOCK();
5803 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5804 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5805 PRE_REG_READ3(long, "fstatat",
5806 int, dfd, char *, file_name, struct stat *, buf);
5807 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5808 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5811 POST(sys_newfstatat)
5813 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5815 #endif
5817 PRE(sys_unlinkat)
5819 *flags |= SfMayBlock;
5820 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5821 (HChar*)(Addr)ARG2);
5822 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5823 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5826 PRE(sys_renameat)
5828 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5829 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5830 ARG4, (HChar*)(Addr)ARG4);
5831 PRE_REG_READ4(long, "renameat",
5832 int, olddfd, const char *, oldpath,
5833 int, newdfd, const char *, newpath);
5834 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5835 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5838 PRE(sys_renameat2)
5840 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5841 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5842 ARG4, (HChar*)(Addr)ARG4, ARG5);
5843 PRE_REG_READ5(long, "renameat2",
5844 int, olddfd, const char *, oldpath,
5845 int, newdfd, const char *, newpath,
5846 unsigned int, flags);
5847 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5848 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5851 PRE(sys_linkat)
5853 *flags |= SfMayBlock;
5854 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5855 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5856 (HChar*)(Addr)ARG4, SARG5);
5857 PRE_REG_READ5(long, "linkat",
5858 int, olddfd, const char *, oldpath,
5859 int, newdfd, const char *, newpath,
5860 int, flags);
5861 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5862 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5865 PRE(sys_symlinkat)
5867 *flags |= SfMayBlock;
5868 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5869 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5870 PRE_REG_READ3(long, "symlinkat",
5871 const char *, oldpath, int, newdfd, const char *, newpath);
5872 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5873 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5876 PRE(sys_readlinkat)
5878 HChar name[30]; // large enough
5879 Word saved = SYSNO;
5881 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5882 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5883 PRE_REG_READ4(long, "readlinkat",
5884 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5885 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5886 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5889 * Handle the case where readlinkat is looking at /proc/self/exe or
5890 * /proc/<pid>/exe.
5892 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5893 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5894 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5895 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5896 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5897 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5898 ARG3, ARG4));
5899 } else {
5900 /* Normal case */
5901 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5904 if (SUCCESS && RES > 0)
5905 POST_MEM_WRITE( ARG3, RES );
5908 PRE(sys_fchmodat)
5910 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5911 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5912 PRE_REG_READ3(long, "fchmodat",
5913 int, dfd, const char *, path, vki_mode_t, mode);
5914 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5917 PRE(sys_faccessat)
5919 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5920 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5921 PRE_REG_READ3(long, "faccessat",
5922 int, dfd, const char *, pathname, int, mode);
5923 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5926 PRE(sys_name_to_handle_at)
5928 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
5929 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
5930 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5931 PRE_REG_READ5(int, "name_to_handle_at",
5932 int, dfd, const char *, name,
5933 struct vki_file_handle *, handle,
5934 int *, mnt_id, int, flag);
5935 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5936 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
5937 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5938 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5939 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5941 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5944 POST(sys_name_to_handle_at)
5946 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5947 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5948 POST_MEM_WRITE( ARG4, sizeof(int) );
5951 PRE(sys_open_by_handle_at)
5953 *flags |= SfMayBlock;
5954 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
5955 ARG2, SARG3);
5956 PRE_REG_READ3(int, "open_by_handle_at",
5957 int, mountdirfd,
5958 struct vki_file_handle *, handle,
5959 int, flags);
5960 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
5961 sizeof(struct vki_file_handle) +
5962 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
5965 POST(sys_open_by_handle_at)
5967 vg_assert(SUCCESS);
5968 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5969 VG_(close)(RES);
5970 SET_STATUS_Failure( VKI_EMFILE );
5971 } else {
5972 if (VG_(clo_track_fds))
5973 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5977 /* ---------------------------------------------------------------------
5978 p{read,write}v wrappers
5979 ------------------------------------------------------------------ */
5980 /* This handles the common part of the PRE macro for preadv and preadv2. */
5981 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
5982 Int fd, Addr vector, Int count, const char *str)
5984 struct vki_iovec * vec;
5985 Int i;
5986 /* safe size for the "preadv/preadv2(vector[i])" string */
5987 char tmp[30];
5989 if (!ML_(fd_allowed)(fd, str, tid, False)) {
5990 SET_STATUS_Failure( VKI_EBADF );
5991 } else if (count > 0) {
5992 VG_(strcpy) (tmp, str);
5993 VG_(strcat) (tmp, "(vector)");
5994 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
5996 if (ML_(safe_to_deref) ((void *)(Addr)vector,
5997 count * sizeof(struct vki_iovec))) {
5998 vec = (struct vki_iovec *)(Addr)vector;
5999 for (i = 0; i < count; i++) {
6000 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6001 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6007 /* This handles the common part of the POST macro for preadv and preadv2. */
6008 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6010 vg_assert(SUCCESS);
6011 if (RES > 0) {
6012 Int i;
6013 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6014 Int remains = RES;
6016 /* RES holds the number of bytes read. */
6017 for (i = 0; i < count; i++) {
6018 Int nReadThisBuf = vec[i].iov_len;
6019 if (nReadThisBuf > remains) nReadThisBuf = remains;
6020 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6021 remains -= nReadThisBuf;
6022 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6027 PRE(sys_preadv)
6029 *flags |= SfMayBlock;
6030 const char *str = "preadv";
6031 #if VG_WORDSIZE == 4
6032 /* Note that the offset argument here is in lo+hi order on both
6033 big and little endian platforms... */
6034 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6035 "u, %lld )",
6036 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6037 PRE_REG_READ5(ssize_t, "preadv",
6038 unsigned long, fd, const struct iovec *, vector,
6039 unsigned long, count, vki_u32, offset_low,
6040 vki_u32, offset_high);
6041 #elif VG_WORDSIZE == 8
6042 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6043 PRE_REG_READ4(ssize_t, "preadv",
6044 unsigned long, fd, const struct iovec *, vector,
6045 unsigned long, count, Word, offset);
6046 #else
6047 # error Unexpected word size
6048 #endif
6049 Int fd = ARG1;
6050 Addr vector = ARG2;
6051 Int count = ARG3;
6053 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6057 POST(sys_preadv)
6059 Addr vector = ARG2;
6060 Int count = ARG3;
6062 handle_post_sys_preadv(tid, status, vector, count);
6065 PRE(sys_preadv2)
6067 *flags |= SfMayBlock;
6068 const char *str = "preadv2";
6069 #if VG_WORDSIZE == 4
6070 /* Note that the offset argument here is in lo+hi order on both
6071 big and little endian platforms... */
6072 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6073 "u, %lld, %" FMT_REGWORD "u )",
6074 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6075 PRE_REG_READ6(ssize_t, "preadv2",
6076 unsigned long, fd, const struct iovec *, vector,
6077 unsigned long, count, vki_u32, offset_low,
6078 vki_u32, offset_high, unsigned long, flags);
6079 #elif VG_WORDSIZE == 8
6080 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6081 PRE_REG_READ5(ssize_t, "preadv2",
6082 unsigned long, fd, const struct iovec *, vector,
6083 unsigned long, count, Word, offset, unsigned long, flags);
6084 #else
6085 # error Unexpected word size
6086 #endif
6087 Int fd = ARG1;
6088 Addr vector = ARG2;
6089 Int count = ARG3;
6091 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6094 POST(sys_preadv2)
6096 Addr vector = ARG2;
6097 Int count = ARG3;
6099 handle_post_sys_preadv(tid, status, vector, count);
6102 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6103 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6104 Int fd, Addr vector, Int count, const char *str)
6106 Int i;
6107 struct vki_iovec * vec;
6108 /* safe size for the "preadv/preadv2(vector[i])" string */
6109 char tmp[30];
6111 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6112 SET_STATUS_Failure( VKI_EBADF );
6113 } else if (count > 0) {
6114 VG_(strcpy) (tmp, str);
6115 VG_(strcat) (tmp, "(vector)");
6116 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6117 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6118 count * sizeof(struct vki_iovec))) {
6119 vec = (struct vki_iovec *)(Addr)vector;
6120 for (i = 0; i < count; i++) {
6121 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6122 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6128 PRE(sys_pwritev)
6130 *flags |= SfMayBlock;
6131 const char *str = "pwritev";
6132 #if VG_WORDSIZE == 4
6133 /* Note that the offset argument here is in lo+hi order on both
6134 big and little endian platforms... */
6135 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6136 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6137 PRE_REG_READ5(ssize_t, "pwritev",
6138 unsigned long, fd, const struct iovec *, vector,
6139 unsigned long, count, vki_u32, offset_low,
6140 vki_u32, offset_high);
6141 #elif VG_WORDSIZE == 8
6142 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6143 PRE_REG_READ4(ssize_t, "pwritev",
6144 unsigned long, fd, const struct iovec *, vector,
6145 unsigned long, count, Word, offset);
6146 #else
6147 # error Unexpected word size
6148 #endif
6149 Int fd = ARG1;
6150 Addr vector = ARG2;
6151 Int count = ARG3;
6153 handle_sys_pwritev(tid, status, fd, vector, count, str);
6156 PRE(sys_pwritev2)
6158 *flags |= SfMayBlock;
6159 const char *str = "pwritev2";
6160 #if VG_WORDSIZE == 4
6161 /* Note that the offset argument here is in lo+hi order on both
6162 big and little endian platforms... */
6163 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6164 "u, %lld, %" FMT_REGWORD "u )",
6165 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6166 PRE_REG_READ6(ssize_t, "pwritev2",
6167 unsigned long, fd, const struct iovec *, vector,
6168 unsigned long, count, vki_u32, offset_low,
6169 vki_u32, offset_high, unsigned long, flags);
6170 #elif VG_WORDSIZE == 8
6171 /* Note offset_high isn't actually used? */
6172 PRE_REG_READ6(ssize_t, "pwritev2",
6173 unsigned long, fd, const struct iovec *, vector,
6174 unsigned long, count, Word, offset,
6175 Word, offset_high, unsigned long, flags);
6176 #else
6177 # error Unexpected word size
6178 #endif
6179 Int fd = ARG1;
6180 Addr vector = ARG2;
6181 Int count = ARG3;
6183 handle_sys_pwritev(tid, status, fd, vector, count, str);
6186 /* ---------------------------------------------------------------------
6187 process_vm_{read,write}v wrappers
6188 ------------------------------------------------------------------ */
6190 PRE(sys_process_vm_readv)
6192 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6193 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6194 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6195 PRE_REG_READ6(ssize_t, "process_vm_readv",
6196 vki_pid_t, pid,
6197 const struct iovec *, lvec,
6198 unsigned long, liovcnt,
6199 const struct iovec *, rvec,
6200 unsigned long, riovcnt,
6201 unsigned long, flags);
6202 PRE_MEM_READ( "process_vm_readv(lvec)",
6203 ARG2, ARG3 * sizeof(struct vki_iovec) );
6204 PRE_MEM_READ( "process_vm_readv(rvec)",
6205 ARG4, ARG5 * sizeof(struct vki_iovec) );
6206 if (ARG2 != 0
6207 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6208 sizeof(struct vki_iovec) * ARG3)) {
6209 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6210 UInt i;
6211 for (i = 0; i < ARG3; i++)
6212 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6213 (Addr)vec[i].iov_base, vec[i].iov_len );
6217 POST(sys_process_vm_readv)
6219 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6220 UInt remains = RES;
6221 UInt i;
6222 for (i = 0; i < ARG3; i++) {
6223 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6224 vec[i].iov_len : remains;
6225 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6226 remains -= nReadThisBuf;
6230 PRE(sys_process_vm_writev)
6232 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6233 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6234 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6235 PRE_REG_READ6(ssize_t, "process_vm_writev",
6236 vki_pid_t, pid,
6237 const struct iovec *, lvec,
6238 unsigned long, liovcnt,
6239 const struct iovec *, rvec,
6240 unsigned long, riovcnt,
6241 unsigned long, flags);
6242 PRE_MEM_READ( "process_vm_writev(lvec)",
6243 ARG2, ARG3 * sizeof(struct vki_iovec) );
6244 PRE_MEM_READ( "process_vm_writev(rvec)",
6245 ARG4, ARG5 * sizeof(struct vki_iovec) );
6246 if (ARG2 != 0
6247 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6248 sizeof(struct vki_iovec) * ARG3)) {
6249 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6250 UInt i;
6251 for (i = 0; i < ARG3; i++)
6252 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6253 (Addr)vec[i].iov_base, vec[i].iov_len );
6257 /* ---------------------------------------------------------------------
6258 {send,recv}mmsg wrappers
6259 ------------------------------------------------------------------ */
6261 PRE(sys_sendmmsg)
6263 *flags |= SfMayBlock;
6264 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6265 SARG3, SARG4);
6266 PRE_REG_READ4(long, "sendmmsg",
6267 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6268 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6271 POST(sys_sendmmsg)
6273 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6276 PRE(sys_recvmmsg)
6278 *flags |= SfMayBlock;
6279 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6280 FMT_REGWORD "x )",
6281 SARG1, ARG2, SARG3, SARG4, ARG5);
6282 PRE_REG_READ5(long, "recvmmsg",
6283 int, s, struct mmsghdr *, mmsg, int, vlen,
6284 int, flags, struct timespec *, timeout);
6285 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6288 POST(sys_recvmmsg)
6290 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6293 PRE(sys_recvmmsg_time64)
6295 *flags |= SfMayBlock;
6296 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6297 FMT_REGWORD "x )",
6298 SARG1, ARG2, SARG3, SARG4, ARG5);
6299 PRE_REG_READ5(long, "recvmmsg_time64",
6300 int, s, struct mmsghdr *, mmsg, int, vlen,
6301 int, flags, struct vki_timespec64 *, timeout);
6302 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6303 HChar name[40]; // large enough
6304 UInt i;
6305 for (i = 0; i < ARG3; i++) {
6306 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6307 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6308 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6309 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6311 if (ARG5)
6312 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6315 POST(sys_recvmmsg_time64)
6317 /* ARG5 isn't actually used, so just use the generic POST. */
6318 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6321 /* ---------------------------------------------------------------------
6322 key retention service wrappers
6323 ------------------------------------------------------------------ */
6325 PRE(sys_request_key)
6327 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6328 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6329 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6330 PRE_REG_READ4(long, "request_key",
6331 const char *, type, const char *, description,
6332 const char *, callout_info, vki_key_serial_t, keyring);
6333 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6334 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6335 if (ARG3 != (UWord)NULL)
6336 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6339 PRE(sys_add_key)
6341 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6342 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6343 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6344 PRE_REG_READ5(long, "add_key",
6345 const char *, type, const char *, description,
6346 const void *, payload, vki_size_t, plen,
6347 vki_key_serial_t, keyring);
6348 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6349 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6350 if (ARG3 != (UWord)NULL)
6351 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6354 PRE(sys_keyctl)
6356 switch (ARG1 /* option */) {
6357 case VKI_KEYCTL_GET_KEYRING_ID:
6358 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6359 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6360 int, option, vki_key_serial_t, id, int, create);
6361 break;
6362 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6363 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6364 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6365 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6366 int, option, const char *, name);
6367 if (ARG2 != (UWord)NULL)
6368 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6369 break;
6370 case VKI_KEYCTL_UPDATE:
6371 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6372 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6373 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6374 int, option, vki_key_serial_t, key,
6375 const void *, payload, vki_size_t, plen);
6376 if (ARG3 != (UWord)NULL)
6377 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6378 break;
6379 case VKI_KEYCTL_REVOKE:
6380 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6381 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6382 int, option, vki_key_serial_t, id);
6383 break;
6384 case VKI_KEYCTL_CHOWN:
6385 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6386 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6387 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6388 int, option, vki_key_serial_t, id,
6389 vki_uid_t, uid, vki_gid_t, gid);
6390 break;
6391 case VKI_KEYCTL_SETPERM:
6392 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6393 SARG2, ARG3);
6394 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6395 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6396 break;
6397 case VKI_KEYCTL_DESCRIBE:
6398 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6399 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6400 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6401 int, option, vki_key_serial_t, id,
6402 char *, buffer, vki_size_t, buflen);
6403 if (ARG3 != (UWord)NULL)
6404 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6405 break;
6406 case VKI_KEYCTL_CLEAR:
6407 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6408 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6409 int, option, vki_key_serial_t, keyring);
6410 break;
6411 case VKI_KEYCTL_LINK:
6412 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6413 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6414 vki_key_serial_t, keyring, vki_key_serial_t, key);
6415 break;
6416 case VKI_KEYCTL_UNLINK:
6417 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6418 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6419 vki_key_serial_t, keyring, vki_key_serial_t, key);
6420 break;
6421 case VKI_KEYCTL_SEARCH:
6422 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6423 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6424 ARG4, (HChar*)(Addr)ARG4, SARG5);
6425 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6426 int, option, vki_key_serial_t, keyring,
6427 const char *, type, const char *, description,
6428 vki_key_serial_t, destring);
6429 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6430 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6431 break;
6432 case VKI_KEYCTL_READ:
6433 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6434 "u )", SARG2, ARG3, ARG4);
6435 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6436 int, option, vki_key_serial_t, keyring,
6437 char *, buffer, vki_size_t, buflen);
6438 if (ARG3 != (UWord)NULL)
6439 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6440 break;
6441 case VKI_KEYCTL_INSTANTIATE:
6442 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6443 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6444 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6445 int, option, vki_key_serial_t, key,
6446 char *, payload, vki_size_t, plen,
6447 vki_key_serial_t, keyring);
6448 if (ARG3 != (UWord)NULL)
6449 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6450 break;
6451 case VKI_KEYCTL_NEGATE:
6452 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6453 SARG2, ARG3, SARG4);
6454 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6455 int, option, vki_key_serial_t, key,
6456 unsigned, timeout, vki_key_serial_t, keyring);
6457 break;
6458 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6459 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6460 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6461 int, option, int, reqkey_defl);
6462 break;
6463 case VKI_KEYCTL_SET_TIMEOUT:
6464 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6465 SARG2, ARG3);
6466 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6467 int, option, vki_key_serial_t, key, unsigned, timeout);
6468 break;
6469 case VKI_KEYCTL_ASSUME_AUTHORITY:
6470 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6471 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6472 int, option, vki_key_serial_t, key);
6473 break;
6474 default:
6475 PRINT("sys_keyctl ( %ld ) ", SARG1);
6476 PRE_REG_READ1(long, "keyctl", int, option);
6477 break;
6481 POST(sys_keyctl)
6483 vg_assert(SUCCESS);
6484 switch (ARG1 /* option */) {
6485 case VKI_KEYCTL_DESCRIBE:
6486 case VKI_KEYCTL_READ:
6487 if (RES > ARG4)
6488 POST_MEM_WRITE(ARG3, ARG4);
6489 else
6490 POST_MEM_WRITE(ARG3, RES);
6491 break;
6492 default:
6493 break;
6497 /* ---------------------------------------------------------------------
6498 ioprio_ wrappers
6499 ------------------------------------------------------------------ */
6501 PRE(sys_ioprio_set)
6503 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6504 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6507 PRE(sys_ioprio_get)
6509 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6510 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6513 /* ---------------------------------------------------------------------
6514 _module wrappers
6515 ------------------------------------------------------------------ */
6517 PRE(sys_init_module)
6519 *flags |= SfMayBlock;
6520 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6521 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6522 PRE_REG_READ3(long, "init_module",
6523 void *, umod, unsigned long, len, const char *, uargs);
6524 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6525 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6528 PRE(sys_finit_module)
6530 *flags |= SfMayBlock;
6532 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6533 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6534 PRE_REG_READ3(long, "finit_module",
6535 int, fd, const char *, params, int, flags);
6536 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6539 PRE(sys_delete_module)
6541 *flags |= SfMayBlock;
6542 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6543 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6544 PRE_REG_READ2(long, "delete_module",
6545 const char *, name_user, unsigned int, flags);
6546 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6549 /* ---------------------------------------------------------------------
6550 splice wrappers
6551 ------------------------------------------------------------------ */
6553 PRE(sys_splice)
6555 *flags |= SfMayBlock;
6556 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6557 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6558 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6559 PRE_REG_READ6(vki_ssize_t, "splice",
6560 int, fd_in, vki_loff_t *, off_in,
6561 int, fd_out, vki_loff_t *, off_out,
6562 vki_size_t, len, unsigned int, flags);
6563 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6564 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6565 SET_STATUS_Failure( VKI_EBADF );
6566 } else {
6567 if (ARG2 != 0)
6568 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6569 if (ARG4 != 0)
6570 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6574 PRE(sys_tee)
6576 *flags |= SfMayBlock;
6577 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6578 SARG1, SARG2, ARG3, ARG4);
6579 PRE_REG_READ4(vki_ssize_t, "tee",
6580 int, fd_in, int, fd_out,
6581 vki_size_t, len, unsigned int, flags);
6582 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6583 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6584 SET_STATUS_Failure( VKI_EBADF );
6588 PRE(sys_vmsplice)
6590 Int fdfl;
6591 *flags |= SfMayBlock;
6592 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6593 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6594 PRE_REG_READ4(vki_ssize_t, "splice",
6595 int, fd, struct vki_iovec *, iov,
6596 unsigned long, nr_segs, unsigned int, flags);
6597 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6598 SET_STATUS_Failure( VKI_EBADF );
6599 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6600 SET_STATUS_Failure( VKI_EBADF );
6601 } else {
6602 const struct vki_iovec *iov;
6603 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6604 for (iov = (struct vki_iovec *)(Addr)ARG2;
6605 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6607 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6608 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6609 PRE_MEM_WRITE( "vmsplice(iov[...])",
6610 (Addr)iov->iov_base, iov->iov_len );
6611 else
6612 PRE_MEM_READ( "vmsplice(iov[...])",
6613 (Addr)iov->iov_base, iov->iov_len );
6619 POST(sys_vmsplice)
6621 vg_assert(SUCCESS);
6622 if (RES > 0) {
6623 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6624 vg_assert(fdfl >= 0);
6625 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6627 const struct vki_iovec *iov;
6628 for (iov = (struct vki_iovec *)(Addr)ARG2;
6629 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6631 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6637 /* ---------------------------------------------------------------------
6638 oprofile-related wrappers
6639 ------------------------------------------------------------------ */
6641 #if defined(VGP_x86_linux)
6642 PRE(sys_lookup_dcookie)
6644 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6645 MERGE64(ARG1,ARG2), ARG3, ARG4);
6646 PRE_REG_READ4(long, "lookup_dcookie",
6647 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6648 char *, buf, vki_size_t, len);
6649 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6651 POST(sys_lookup_dcookie)
6653 vg_assert(SUCCESS);
6654 if (ARG3 != (Addr)NULL)
6655 POST_MEM_WRITE( ARG3, RES);
6657 #endif
6659 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6660 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6661 PRE(sys_lookup_dcookie)
6663 *flags |= SfMayBlock;
6664 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6665 PRE_REG_READ3(int, "lookup_dcookie",
6666 unsigned long long, cookie, char *, buf, vki_size_t, len);
6668 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6671 POST(sys_lookup_dcookie)
6673 vg_assert(SUCCESS);
6674 if (ARG2 != (Addr)NULL)
6675 POST_MEM_WRITE( ARG2, RES );
6677 #endif
6679 /* ---------------------------------------------------------------------
6680 fcntl wrappers
6681 ------------------------------------------------------------------ */
6683 PRE(sys_fcntl)
6685 switch (ARG2) {
6686 // These ones ignore ARG3.
6687 case VKI_F_GETFD:
6688 case VKI_F_GETFL:
6689 case VKI_F_GETOWN:
6690 case VKI_F_GETSIG:
6691 case VKI_F_GETLEASE:
6692 case VKI_F_GETPIPE_SZ:
6693 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6694 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6695 break;
6697 // These ones use ARG3 as "arg".
6698 case VKI_F_DUPFD:
6699 case VKI_F_DUPFD_CLOEXEC:
6700 case VKI_F_SETFD:
6701 case VKI_F_SETFL:
6702 case VKI_F_SETLEASE:
6703 case VKI_F_NOTIFY:
6704 case VKI_F_SETOWN:
6705 case VKI_F_SETSIG:
6706 case VKI_F_SETPIPE_SZ:
6707 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6708 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6709 PRE_REG_READ3(long, "fcntl",
6710 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6711 break;
6713 // These ones use ARG3 as "lock".
6714 case VKI_F_GETLK:
6715 case VKI_F_SETLK:
6716 case VKI_F_SETLKW:
6717 case VKI_F_OFD_GETLK:
6718 case VKI_F_OFD_SETLK:
6719 case VKI_F_OFD_SETLKW:
6720 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6721 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6722 PRE_REG_READ3(long, "fcntl",
6723 unsigned int, fd, unsigned int, cmd,
6724 struct vki_flock *, lock);
6726 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6727 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6728 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6729 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6730 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6731 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6732 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6735 break;
6737 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6738 case VKI_F_GETLK64:
6739 case VKI_F_SETLK64:
6740 case VKI_F_SETLKW64:
6741 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6742 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6743 PRE_REG_READ3(long, "fcntl",
6744 unsigned int, fd, unsigned int, cmd,
6745 struct flock64 *, lock);
6747 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6748 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6749 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6750 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6751 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6752 if (ARG2 == VKI_F_GETLK64) {
6753 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6756 break;
6757 # endif
6759 case VKI_F_SETOWN_EX:
6760 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6761 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6762 PRE_REG_READ3(long, "fcntl",
6763 unsigned int, fd, unsigned int, cmd,
6764 struct vki_f_owner_ex *, arg);
6765 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6766 break;
6768 case VKI_F_GETOWN_EX:
6769 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6770 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6771 PRE_REG_READ3(long, "fcntl",
6772 unsigned int, fd, unsigned int, cmd,
6773 struct vki_f_owner_ex *, arg);
6774 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6775 break;
6777 default:
6778 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6779 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6780 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6781 ARG2);
6782 SET_STATUS_Failure( VKI_EINVAL );
6783 break;
6786 # if defined(VGP_x86_linux)
6787 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6788 # else
6789 if (ARG2 == VKI_F_SETLKW)
6790 # endif
6791 *flags |= SfMayBlock;
6794 POST(sys_fcntl)
6796 vg_assert(SUCCESS);
6797 if (ARG2 == VKI_F_DUPFD) {
6798 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6799 VG_(close)(RES);
6800 SET_STATUS_Failure( VKI_EMFILE );
6801 } else {
6802 if (VG_(clo_track_fds))
6803 ML_(record_fd_open_named)(tid, RES);
6806 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6807 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6808 VG_(close)(RES);
6809 SET_STATUS_Failure( VKI_EMFILE );
6810 } else {
6811 if (VG_(clo_track_fds))
6812 ML_(record_fd_open_named)(tid, RES);
6814 } else if (ARG2 == VKI_F_GETOWN_EX) {
6815 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6816 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6817 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6818 POST_FIELD_WRITE(lock->l_pid);
6819 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6820 } else if (ARG2 == VKI_F_GETLK64) {
6821 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6822 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6823 # endif
6827 // XXX: wrapper only suitable for 32-bit systems
6828 PRE(sys_fcntl64)
6830 switch (ARG2) {
6831 // These ones ignore ARG3.
6832 case VKI_F_GETFD:
6833 case VKI_F_GETFL:
6834 case VKI_F_GETOWN:
6835 case VKI_F_SETOWN:
6836 case VKI_F_GETSIG:
6837 case VKI_F_SETSIG:
6838 case VKI_F_GETLEASE:
6839 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6840 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6841 break;
6843 // These ones use ARG3 as "arg".
6844 case VKI_F_DUPFD:
6845 case VKI_F_DUPFD_CLOEXEC:
6846 case VKI_F_SETFD:
6847 case VKI_F_SETFL:
6848 case VKI_F_SETLEASE:
6849 case VKI_F_NOTIFY:
6850 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6851 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6852 PRE_REG_READ3(long, "fcntl64",
6853 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6854 break;
6856 // These ones use ARG3 as "lock".
6857 case VKI_F_GETLK:
6858 case VKI_F_SETLK:
6859 case VKI_F_SETLKW:
6860 # if defined(VGP_x86_linux)
6861 case VKI_F_GETLK64:
6862 case VKI_F_SETLK64:
6863 case VKI_F_SETLKW64:
6864 # endif
6865 case VKI_F_OFD_GETLK:
6866 case VKI_F_OFD_SETLK:
6867 case VKI_F_OFD_SETLKW:
6868 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6869 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6870 PRE_REG_READ3(long, "fcntl64",
6871 unsigned int, fd, unsigned int, cmd,
6872 struct flock64 *, lock);
6873 break;
6875 case VKI_F_SETOWN_EX:
6876 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6877 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6878 PRE_REG_READ3(long, "fcntl",
6879 unsigned int, fd, unsigned int, cmd,
6880 struct vki_f_owner_ex *, arg);
6881 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6882 break;
6884 case VKI_F_GETOWN_EX:
6885 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6886 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6887 PRE_REG_READ3(long, "fcntl",
6888 unsigned int, fd, unsigned int, cmd,
6889 struct vki_f_owner_ex *, arg);
6890 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6891 break;
6894 # if defined(VGP_x86_linux)
6895 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6896 # else
6897 if (ARG2 == VKI_F_SETLKW)
6898 # endif
6899 *flags |= SfMayBlock;
6902 POST(sys_fcntl64)
6904 vg_assert(SUCCESS);
6905 if (ARG2 == VKI_F_DUPFD) {
6906 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6907 VG_(close)(RES);
6908 SET_STATUS_Failure( VKI_EMFILE );
6909 } else {
6910 if (VG_(clo_track_fds))
6911 ML_(record_fd_open_named)(tid, RES);
6914 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6915 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6916 VG_(close)(RES);
6917 SET_STATUS_Failure( VKI_EMFILE );
6918 } else {
6919 if (VG_(clo_track_fds))
6920 ML_(record_fd_open_named)(tid, RES);
6922 } else if (ARG2 == VKI_F_GETOWN_EX) {
6923 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6927 /* ---------------------------------------------------------------------
6928 ioctl wrappers
6929 ------------------------------------------------------------------ */
6931 struct vg_drm_version_info {
6932 struct vki_drm_version data;
6933 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6936 PRE(sys_ioctl)
6938 *flags |= SfMayBlock;
6940 ARG2 = (UInt)ARG2;
6942 // We first handle the ones that don't use ARG3 (even as a
6943 // scalar/non-pointer argument).
6944 switch (ARG2 /* request */) {
6946 /* asm-generic/ioctls.h */
6947 case VKI_FIOCLEX:
6948 case VKI_FIONCLEX:
6949 case VKI_TIOCNOTTY:
6951 /* linux perf_event ioctls */
6952 case VKI_PERF_EVENT_IOC_ENABLE:
6953 case VKI_PERF_EVENT_IOC_DISABLE:
6955 /* linux/soundcard interface (ALSA) */
6956 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6957 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6958 case VKI_SNDRV_PCM_IOCTL_PREPARE:
6959 case VKI_SNDRV_PCM_IOCTL_RESET:
6960 case VKI_SNDRV_PCM_IOCTL_START:
6961 case VKI_SNDRV_PCM_IOCTL_DROP:
6962 case VKI_SNDRV_PCM_IOCTL_DRAIN:
6963 case VKI_SNDRV_PCM_IOCTL_RESUME:
6964 case VKI_SNDRV_PCM_IOCTL_XRUN:
6965 case VKI_SNDRV_PCM_IOCTL_UNLINK:
6966 case VKI_SNDRV_TIMER_IOCTL_START:
6967 case VKI_SNDRV_TIMER_IOCTL_STOP:
6968 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6969 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6971 /* SCSI no operand */
6972 case VKI_SCSI_IOCTL_DOORLOCK:
6973 case VKI_SCSI_IOCTL_DOORUNLOCK:
6975 /* CDROM stuff. */
6976 case VKI_CDROM_DISC_STATUS:
6977 case VKI_CDROMSTOP:
6979 /* DVD stuff */
6980 case VKI_DVD_READ_STRUCT:
6982 /* KVM ioctls that don't check for a numeric value as parameter */
6983 case VKI_KVM_S390_ENABLE_SIE:
6984 case VKI_KVM_CREATE_IRQCHIP:
6985 case VKI_KVM_S390_INITIAL_RESET:
6986 case VKI_KVM_KVMCLOCK_CTRL:
6988 /* vhost without parameter */
6989 case VKI_VHOST_SET_OWNER:
6990 case VKI_VHOST_RESET_OWNER:
6992 /* User input device creation */
6993 case VKI_UI_DEV_CREATE:
6994 case VKI_UI_DEV_DESTROY:
6996 /* InfiniBand */
6997 case VKI_IB_USER_MAD_ENABLE_PKEY:
6999 /* Lustre */
7000 case VKI_LL_IOC_GROUP_LOCK:
7001 case VKI_LL_IOC_GROUP_UNLOCK:
7003 /* V4L2 */
7004 case VKI_V4L2_LOG_STATUS:
7006 /* Mesa */
7007 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7009 /* DVB */
7010 case VKI_DMX_STOP:
7011 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7012 PRE_REG_READ2(long, "ioctl",
7013 unsigned int, fd, unsigned int, request);
7014 return;
7016 default:
7017 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7018 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7019 PRE_REG_READ3(long, "ioctl",
7020 unsigned int, fd, unsigned int, request, unsigned long, arg);
7021 break;
7024 // We now handle those that do look at ARG3 (and unknown ones fall into
7025 // this category). Nb: some of these may well belong in the
7026 // doesn't-use-ARG3 switch above.
7027 switch (ARG2 /* request */) {
7029 case VKI_ION_IOC_ALLOC: {
7030 struct vki_ion_allocation_data* data
7031 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7032 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7033 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7034 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7035 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7036 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7037 break;
7039 case VKI_ION_IOC_MAP: {
7040 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7041 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7042 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7043 break;
7045 case VKI_ION_IOC_IMPORT: {
7046 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7047 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7048 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7049 break;
7052 case VKI_SYNC_IOC_MERGE: {
7053 struct vki_sync_merge_data* data =
7054 (struct vki_sync_merge_data*)(Addr)ARG3;
7055 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7056 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7057 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7058 break;
7061 case VKI_TCSETS:
7062 case VKI_TCSETSW:
7063 case VKI_TCSETSF:
7064 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7065 break;
7066 case VKI_TCGETS:
7067 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7068 break;
7069 case VKI_TCSETA:
7070 case VKI_TCSETAW:
7071 case VKI_TCSETAF:
7072 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7073 break;
7074 case VKI_TCGETA:
7075 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7076 break;
7077 case VKI_TCSBRK:
7078 case VKI_TCXONC:
7079 case VKI_TCSBRKP:
7080 case VKI_TCFLSH:
7081 case VKI_TIOCSIG:
7082 /* These just take an int by value */
7083 break;
7084 case VKI_TIOCGWINSZ:
7085 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7086 break;
7087 case VKI_TIOCSWINSZ:
7088 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7089 break;
7090 case VKI_TIOCMBIS:
7091 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7092 break;
7093 case VKI_TIOCMBIC:
7094 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7095 break;
7096 case VKI_TIOCMSET:
7097 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7098 break;
7099 case VKI_TIOCMGET:
7100 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7101 break;
7102 case VKI_TIOCLINUX:
7103 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7104 if (*(char *)(Addr)ARG3 == 11) {
7105 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7107 break;
7108 case VKI_TIOCGPGRP:
7109 /* Get process group ID for foreground processing group. */
7110 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7111 break;
7112 case VKI_TIOCSPGRP:
7113 /* Set a process group ID? */
7114 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7115 break;
7116 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7117 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7118 break;
7119 case VKI_TIOCSCTTY:
7120 /* Just takes an int value. */
7121 break;
7122 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7123 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7124 break;
7125 case VKI_FIONBIO:
7126 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7127 break;
7128 case VKI_FIOASYNC:
7129 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7130 break;
7131 case VKI_FIONREAD: /* identical to SIOCINQ */
7132 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7133 break;
7134 case VKI_FIOQSIZE:
7135 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7136 break;
7138 case VKI_TIOCSERGETLSR:
7139 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7140 break;
7141 case VKI_TIOCGICOUNT:
7142 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7143 sizeof(struct vki_serial_icounter_struct) );
7144 break;
7146 case VKI_SG_SET_COMMAND_Q:
7147 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7148 break;
7149 case VKI_SG_IO:
7150 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7152 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7153 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7154 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7155 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7156 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7159 break;
7160 case VKI_SG_GET_SCSI_ID:
7161 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7162 break;
7163 case VKI_SG_SET_RESERVED_SIZE:
7164 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7165 break;
7166 case VKI_SG_SET_TIMEOUT:
7167 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7168 break;
7169 case VKI_SG_GET_RESERVED_SIZE:
7170 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7171 break;
7172 case VKI_SG_GET_TIMEOUT:
7173 break;
7174 case VKI_SG_GET_VERSION_NUM:
7175 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7176 break;
7177 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7178 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7179 break;
7180 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7181 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7182 break;
7184 case VKI_IIOCGETCPS:
7185 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7186 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7187 break;
7188 case VKI_IIOCNETGPN:
7189 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7190 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7191 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7192 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7193 sizeof(vki_isdn_net_ioctl_phone) );
7194 break;
7196 /* These all use struct ifreq AFAIK */
7197 case VKI_SIOCGIFINDEX: /* get iface index */
7198 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7199 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7200 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7201 break;
7202 case VKI_SIOCGIFFLAGS: /* get flags */
7203 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7204 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7205 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7206 break;
7207 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7208 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7209 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7210 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7211 break;
7212 case VKI_SIOCGIFMTU: /* get MTU size */
7213 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7214 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7215 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7216 break;
7217 case VKI_SIOCGIFADDR: /* get PA address */
7218 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7219 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7220 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7221 break;
7222 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7223 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7224 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7225 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7226 break;
7227 case VKI_SIOCGIFMETRIC: /* get metric */
7228 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7229 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7230 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7231 break;
7232 case VKI_SIOCGIFMAP: /* Get device parameters */
7233 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7234 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7235 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7236 break;
7237 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7238 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7239 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7240 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7241 break;
7242 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7243 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7244 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7245 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7246 break;
7247 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7248 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7249 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7250 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7251 break;
7252 case VKI_SIOCGIFNAME: /* get iface name */
7253 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7254 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7255 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7256 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7257 break;
7259 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7260 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7261 // The kernel will have to look at ifr_data to determine which operation
7262 // to perform.
7263 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7264 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7266 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7268 // Is this correct? Is ifr_name *always* looked at?
7269 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7270 (Addr)ir->vki_ifr_name );
7272 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7273 // the whole structure is defined. So in this case, just check it's
7274 // accessible.
7275 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7276 case VKI_ETHTOOL_GSET:
7277 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7278 (Addr)ir, sizeof(struct vki_ifreq) );
7279 break;
7280 default:
7281 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7282 (Addr)ir, sizeof(struct vki_ifreq) );
7283 break;
7286 // Now perform the relevant pre-action for the operation.
7287 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7288 case VKI_ETHTOOL_GSET:
7289 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7290 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7291 break;
7292 case VKI_ETHTOOL_SSET:
7293 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7294 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7295 break;
7296 case VKI_ETHTOOL_GDRVINFO:
7297 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7298 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7299 break;
7300 case VKI_ETHTOOL_GREGS:
7301 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7302 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7303 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7304 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7305 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7306 break;
7307 case VKI_ETHTOOL_GWOL:
7308 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7309 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7310 break;
7311 case VKI_ETHTOOL_SWOL:
7312 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7313 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7314 break;
7315 case VKI_ETHTOOL_GMSGLVL:
7316 case VKI_ETHTOOL_GLINK:
7317 case VKI_ETHTOOL_GRXCSUM:
7318 case VKI_ETHTOOL_GSG:
7319 case VKI_ETHTOOL_GTSO:
7320 case VKI_ETHTOOL_GUFO:
7321 case VKI_ETHTOOL_GGSO:
7322 case VKI_ETHTOOL_GFLAGS:
7323 case VKI_ETHTOOL_GGRO:
7324 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7325 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7326 break;
7327 case VKI_ETHTOOL_SMSGLVL:
7328 case VKI_ETHTOOL_SRXCSUM:
7329 case VKI_ETHTOOL_SSG:
7330 case VKI_ETHTOOL_STSO:
7331 case VKI_ETHTOOL_SUFO:
7332 case VKI_ETHTOOL_SGSO:
7333 case VKI_ETHTOOL_SFLAGS:
7334 case VKI_ETHTOOL_SGRO:
7335 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7336 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7337 break;
7338 case VKI_ETHTOOL_NWAY_RST:
7339 break;
7340 case VKI_ETHTOOL_GRINGPARAM:
7341 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7342 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7343 break;
7344 case VKI_ETHTOOL_SRINGPARAM:
7345 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7346 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7347 break;
7348 case VKI_ETHTOOL_TEST:
7349 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7350 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7351 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7352 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7353 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7354 break;
7355 case VKI_ETHTOOL_PHYS_ID:
7356 break;
7357 case VKI_ETHTOOL_GPERMADDR:
7358 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7359 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7360 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7361 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7362 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7363 break;
7364 case VKI_ETHTOOL_RESET:
7365 break;
7366 case VKI_ETHTOOL_GSSET_INFO:
7367 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7368 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7369 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7370 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7371 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7372 break;
7373 case VKI_ETHTOOL_GFEATURES:
7374 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7375 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7376 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7377 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7378 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7379 break;
7380 case VKI_ETHTOOL_SFEATURES:
7381 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7382 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7383 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7384 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7385 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7386 break;
7387 case VKI_ETHTOOL_GCHANNELS:
7388 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7389 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7390 break;
7391 case VKI_ETHTOOL_SCHANNELS:
7392 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7393 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7394 break;
7395 case VKI_ETHTOOL_GET_TS_INFO:
7396 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7397 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7398 break;
7400 break;
7401 } /* case VKI_SIOCETHTOOL */
7403 case VKI_SIOCGMIIPHY: /* get hardware entry */
7404 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7405 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7406 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7407 break;
7408 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7409 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7410 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7411 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7412 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7413 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7414 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7415 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7416 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7417 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7418 sizeof(struct vki_ifreq));
7419 break;
7420 case VKI_SIOCGIFCONF: /* get iface list */
7421 /* WAS:
7422 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7423 KERNEL_DO_SYSCALL(tid,RES);
7424 if (!VG_(is_kerror)(RES) && RES == 0)
7425 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7427 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7428 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7429 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7430 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7431 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7432 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7433 if ( ARG3 ) {
7434 // TODO len must be readable and writable
7435 // buf pointer only needs to be readable
7436 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7437 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7438 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7440 break;
7441 case VKI_SIOCGSTAMP:
7442 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7443 break;
7444 case VKI_SIOCGSTAMPNS:
7445 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7446 break;
7447 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7448 the number of bytes currently in that socket's send buffer.
7449 It writes this value as an int to the memory location
7450 indicated by the third argument of ioctl(2). */
7451 case VKI_SIOCOUTQ:
7452 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7453 break;
7454 case VKI_SIOCGRARP: /* get RARP table entry */
7455 case VKI_SIOCGARP: /* get ARP table entry */
7456 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7457 break;
7459 case VKI_SIOCSIFFLAGS: /* set flags */
7460 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7461 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7462 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7463 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7464 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7465 break;
7466 case VKI_SIOCSIFMAP: /* Set device parameters */
7467 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7468 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7469 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7470 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7471 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7472 break;
7473 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7474 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7475 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7476 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7477 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7478 sizeof(struct vki_hwtstamp_config) );
7479 break;
7480 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7481 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7482 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7483 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7484 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7485 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7486 break;
7487 case VKI_SIOCSIFADDR: /* set PA address */
7488 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7489 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7490 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7491 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7492 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7493 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7494 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7495 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7496 break;
7497 case VKI_SIOCSIFMETRIC: /* set metric */
7498 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7499 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7500 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7501 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7502 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7503 break;
7504 case VKI_SIOCSIFMTU: /* set MTU size */
7505 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7506 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7507 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7508 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7509 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7510 break;
7511 case VKI_SIOCSIFHWADDR: /* set hardware address */
7512 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7513 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7514 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7515 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7516 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7517 break;
7518 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7519 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7520 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7521 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7522 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7523 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7524 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7525 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7526 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7527 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7528 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7529 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7530 break;
7531 /* Routing table calls. */
7532 case VKI_SIOCADDRT: /* add routing table entry */
7533 case VKI_SIOCDELRT: /* delete routing table entry */
7534 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7535 sizeof(struct vki_rtentry));
7536 break;
7538 /* tun/tap related ioctls */
7539 case VKI_TUNSETNOCSUM:
7540 case VKI_TUNSETDEBUG:
7541 break;
7542 case VKI_TUNSETIFF:
7543 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7544 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7545 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7546 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7547 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7548 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7549 break;
7550 case VKI_TUNSETPERSIST:
7551 case VKI_TUNSETOWNER:
7552 case VKI_TUNSETLINK:
7553 case VKI_TUNSETGROUP:
7554 break;
7555 case VKI_TUNGETFEATURES:
7556 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7557 break;
7558 case VKI_TUNSETOFFLOAD:
7559 break;
7560 case VKI_TUNGETIFF:
7561 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7562 break;
7563 case VKI_TUNGETSNDBUF:
7564 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7565 break;
7566 case VKI_TUNSETSNDBUF:
7567 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7568 break;
7569 case VKI_TUNGETVNETHDRSZ:
7570 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7571 break;
7572 case VKI_TUNSETVNETHDRSZ:
7573 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7574 break;
7575 case VKI_TUNSETQUEUE:
7576 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7577 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7578 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7579 break;
7580 case VKI_TUNSETIFINDEX:
7581 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7582 break;
7584 /* RARP cache control calls. */
7585 case VKI_SIOCDRARP: /* delete RARP table entry */
7586 case VKI_SIOCSRARP: /* set RARP table entry */
7587 /* ARP cache control calls. */
7588 case VKI_SIOCSARP: /* set ARP table entry */
7589 case VKI_SIOCDARP: /* delete ARP table entry */
7590 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7591 break;
7593 case VKI_SIOCGPGRP:
7594 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7595 break;
7596 case VKI_SIOCSPGRP:
7597 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7598 //tst->sys_flags &= ~SfMayBlock;
7599 break;
7601 case VKI_SIOCATMARK:
7602 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7603 break;
7605 /* linux/soundcard interface (OSS) */
7606 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7607 case VKI_SNDCTL_SEQ_GETINCOUNT:
7608 case VKI_SNDCTL_SEQ_PERCMODE:
7609 case VKI_SNDCTL_SEQ_TESTMIDI:
7610 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7611 case VKI_SNDCTL_SEQ_NRSYNTHS:
7612 case VKI_SNDCTL_SEQ_NRMIDIS:
7613 case VKI_SNDCTL_SEQ_GETTIME:
7614 case VKI_SNDCTL_DSP_GETBLKSIZE:
7615 case VKI_SNDCTL_DSP_GETFMTS:
7616 case VKI_SNDCTL_DSP_GETTRIGGER:
7617 case VKI_SNDCTL_DSP_GETODELAY:
7618 case VKI_SNDCTL_DSP_GETSPDIF:
7619 case VKI_SNDCTL_DSP_GETCAPS:
7620 case VKI_SOUND_PCM_READ_RATE:
7621 case VKI_SOUND_PCM_READ_CHANNELS:
7622 case VKI_SOUND_PCM_READ_BITS:
7623 case VKI_SOUND_PCM_READ_FILTER:
7624 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7625 ARG3, sizeof(int));
7626 break;
7627 case VKI_SNDCTL_SEQ_CTRLRATE:
7628 case VKI_SNDCTL_DSP_SPEED:
7629 case VKI_SNDCTL_DSP_STEREO:
7630 case VKI_SNDCTL_DSP_CHANNELS:
7631 case VKI_SOUND_PCM_WRITE_FILTER:
7632 case VKI_SNDCTL_DSP_SUBDIVIDE:
7633 case VKI_SNDCTL_DSP_SETFRAGMENT:
7634 case VKI_SNDCTL_DSP_SETFMT:
7635 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7636 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7637 case VKI_SNDCTL_TMR_TIMEBASE:
7638 case VKI_SNDCTL_TMR_TEMPO:
7639 case VKI_SNDCTL_TMR_SOURCE:
7640 case VKI_SNDCTL_MIDI_PRETIME:
7641 case VKI_SNDCTL_MIDI_MPUMODE:
7642 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7643 ARG3, sizeof(int));
7644 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7645 ARG3, sizeof(int));
7646 break;
7647 case VKI_SNDCTL_DSP_GETOSPACE:
7648 case VKI_SNDCTL_DSP_GETISPACE:
7649 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7650 ARG3, sizeof(vki_audio_buf_info));
7651 break;
7652 case VKI_SNDCTL_DSP_NONBLOCK:
7653 break;
7654 case VKI_SNDCTL_DSP_SETTRIGGER:
7655 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7656 ARG3, sizeof(int));
7657 break;
7659 case VKI_SNDCTL_DSP_POST:
7660 case VKI_SNDCTL_DSP_RESET:
7661 case VKI_SNDCTL_DSP_SYNC:
7662 case VKI_SNDCTL_DSP_SETSYNCRO:
7663 case VKI_SNDCTL_DSP_SETDUPLEX:
7664 break;
7666 /* linux/soundcard interface (ALSA) */
7667 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7668 case VKI_SNDRV_PCM_IOCTL_LINK:
7669 /* these just take an int by value */
7670 break;
7671 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7672 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7673 break;
7674 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7675 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7676 break;
7677 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7678 struct vki_snd_ctl_elem_list *data =
7679 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7680 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7681 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7682 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7683 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7684 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7685 if (data->pids) {
7686 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7688 break;
7690 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7691 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7692 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7693 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7694 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7695 break;
7697 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7698 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7699 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7700 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7701 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7702 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7703 break;
7706 /* Real Time Clock (/dev/rtc) ioctls */
7707 case VKI_RTC_UIE_ON:
7708 case VKI_RTC_UIE_OFF:
7709 case VKI_RTC_AIE_ON:
7710 case VKI_RTC_AIE_OFF:
7711 case VKI_RTC_PIE_ON:
7712 case VKI_RTC_PIE_OFF:
7713 case VKI_RTC_IRQP_SET:
7714 break;
7715 case VKI_RTC_RD_TIME:
7716 case VKI_RTC_ALM_READ:
7717 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7718 ARG3, sizeof(struct vki_rtc_time));
7719 break;
7720 case VKI_RTC_ALM_SET:
7721 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7722 break;
7723 case VKI_RTC_IRQP_READ:
7724 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7725 break;
7727 /* Block devices */
7728 case VKI_BLKROSET:
7729 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7730 break;
7731 case VKI_BLKROGET:
7732 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7733 break;
7734 case VKI_BLKGETSIZE:
7735 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7736 break;
7737 case VKI_BLKFLSBUF:
7738 break;
7739 case VKI_BLKRASET:
7740 break;
7741 case VKI_BLKRAGET:
7742 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7743 break;
7744 case VKI_BLKFRASET:
7745 break;
7746 case VKI_BLKFRAGET:
7747 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7748 break;
7749 case VKI_BLKSECTGET:
7750 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7751 break;
7752 case VKI_BLKSSZGET:
7753 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7754 break;
7755 case VKI_BLKBSZGET:
7756 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7757 break;
7758 case VKI_BLKBSZSET:
7759 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7760 break;
7761 case VKI_BLKGETSIZE64:
7762 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7763 break;
7764 case VKI_BLKPBSZGET:
7765 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7766 break;
7767 case VKI_BLKIOMIN:
7768 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7769 break;
7770 case VKI_BLKIOOPT:
7771 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7772 break;
7773 case VKI_BLKALIGNOFF:
7774 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7775 break;
7776 case VKI_BLKDISCARDZEROES:
7777 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7778 break;
7779 case VKI_BLKREPORTZONE:
7780 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7781 sizeof(struct vki_blk_zone_report));
7782 break;
7783 case VKI_BLKRESETZONE:
7784 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7785 sizeof(struct vki_blk_zone_range));
7786 break;
7788 /* Hard disks */
7789 case VKI_HDIO_GETGEO: /* 0x0301 */
7790 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7791 break;
7792 case VKI_HDIO_GET_DMA: /* 0x030b */
7793 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7794 break;
7795 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7796 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7797 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7798 break;
7800 /* SCSI */
7801 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7802 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7803 break;
7804 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7805 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7806 break;
7808 /* CD ROM stuff (??) */
7809 case VKI_CDROM_GET_MCN:
7810 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7811 sizeof(struct vki_cdrom_mcn) );
7812 break;
7813 case VKI_CDROM_SEND_PACKET:
7814 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7815 sizeof(struct vki_cdrom_generic_command));
7816 break;
7817 case VKI_CDROMSUBCHNL:
7818 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7819 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7820 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7821 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7822 sizeof(struct vki_cdrom_subchnl));
7823 break;
7824 case VKI_CDROMREADMODE1: /*0x530d*/
7825 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7826 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7827 break;
7828 case VKI_CDROMREADMODE2: /*0x530c*/
7829 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7830 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7831 break;
7832 case VKI_CDROMREADTOCHDR:
7833 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7834 sizeof(struct vki_cdrom_tochdr));
7835 break;
7836 case VKI_CDROMREADTOCENTRY:
7837 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7838 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7839 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7840 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7841 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7842 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7843 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7844 sizeof(struct vki_cdrom_tocentry));
7845 break;
7846 case VKI_CDROMMULTISESSION: /* 0x5310 */
7847 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7848 sizeof(struct vki_cdrom_multisession));
7849 break;
7850 case VKI_CDROMVOLREAD: /* 0x5313 */
7851 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7852 sizeof(struct vki_cdrom_volctrl));
7853 break;
7854 case VKI_CDROMREADRAW: /* 0x5314 */
7855 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7856 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7857 break;
7858 case VKI_CDROMREADAUDIO: /* 0x530e */
7859 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7860 sizeof (struct vki_cdrom_read_audio));
7861 if ( ARG3 ) {
7862 /* ToDo: don't do any of the following if the structure is invalid */
7863 struct vki_cdrom_read_audio *cra =
7864 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7865 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7866 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7868 break;
7869 case VKI_CDROMPLAYMSF:
7870 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7871 break;
7872 /* The following two are probably bogus (should check args
7873 for readability). JRS 20021117 */
7874 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7875 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7876 break;
7877 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7878 break;
7880 case VKI_FIGETBSZ:
7881 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7882 break;
7883 case VKI_FIBMAP:
7884 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7885 break;
7887 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7888 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7889 sizeof(struct vki_fb_var_screeninfo));
7890 break;
7891 case VKI_FBIOPUT_VSCREENINFO:
7892 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7893 sizeof(struct vki_fb_var_screeninfo));
7894 break;
7895 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7896 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7897 sizeof(struct vki_fb_fix_screeninfo));
7898 break;
7899 case VKI_FBIOPAN_DISPLAY:
7900 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7901 sizeof(struct vki_fb_var_screeninfo));
7903 break;
7904 case VKI_PPCLAIM:
7905 case VKI_PPEXCL:
7906 case VKI_PPYIELD:
7907 case VKI_PPRELEASE:
7908 break;
7909 case VKI_PPSETMODE:
7910 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7911 break;
7912 case VKI_PPGETMODE:
7913 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7914 break;
7915 case VKI_PPSETPHASE:
7916 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7917 break;
7918 case VKI_PPGETPHASE:
7919 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7920 break;
7921 case VKI_PPGETMODES:
7922 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7923 break;
7924 case VKI_PPSETFLAGS:
7925 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7926 break;
7927 case VKI_PPGETFLAGS:
7928 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7929 break;
7930 case VKI_PPRSTATUS:
7931 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
7932 break;
7933 case VKI_PPRDATA:
7934 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
7935 break;
7936 case VKI_PPRCONTROL:
7937 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7938 break;
7939 case VKI_PPWDATA:
7940 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
7941 break;
7942 case VKI_PPWCONTROL:
7943 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7944 break;
7945 case VKI_PPFCONTROL:
7946 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7947 break;
7948 case VKI_PPDATADIR:
7949 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
7950 break;
7951 case VKI_PPNEGOT:
7952 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
7953 break;
7954 case VKI_PPWCTLONIRQ:
7955 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7956 break;
7957 case VKI_PPCLRIRQ:
7958 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
7959 break;
7960 case VKI_PPSETTIME:
7961 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
7962 break;
7963 case VKI_PPGETTIME:
7964 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
7965 break;
7967 case VKI_GIO_FONT:
7968 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7969 break;
7970 case VKI_PIO_FONT:
7971 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7972 break;
7974 case VKI_GIO_FONTX:
7975 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7976 if ( ARG3 ) {
7977 /* ToDo: don't do any of the following if the structure is invalid */
7978 struct vki_consolefontdesc *cfd =
7979 (struct vki_consolefontdesc *)(Addr)ARG3;
7980 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7981 32 * cfd->charcount );
7983 break;
7984 case VKI_PIO_FONTX:
7985 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7986 if ( ARG3 ) {
7987 /* ToDo: don't do any of the following if the structure is invalid */
7988 struct vki_consolefontdesc *cfd =
7989 (struct vki_consolefontdesc *)(Addr)ARG3;
7990 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7991 32 * cfd->charcount );
7993 break;
7995 case VKI_PIO_FONTRESET:
7996 break;
7998 case VKI_GIO_CMAP:
7999 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8000 break;
8001 case VKI_PIO_CMAP:
8002 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8003 break;
8005 case VKI_KIOCSOUND:
8006 case VKI_KDMKTONE:
8007 break;
8009 case VKI_KDGETLED:
8010 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8011 break;
8012 case VKI_KDSETLED:
8013 break;
8015 case VKI_KDGKBTYPE:
8016 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8017 break;
8019 case VKI_KDADDIO:
8020 case VKI_KDDELIO:
8021 case VKI_KDENABIO:
8022 case VKI_KDDISABIO:
8023 break;
8025 case VKI_KDSETMODE:
8026 break;
8027 case VKI_KDGETMODE:
8028 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8029 break;
8031 case VKI_KDMAPDISP:
8032 case VKI_KDUNMAPDISP:
8033 break;
8035 case VKI_GIO_SCRNMAP:
8036 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8037 break;
8038 case VKI_PIO_SCRNMAP:
8039 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8040 break;
8041 case VKI_GIO_UNISCRNMAP:
8042 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8043 VKI_E_TABSZ * sizeof(unsigned short) );
8044 break;
8045 case VKI_PIO_UNISCRNMAP:
8046 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8047 VKI_E_TABSZ * sizeof(unsigned short) );
8048 break;
8050 case VKI_GIO_UNIMAP:
8051 if ( ARG3 ) {
8052 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8053 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8054 sizeof(unsigned short));
8055 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8056 sizeof(struct vki_unipair *));
8057 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8058 desc->entry_ct * sizeof(struct vki_unipair));
8060 break;
8061 case VKI_PIO_UNIMAP:
8062 if ( ARG3 ) {
8063 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8064 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8065 sizeof(unsigned short) );
8066 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8067 sizeof(struct vki_unipair *) );
8068 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8069 desc->entry_ct * sizeof(struct vki_unipair) );
8071 break;
8072 case VKI_PIO_UNIMAPCLR:
8073 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8074 break;
8076 case VKI_KDGKBMODE:
8077 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8078 break;
8079 case VKI_KDSKBMODE:
8080 break;
8082 case VKI_KDGKBMETA:
8083 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8084 break;
8085 case VKI_KDSKBMETA:
8086 break;
8088 case VKI_KDGKBLED:
8089 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8090 break;
8091 case VKI_KDSKBLED:
8092 break;
8094 case VKI_KDGKBENT:
8095 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8096 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8097 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8098 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8099 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8100 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8101 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8102 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8103 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8104 break;
8105 case VKI_KDSKBENT:
8106 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8107 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8108 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8109 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8110 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8111 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8112 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8113 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8114 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8115 break;
8117 case VKI_KDGKBSENT:
8118 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8119 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8120 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8121 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8122 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8123 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8124 break;
8125 case VKI_KDSKBSENT:
8126 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8127 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8128 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8129 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8130 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8131 break;
8133 case VKI_KDGKBDIACR:
8134 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8135 break;
8136 case VKI_KDSKBDIACR:
8137 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8138 break;
8140 case VKI_KDGETKEYCODE:
8141 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8142 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8143 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8144 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8145 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8146 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8147 break;
8148 case VKI_KDSETKEYCODE:
8149 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8150 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8151 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8152 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8153 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8154 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8155 break;
8157 case VKI_KDSIGACCEPT:
8158 break;
8160 case VKI_KDKBDREP:
8161 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8162 break;
8164 case VKI_KDFONTOP:
8165 if ( ARG3 ) {
8166 struct vki_console_font_op *op =
8167 (struct vki_console_font_op *) (Addr)ARG3;
8168 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8169 sizeof(struct vki_console_font_op) );
8170 switch ( op->op ) {
8171 case VKI_KD_FONT_OP_SET:
8172 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8173 (Addr)op->data,
8174 (op->width + 7) / 8 * 32 * op->charcount );
8175 break;
8176 case VKI_KD_FONT_OP_GET:
8177 if ( op->data )
8178 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8179 (Addr)op->data,
8180 (op->width + 7) / 8 * 32 * op->charcount );
8181 break;
8182 case VKI_KD_FONT_OP_SET_DEFAULT:
8183 if ( op->data )
8184 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8185 (Addr)op->data );
8186 break;
8187 case VKI_KD_FONT_OP_COPY:
8188 break;
8191 break;
8193 case VKI_VT_OPENQRY:
8194 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8195 break;
8196 case VKI_VT_GETMODE:
8197 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8198 break;
8199 case VKI_VT_SETMODE:
8200 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8201 break;
8202 case VKI_VT_GETSTATE:
8203 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8204 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8205 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8206 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8207 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8208 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8209 break;
8210 case VKI_VT_RELDISP:
8211 case VKI_VT_ACTIVATE:
8212 case VKI_VT_WAITACTIVE:
8213 case VKI_VT_DISALLOCATE:
8214 break;
8215 case VKI_VT_RESIZE:
8216 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8217 break;
8218 case VKI_VT_RESIZEX:
8219 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8220 break;
8221 case VKI_VT_LOCKSWITCH:
8222 case VKI_VT_UNLOCKSWITCH:
8223 break;
8225 case VKI_USBDEVFS_CONTROL:
8226 if ( ARG3 ) {
8227 struct vki_usbdevfs_ctrltransfer *vkuc =
8228 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8229 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8230 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8231 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8232 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8233 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8234 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8235 if (vkuc->bRequestType & 0x80)
8236 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8237 else
8238 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8240 break;
8241 case VKI_USBDEVFS_BULK:
8242 if ( ARG3 ) {
8243 struct vki_usbdevfs_bulktransfer *vkub =
8244 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8245 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8246 if (vkub->ep & 0x80)
8247 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8248 else
8249 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8251 break;
8252 case VKI_USBDEVFS_GETDRIVER:
8253 if ( ARG3 ) {
8254 struct vki_usbdevfs_getdriver *vkugd =
8255 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8256 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8258 break;
8259 case VKI_USBDEVFS_SUBMITURB:
8260 if ( ARG3 ) {
8261 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8263 /* Not the whole struct needs to be initialized */
8264 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8265 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8266 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8267 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8268 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8269 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8270 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8271 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8272 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8273 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8274 if (vkusp->bRequestType & 0x80)
8275 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8276 else
8277 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8278 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8279 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8280 int total_length = 0;
8281 int i;
8282 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8283 for(i=0; i<vkuu->number_of_packets; i++) {
8284 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8285 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));
8286 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8287 total_length += vkuu->iso_frame_desc[i].length;
8289 if (vkuu->endpoint & 0x80)
8290 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8291 else
8292 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8293 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8294 } else {
8295 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8296 if (vkuu->endpoint & 0x80)
8297 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8298 else
8299 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8300 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8303 break;
8304 case VKI_USBDEVFS_DISCARDURB:
8305 break;
8306 case VKI_USBDEVFS_REAPURB:
8307 if ( ARG3 ) {
8308 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8310 break;
8311 case VKI_USBDEVFS_REAPURBNDELAY:
8312 if ( ARG3 ) {
8313 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8315 break;
8316 case VKI_USBDEVFS_CONNECTINFO:
8317 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8318 break;
8319 case VKI_USBDEVFS_IOCTL:
8320 if ( ARG3 ) {
8321 struct vki_usbdevfs_ioctl *vkui =
8322 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8323 UInt dir2, size2;
8324 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8325 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8326 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8327 if (size2 > 0) {
8328 if (dir2 & _VKI_IOC_WRITE)
8329 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8330 else if (dir2 & _VKI_IOC_READ)
8331 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8334 break;
8335 case VKI_USBDEVFS_RESET:
8336 break;
8338 /* I2C (/dev/i2c-*) ioctls */
8339 case VKI_I2C_SLAVE:
8340 case VKI_I2C_SLAVE_FORCE:
8341 case VKI_I2C_TENBIT:
8342 case VKI_I2C_PEC:
8343 break;
8344 case VKI_I2C_FUNCS:
8345 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8346 break;
8347 case VKI_I2C_RDWR:
8348 if ( ARG3 ) {
8349 struct vki_i2c_rdwr_ioctl_data *vkui =
8350 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8351 UInt i;
8352 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8353 for (i=0; i < vkui->nmsgs; i++) {
8354 struct vki_i2c_msg *msg = vkui->msgs + i;
8355 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8356 if (msg->flags & VKI_I2C_M_RD)
8357 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8358 else
8359 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8362 break;
8363 case VKI_I2C_SMBUS:
8364 if ( ARG3 ) {
8365 struct vki_i2c_smbus_ioctl_data *vkis
8366 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8367 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8368 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8369 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8370 (Addr)&vkis->size, sizeof(vkis->size));
8371 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8372 (Addr)&vkis->command, sizeof(vkis->command));
8373 /* i2c_smbus_write_quick hides its value in read_write, so
8374 this variable can have a different meaning */
8375 /* to make matters worse i2c_smbus_write_byte stores its
8376 value in command */
8377 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8378 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8379 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8380 /* the rest uses the byte array to store the data,
8381 some the first byte for size */
8382 UInt size;
8383 switch(vkis->size) {
8384 case VKI_I2C_SMBUS_BYTE_DATA:
8385 size = 1;
8386 break;
8387 case VKI_I2C_SMBUS_WORD_DATA:
8388 case VKI_I2C_SMBUS_PROC_CALL:
8389 size = 2;
8390 break;
8391 case VKI_I2C_SMBUS_BLOCK_DATA:
8392 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8393 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8394 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8395 size = 1 + vkis->data->block[0];
8396 break;
8397 default:
8398 size = 0;
8401 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8402 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8403 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8404 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8405 ".i2c_smbus_ioctl_data.data",
8406 (Addr)&vkis->data->block[0], size);
8407 else
8408 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8409 "i2c_smbus_ioctl_data.data",
8410 (Addr)&vkis->data->block[0], size);
8413 break;
8415 /* Wireless extensions ioctls */
8416 case VKI_SIOCSIWCOMMIT:
8417 case VKI_SIOCSIWNWID:
8418 case VKI_SIOCSIWFREQ:
8419 case VKI_SIOCSIWMODE:
8420 case VKI_SIOCSIWSENS:
8421 case VKI_SIOCSIWRANGE:
8422 case VKI_SIOCSIWPRIV:
8423 case VKI_SIOCSIWSTATS:
8424 case VKI_SIOCSIWSPY:
8425 case VKI_SIOCSIWTHRSPY:
8426 case VKI_SIOCSIWAP:
8427 case VKI_SIOCSIWSCAN:
8428 case VKI_SIOCSIWESSID:
8429 case VKI_SIOCSIWRATE:
8430 case VKI_SIOCSIWNICKN:
8431 case VKI_SIOCSIWRTS:
8432 case VKI_SIOCSIWFRAG:
8433 case VKI_SIOCSIWTXPOW:
8434 case VKI_SIOCSIWRETRY:
8435 case VKI_SIOCSIWENCODE:
8436 case VKI_SIOCSIWPOWER:
8437 case VKI_SIOCSIWGENIE:
8438 case VKI_SIOCSIWMLME:
8439 case VKI_SIOCSIWAUTH:
8440 case VKI_SIOCSIWENCODEEXT:
8441 case VKI_SIOCSIWPMKSA:
8442 break;
8443 case VKI_SIOCGIWNAME:
8444 if (ARG3) {
8445 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8446 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8447 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8449 break;
8450 case VKI_SIOCGIWNWID:
8451 case VKI_SIOCGIWSENS:
8452 case VKI_SIOCGIWRATE:
8453 case VKI_SIOCGIWRTS:
8454 case VKI_SIOCGIWFRAG:
8455 case VKI_SIOCGIWTXPOW:
8456 case VKI_SIOCGIWRETRY:
8457 case VKI_SIOCGIWPOWER:
8458 case VKI_SIOCGIWAUTH:
8459 if (ARG3) {
8460 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8461 "RETRY|PARAM|AUTH])",
8462 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8463 sizeof(struct vki_iw_param));
8465 break;
8466 case VKI_SIOCGIWFREQ:
8467 if (ARG3) {
8468 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8469 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8470 sizeof(struct vki_iw_freq));
8472 break;
8473 case VKI_SIOCGIWMODE:
8474 if (ARG3) {
8475 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8476 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8477 sizeof(__vki_u32));
8479 break;
8480 case VKI_SIOCGIWRANGE:
8481 case VKI_SIOCGIWPRIV:
8482 case VKI_SIOCGIWSTATS:
8483 case VKI_SIOCGIWSPY:
8484 case VKI_SIOCGIWTHRSPY:
8485 case VKI_SIOCGIWAPLIST:
8486 case VKI_SIOCGIWSCAN:
8487 case VKI_SIOCGIWESSID:
8488 case VKI_SIOCGIWNICKN:
8489 case VKI_SIOCGIWENCODE:
8490 case VKI_SIOCGIWGENIE:
8491 case VKI_SIOCGIWENCODEEXT:
8492 if (ARG3) {
8493 struct vki_iw_point* point;
8494 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8495 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8496 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8497 (Addr)point->pointer, point->length);
8499 break;
8500 case VKI_SIOCGIWAP:
8501 if (ARG3) {
8502 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8503 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8504 sizeof(struct vki_sockaddr));
8506 break;
8508 /* User input device creation */
8509 case VKI_UI_SET_EVBIT:
8510 case VKI_UI_SET_KEYBIT:
8511 case VKI_UI_SET_RELBIT:
8512 case VKI_UI_SET_ABSBIT:
8513 case VKI_UI_SET_MSCBIT:
8514 case VKI_UI_SET_LEDBIT:
8515 case VKI_UI_SET_SNDBIT:
8516 case VKI_UI_SET_FFBIT:
8517 case VKI_UI_SET_SWBIT:
8518 case VKI_UI_SET_PROPBIT:
8519 /* These just take an int by value */
8520 break;
8522 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8523 || defined(VGPV_mips32_linux_android) \
8524 || defined(VGPV_arm64_linux_android)
8525 /* ashmem */
8526 case VKI_ASHMEM_GET_SIZE:
8527 case VKI_ASHMEM_SET_SIZE:
8528 case VKI_ASHMEM_GET_PROT_MASK:
8529 case VKI_ASHMEM_SET_PROT_MASK:
8530 case VKI_ASHMEM_GET_PIN_STATUS:
8531 case VKI_ASHMEM_PURGE_ALL_CACHES:
8532 break;
8533 case VKI_ASHMEM_GET_NAME:
8534 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8535 break;
8536 case VKI_ASHMEM_SET_NAME:
8537 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8538 break;
8539 case VKI_ASHMEM_PIN:
8540 case VKI_ASHMEM_UNPIN:
8541 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8542 ARG3, sizeof(struct vki_ashmem_pin) );
8543 break;
8545 /* binder */
8546 case VKI_BINDER_WRITE_READ:
8547 if (ARG3) {
8548 struct vki_binder_write_read* bwr
8549 = (struct vki_binder_write_read*)(Addr)ARG3;
8551 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8552 bwr->write_buffer);
8553 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8554 bwr->write_size);
8555 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8556 bwr->write_consumed);
8557 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8558 bwr->read_buffer);
8559 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8560 bwr->read_size);
8561 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8562 bwr->read_consumed);
8564 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8565 bwr->write_consumed);
8566 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8567 bwr->read_consumed);
8569 if (bwr->read_size)
8570 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8571 (Addr)bwr->read_buffer, bwr->read_size);
8572 if (bwr->write_size)
8573 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8574 (Addr)bwr->write_buffer, bwr->write_size);
8576 break;
8578 case VKI_BINDER_SET_IDLE_TIMEOUT:
8579 case VKI_BINDER_SET_MAX_THREADS:
8580 case VKI_BINDER_SET_IDLE_PRIORITY:
8581 case VKI_BINDER_SET_CONTEXT_MGR:
8582 case VKI_BINDER_THREAD_EXIT:
8583 break;
8584 case VKI_BINDER_VERSION:
8585 if (ARG3) {
8586 struct vki_binder_version* bv =
8587 (struct vki_binder_version*)(Addr)ARG3;
8588 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8590 break;
8591 # endif /* defined(VGPV_*_linux_android) */
8593 case VKI_HCIGETDEVLIST:
8594 if (ARG3) {
8595 struct vki_hci_dev_list_req* dlr =
8596 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8597 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8598 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8599 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8600 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8601 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8603 break;
8605 case VKI_HCIINQUIRY:
8606 if (ARG3) {
8607 struct vki_hci_inquiry_req* ir =
8608 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8609 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8610 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8611 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8612 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8613 ir->num_rsp * sizeof(struct vki_inquiry_info));
8615 break;
8617 case VKI_DRM_IOCTL_VERSION:
8618 if (ARG3) {
8619 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8620 struct vg_drm_version_info* info;
8621 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8622 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8623 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8624 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8625 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8626 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8627 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8628 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8629 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8630 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8631 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8632 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8633 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8634 // To ensure we VG_(free) info even when syscall fails:
8635 *flags |= SfPostOnFail;
8636 info->data = *data;
8637 info->orig = data;
8638 ARG3 = (Addr)&info->data;
8640 break;
8641 case VKI_DRM_IOCTL_GET_UNIQUE:
8642 if (ARG3) {
8643 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8644 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8645 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8646 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8648 break;
8649 case VKI_DRM_IOCTL_GET_MAGIC:
8650 if (ARG3) {
8651 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8652 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8654 break;
8655 case VKI_DRM_IOCTL_WAIT_VBLANK:
8656 if (ARG3) {
8657 union vki_drm_wait_vblank *data =
8658 (union vki_drm_wait_vblank *)(Addr)ARG3;
8659 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8660 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8661 /* XXX: It seems request.signal isn't used */
8662 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8664 break;
8665 case VKI_DRM_IOCTL_GEM_CLOSE:
8666 if (ARG3) {
8667 struct vki_drm_gem_close *data =
8668 (struct vki_drm_gem_close *)(Addr)ARG3;
8669 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8671 break;
8672 case VKI_DRM_IOCTL_GEM_FLINK:
8673 if (ARG3) {
8674 struct vki_drm_gem_flink *data =
8675 (struct vki_drm_gem_flink *)(Addr)ARG3;
8676 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8677 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8679 break;
8680 case VKI_DRM_IOCTL_GEM_OPEN:
8681 if (ARG3) {
8682 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8683 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8684 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8685 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8687 break;
8688 case VKI_DRM_IOCTL_I915_GETPARAM:
8689 if (ARG3) {
8690 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8691 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8692 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8694 break;
8695 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8696 if (ARG3) {
8697 struct vki_drm_i915_gem_busy *data =
8698 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8699 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8700 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8702 break;
8703 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8704 if (ARG3) {
8705 struct vki_drm_i915_gem_create *data =
8706 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8707 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8708 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8710 break;
8711 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8712 if (ARG3) {
8713 struct vki_drm_i915_gem_pread *data =
8714 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8715 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8716 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8717 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8718 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8719 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8721 break;
8722 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8723 if (ARG3) {
8724 struct vki_drm_i915_gem_pwrite *data =
8725 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8726 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8727 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8728 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8729 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8730 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8731 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8732 * interleaved vertex attributes may have a wide stride with uninitialized data between
8733 * consecutive vertices) */
8735 break;
8736 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8737 if (ARG3) {
8738 struct vki_drm_i915_gem_mmap_v1 *data =
8739 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8740 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8741 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8742 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8743 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8745 break;
8746 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8747 if (ARG3) {
8748 struct vki_drm_i915_gem_mmap *data =
8749 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8750 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8751 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8752 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8753 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8754 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8756 break;
8757 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8758 if (ARG3) {
8759 struct vki_drm_i915_gem_mmap_gtt *data =
8760 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8761 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8762 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8764 break;
8765 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8766 if (ARG3) {
8767 struct vki_drm_i915_gem_set_domain *data =
8768 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8769 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8770 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8771 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8773 break;
8774 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8775 if (ARG3) {
8776 struct vki_drm_i915_gem_set_tiling *data =
8777 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8778 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8779 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8780 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8781 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8783 break;
8784 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8785 if (ARG3) {
8786 struct vki_drm_i915_gem_get_tiling *data =
8787 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8788 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8789 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8790 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8792 break;
8793 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8794 if (ARG3) {
8795 struct vki_drm_i915_gem_get_aperture *data =
8796 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8797 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8798 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8800 break;
8802 /* KVM ioctls that check for a numeric value as parameter */
8803 case VKI_KVM_GET_API_VERSION:
8804 case VKI_KVM_CREATE_VM:
8805 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8806 case VKI_KVM_CHECK_EXTENSION:
8807 case VKI_KVM_SET_TSS_ADDR:
8808 case VKI_KVM_CREATE_VCPU:
8809 case VKI_KVM_RUN:
8810 break;
8812 case VKI_KVM_S390_MEM_OP: {
8813 struct vki_kvm_s390_mem_op *args =
8814 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8815 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8816 sizeof(struct vki_kvm_s390_mem_op));
8817 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8818 break;
8819 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8820 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8821 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8822 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8824 break;
8827 #ifdef ENABLE_XEN
8828 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8829 SyscallArgs harrghs;
8830 struct vki_xen_privcmd_hypercall *args =
8831 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8833 if (!args)
8834 break;
8836 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8837 harrghs.sysno = args->op;
8838 harrghs.arg1 = args->arg[0];
8839 harrghs.arg2 = args->arg[1];
8840 harrghs.arg3 = args->arg[2];
8841 harrghs.arg4 = args->arg[3];
8842 harrghs.arg5 = args->arg[4];
8843 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8845 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8847 /* HACK. arg8 is used to return the number of hypercall
8848 * arguments actually consumed! */
8849 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8850 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8852 break;
8855 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8856 struct vki_xen_privcmd_mmap *args =
8857 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8858 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8859 (Addr)&args->num, sizeof(args->num));
8860 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8861 (Addr)&args->dom, sizeof(args->dom));
8862 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8863 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8864 break;
8866 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8867 struct vki_xen_privcmd_mmapbatch *args =
8868 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8869 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8870 (Addr)&args->num, sizeof(args->num));
8871 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8872 (Addr)&args->dom, sizeof(args->dom));
8873 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8874 (Addr)&args->addr, sizeof(args->addr));
8875 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8876 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8877 break;
8879 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8880 struct vki_xen_privcmd_mmapbatch_v2 *args =
8881 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8882 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8883 (Addr)&args->num, sizeof(args->num));
8884 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8885 (Addr)&args->dom, sizeof(args->dom));
8886 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8887 (Addr)&args->addr, sizeof(args->addr));
8888 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8889 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8890 break;
8893 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8894 struct vki_xen_ioctl_evtchn_bind_virq *args =
8895 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8896 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8897 (Addr)&args->virq, sizeof(args->virq));
8899 break;
8900 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8901 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8902 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8903 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8904 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8905 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8906 (Addr)&args->remote_port, sizeof(args->remote_port));
8908 break;
8909 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8910 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8911 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8912 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8913 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8915 break;
8916 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8917 struct vki_xen_ioctl_evtchn_unbind *args =
8918 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8919 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8920 (Addr)&args->port, sizeof(args->port));
8922 break;
8923 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8924 struct vki_xen_ioctl_evtchn_notify *args =
8925 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
8926 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8927 (Addr)&args->port, sizeof(args->port));
8929 break;
8930 case VKI_XEN_IOCTL_EVTCHN_RESET:
8931 /* No input*/
8932 break;
8933 #endif
8935 /* Lustre */
8936 case VKI_OBD_IOC_FID2PATH: {
8937 struct vki_getinfo_fid2path *gf =
8938 (struct vki_getinfo_fid2path *)(Addr)ARG3;
8939 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8940 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8941 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8942 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8943 break;
8946 case VKI_LL_IOC_PATH2FID:
8947 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8948 break;
8950 case VKI_LL_IOC_GETPARENT: {
8951 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
8952 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8953 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8954 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8955 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8956 break;
8959 /* V4L2 */
8960 case VKI_V4L2_QUERYCAP: {
8961 struct vki_v4l2_capability *data =
8962 (struct vki_v4l2_capability *)(Addr)ARG3;
8963 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8964 break;
8966 case VKI_V4L2_ENUM_FMT: {
8967 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
8968 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8969 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8970 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8971 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8972 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8973 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8974 break;
8976 case VKI_V4L2_G_FMT: {
8977 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8978 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8979 switch (data->type) {
8980 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8981 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8982 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8983 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8984 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8985 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8986 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8987 break;
8988 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8989 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8990 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8991 break;
8992 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8993 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8994 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8995 break;
8996 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8997 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8998 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8999 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9000 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9001 if (data->fmt.win.clipcount && data->fmt.win.clips)
9002 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9003 (Addr)data->fmt.win.clips,
9004 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9005 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9006 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9007 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9008 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9009 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9010 break;
9011 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9012 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9013 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9014 break;
9015 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9016 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9017 break;
9019 break;
9021 case VKI_V4L2_S_FMT: {
9022 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9023 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9024 switch (data->type) {
9025 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9026 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9027 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9028 (Addr)&data->type + sizeof(data->type),
9029 sizeof(*data) - sizeof(data->type));
9030 break;
9031 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9032 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9033 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9034 break;
9035 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9036 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9037 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9038 break;
9039 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9040 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9041 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9042 if (data->fmt.win.clipcount && data->fmt.win.clips)
9043 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9044 (Addr)data->fmt.win.clips,
9045 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9046 if (data->fmt.win.bitmap)
9047 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9048 (Addr)data->fmt.win.bitmap,
9049 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
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_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9054 break;
9055 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9056 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9057 break;
9059 break;
9061 case VKI_V4L2_TRY_FMT: {
9062 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9063 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9064 switch (data->type) {
9065 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9066 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9067 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9068 (Addr)&data->type + sizeof(data->type),
9069 sizeof(*data) - sizeof(data->type));
9070 break;
9071 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9072 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9073 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9074 break;
9075 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9076 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9077 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9078 break;
9079 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9080 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9081 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9082 if (data->fmt.win.clipcount && data->fmt.win.clips)
9083 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9084 (Addr)data->fmt.win.clips,
9085 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9086 if (data->fmt.win.bitmap)
9087 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9088 (Addr)data->fmt.win.bitmap,
9089 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9090 break;
9091 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9092 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9093 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9094 break;
9095 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9096 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9097 break;
9099 break;
9101 case VKI_V4L2_REQBUFS: {
9102 struct vki_v4l2_requestbuffers *data =
9103 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9104 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9105 break;
9107 case VKI_V4L2_QUERYBUF: {
9108 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9109 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9110 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9111 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9112 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9113 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9114 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9115 unsigned i;
9117 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9118 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9119 for (i = 0; i < data->length; i++) {
9120 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9121 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9122 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9123 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9124 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9126 } else {
9127 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9128 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9130 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9131 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9132 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9133 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9134 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9135 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9136 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9137 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9138 break;
9140 case VKI_V4L2_G_FBUF: {
9141 struct vki_v4l2_framebuffer *data =
9142 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9143 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9144 break;
9146 case VKI_V4L2_S_FBUF: {
9147 struct vki_v4l2_framebuffer *data =
9148 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9149 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9150 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9151 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9152 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9153 break;
9155 case VKI_V4L2_OVERLAY: {
9156 int *data = (int *)(Addr)ARG3;
9157 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9158 break;
9160 case VKI_V4L2_QBUF: {
9161 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9162 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9163 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9164 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9165 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9167 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9168 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9169 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9170 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9171 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9172 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9173 if (is_output) {
9174 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9175 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9177 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9178 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9179 unsigned i;
9181 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9182 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9183 for (i = 0; i < data->length; i++) {
9184 if (is_output) {
9185 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9186 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9188 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9189 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9190 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9191 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9192 else
9193 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9194 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9196 } else {
9197 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9198 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9199 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9200 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9201 else
9202 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9203 if (is_output) {
9204 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9205 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9208 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9209 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9210 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9212 break;
9214 case VKI_V4L2_EXPBUF: {
9215 struct vki_v4l2_exportbuffer *data =
9216 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9217 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9218 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9219 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9220 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9221 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9222 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9223 break;
9225 case VKI_V4L2_DQBUF: {
9226 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9227 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9228 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9229 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9231 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9232 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9233 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9234 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9235 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9236 unsigned i;
9238 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9239 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9240 for (i = 0; i < data->length; i++) {
9241 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9242 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9243 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9244 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9245 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9247 } else {
9248 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9249 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9250 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9251 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9253 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9254 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9255 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9256 break;
9258 case VKI_V4L2_STREAMON: {
9259 int *data = (int *)(Addr)ARG3;
9260 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9261 break;
9263 case VKI_V4L2_STREAMOFF: {
9264 int *data = (int *)(Addr)ARG3;
9265 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9266 break;
9268 case VKI_V4L2_G_PARM: {
9269 struct vki_v4l2_streamparm *data =
9270 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9271 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9272 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9273 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9274 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9276 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9277 if (is_output) {
9278 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9279 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9280 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9281 } else {
9282 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9283 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9284 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9286 break;
9288 case VKI_V4L2_S_PARM: {
9289 struct vki_v4l2_streamparm *data =
9290 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9291 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9292 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9293 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9294 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9296 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9297 if (is_output)
9298 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9299 else
9300 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9301 break;
9303 case VKI_V4L2_G_STD: {
9304 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9305 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9306 break;
9308 case VKI_V4L2_S_STD: {
9309 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9310 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9311 break;
9313 case VKI_V4L2_ENUMSTD: {
9314 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9315 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9316 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9317 break;
9319 case VKI_V4L2_ENUMINPUT: {
9320 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9321 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9322 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9323 break;
9325 case VKI_V4L2_G_CTRL: {
9326 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9327 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9328 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9329 break;
9331 case VKI_V4L2_S_CTRL: {
9332 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9333 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9334 break;
9336 case VKI_V4L2_G_TUNER: {
9337 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9338 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9339 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9340 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9341 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9342 break;
9344 case VKI_V4L2_S_TUNER: {
9345 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9346 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9347 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9348 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9349 break;
9351 case VKI_V4L2_G_AUDIO: {
9352 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9353 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9354 sizeof(*data) - sizeof(data->reserved));
9355 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9356 break;
9358 case VKI_V4L2_S_AUDIO: {
9359 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9360 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9361 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9362 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9363 break;
9365 case VKI_V4L2_QUERYCTRL: {
9366 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9367 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9368 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9369 sizeof(*data) - sizeof(data->id));
9370 break;
9372 case VKI_V4L2_QUERYMENU: {
9373 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9374 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9375 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9376 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9377 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9378 break;
9380 case VKI_V4L2_G_INPUT: {
9381 int *data = (int *)(Addr)ARG3;
9382 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9383 break;
9385 case VKI_V4L2_S_INPUT: {
9386 int *data = (int *)(Addr)ARG3;
9387 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9388 break;
9390 case VKI_V4L2_G_EDID: {
9391 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9392 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9393 if (data->blocks && data->edid)
9394 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9395 break;
9397 case VKI_V4L2_S_EDID: {
9398 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9399 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9400 if (data->blocks && data->edid)
9401 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9402 break;
9404 case VKI_V4L2_G_OUTPUT: {
9405 int *data = (int *)(Addr)ARG3;
9406 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9407 break;
9409 case VKI_V4L2_S_OUTPUT: {
9410 int *data = (int *)(Addr)ARG3;
9411 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9412 break;
9414 case VKI_V4L2_ENUMOUTPUT: {
9415 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9416 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9417 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9418 break;
9420 case VKI_V4L2_G_AUDOUT: {
9421 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9422 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9423 sizeof(*data) - sizeof(data->reserved));
9424 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9425 break;
9427 case VKI_V4L2_S_AUDOUT: {
9428 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9429 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9430 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9431 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9432 break;
9434 case VKI_V4L2_G_MODULATOR: {
9435 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9436 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9437 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9438 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9439 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9440 break;
9442 case VKI_V4L2_S_MODULATOR: {
9443 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9444 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9445 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9446 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9447 break;
9449 case VKI_V4L2_G_FREQUENCY: {
9450 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9451 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9452 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9453 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9454 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9455 break;
9457 case VKI_V4L2_S_FREQUENCY: {
9458 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9459 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9460 break;
9462 case VKI_V4L2_CROPCAP: {
9463 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9464 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9465 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9466 break;
9468 case VKI_V4L2_G_CROP: {
9469 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9470 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9471 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9472 break;
9474 case VKI_V4L2_S_CROP: {
9475 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9476 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9477 break;
9479 case VKI_V4L2_G_JPEGCOMP: {
9480 struct vki_v4l2_jpegcompression *data =
9481 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9482 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9483 break;
9485 case VKI_V4L2_S_JPEGCOMP: {
9486 struct vki_v4l2_jpegcompression *data =
9487 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9488 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9489 break;
9491 case VKI_V4L2_QUERYSTD: {
9492 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9493 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9494 break;
9496 case VKI_V4L2_ENUMAUDIO: {
9497 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9498 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9499 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9500 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9501 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9502 break;
9504 case VKI_V4L2_ENUMAUDOUT: {
9505 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9506 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9507 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9508 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9509 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9510 break;
9512 case VKI_V4L2_G_PRIORITY: {
9513 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9514 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9515 break;
9517 case VKI_V4L2_S_PRIORITY: {
9518 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9519 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9520 break;
9522 case VKI_V4L2_G_SLICED_VBI_CAP: {
9523 struct vki_v4l2_sliced_vbi_cap *data =
9524 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9525 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9526 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9527 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9528 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9529 break;
9531 case VKI_V4L2_G_EXT_CTRLS: {
9532 struct vki_v4l2_ext_controls *data =
9533 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9534 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9535 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9536 if (data->count) {
9537 unsigned i;
9539 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9540 for (i = 0; i < data->count; i++) {
9541 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9542 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9543 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9544 if (data->controls[i].size) {
9545 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9546 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9547 (Addr)data->controls[i].ptr, data->controls[i].size);
9548 } else {
9549 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9550 data->controls[i].value64);
9554 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9555 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9556 break;
9558 case VKI_V4L2_S_EXT_CTRLS: {
9559 struct vki_v4l2_ext_controls *data =
9560 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9561 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9562 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9563 if (data->count) {
9564 unsigned i;
9566 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9567 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9568 data->count * sizeof(data->controls[0]));
9569 for (i = 0; i < data->count; i++) {
9570 if (data->controls[i].size) {
9571 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9572 (Addr)data->controls[i].ptr, data->controls[i].size);
9576 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9577 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9578 break;
9580 case VKI_V4L2_TRY_EXT_CTRLS: {
9581 struct vki_v4l2_ext_controls *data =
9582 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9583 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9584 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9585 if (data->count) {
9586 unsigned i;
9588 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9589 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9590 data->count * sizeof(data->controls[0]));
9591 for (i = 0; i < data->count; i++) {
9592 if (data->controls[i].size) {
9593 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9594 (Addr)data->controls[i].ptr, data->controls[i].size);
9598 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9599 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9600 break;
9602 case VKI_V4L2_ENUM_FRAMESIZES: {
9603 struct vki_v4l2_frmsizeenum *data =
9604 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9605 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9606 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9607 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9608 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9609 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9610 break;
9612 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9613 struct vki_v4l2_frmivalenum *data =
9614 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9615 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9616 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9617 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9618 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9619 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9620 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9621 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9622 break;
9624 case VKI_V4L2_G_ENC_INDEX: {
9625 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9626 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9627 break;
9629 case VKI_V4L2_ENCODER_CMD: {
9630 struct vki_v4l2_encoder_cmd *data =
9631 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9632 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9633 break;
9635 case VKI_V4L2_TRY_ENCODER_CMD: {
9636 struct vki_v4l2_encoder_cmd *data =
9637 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9638 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9639 break;
9641 case VKI_V4L2_DBG_S_REGISTER: {
9642 struct vki_v4l2_dbg_register *data =
9643 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9644 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9645 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9646 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9647 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9648 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9649 break;
9651 case VKI_V4L2_DBG_G_REGISTER: {
9652 struct vki_v4l2_dbg_register *data =
9653 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9654 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9655 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9656 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9657 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9658 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9659 break;
9661 case VKI_V4L2_S_HW_FREQ_SEEK: {
9662 struct vki_v4l2_hw_freq_seek *data =
9663 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9664 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9665 break;
9667 case VKI_V4L2_S_DV_TIMINGS: {
9668 struct vki_v4l2_dv_timings *data =
9669 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9670 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9671 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9672 break;
9674 case VKI_V4L2_G_DV_TIMINGS: {
9675 struct vki_v4l2_dv_timings *data =
9676 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9677 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9678 break;
9680 case VKI_V4L2_DQEVENT: {
9681 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9682 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9683 break;
9685 case VKI_V4L2_SUBSCRIBE_EVENT: {
9686 struct vki_v4l2_event_subscription *data =
9687 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9688 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9689 break;
9691 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9692 struct vki_v4l2_event_subscription *data =
9693 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9694 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9695 break;
9697 case VKI_V4L2_CREATE_BUFS: {
9698 struct vki_v4l2_create_buffers *data =
9699 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9700 struct vki_v4l2_format *fmt = &data->format;
9701 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9702 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9703 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9704 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9705 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9706 switch (fmt->type) {
9707 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9708 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9709 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9710 break;
9711 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9712 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9713 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9714 break;
9715 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9716 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9717 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9718 break;
9719 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9720 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9721 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9722 break;
9723 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9724 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9725 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9726 break;
9727 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9728 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9729 break;
9731 break;
9733 case VKI_V4L2_PREPARE_BUF: {
9734 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9735 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9736 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9737 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9738 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9739 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9740 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9741 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9742 unsigned i;
9744 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9745 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9746 for (i = 0; i < data->length; i++) {
9747 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9750 break;
9752 case VKI_V4L2_G_SELECTION: {
9753 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9754 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9755 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9756 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9757 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9758 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9759 break;
9761 case VKI_V4L2_S_SELECTION: {
9762 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9763 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9764 break;
9766 case VKI_V4L2_DECODER_CMD: {
9767 struct vki_v4l2_decoder_cmd *data =
9768 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9769 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9770 break;
9772 case VKI_V4L2_TRY_DECODER_CMD: {
9773 struct vki_v4l2_decoder_cmd *data =
9774 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9775 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9776 break;
9778 case VKI_V4L2_ENUM_DV_TIMINGS: {
9779 struct vki_v4l2_enum_dv_timings *data =
9780 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9781 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9782 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9783 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9784 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9785 break;
9787 case VKI_V4L2_QUERY_DV_TIMINGS: {
9788 struct vki_v4l2_dv_timings *data =
9789 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9790 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9791 break;
9793 case VKI_V4L2_DV_TIMINGS_CAP: {
9794 struct vki_v4l2_dv_timings_cap *data =
9795 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9796 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9797 break;
9799 case VKI_V4L2_ENUM_FREQ_BANDS: {
9800 struct vki_v4l2_frequency_band *data =
9801 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9802 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9803 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9804 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9805 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9806 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9807 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9808 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9809 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9810 break;
9812 case VKI_V4L2_DBG_G_CHIP_INFO: {
9813 struct vki_v4l2_dbg_chip_info *data =
9814 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9815 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9816 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9817 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9818 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9819 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9820 break;
9822 case VKI_V4L2_QUERY_EXT_CTRL: {
9823 struct vki_v4l2_query_ext_ctrl *data =
9824 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9825 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9826 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9827 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9828 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9829 break;
9831 case VKI_V4L2_SUBDEV_G_FMT: {
9832 struct vki_v4l2_subdev_format *data =
9833 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9834 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9835 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9836 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9837 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9838 break;
9840 case VKI_V4L2_SUBDEV_S_FMT: {
9841 struct vki_v4l2_subdev_format *data =
9842 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9843 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9844 break;
9846 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9847 struct vki_v4l2_subdev_frame_interval *data =
9848 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9849 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9850 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9851 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9852 break;
9854 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9855 struct vki_v4l2_subdev_frame_interval *data =
9856 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9857 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9858 break;
9860 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9861 struct vki_v4l2_subdev_mbus_code_enum *data =
9862 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9863 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9864 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9865 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9866 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9867 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9868 break;
9870 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9871 struct vki_v4l2_subdev_frame_size_enum *data =
9872 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9873 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9874 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9875 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9876 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9877 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9878 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9879 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9880 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9881 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9882 break;
9884 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9885 struct vki_v4l2_subdev_frame_interval_enum *data =
9886 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9887 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9888 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9889 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9890 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9891 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9892 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9893 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9894 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9895 break;
9897 case VKI_V4L2_SUBDEV_G_CROP: {
9898 struct vki_v4l2_subdev_crop *data =
9899 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9900 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9901 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9902 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9903 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9904 break;
9906 case VKI_V4L2_SUBDEV_S_CROP: {
9907 struct vki_v4l2_subdev_crop *data =
9908 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9909 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9910 break;
9912 case VKI_V4L2_SUBDEV_G_SELECTION: {
9913 struct vki_v4l2_subdev_selection *data =
9914 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9915 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9916 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9917 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9918 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9919 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9920 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9921 break;
9923 case VKI_V4L2_SUBDEV_S_SELECTION: {
9924 struct vki_v4l2_subdev_selection *data =
9925 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9926 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
9927 break;
9929 case VKI_MEDIA_IOC_DEVICE_INFO: {
9930 struct vki_media_device_info *data =
9931 (struct vki_media_device_info *)(Addr)ARG3;
9932 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
9933 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
9934 (Addr)data, sizeof(*data) - sizeof(data->reserved));
9935 break;
9937 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
9938 struct vki_media_entity_desc *data =
9939 (struct vki_media_entity_desc *)(Addr)ARG3;
9940 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
9941 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
9942 (Addr)data->name, sizeof(*data) - sizeof(data->id));
9943 break;
9945 case VKI_MEDIA_IOC_ENUM_LINKS: {
9946 struct vki_media_links_enum *data =
9947 (struct vki_media_links_enum *)(Addr)ARG3;
9948 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
9949 break;
9951 case VKI_MEDIA_IOC_SETUP_LINK: {
9952 struct vki_media_link_desc *data =
9953 (struct vki_media_link_desc *)(Addr)ARG3;
9954 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
9955 break;
9958 /* Serial */
9959 case VKI_TIOCGSERIAL: {
9960 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9961 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9962 break;
9964 case VKI_TIOCSSERIAL: {
9965 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9966 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9967 break;
9970 case VKI_PERF_EVENT_IOC_RESET:
9971 case VKI_PERF_EVENT_IOC_REFRESH:
9972 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9973 case VKI_PERF_EVENT_IOC_SET_BPF:
9974 /* These take scalar arguments, so already handled above */
9975 break;
9977 case VKI_PERF_EVENT_IOC_PERIOD:
9978 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9979 break;
9981 case VKI_PERF_EVENT_IOC_SET_FILTER:
9982 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9983 break;
9985 case VKI_PERF_EVENT_IOC_ID:
9986 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9987 break;
9989 /* Pulse Per Second (PPS) */
9990 case VKI_PPS_GETPARAMS: {
9991 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
9992 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
9993 break;
9995 case VKI_PPS_SETPARAMS: {
9996 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
9997 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
9998 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
9999 data->assert_off_tu.sec);
10000 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10001 data->assert_off_tu.nsec);
10002 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10003 data->clear_off_tu.sec);
10004 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10005 data->clear_off_tu.nsec);
10006 break;
10008 case VKI_PPS_GETCAP:
10009 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10010 break;
10011 case VKI_PPS_FETCH: {
10012 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10013 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10014 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10015 break;
10017 case VKI_PPS_KC_BIND: {
10018 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10019 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10020 break;
10023 /* PTP Hardware Clock */
10024 case VKI_PTP_CLOCK_GETCAPS: {
10025 struct vki_ptp_clock_caps *data =
10026 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10027 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10028 break;
10030 case VKI_PTP_EXTTS_REQUEST: {
10031 struct vki_ptp_extts_request *data =
10032 (struct vki_ptp_extts_request *)(Addr)ARG3;
10033 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10034 break;
10036 case VKI_PTP_PEROUT_REQUEST: {
10037 struct vki_ptp_perout_request *data =
10038 (struct vki_ptp_perout_request *)(Addr)ARG3;
10039 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10040 break;
10042 case VKI_PTP_ENABLE_PPS:
10043 break;
10044 case VKI_PTP_SYS_OFFSET: {
10045 struct vki_ptp_sys_offset *data =
10046 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10047 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10048 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10049 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10050 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10051 break;
10053 case VKI_PTP_PIN_GETFUNC: {
10054 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10055 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10056 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10057 break;
10059 case VKI_PTP_PIN_SETFUNC: {
10060 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10061 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10062 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10063 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10064 break;
10066 case VKI_PTP_SYS_OFFSET_PRECISE: {
10067 struct vki_ptp_sys_offset_precise *data =
10068 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10069 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10070 break;
10072 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10073 struct vki_ptp_sys_offset_extended *data =
10074 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10075 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10076 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10077 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10078 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10079 3 * data->n_samples * sizeof(data->ts[0][0]));
10080 break;
10083 default:
10084 /* EVIOC* are variable length and return size written on success */
10085 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10086 case VKI_EVIOCGNAME(0):
10087 case VKI_EVIOCGPHYS(0):
10088 case VKI_EVIOCGUNIQ(0):
10089 case VKI_EVIOCGKEY(0):
10090 case VKI_EVIOCGLED(0):
10091 case VKI_EVIOCGSND(0):
10092 case VKI_EVIOCGSW(0):
10093 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10094 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10095 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10096 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10097 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10098 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10099 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10100 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10101 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10102 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10103 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10104 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10105 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10106 break;
10107 default:
10108 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10109 break;
10111 break;
10115 POST(sys_ioctl)
10117 ARG2 = (UInt)ARG2;
10119 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10121 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10123 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10124 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10125 VG_(clo_kernel_variant))) {
10127 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10128 /* What's going on here: there appear to be a bunch of ioctls
10129 of the form 0xC01C67xx which are undocumented, and if
10130 unhandled give rise to a vast number of false positives in
10131 Memcheck.
10133 The "normal" interpretation of an ioctl of this form would
10134 be that the 3rd arg is a pointer to an area of size 0x1C
10135 (28 bytes) which is filled in by the kernel. Hence you
10136 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10137 But it doesn't.
10139 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10140 One interpretation of this is that ARG3 really does point
10141 to a 28 byte struct, but inside that are pointers to other
10142 areas also filled in by the kernel. If these happen to be
10143 allocated just back up the stack then the 256 byte paint
10144 might cover them too, somewhat indiscriminately.
10146 By printing out ARG3 and also the 28 bytes that it points
10147 at, it's possible to guess that the 7 word structure has
10148 this form
10150 0 1 2 3 4 5 6
10151 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10153 Unfortunately that doesn't seem to work for some reason,
10154 so stay with the blunt-instrument approach for the time
10155 being.
10157 if (1) {
10158 /* blunt-instrument approach */
10159 POST_MEM_WRITE(ARG3, 256);
10160 } else {
10161 /* be a bit more sophisticated */
10162 POST_MEM_WRITE(ARG3, 28);
10163 UInt* word = (UInt*)(Addr)ARG3;
10164 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10165 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10166 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10167 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10169 goto post_sys_ioctl__out;
10172 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10174 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10175 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10176 VG_(clo_kernel_variant))) {
10177 if (ARG2 == 0xC00C0902) {
10178 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10179 goto post_sys_ioctl__out;
10182 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10184 /* --- END special IOCTL handlers for specific Android hardware --- */
10186 /* --- normal handling --- */
10187 switch (ARG2 /* request */) {
10189 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10190 this is pretty poor given that there's no pre-handling to check
10191 that writable areas are addressable. */
10192 case VKI_ION_IOC_ALLOC: {
10193 struct vki_ion_allocation_data* data
10194 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10195 POST_FIELD_WRITE(data->handle);
10196 break;
10198 case VKI_ION_IOC_MAP: {
10199 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10200 POST_FIELD_WRITE(data->fd);
10201 break;
10203 case VKI_ION_IOC_FREE: // is this necessary?
10204 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10205 break;
10206 case VKI_ION_IOC_SHARE:
10207 break;
10208 case VKI_ION_IOC_IMPORT: {
10209 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10210 POST_FIELD_WRITE(data->handle);
10211 break;
10213 case VKI_ION_IOC_SYNC:
10214 break;
10215 case VKI_ION_IOC_CUSTOM: // is this necessary?
10216 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10217 break;
10219 case VKI_SYNC_IOC_MERGE: {
10220 struct vki_sync_merge_data* data =
10221 (struct vki_sync_merge_data*)(Addr)ARG3;
10222 POST_FIELD_WRITE(data->fence);
10223 break;
10226 case VKI_TCSETS:
10227 case VKI_TCSETSW:
10228 case VKI_TCSETSF:
10229 case VKI_IB_USER_MAD_ENABLE_PKEY:
10230 break;
10231 case VKI_TCGETS:
10232 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10233 break;
10234 case VKI_TCSETA:
10235 case VKI_TCSETAW:
10236 case VKI_TCSETAF:
10237 break;
10238 case VKI_TCGETA:
10239 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10240 break;
10241 case VKI_TCSBRK:
10242 case VKI_TCXONC:
10243 case VKI_TCSBRKP:
10244 case VKI_TCFLSH:
10245 case VKI_TIOCSIG:
10246 break;
10247 case VKI_TIOCGWINSZ:
10248 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10249 break;
10250 case VKI_TIOCSWINSZ:
10251 case VKI_TIOCMBIS:
10252 case VKI_TIOCMBIC:
10253 case VKI_TIOCMSET:
10254 break;
10255 case VKI_TIOCMGET:
10256 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10257 break;
10258 case VKI_TIOCLINUX:
10259 POST_MEM_WRITE( ARG3, sizeof(char *) );
10260 break;
10261 case VKI_TIOCGPGRP:
10262 /* Get process group ID for foreground processing group. */
10263 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10264 break;
10265 case VKI_TIOCSPGRP:
10266 /* Set a process group ID? */
10267 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10268 break;
10269 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10270 POST_MEM_WRITE( ARG3, sizeof(int));
10271 break;
10272 case VKI_TIOCSCTTY:
10273 break;
10274 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10275 break;
10276 case VKI_FIONBIO:
10277 break;
10278 case VKI_FIONCLEX:
10279 break;
10280 case VKI_FIOCLEX:
10281 break;
10282 case VKI_TIOCNOTTY:
10283 break;
10284 case VKI_FIOASYNC:
10285 break;
10286 case VKI_FIONREAD: /* identical to SIOCINQ */
10287 POST_MEM_WRITE( ARG3, sizeof(int) );
10288 break;
10289 case VKI_FIOQSIZE:
10290 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10291 break;
10293 case VKI_TIOCSERGETLSR:
10294 POST_MEM_WRITE( ARG3, sizeof(int) );
10295 break;
10296 case VKI_TIOCGICOUNT:
10297 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10298 break;
10300 case VKI_SG_SET_COMMAND_Q:
10301 break;
10302 case VKI_SG_IO:
10304 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10305 if ( sgio->sbp ) {
10306 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10308 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10309 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10310 int transferred = sgio->dxfer_len - sgio->resid;
10311 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10314 break;
10315 case VKI_SG_GET_SCSI_ID:
10316 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10317 break;
10318 case VKI_SG_SET_RESERVED_SIZE:
10319 break;
10320 case VKI_SG_SET_TIMEOUT:
10321 break;
10322 case VKI_SG_GET_RESERVED_SIZE:
10323 POST_MEM_WRITE(ARG3, sizeof(int));
10324 break;
10325 case VKI_SG_GET_TIMEOUT:
10326 break;
10327 case VKI_SG_GET_VERSION_NUM:
10328 POST_MEM_WRITE(ARG3, sizeof(int));
10329 break;
10330 case VKI_SG_EMULATED_HOST:
10331 POST_MEM_WRITE(ARG3, sizeof(int));
10332 break;
10333 case VKI_SG_GET_SG_TABLESIZE:
10334 POST_MEM_WRITE(ARG3, sizeof(int));
10335 break;
10337 case VKI_IIOCGETCPS:
10338 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10339 break;
10340 case VKI_IIOCNETGPN:
10341 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10342 break;
10344 /* These all use struct ifreq AFAIK */
10345 case VKI_SIOCGIFINDEX: /* get iface index */
10346 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10347 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10348 break;
10349 case VKI_SIOCGIFFLAGS: /* get flags */
10350 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10351 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10352 break;
10353 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10354 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10355 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10356 break;
10357 case VKI_SIOCGIFMTU: /* get MTU size */
10358 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10359 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10360 break;
10361 case VKI_SIOCGIFADDR: /* get PA address */
10362 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10363 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10364 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10365 POST_MEM_WRITE(
10366 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10367 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10368 break;
10369 case VKI_SIOCGIFMETRIC: /* get metric */
10370 POST_MEM_WRITE(
10371 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10372 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10373 break;
10374 case VKI_SIOCGIFMAP: /* Get device parameters */
10375 POST_MEM_WRITE(
10376 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10377 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10378 break;
10379 break;
10380 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10381 POST_MEM_WRITE(
10382 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10383 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10384 break;
10385 case VKI_SIOCGIFNAME: /* get iface name */
10386 POST_MEM_WRITE(
10387 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10388 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10389 break;
10390 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10391 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10392 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10393 case VKI_ETHTOOL_GSET:
10394 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10395 break;
10396 case VKI_ETHTOOL_SSET:
10397 break;
10398 case VKI_ETHTOOL_GDRVINFO:
10399 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10400 break;
10401 case VKI_ETHTOOL_GREGS:
10402 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10403 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10404 break;
10405 case VKI_ETHTOOL_GWOL:
10406 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10407 break;
10408 case VKI_ETHTOOL_SWOL:
10409 break;
10410 case VKI_ETHTOOL_GMSGLVL:
10411 case VKI_ETHTOOL_GLINK:
10412 case VKI_ETHTOOL_GRXCSUM:
10413 case VKI_ETHTOOL_GSG:
10414 case VKI_ETHTOOL_GTSO:
10415 case VKI_ETHTOOL_GUFO:
10416 case VKI_ETHTOOL_GGSO:
10417 case VKI_ETHTOOL_GFLAGS:
10418 case VKI_ETHTOOL_GGRO:
10419 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10420 break;
10421 case VKI_ETHTOOL_SMSGLVL:
10422 case VKI_ETHTOOL_SRXCSUM:
10423 case VKI_ETHTOOL_SSG:
10424 case VKI_ETHTOOL_STSO:
10425 case VKI_ETHTOOL_SUFO:
10426 case VKI_ETHTOOL_SGSO:
10427 case VKI_ETHTOOL_SFLAGS:
10428 case VKI_ETHTOOL_SGRO:
10429 break;
10430 case VKI_ETHTOOL_NWAY_RST:
10431 break;
10432 case VKI_ETHTOOL_GRINGPARAM:
10433 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10434 break;
10435 case VKI_ETHTOOL_SRINGPARAM:
10436 break;
10437 case VKI_ETHTOOL_TEST:
10438 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10439 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10440 break;
10441 case VKI_ETHTOOL_PHYS_ID:
10442 break;
10443 case VKI_ETHTOOL_GPERMADDR:
10444 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10445 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10446 break;
10447 case VKI_ETHTOOL_RESET:
10448 break;
10449 case VKI_ETHTOOL_GSSET_INFO:
10450 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10451 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10452 break;
10453 case VKI_ETHTOOL_GFEATURES:
10454 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10455 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10456 break;
10457 case VKI_ETHTOOL_SFEATURES:
10458 break;
10459 case VKI_ETHTOOL_GCHANNELS:
10460 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10461 break;
10462 case VKI_ETHTOOL_SCHANNELS:
10463 break;
10464 case VKI_ETHTOOL_GET_TS_INFO:
10465 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10466 break;
10468 break;
10470 case VKI_SIOCGMIIPHY: /* get hardware entry */
10471 POST_MEM_WRITE(
10472 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10473 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10474 break;
10475 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10476 POST_MEM_WRITE(
10477 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10478 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10479 break;
10481 /* tun/tap related ioctls */
10482 case VKI_TUNSETIFF:
10483 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10484 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10485 break;
10486 case VKI_TUNGETFEATURES:
10487 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10488 break;
10489 case VKI_TUNGETIFF:
10490 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10491 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10492 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10493 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10494 break;
10495 case VKI_TUNGETSNDBUF:
10496 POST_MEM_WRITE( ARG3, sizeof(int) );
10497 break;
10498 case VKI_TUNGETVNETHDRSZ:
10499 POST_MEM_WRITE( ARG3, sizeof(int) );
10500 break;
10502 case VKI_SIOCGIFCONF: /* get iface list */
10503 /* WAS:
10504 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10505 KERNEL_DO_SYSCALL(tid,RES);
10506 if (!VG_(is_kerror)(RES) && RES == 0)
10507 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10509 if (RES == 0 && ARG3 ) {
10510 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10511 if (ifc->vki_ifc_buf != NULL)
10512 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10514 break;
10515 case VKI_SIOCGSTAMP:
10516 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10517 break;
10518 case VKI_SIOCGSTAMPNS:
10519 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10520 break;
10521 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10522 the number of bytes currently in that socket's send buffer.
10523 It writes this value as an int to the memory location
10524 indicated by the third argument of ioctl(2). */
10525 case VKI_SIOCOUTQ:
10526 POST_MEM_WRITE(ARG3, sizeof(int));
10527 break;
10528 case VKI_SIOCGRARP: /* get RARP table entry */
10529 case VKI_SIOCGARP: /* get ARP table entry */
10530 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10531 break;
10533 case VKI_SIOCSIFFLAGS: /* set flags */
10534 case VKI_SIOCSIFMAP: /* Set device parameters */
10535 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10536 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10537 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10538 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10539 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10540 case VKI_SIOCSIFMETRIC: /* set metric */
10541 case VKI_SIOCSIFADDR: /* set PA address */
10542 case VKI_SIOCSIFMTU: /* set MTU size */
10543 case VKI_SIOCSIFHWADDR: /* set hardware address */
10544 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10545 break;
10546 /* Routing table calls. */
10547 case VKI_SIOCADDRT: /* add routing table entry */
10548 case VKI_SIOCDELRT: /* delete routing table entry */
10549 break;
10551 /* RARP cache control calls. */
10552 case VKI_SIOCDRARP: /* delete RARP table entry */
10553 case VKI_SIOCSRARP: /* set RARP table entry */
10554 /* ARP cache control calls. */
10555 case VKI_SIOCSARP: /* set ARP table entry */
10556 case VKI_SIOCDARP: /* delete ARP table entry */
10557 break;
10559 case VKI_SIOCGPGRP:
10560 POST_MEM_WRITE(ARG3, sizeof(int));
10561 break;
10562 case VKI_SIOCSPGRP:
10563 break;
10565 case VKI_SIOCATMARK:
10566 POST_MEM_WRITE(ARG3, sizeof(int));
10567 break;
10569 /* linux/soundcard interface (OSS) */
10570 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10571 case VKI_SNDCTL_SEQ_GETINCOUNT:
10572 case VKI_SNDCTL_SEQ_PERCMODE:
10573 case VKI_SNDCTL_SEQ_TESTMIDI:
10574 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10575 case VKI_SNDCTL_SEQ_NRSYNTHS:
10576 case VKI_SNDCTL_SEQ_NRMIDIS:
10577 case VKI_SNDCTL_SEQ_GETTIME:
10578 case VKI_SNDCTL_DSP_GETBLKSIZE:
10579 case VKI_SNDCTL_DSP_GETFMTS:
10580 case VKI_SNDCTL_DSP_SETFMT:
10581 case VKI_SNDCTL_DSP_GETTRIGGER:
10582 case VKI_SNDCTL_DSP_GETODELAY:
10583 case VKI_SNDCTL_DSP_GETSPDIF:
10584 case VKI_SNDCTL_DSP_GETCAPS:
10585 case VKI_SOUND_PCM_READ_RATE:
10586 case VKI_SOUND_PCM_READ_CHANNELS:
10587 case VKI_SOUND_PCM_READ_BITS:
10588 case VKI_SOUND_PCM_READ_FILTER:
10589 POST_MEM_WRITE(ARG3, sizeof(int));
10590 break;
10591 case VKI_SNDCTL_SEQ_CTRLRATE:
10592 case VKI_SNDCTL_DSP_SPEED:
10593 case VKI_SNDCTL_DSP_STEREO:
10594 case VKI_SNDCTL_DSP_CHANNELS:
10595 case VKI_SOUND_PCM_WRITE_FILTER:
10596 case VKI_SNDCTL_DSP_SUBDIVIDE:
10597 case VKI_SNDCTL_DSP_SETFRAGMENT:
10598 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10599 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10600 case VKI_SNDCTL_TMR_TIMEBASE:
10601 case VKI_SNDCTL_TMR_TEMPO:
10602 case VKI_SNDCTL_TMR_SOURCE:
10603 case VKI_SNDCTL_MIDI_PRETIME:
10604 case VKI_SNDCTL_MIDI_MPUMODE:
10605 break;
10606 case VKI_SNDCTL_DSP_GETOSPACE:
10607 case VKI_SNDCTL_DSP_GETISPACE:
10608 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10609 break;
10610 case VKI_SNDCTL_DSP_NONBLOCK:
10611 break;
10612 case VKI_SNDCTL_DSP_SETTRIGGER:
10613 break;
10615 case VKI_SNDCTL_DSP_POST:
10616 case VKI_SNDCTL_DSP_RESET:
10617 case VKI_SNDCTL_DSP_SYNC:
10618 case VKI_SNDCTL_DSP_SETSYNCRO:
10619 case VKI_SNDCTL_DSP_SETDUPLEX:
10620 break;
10622 /* linux/soundcard interface (ALSA) */
10623 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10624 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10625 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10626 case VKI_SNDRV_PCM_IOCTL_RESET:
10627 case VKI_SNDRV_PCM_IOCTL_START:
10628 case VKI_SNDRV_PCM_IOCTL_DROP:
10629 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10630 case VKI_SNDRV_PCM_IOCTL_RESUME:
10631 case VKI_SNDRV_PCM_IOCTL_XRUN:
10632 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10633 case VKI_SNDRV_TIMER_IOCTL_START:
10634 case VKI_SNDRV_TIMER_IOCTL_STOP:
10635 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10636 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10637 break;
10639 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10640 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10641 break;
10643 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10644 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10645 break;
10646 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10647 struct vki_snd_ctl_elem_list *data =
10648 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10649 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10650 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10651 if (data->pids) {
10652 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10654 break;
10656 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10657 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10658 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10659 break;
10661 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10662 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10663 break;
10665 /* SCSI no operand */
10666 case VKI_SCSI_IOCTL_DOORLOCK:
10667 case VKI_SCSI_IOCTL_DOORUNLOCK:
10668 break;
10670 /* Real Time Clock (/dev/rtc) ioctls */
10671 case VKI_RTC_UIE_ON:
10672 case VKI_RTC_UIE_OFF:
10673 case VKI_RTC_AIE_ON:
10674 case VKI_RTC_AIE_OFF:
10675 case VKI_RTC_PIE_ON:
10676 case VKI_RTC_PIE_OFF:
10677 case VKI_RTC_IRQP_SET:
10678 break;
10679 case VKI_RTC_RD_TIME:
10680 case VKI_RTC_ALM_READ:
10681 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10682 break;
10683 case VKI_RTC_ALM_SET:
10684 break;
10685 case VKI_RTC_IRQP_READ:
10686 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10687 break;
10689 /* Block devices */
10690 case VKI_BLKROSET:
10691 break;
10692 case VKI_BLKROGET:
10693 POST_MEM_WRITE(ARG3, sizeof(int));
10694 break;
10695 case VKI_BLKGETSIZE:
10696 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10697 break;
10698 case VKI_BLKFLSBUF:
10699 break;
10700 case VKI_BLKRASET:
10701 break;
10702 case VKI_BLKRAGET:
10703 POST_MEM_WRITE(ARG3, sizeof(long));
10704 break;
10705 case VKI_BLKFRASET:
10706 break;
10707 case VKI_BLKFRAGET:
10708 POST_MEM_WRITE(ARG3, sizeof(long));
10709 break;
10710 case VKI_BLKSECTGET:
10711 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10712 break;
10713 case VKI_BLKSSZGET:
10714 POST_MEM_WRITE(ARG3, sizeof(int));
10715 break;
10716 case VKI_BLKBSZGET:
10717 POST_MEM_WRITE(ARG3, sizeof(int));
10718 break;
10719 case VKI_BLKBSZSET:
10720 break;
10721 case VKI_BLKGETSIZE64:
10722 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10723 break;
10724 case VKI_BLKPBSZGET:
10725 POST_MEM_WRITE(ARG3, sizeof(int));
10726 break;
10727 case VKI_BLKIOMIN:
10728 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10729 break;
10730 case VKI_BLKIOOPT:
10731 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10732 break;
10733 case VKI_BLKALIGNOFF:
10734 POST_MEM_WRITE(ARG3, sizeof(int));
10735 break;
10736 case VKI_BLKDISCARDZEROES:
10737 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10738 break;
10739 case VKI_BLKREPORTZONE: {
10740 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10742 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10743 break;
10745 case VKI_BLKRESETZONE:
10746 break;
10748 /* Hard disks */
10749 case VKI_HDIO_GETGEO: /* 0x0301 */
10750 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10751 break;
10752 case VKI_HDIO_GET_DMA: /* 0x030b */
10753 POST_MEM_WRITE(ARG3, sizeof(long));
10754 break;
10755 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10756 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10757 break;
10759 /* SCSI */
10760 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10761 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10762 break;
10763 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10764 POST_MEM_WRITE(ARG3, sizeof(int));
10765 break;
10767 /* CD ROM stuff (??) */
10768 case VKI_CDROM_DISC_STATUS:
10769 case VKI_CDROMSTOP:
10770 break;
10771 case VKI_CDROMSUBCHNL:
10772 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10773 break;
10774 case VKI_CDROMREADTOCHDR:
10775 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10776 break;
10777 case VKI_CDROMREADTOCENTRY:
10778 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10779 break;
10780 case VKI_CDROMMULTISESSION:
10781 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10782 break;
10783 case VKI_CDROMVOLREAD:
10784 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10785 break;
10786 case VKI_CDROMREADMODE1:
10787 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10788 break;
10789 case VKI_CDROMREADMODE2:
10790 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10791 break;
10792 case VKI_CDROMREADRAW:
10793 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10794 break;
10795 case VKI_CDROMREADAUDIO:
10797 struct vki_cdrom_read_audio *cra =
10798 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10799 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10800 break;
10803 case VKI_CDROMPLAYMSF:
10804 break;
10805 /* The following two are probably bogus (should check args
10806 for readability). JRS 20021117 */
10807 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10808 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10809 break;
10810 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10811 break;
10813 /* DVD stuff */
10814 case VKI_DVD_READ_STRUCT:
10815 break;
10817 case VKI_FIGETBSZ:
10818 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10819 break;
10820 case VKI_FIBMAP:
10821 POST_MEM_WRITE(ARG3, sizeof(int));
10822 break;
10824 case VKI_FBIOGET_VSCREENINFO: //0x4600
10825 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10826 break;
10827 case VKI_FBIOGET_FSCREENINFO: //0x4602
10828 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10829 break;
10831 case VKI_PPCLAIM:
10832 case VKI_PPEXCL:
10833 case VKI_PPYIELD:
10834 case VKI_PPRELEASE:
10835 case VKI_PPSETMODE:
10836 case VKI_PPSETPHASE:
10837 case VKI_PPSETFLAGS:
10838 case VKI_PPWDATA:
10839 case VKI_PPWCONTROL:
10840 case VKI_PPFCONTROL:
10841 case VKI_PPDATADIR:
10842 case VKI_PPNEGOT:
10843 case VKI_PPWCTLONIRQ:
10844 case VKI_PPSETTIME:
10845 break;
10846 case VKI_PPGETMODE:
10847 POST_MEM_WRITE( ARG3, sizeof(int) );
10848 break;
10849 case VKI_PPGETPHASE:
10850 POST_MEM_WRITE( ARG3, sizeof(int) );
10851 break;
10852 case VKI_PPGETMODES:
10853 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10854 break;
10855 case VKI_PPGETFLAGS:
10856 POST_MEM_WRITE( ARG3, sizeof(int) );
10857 break;
10858 case VKI_PPRSTATUS:
10859 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10860 break;
10861 case VKI_PPRDATA:
10862 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10863 break;
10864 case VKI_PPRCONTROL:
10865 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10866 break;
10867 case VKI_PPCLRIRQ:
10868 POST_MEM_WRITE( ARG3, sizeof(int) );
10869 break;
10870 case VKI_PPGETTIME:
10871 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10872 break;
10874 case VKI_GIO_FONT:
10875 POST_MEM_WRITE( ARG3, 32 * 256 );
10876 break;
10877 case VKI_PIO_FONT:
10878 break;
10880 case VKI_GIO_FONTX:
10881 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10882 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10883 break;
10884 case VKI_PIO_FONTX:
10885 break;
10887 case VKI_PIO_FONTRESET:
10888 break;
10890 case VKI_GIO_CMAP:
10891 POST_MEM_WRITE( ARG3, 16 * 3 );
10892 break;
10893 case VKI_PIO_CMAP:
10894 break;
10896 case VKI_KIOCSOUND:
10897 case VKI_KDMKTONE:
10898 break;
10900 case VKI_KDGETLED:
10901 POST_MEM_WRITE( ARG3, sizeof(char) );
10902 break;
10903 case VKI_KDSETLED:
10904 break;
10906 case VKI_KDGKBTYPE:
10907 POST_MEM_WRITE( ARG3, sizeof(char) );
10908 break;
10910 case VKI_KDADDIO:
10911 case VKI_KDDELIO:
10912 case VKI_KDENABIO:
10913 case VKI_KDDISABIO:
10914 break;
10916 case VKI_KDSETMODE:
10917 break;
10918 case VKI_KDGETMODE:
10919 POST_MEM_WRITE( ARG3, sizeof(int) );
10920 break;
10922 case VKI_KDMAPDISP:
10923 case VKI_KDUNMAPDISP:
10924 break;
10926 case VKI_GIO_SCRNMAP:
10927 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
10928 break;
10929 case VKI_PIO_SCRNMAP:
10930 break;
10931 case VKI_GIO_UNISCRNMAP:
10932 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
10933 break;
10934 case VKI_PIO_UNISCRNMAP:
10935 break;
10937 case VKI_GIO_UNIMAP:
10938 if ( ARG3 ) {
10939 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
10940 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
10941 POST_MEM_WRITE( (Addr)desc->entries,
10942 desc->entry_ct * sizeof(struct vki_unipair) );
10944 break;
10945 case VKI_PIO_UNIMAP:
10946 break;
10947 case VKI_PIO_UNIMAPCLR:
10948 break;
10950 case VKI_KDGKBMODE:
10951 POST_MEM_WRITE( ARG3, sizeof(int) );
10952 break;
10953 case VKI_KDSKBMODE:
10954 break;
10956 case VKI_KDGKBMETA:
10957 POST_MEM_WRITE( ARG3, sizeof(int) );
10958 break;
10959 case VKI_KDSKBMETA:
10960 break;
10962 case VKI_KDGKBLED:
10963 POST_MEM_WRITE( ARG3, sizeof(char) );
10964 break;
10965 case VKI_KDSKBLED:
10966 break;
10968 case VKI_KDGKBENT:
10969 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
10970 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
10971 break;
10972 case VKI_KDSKBENT:
10973 break;
10975 case VKI_KDGKBSENT:
10976 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
10977 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
10978 break;
10979 case VKI_KDSKBSENT:
10980 break;
10982 case VKI_KDGKBDIACR:
10983 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
10984 break;
10985 case VKI_KDSKBDIACR:
10986 break;
10988 case VKI_KDGETKEYCODE:
10989 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
10990 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
10991 break;
10992 case VKI_KDSETKEYCODE:
10993 break;
10995 case VKI_KDSIGACCEPT:
10996 break;
10998 case VKI_KDKBDREP:
10999 break;
11001 case VKI_KDFONTOP:
11002 if ( ARG3 ) {
11003 struct vki_console_font_op *op =
11004 (struct vki_console_font_op *) (Addr)ARG3;
11005 switch ( op->op ) {
11006 case VKI_KD_FONT_OP_SET:
11007 break;
11008 case VKI_KD_FONT_OP_GET:
11009 if ( op->data )
11010 POST_MEM_WRITE( (Addr) op->data,
11011 (op->width + 7) / 8 * 32 * op->charcount );
11012 break;
11013 case VKI_KD_FONT_OP_SET_DEFAULT:
11014 break;
11015 case VKI_KD_FONT_OP_COPY:
11016 break;
11018 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11020 break;
11022 case VKI_VT_OPENQRY:
11023 POST_MEM_WRITE( ARG3, sizeof(int) );
11024 break;
11025 case VKI_VT_GETMODE:
11026 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11027 break;
11028 case VKI_VT_SETMODE:
11029 break;
11030 case VKI_VT_GETSTATE:
11031 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11032 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11033 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11034 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11035 break;
11036 case VKI_VT_RELDISP:
11037 case VKI_VT_ACTIVATE:
11038 case VKI_VT_WAITACTIVE:
11039 case VKI_VT_DISALLOCATE:
11040 break;
11041 case VKI_VT_RESIZE:
11042 break;
11043 case VKI_VT_RESIZEX:
11044 break;
11045 case VKI_VT_LOCKSWITCH:
11046 case VKI_VT_UNLOCKSWITCH:
11047 break;
11049 case VKI_USBDEVFS_CONTROL:
11050 if ( ARG3 ) {
11051 struct vki_usbdevfs_ctrltransfer *vkuc =
11052 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11053 if (vkuc->bRequestType & 0x80)
11054 POST_MEM_WRITE((Addr)vkuc->data, RES);
11056 break;
11057 case VKI_USBDEVFS_BULK:
11058 if ( ARG3 ) {
11059 struct vki_usbdevfs_bulktransfer *vkub =
11060 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11061 if (vkub->ep & 0x80)
11062 POST_MEM_WRITE((Addr)vkub->data, RES);
11064 break;
11065 case VKI_USBDEVFS_GETDRIVER:
11066 if ( ARG3 ) {
11067 struct vki_usbdevfs_getdriver *vkugd =
11068 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11069 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11071 break;
11072 case VKI_USBDEVFS_REAPURB:
11073 case VKI_USBDEVFS_REAPURBNDELAY:
11074 if ( ARG3 ) {
11075 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11076 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11077 if (!*vkuu)
11078 break;
11079 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11080 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11081 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11082 if (vkusp->bRequestType & 0x80)
11083 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11084 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11085 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11086 char *bp = (*vkuu)->buffer;
11087 int i;
11088 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11089 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11090 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11091 if ((*vkuu)->endpoint & 0x80)
11092 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11093 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11095 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11096 } else {
11097 if ((*vkuu)->endpoint & 0x80)
11098 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11099 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11102 break;
11103 case VKI_USBDEVFS_CONNECTINFO:
11104 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11105 break;
11106 case VKI_USBDEVFS_IOCTL:
11107 if ( ARG3 ) {
11108 struct vki_usbdevfs_ioctl *vkui =
11109 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11110 UInt dir2, size2;
11111 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11112 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11113 if (size2 > 0) {
11114 if (dir2 & _VKI_IOC_READ)
11115 POST_MEM_WRITE((Addr)vkui->data, size2);
11118 break;
11120 /* I2C (/dev/i2c-*) ioctls */
11121 case VKI_I2C_SLAVE:
11122 case VKI_I2C_SLAVE_FORCE:
11123 case VKI_I2C_TENBIT:
11124 case VKI_I2C_PEC:
11125 break;
11126 case VKI_I2C_FUNCS:
11127 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11128 break;
11129 case VKI_I2C_RDWR:
11130 if ( ARG3 ) {
11131 struct vki_i2c_rdwr_ioctl_data *vkui =
11132 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11133 UInt i;
11134 for (i=0; i < vkui->nmsgs; i++) {
11135 struct vki_i2c_msg *msg = vkui->msgs + i;
11136 if (msg->flags & VKI_I2C_M_RD)
11137 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11140 break;
11141 case VKI_I2C_SMBUS:
11142 if ( ARG3 ) {
11143 struct vki_i2c_smbus_ioctl_data *vkis
11144 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11145 /* i2c_smbus_write_quick hides its value in read_write, so
11146 this variable can have a different meaning */
11147 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11148 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11149 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11150 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11151 UInt size;
11152 switch(vkis->size) {
11153 case VKI_I2C_SMBUS_BYTE:
11154 case VKI_I2C_SMBUS_BYTE_DATA:
11155 size = 1;
11156 break;
11157 case VKI_I2C_SMBUS_WORD_DATA:
11158 case VKI_I2C_SMBUS_PROC_CALL:
11159 size = 2;
11160 break;
11161 case VKI_I2C_SMBUS_BLOCK_DATA:
11162 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11163 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11164 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11165 size = 1 + vkis->data->block[0];
11166 break;
11167 default:
11168 size = 0;
11170 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11174 break;
11176 /* Wireless extensions ioctls */
11177 case VKI_SIOCSIWCOMMIT:
11178 case VKI_SIOCSIWNWID:
11179 case VKI_SIOCSIWFREQ:
11180 case VKI_SIOCSIWMODE:
11181 case VKI_SIOCSIWSENS:
11182 case VKI_SIOCSIWRANGE:
11183 case VKI_SIOCSIWPRIV:
11184 case VKI_SIOCSIWSTATS:
11185 case VKI_SIOCSIWSPY:
11186 case VKI_SIOCSIWTHRSPY:
11187 case VKI_SIOCSIWAP:
11188 case VKI_SIOCSIWSCAN:
11189 case VKI_SIOCSIWESSID:
11190 case VKI_SIOCSIWRATE:
11191 case VKI_SIOCSIWNICKN:
11192 case VKI_SIOCSIWRTS:
11193 case VKI_SIOCSIWFRAG:
11194 case VKI_SIOCSIWTXPOW:
11195 case VKI_SIOCSIWRETRY:
11196 case VKI_SIOCSIWENCODE:
11197 case VKI_SIOCSIWPOWER:
11198 case VKI_SIOCSIWGENIE:
11199 case VKI_SIOCSIWMLME:
11200 case VKI_SIOCSIWAUTH:
11201 case VKI_SIOCSIWENCODEEXT:
11202 case VKI_SIOCSIWPMKSA:
11203 break;
11204 case VKI_SIOCGIWNAME:
11205 if (ARG3) {
11206 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11207 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11209 break;
11210 case VKI_SIOCGIWNWID:
11211 case VKI_SIOCGIWSENS:
11212 case VKI_SIOCGIWRATE:
11213 case VKI_SIOCGIWRTS:
11214 case VKI_SIOCGIWFRAG:
11215 case VKI_SIOCGIWTXPOW:
11216 case VKI_SIOCGIWRETRY:
11217 case VKI_SIOCGIWPOWER:
11218 case VKI_SIOCGIWAUTH:
11219 if (ARG3) {
11220 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11221 sizeof(struct vki_iw_param));
11223 break;
11224 case VKI_SIOCGIWFREQ:
11225 if (ARG3) {
11226 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11227 sizeof(struct vki_iw_freq));
11229 break;
11230 case VKI_SIOCGIWMODE:
11231 if (ARG3) {
11232 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11233 sizeof(__vki_u32));
11235 break;
11236 case VKI_SIOCGIWRANGE:
11237 case VKI_SIOCGIWPRIV:
11238 case VKI_SIOCGIWSTATS:
11239 case VKI_SIOCGIWSPY:
11240 case VKI_SIOCGIWTHRSPY:
11241 case VKI_SIOCGIWAPLIST:
11242 case VKI_SIOCGIWSCAN:
11243 case VKI_SIOCGIWESSID:
11244 case VKI_SIOCGIWNICKN:
11245 case VKI_SIOCGIWENCODE:
11246 case VKI_SIOCGIWGENIE:
11247 case VKI_SIOCGIWENCODEEXT:
11248 if (ARG3) {
11249 struct vki_iw_point* point;
11250 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11251 POST_MEM_WRITE((Addr)point->pointer, point->length);
11253 break;
11254 case VKI_SIOCGIWAP:
11255 if (ARG3) {
11256 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11257 sizeof(struct vki_sockaddr));
11259 break;
11261 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11262 || defined(VGPV_mips32_linux_android) \
11263 || defined(VGPV_arm64_linux_android)
11264 /* ashmem */
11265 case VKI_ASHMEM_GET_SIZE:
11266 case VKI_ASHMEM_SET_SIZE:
11267 case VKI_ASHMEM_GET_PROT_MASK:
11268 case VKI_ASHMEM_SET_PROT_MASK:
11269 case VKI_ASHMEM_GET_PIN_STATUS:
11270 case VKI_ASHMEM_PURGE_ALL_CACHES:
11271 case VKI_ASHMEM_SET_NAME:
11272 case VKI_ASHMEM_PIN:
11273 case VKI_ASHMEM_UNPIN:
11274 break;
11275 case VKI_ASHMEM_GET_NAME:
11276 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11277 break;
11279 /* binder */
11280 case VKI_BINDER_WRITE_READ:
11281 if (ARG3) {
11282 struct vki_binder_write_read* bwr
11283 = (struct vki_binder_write_read*)(Addr)ARG3;
11284 POST_FIELD_WRITE(bwr->write_consumed);
11285 POST_FIELD_WRITE(bwr->read_consumed);
11287 if (bwr->read_size)
11288 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11290 break;
11292 case VKI_BINDER_SET_IDLE_TIMEOUT:
11293 case VKI_BINDER_SET_MAX_THREADS:
11294 case VKI_BINDER_SET_IDLE_PRIORITY:
11295 case VKI_BINDER_SET_CONTEXT_MGR:
11296 case VKI_BINDER_THREAD_EXIT:
11297 break;
11298 case VKI_BINDER_VERSION:
11299 if (ARG3) {
11300 struct vki_binder_version* bv =
11301 (struct vki_binder_version*)(Addr)ARG3;
11302 POST_FIELD_WRITE(bv->protocol_version);
11304 break;
11305 # endif /* defined(VGPV_*_linux_android) */
11307 case VKI_HCIGETDEVLIST:
11308 if (ARG3) {
11309 struct vki_hci_dev_list_req* dlr =
11310 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11311 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11312 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11314 break;
11316 case VKI_HCIINQUIRY:
11317 if (ARG3) {
11318 struct vki_hci_inquiry_req* ir =
11319 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11320 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11321 ir->num_rsp * sizeof(struct vki_inquiry_info));
11323 break;
11325 case VKI_DRM_IOCTL_VERSION:
11326 if (ARG3) {
11327 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11328 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11329 const vki_size_t orig_name_len = info->orig->name_len;
11330 const vki_size_t orig_date_len = info->orig->date_len;
11331 const vki_size_t orig_desc_len = info->orig->desc_len;
11332 *info->orig = info->data;
11333 ARG3 = (Addr)info->orig;
11334 data = info->orig;
11335 VG_(free)(info);
11336 if (SUCCESS) {
11337 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11338 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11339 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11340 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11341 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11342 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11343 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11344 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11345 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11348 break;
11349 case VKI_DRM_IOCTL_GET_UNIQUE:
11350 if (ARG3) {
11351 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11352 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11354 break;
11355 case VKI_DRM_IOCTL_GET_MAGIC:
11356 if (ARG3) {
11357 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11358 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11360 break;
11361 case VKI_DRM_IOCTL_WAIT_VBLANK:
11362 if (ARG3) {
11363 union vki_drm_wait_vblank *data =
11364 (union vki_drm_wait_vblank *)(Addr)ARG3;
11365 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11367 break;
11368 case VKI_DRM_IOCTL_GEM_FLINK:
11369 if (ARG3) {
11370 struct vki_drm_gem_flink *data =
11371 (struct vki_drm_gem_flink *)(Addr)ARG3;
11372 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11374 break;
11375 case VKI_DRM_IOCTL_GEM_OPEN:
11376 if (ARG3) {
11377 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11378 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11379 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11381 break;
11382 case VKI_DRM_IOCTL_I915_GETPARAM:
11383 if (ARG3) {
11384 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11385 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11387 break;
11388 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11389 if (ARG3) {
11390 struct vki_drm_i915_gem_busy *data =
11391 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11392 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11394 break;
11395 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11396 if (ARG3) {
11397 struct vki_drm_i915_gem_create *data =
11398 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11399 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11401 break;
11402 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11403 if (ARG3) {
11404 struct vki_drm_i915_gem_pread *data =
11405 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11406 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11408 break;
11409 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11410 if (ARG3) {
11411 struct vki_drm_i915_gem_mmap_v1 *data =
11412 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11413 Addr addr = data->addr_ptr;
11414 SizeT size = data->size;
11415 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11416 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11417 ML_(notify_core_and_tool_of_mmap)(addr, size,
11418 VKI_PROT_READ | VKI_PROT_WRITE,
11419 VKI_MAP_ANONYMOUS, -1, 0 );
11420 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11422 break;
11423 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11424 if (ARG3) {
11425 struct vki_drm_i915_gem_mmap *data =
11426 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11427 Addr addr = data->addr_ptr;
11428 SizeT size = data->size;
11429 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11430 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11431 ML_(notify_core_and_tool_of_mmap)(addr, size,
11432 VKI_PROT_READ | VKI_PROT_WRITE,
11433 VKI_MAP_ANONYMOUS, -1, 0 );
11434 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11436 break;
11437 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11438 if (ARG3) {
11439 struct vki_drm_i915_gem_mmap_gtt *data =
11440 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11441 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11443 break;
11444 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11445 if (ARG3) {
11446 struct vki_drm_i915_gem_set_tiling *data =
11447 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11448 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11449 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11450 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11452 break;
11453 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11454 if (ARG3) {
11455 struct vki_drm_i915_gem_get_tiling *data =
11456 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11457 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11458 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11460 break;
11461 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11462 if (ARG3) {
11463 struct vki_drm_i915_gem_get_aperture *data =
11464 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11465 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11466 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11468 break;
11470 /* KVM ioctls that only write the system call return value */
11471 case VKI_KVM_GET_API_VERSION:
11472 case VKI_KVM_CREATE_VM:
11473 case VKI_KVM_CHECK_EXTENSION:
11474 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11475 case VKI_KVM_S390_ENABLE_SIE:
11476 case VKI_KVM_CREATE_VCPU:
11477 case VKI_KVM_SET_TSS_ADDR:
11478 case VKI_KVM_CREATE_IRQCHIP:
11479 case VKI_KVM_RUN:
11480 case VKI_KVM_S390_INITIAL_RESET:
11481 case VKI_KVM_KVMCLOCK_CTRL:
11482 break;
11484 case VKI_KVM_S390_MEM_OP: {
11485 struct vki_kvm_s390_mem_op *args =
11486 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11487 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11488 break;
11489 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11490 POST_MEM_WRITE((Addr)args->buf, args->size);
11492 break;
11494 #ifdef ENABLE_XEN
11495 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11496 SyscallArgs harrghs;
11497 struct vki_xen_privcmd_hypercall *args =
11498 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11500 if (!args)
11501 break;
11503 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11504 harrghs.sysno = args->op;
11505 harrghs.arg1 = args->arg[0];
11506 harrghs.arg2 = args->arg[1];
11507 harrghs.arg3 = args->arg[2];
11508 harrghs.arg4 = args->arg[3];
11509 harrghs.arg5 = args->arg[4];
11510 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11512 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11514 break;
11516 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11517 break;
11518 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11519 struct vki_xen_privcmd_mmapbatch *args =
11520 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11521 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11523 break;
11524 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11525 struct vki_xen_privcmd_mmapbatch_v2 *args =
11526 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11527 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11529 break;
11531 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11532 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11533 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11534 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11535 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11536 case VKI_XEN_IOCTL_EVTCHN_RESET:
11537 /* No output */
11538 break;
11539 #endif
11541 /* Lustre */
11542 case VKI_OBD_IOC_FID2PATH: {
11543 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11544 POST_FIELD_WRITE(args->gf_recno);
11545 POST_FIELD_WRITE(args->gf_linkno);
11546 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11547 break;
11550 case VKI_LL_IOC_PATH2FID:
11551 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11552 break;
11554 case VKI_LL_IOC_GETPARENT: {
11555 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11556 POST_FIELD_WRITE(gp->gp_fid);
11557 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11558 break;
11561 /* V4L2 */
11562 case VKI_V4L2_S_FMT:
11563 case VKI_V4L2_TRY_FMT:
11564 case VKI_V4L2_REQBUFS:
11565 case VKI_V4L2_OVERLAY:
11566 case VKI_V4L2_STREAMON:
11567 case VKI_V4L2_STREAMOFF:
11568 case VKI_V4L2_S_PARM:
11569 case VKI_V4L2_S_STD:
11570 case VKI_V4L2_S_FREQUENCY:
11571 case VKI_V4L2_S_CTRL:
11572 case VKI_V4L2_S_TUNER:
11573 case VKI_V4L2_S_AUDIO:
11574 case VKI_V4L2_S_INPUT:
11575 case VKI_V4L2_S_EDID:
11576 case VKI_V4L2_S_OUTPUT:
11577 case VKI_V4L2_S_AUDOUT:
11578 case VKI_V4L2_S_MODULATOR:
11579 case VKI_V4L2_S_JPEGCOMP:
11580 case VKI_V4L2_S_CROP:
11581 case VKI_V4L2_S_PRIORITY:
11582 case VKI_V4L2_S_HW_FREQ_SEEK:
11583 case VKI_V4L2_S_DV_TIMINGS:
11584 case VKI_V4L2_SUBSCRIBE_EVENT:
11585 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11586 case VKI_V4L2_PREPARE_BUF:
11587 break;
11588 case VKI_V4L2_QUERYCAP: {
11589 struct vki_v4l2_capability *data =
11590 (struct vki_v4l2_capability *)(Addr)ARG3;
11591 POST_MEM_WRITE((Addr)data, sizeof(*data));
11592 break;
11594 case VKI_V4L2_ENUM_FMT: {
11595 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11596 POST_FIELD_WRITE(data->flags);
11597 POST_FIELD_WRITE(data->description);
11598 POST_FIELD_WRITE(data->pixelformat);
11599 POST_FIELD_WRITE(data->reserved);
11600 break;
11602 case VKI_V4L2_G_FMT: {
11603 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11604 switch (data->type) {
11605 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11606 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11607 POST_FIELD_WRITE(data->fmt.pix);
11608 break;
11609 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11610 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11611 POST_FIELD_WRITE(data->fmt.vbi);
11612 break;
11613 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11614 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11615 POST_FIELD_WRITE(data->fmt.sliced);
11616 break;
11617 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11618 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11619 POST_FIELD_WRITE(data->fmt.win);
11620 break;
11621 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11622 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11623 POST_FIELD_WRITE(data->fmt.pix_mp);
11624 break;
11625 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11626 POST_FIELD_WRITE(data->fmt.sdr);
11627 break;
11629 break;
11631 case VKI_V4L2_QUERYBUF: {
11632 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11633 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11634 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11635 unsigned i;
11637 for (i = 0; i < data->length; i++) {
11638 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11639 POST_FIELD_WRITE(data->m.planes[i].length);
11640 POST_FIELD_WRITE(data->m.planes[i].m);
11641 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11642 POST_FIELD_WRITE(data->m.planes[i].reserved);
11644 } else {
11645 POST_FIELD_WRITE(data->m);
11646 POST_FIELD_WRITE(data->length);
11648 POST_FIELD_WRITE(data->bytesused);
11649 POST_FIELD_WRITE(data->flags);
11650 POST_FIELD_WRITE(data->field);
11651 POST_FIELD_WRITE(data->timestamp);
11652 POST_FIELD_WRITE(data->timecode);
11653 POST_FIELD_WRITE(data->sequence);
11654 POST_FIELD_WRITE(data->memory);
11655 POST_FIELD_WRITE(data->sequence);
11656 break;
11658 case VKI_V4L2_G_FBUF: {
11659 struct vki_v4l2_framebuffer *data =
11660 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11661 POST_MEM_WRITE((Addr)data, sizeof(*data));
11662 break;
11664 case VKI_V4L2_S_FBUF: {
11665 struct vki_v4l2_framebuffer *data =
11666 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11667 POST_FIELD_WRITE(data->capability);
11668 POST_FIELD_WRITE(data->flags);
11669 POST_FIELD_WRITE(data->fmt);
11670 break;
11672 case VKI_V4L2_QBUF: {
11673 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11675 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11676 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11677 unsigned i;
11679 for (i = 0; i < data->length; i++) {
11680 POST_FIELD_WRITE(data->m.planes[i].length);
11681 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11682 POST_FIELD_WRITE(data->m.planes[i].m);
11684 } else {
11685 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11686 POST_FIELD_WRITE(data->m);
11687 POST_FIELD_WRITE(data->length);
11689 break;
11691 case VKI_V4L2_EXPBUF: {
11692 struct vki_v4l2_exportbuffer *data =
11693 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11694 POST_FIELD_WRITE(data->fd);
11695 break;
11697 case VKI_V4L2_DQBUF: {
11698 struct vki_v4l2_buffer *data =
11699 (struct vki_v4l2_buffer *)(Addr)ARG3;
11700 POST_FIELD_WRITE(data->index);
11701 POST_FIELD_WRITE(data->bytesused);
11702 POST_FIELD_WRITE(data->field);
11703 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11704 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11705 unsigned i;
11707 for (i = 0; i < data->length; i++) {
11708 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11709 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11710 POST_FIELD_WRITE(data->m.planes[i].length);
11711 POST_FIELD_WRITE(data->m.planes[i].m);
11713 } else {
11714 POST_FIELD_WRITE(data->m);
11715 POST_FIELD_WRITE(data->length);
11716 POST_FIELD_WRITE(data->bytesused);
11717 POST_FIELD_WRITE(data->field);
11719 POST_FIELD_WRITE(data->timestamp);
11720 POST_FIELD_WRITE(data->timecode);
11721 POST_FIELD_WRITE(data->sequence);
11722 break;
11724 case VKI_V4L2_G_PARM: {
11725 struct vki_v4l2_streamparm *data =
11726 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11727 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11728 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11729 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11730 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11732 if (is_output)
11733 POST_MEM_WRITE((Addr)&data->parm.output,
11734 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11735 else
11736 POST_MEM_WRITE((Addr)&data->parm.capture,
11737 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11738 break;
11740 case VKI_V4L2_G_STD: {
11741 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11742 POST_MEM_WRITE((Addr)data, sizeof(*data));
11743 break;
11745 case VKI_V4L2_ENUMSTD: {
11746 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11747 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11748 break;
11750 case VKI_V4L2_ENUMINPUT: {
11751 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11752 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11753 break;
11755 case VKI_V4L2_G_CTRL: {
11756 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11757 POST_FIELD_WRITE(data->value);
11758 break;
11760 case VKI_V4L2_G_TUNER: {
11761 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11762 POST_MEM_WRITE((Addr)data->name,
11763 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11764 break;
11766 case VKI_V4L2_G_AUDIO: {
11767 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11768 POST_MEM_WRITE((Addr)data,
11769 sizeof(*data) - sizeof(data->reserved));
11770 break;
11772 case VKI_V4L2_QUERYCTRL: {
11773 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11774 POST_MEM_WRITE((Addr)&data->type,
11775 sizeof(*data) - sizeof(data->id));
11776 break;
11778 case VKI_V4L2_QUERYMENU: {
11779 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11780 POST_MEM_WRITE((Addr)data->name,
11781 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11782 break;
11784 case VKI_V4L2_G_INPUT: {
11785 int *data = (int *)(Addr)ARG3;
11786 POST_MEM_WRITE((Addr)data, sizeof(*data));
11787 break;
11789 case VKI_V4L2_G_EDID: {
11790 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11791 if (data->blocks && data->edid)
11792 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11793 break;
11795 case VKI_V4L2_G_OUTPUT: {
11796 int *data = (int *)(Addr)ARG3;
11797 POST_MEM_WRITE((Addr)data, sizeof(*data));
11798 break;
11800 case VKI_V4L2_ENUMOUTPUT: {
11801 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11802 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11803 break;
11805 case VKI_V4L2_G_AUDOUT: {
11806 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11807 POST_MEM_WRITE((Addr)data,
11808 sizeof(*data) - sizeof(data->reserved));
11809 break;
11811 case VKI_V4L2_G_MODULATOR: {
11812 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11813 POST_MEM_WRITE((Addr)data->name,
11814 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11815 break;
11817 case VKI_V4L2_G_FREQUENCY: {
11818 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11819 POST_FIELD_WRITE(data->type);
11820 POST_FIELD_WRITE(data->frequency);
11821 break;
11823 case VKI_V4L2_CROPCAP: {
11824 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11825 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11826 break;
11828 case VKI_V4L2_G_CROP: {
11829 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11830 POST_FIELD_WRITE(data->c);
11831 break;
11833 case VKI_V4L2_G_JPEGCOMP: {
11834 struct vki_v4l2_jpegcompression *data =
11835 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11836 POST_MEM_WRITE((Addr)data, sizeof(*data));
11837 break;
11839 case VKI_V4L2_QUERYSTD: {
11840 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11841 POST_MEM_WRITE((Addr)data, sizeof(*data));
11842 break;
11844 case VKI_V4L2_ENUMAUDIO: {
11845 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11846 POST_MEM_WRITE((Addr)data->name,
11847 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11848 break;
11850 case VKI_V4L2_ENUMAUDOUT: {
11851 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11852 POST_MEM_WRITE((Addr)data->name,
11853 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11854 break;
11856 case VKI_V4L2_G_PRIORITY: {
11857 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11858 POST_MEM_WRITE((Addr)data, sizeof(*data));
11859 break;
11861 case VKI_V4L2_G_SLICED_VBI_CAP: {
11862 struct vki_v4l2_sliced_vbi_cap *data =
11863 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11864 POST_MEM_WRITE((Addr)data,
11865 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11866 break;
11868 case VKI_V4L2_G_EXT_CTRLS: {
11869 struct vki_v4l2_ext_controls *data =
11870 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11871 if (data->count) {
11872 unsigned i;
11874 for (i = 0; i < data->count; i++) {
11875 if (data->controls[i].size)
11876 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11877 else
11878 POST_FIELD_WRITE(data->controls[i].value64);
11881 POST_FIELD_WRITE(data->error_idx);
11882 break;
11884 case VKI_V4L2_S_EXT_CTRLS: {
11885 struct vki_v4l2_ext_controls *data =
11886 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11887 POST_FIELD_WRITE(data->error_idx);
11888 break;
11890 case VKI_V4L2_TRY_EXT_CTRLS: {
11891 struct vki_v4l2_ext_controls *data =
11892 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11893 POST_FIELD_WRITE(data->error_idx);
11894 break;
11896 case VKI_V4L2_ENUM_FRAMESIZES: {
11897 struct vki_v4l2_frmsizeenum *data =
11898 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11899 POST_FIELD_WRITE(data->type);
11900 POST_FIELD_WRITE(data->stepwise);
11901 break;
11903 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11904 struct vki_v4l2_frmivalenum *data =
11905 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11906 POST_FIELD_WRITE(data->type);
11907 POST_FIELD_WRITE(data->stepwise);
11908 break;
11910 case VKI_V4L2_G_ENC_INDEX: {
11911 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11912 POST_MEM_WRITE((Addr)data, sizeof(*data));
11913 break;
11915 case VKI_V4L2_ENCODER_CMD: {
11916 struct vki_v4l2_encoder_cmd *data =
11917 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11918 POST_FIELD_WRITE(data->flags);
11919 break;
11921 case VKI_V4L2_TRY_ENCODER_CMD: {
11922 struct vki_v4l2_encoder_cmd *data =
11923 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11924 POST_FIELD_WRITE(data->flags);
11925 break;
11927 case VKI_V4L2_DBG_S_REGISTER: {
11928 struct vki_v4l2_dbg_register *data =
11929 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11930 POST_FIELD_WRITE(data->size);
11931 break;
11933 case VKI_V4L2_DBG_G_REGISTER: {
11934 struct vki_v4l2_dbg_register *data =
11935 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11936 POST_FIELD_WRITE(data->val);
11937 POST_FIELD_WRITE(data->size);
11938 break;
11940 case VKI_V4L2_G_DV_TIMINGS: {
11941 struct vki_v4l2_dv_timings *data =
11942 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11943 POST_MEM_WRITE((Addr)data, sizeof(*data));
11944 break;
11946 case VKI_V4L2_DQEVENT: {
11947 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
11948 POST_MEM_WRITE((Addr)data, sizeof(*data));
11949 break;
11951 case VKI_V4L2_CREATE_BUFS: {
11952 struct vki_v4l2_create_buffers *data =
11953 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
11954 POST_FIELD_WRITE(data->index);
11955 break;
11957 case VKI_V4L2_G_SELECTION: {
11958 struct vki_v4l2_selection *data =
11959 (struct vki_v4l2_selection *)(Addr)ARG3;
11960 POST_FIELD_WRITE(data->r);
11961 break;
11963 case VKI_V4L2_S_SELECTION: {
11964 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
11965 POST_FIELD_WRITE(data->r);
11966 break;
11968 case VKI_V4L2_DECODER_CMD: {
11969 struct vki_v4l2_decoder_cmd *data =
11970 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11971 POST_FIELD_WRITE(data->flags);
11972 break;
11974 case VKI_V4L2_TRY_DECODER_CMD: {
11975 struct vki_v4l2_decoder_cmd *data =
11976 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11977 POST_FIELD_WRITE(data->flags);
11978 break;
11980 case VKI_V4L2_ENUM_DV_TIMINGS: {
11981 struct vki_v4l2_enum_dv_timings *data =
11982 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
11983 POST_FIELD_WRITE(data->timings);
11984 break;
11986 case VKI_V4L2_QUERY_DV_TIMINGS: {
11987 struct vki_v4l2_dv_timings *data =
11988 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11989 POST_MEM_WRITE((Addr)data, sizeof(*data));
11990 break;
11992 case VKI_V4L2_DV_TIMINGS_CAP: {
11993 struct vki_v4l2_dv_timings_cap *data =
11994 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
11995 POST_MEM_WRITE((Addr)data, sizeof(*data));
11996 break;
11998 case VKI_V4L2_ENUM_FREQ_BANDS: {
11999 struct vki_v4l2_frequency_band *data =
12000 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12001 POST_FIELD_WRITE(data->capability);
12002 POST_FIELD_WRITE(data->rangelow);
12003 POST_FIELD_WRITE(data->rangehigh);
12004 POST_FIELD_WRITE(data->modulation);
12005 break;
12007 case VKI_V4L2_DBG_G_CHIP_INFO: {
12008 struct vki_v4l2_dbg_chip_info *data =
12009 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12010 POST_FIELD_WRITE(data->name);
12011 POST_FIELD_WRITE(data->flags);
12012 break;
12014 case VKI_V4L2_QUERY_EXT_CTRL: {
12015 struct vki_v4l2_query_ext_ctrl *data =
12016 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12017 POST_MEM_WRITE((Addr)&data->type,
12018 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12019 break;
12022 case VKI_V4L2_SUBDEV_S_FMT:
12023 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12024 case VKI_V4L2_SUBDEV_S_CROP:
12025 case VKI_V4L2_SUBDEV_S_SELECTION:
12026 break;
12028 case VKI_V4L2_SUBDEV_G_FMT: {
12029 struct vki_v4l2_subdev_format *data =
12030 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12031 POST_FIELD_WRITE(data->format);
12032 break;
12034 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12035 struct vki_v4l2_subdev_frame_interval *data =
12036 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12037 POST_FIELD_WRITE(data->interval);
12038 break;
12040 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12041 struct vki_v4l2_subdev_mbus_code_enum *data =
12042 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12043 POST_FIELD_WRITE(data->code);
12044 break;
12046 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12047 struct vki_v4l2_subdev_frame_size_enum *data =
12048 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12049 POST_FIELD_WRITE(data->min_width);
12050 POST_FIELD_WRITE(data->min_height);
12051 POST_FIELD_WRITE(data->max_width);
12052 POST_FIELD_WRITE(data->max_height);
12053 break;
12055 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12056 struct vki_v4l2_subdev_frame_interval_enum *data =
12057 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12058 POST_FIELD_WRITE(data->interval);
12059 break;
12061 case VKI_V4L2_SUBDEV_G_CROP: {
12062 struct vki_v4l2_subdev_crop *data =
12063 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12064 POST_FIELD_WRITE(data->rect);
12065 break;
12067 case VKI_V4L2_SUBDEV_G_SELECTION: {
12068 struct vki_v4l2_subdev_selection *data =
12069 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12070 POST_FIELD_WRITE(data->r);
12071 break;
12073 case VKI_MEDIA_IOC_DEVICE_INFO: {
12074 struct vki_media_device_info *data =
12075 (struct vki_media_device_info *)(Addr)ARG3;
12076 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12077 break;
12079 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12080 struct vki_media_entity_desc *data =
12081 (struct vki_media_entity_desc *)(Addr)ARG3;
12082 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12083 break;
12085 case VKI_MEDIA_IOC_ENUM_LINKS:
12087 * This ioctl does write to the provided pointers, but it's not
12088 * possible to deduce the size of the array those pointers point to.
12090 break;
12091 case VKI_MEDIA_IOC_SETUP_LINK:
12092 break;
12094 /* Serial */
12095 case VKI_TIOCGSERIAL: {
12096 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12097 POST_MEM_WRITE((Addr)data, sizeof(*data));
12098 break;
12100 case VKI_TIOCSSERIAL:
12101 break;
12103 case VKI_PERF_EVENT_IOC_ENABLE:
12104 case VKI_PERF_EVENT_IOC_DISABLE:
12105 case VKI_PERF_EVENT_IOC_REFRESH:
12106 case VKI_PERF_EVENT_IOC_RESET:
12107 case VKI_PERF_EVENT_IOC_PERIOD:
12108 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12109 case VKI_PERF_EVENT_IOC_SET_FILTER:
12110 case VKI_PERF_EVENT_IOC_SET_BPF:
12111 break;
12113 case VKI_PERF_EVENT_IOC_ID:
12114 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12115 break;
12117 /* Pulse Per Second (PPS) */
12118 case VKI_PPS_GETPARAMS: {
12119 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12120 POST_MEM_WRITE((Addr)data, sizeof(*data));
12121 break;
12123 case VKI_PPS_GETCAP:
12124 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12125 break;
12126 case VKI_PPS_FETCH: {
12127 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12128 POST_FIELD_WRITE(data->info);
12129 break;
12131 case VKI_PPS_SETPARAMS:
12132 case VKI_PPS_KC_BIND:
12133 break;
12135 /* PTP Hardware Clock */
12136 case VKI_PTP_CLOCK_GETCAPS: {
12137 struct vki_ptp_clock_caps *data =
12138 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12139 POST_MEM_WRITE((Addr)data, sizeof(*data));
12140 break;
12142 case VKI_PTP_SYS_OFFSET: {
12143 struct vki_ptp_sys_offset *data =
12144 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12145 POST_MEM_WRITE((Addr)data->ts,
12146 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12147 break;
12149 case VKI_PTP_PIN_GETFUNC: {
12150 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12151 POST_MEM_WRITE((Addr)data, sizeof(*data));
12152 break;
12154 case VKI_PTP_SYS_OFFSET_PRECISE: {
12155 struct vki_ptp_sys_offset_precise *data =
12156 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12157 POST_MEM_WRITE((Addr)data, sizeof(*data));
12158 break;
12160 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12161 struct vki_ptp_sys_offset_extended *data =
12162 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12163 POST_MEM_WRITE((Addr)data->ts,
12164 3 * data->n_samples * sizeof(data->ts[0][0]));
12165 break;
12167 case VKI_PTP_EXTTS_REQUEST:
12168 case VKI_PTP_PEROUT_REQUEST:
12169 case VKI_PTP_ENABLE_PPS:
12170 case VKI_PTP_PIN_SETFUNC:
12171 break;
12173 default:
12174 /* EVIOC* are variable length and return size written on success */
12175 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12176 case VKI_EVIOCGNAME(0):
12177 case VKI_EVIOCGPHYS(0):
12178 case VKI_EVIOCGUNIQ(0):
12179 case VKI_EVIOCGKEY(0):
12180 case VKI_EVIOCGLED(0):
12181 case VKI_EVIOCGSND(0):
12182 case VKI_EVIOCGSW(0):
12183 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12184 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12185 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12186 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12187 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12188 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12189 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12190 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12191 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12192 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12193 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12194 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12195 if (RES > 0)
12196 POST_MEM_WRITE(ARG3, RES);
12197 break;
12198 default:
12199 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12200 break;
12202 break;
12205 post_sys_ioctl__out:
12206 {} /* keep C compilers happy */
12209 /* ---------------------------------------------------------------------
12210 socketcall wrapper helpers
12211 ------------------------------------------------------------------ */
12213 void
12214 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12215 UWord arg0, UWord arg1, UWord arg2,
12216 UWord arg3, UWord arg4 )
12218 /* int getsockopt(int s, int level, int optname,
12219 void *optval, socklen_t *optlen); */
12220 Addr optval_p = arg3;
12221 Addr optlen_p = arg4;
12222 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12223 if (optval_p != (Addr)NULL) {
12224 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12225 "socketcall.getsockopt(optval)",
12226 "socketcall.getsockopt(optlen)" );
12227 if (arg1 == VKI_SOL_SCTP &&
12228 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12229 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12231 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12232 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12233 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12234 (Addr)ga->addrs, address_bytes );
12239 void
12240 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12241 SysRes res,
12242 UWord arg0, UWord arg1, UWord arg2,
12243 UWord arg3, UWord arg4 )
12245 Addr optval_p = arg3;
12246 Addr optlen_p = arg4;
12247 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12248 if (optval_p != (Addr)NULL) {
12249 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12250 "socketcall.getsockopt(optlen_out)" );
12251 if (arg1 == VKI_SOL_SCTP &&
12252 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12253 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12255 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12256 struct vki_sockaddr *a = ga->addrs;
12257 int i;
12258 for (i = 0; i < ga->addr_num; i++) {
12259 int sl = 0;
12260 if (a->sa_family == VKI_AF_INET)
12261 sl = sizeof(struct vki_sockaddr_in);
12262 else if (a->sa_family == VKI_AF_INET6)
12263 sl = sizeof(struct vki_sockaddr_in6);
12264 else {
12265 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12266 "address type %d\n", a->sa_family);
12268 a = (struct vki_sockaddr*)((char*)a + sl);
12270 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12275 void
12276 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12277 UWord arg0, UWord arg1, UWord arg2,
12278 UWord arg3, UWord arg4 )
12280 /* int setsockopt(int s, int level, int optname,
12281 const void *optval, socklen_t optlen); */
12282 Addr optval_p = arg3;
12283 if (optval_p != (Addr)NULL) {
12285 * OK, let's handle at least some setsockopt levels and options
12286 * ourselves, so we don't get false claims of references to
12287 * uninitialized memory (such as padding in structures) and *do*
12288 * check what pointers in the argument point to.
12290 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12292 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12295 * struct sock_fprog has a 16-bit count of instructions,
12296 * followed by a pointer to an array of those instructions.
12297 * There's padding between those two elements.
12299 * So that we don't bogusly complain about the padding bytes,
12300 * we just report that we read len and and filter.
12302 * We then make sure that what filter points to is valid.
12304 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12305 (Addr)&fp->len, sizeof(fp->len) );
12306 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12307 (Addr)&fp->filter, sizeof(fp->filter) );
12309 /* len * sizeof (*filter) */
12310 if (fp->filter != NULL)
12312 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12313 (Addr)(fp->filter),
12314 fp->len * sizeof(*fp->filter) );
12317 else
12319 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12320 arg3, /* optval */
12321 arg4 /* optlen */ );
12326 void
12327 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12328 UWord arg1, UWord arg2, UWord arg3,
12329 UWord arg4, UWord arg5 )
12331 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12332 HChar name[40]; // large enough
12333 UInt i;
12334 for (i = 0; i < arg3; i++) {
12335 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12336 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12337 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12338 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12340 if (arg5)
12341 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12344 void
12345 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12346 UWord arg1, UWord arg2, UWord arg3,
12347 UWord arg4, UWord arg5 )
12349 if (res > 0) {
12350 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12351 HChar name[32]; // large enough
12352 UInt i;
12353 for (i = 0; i < res; i++) {
12354 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12355 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12356 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12361 void
12362 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12363 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12365 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12366 HChar name[40]; // large enough
12367 UInt i;
12368 for (i = 0; i < arg3; i++) {
12369 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12370 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12371 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12372 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12376 void
12377 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12378 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12380 if (res > 0) {
12381 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12382 UInt i;
12383 for (i = 0; i < res; i++) {
12384 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12389 /* ---------------------------------------------------------------------
12390 ptrace wrapper helpers
12391 ------------------------------------------------------------------ */
12393 void
12394 ML_(linux_POST_traceme) ( ThreadId tid )
12396 ThreadState *tst = VG_(get_ThreadState)(tid);
12397 tst->ptrace = VKI_PT_PTRACED;
12400 void
12401 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12403 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12405 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12406 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12407 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12408 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12409 (Addr) iov->iov_base, iov->iov_len);
12413 void
12414 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12416 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12418 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12419 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12420 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12421 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12422 (Addr) iov->iov_base, iov->iov_len);
12426 void
12427 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12429 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12431 /* XXX: The actual amount of data written by the kernel might be
12432 less than iov_len, depending on the regset (arg3). */
12433 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12436 PRE(sys_kcmp)
12438 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12439 SARG1, SARG2, SARG3, ARG4, ARG5);
12440 switch (ARG3) {
12441 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12442 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12443 /* Most of the comparison types don't look at |idx1| or
12444 |idx2|. */
12445 PRE_REG_READ3(long, "kcmp",
12446 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12447 break;
12448 case VKI_KCMP_FILE:
12449 default:
12450 PRE_REG_READ5(long, "kcmp",
12451 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12452 unsigned long, idx1, unsigned long, idx2);
12453 break;
12457 /* ---------------------------------------------------------------------
12458 bpf wrappers
12459 ------------------------------------------------------------------ */
12461 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12463 HChar path[32], buf[1024]; /* large enough */
12464 SysRes sres;
12465 HChar *comp;
12466 Int proc_fd;
12468 *key_size = 0;
12469 *value_size = 0;
12471 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12472 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12473 if (sr_isError(sres))
12474 return False;
12475 proc_fd = sr_Res(sres);
12477 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12478 return False;
12479 VG_(close)(proc_fd);
12481 comp = VG_(strstr)(buf, "key_size:");
12482 if (comp)
12483 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12485 comp = VG_(strstr)(buf, "value_size:");
12486 if (comp)
12487 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12489 return (*key_size && *value_size);
12493 * From a file descriptor for an eBPF object, try to determine the size of the
12494 * struct that will be written, i.e. determine if object is a map or a program.
12495 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12496 * search for strings "prog_type" or "map_type".
12498 static UInt bpf_obj_get_info_size(Int fd)
12500 HChar path[32], buf[1024]; /* large enough */
12501 SysRes sres;
12502 Int proc_fd;
12504 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12505 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12506 if (sr_isError(sres))
12507 return 0;
12508 proc_fd = sr_Res(sres);
12510 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12511 return 0;
12512 VG_(close)(proc_fd);
12514 if (VG_(strstr)(buf, "prog_type:"))
12515 return sizeof(struct vki_bpf_prog_info);
12517 if (VG_(strstr)(buf, "map_type:"))
12518 return sizeof(struct vki_bpf_map_info);
12520 return 0;
12523 PRE(sys_bpf)
12525 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12526 UInt res, key_size, value_size;
12528 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12529 (Word)ARG1, ARG2, ARG3);
12530 PRE_REG_READ3(long, "bpf",
12531 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12532 switch (ARG1) {
12533 case VKI_BPF_PROG_GET_NEXT_ID:
12534 case VKI_BPF_MAP_GET_NEXT_ID:
12535 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12536 break;
12537 case VKI_BPF_PROG_GET_FD_BY_ID:
12538 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12539 break;
12540 case VKI_BPF_MAP_GET_FD_BY_ID:
12541 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12542 break;
12543 case VKI_BPF_BTF_GET_FD_BY_ID:
12544 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12545 break;
12546 case VKI_BPF_MAP_CREATE:
12547 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12548 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12549 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12550 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12551 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12552 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12553 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12554 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12555 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12556 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12557 switch (attr->map_type) {
12558 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12559 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12560 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12561 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12562 SET_STATUS_Failure(VKI_EBADF);
12563 break;
12564 case VKI_BPF_MAP_TYPE_ARRAY:
12565 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12566 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12567 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12568 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12569 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12570 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12571 SET_STATUS_Failure(VKI_EBADF);
12572 break;
12576 break;
12577 case VKI_BPF_MAP_TYPE_UNSPEC:
12578 case VKI_BPF_MAP_TYPE_HASH:
12579 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12580 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12581 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12582 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12583 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12584 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12585 case VKI_BPF_MAP_TYPE_LRU_HASH:
12586 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12587 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12588 case VKI_BPF_MAP_TYPE_DEVMAP:
12589 case VKI_BPF_MAP_TYPE_SOCKMAP:
12590 case VKI_BPF_MAP_TYPE_CPUMAP:
12591 case VKI_BPF_MAP_TYPE_XSKMAP:
12592 case VKI_BPF_MAP_TYPE_SOCKHASH:
12593 default:
12594 break;
12596 break;
12597 case VKI_BPF_MAP_LOOKUP_ELEM:
12598 /* Perform a lookup on an eBPF map. Read key, write value. */
12599 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12600 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12601 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12602 if (ML_(safe_to_deref)(attr, ARG3)) {
12603 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12604 SET_STATUS_Failure(VKI_EBADF);
12605 break;
12607 /* Get size of key and value for this map. */
12608 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12609 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12610 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12613 break;
12614 case VKI_BPF_MAP_UPDATE_ELEM:
12615 /* Add or update a map element in kernel. Read key, read value. */
12616 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12617 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12618 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12619 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12620 if (ML_(safe_to_deref)(attr, ARG3)) {
12621 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12622 SET_STATUS_Failure(VKI_EBADF);
12623 break;
12625 /* Get size of key and value for this map. */
12626 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12627 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12628 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12631 break;
12632 case VKI_BPF_MAP_DELETE_ELEM:
12633 /* Delete a map element in kernel. Read key from user space. */
12634 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12635 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12636 if (ML_(safe_to_deref)(attr, ARG3)) {
12637 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12638 SET_STATUS_Failure(VKI_EBADF);
12639 break;
12641 /* Get size of key for this map. */
12642 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12643 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12645 break;
12646 case VKI_BPF_MAP_GET_NEXT_KEY:
12647 /* From a key, get next key for the map. Read key, write next key. */
12648 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12649 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12650 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12651 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12652 if (ML_(safe_to_deref)(attr, ARG3)) {
12653 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12654 SET_STATUS_Failure(VKI_EBADF);
12655 break;
12657 /* Get size of key for this map. */
12658 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12659 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12660 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12663 break;
12664 case VKI_BPF_PROG_LOAD:
12665 /* Load a program into the kernel from an array of instructions. */
12666 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12667 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12668 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12669 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12670 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12671 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12672 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12673 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12674 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12675 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12676 if (ML_(safe_to_deref)(attr, ARG3)) {
12677 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12678 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12679 /* Read instructions, license, program name. */
12680 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12681 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12682 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12683 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12684 /* Possibly write up to log_len into user space log buffer. */
12685 if (attr->log_level || attr->log_size || attr->log_buf)
12686 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12688 break;
12689 case VKI_BPF_OBJ_PIN:
12690 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12691 /* fall through */
12692 case VKI_BPF_OBJ_GET:
12693 /* Get pinned eBPF program or map. Read path name. */
12694 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12695 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12696 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12697 if (ML_(safe_to_deref)(attr, ARG3)) {
12698 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12699 SET_STATUS_Failure(VKI_EBADF);
12700 break;
12702 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12704 break;
12705 case VKI_BPF_PROG_ATTACH:
12706 case VKI_BPF_PROG_DETACH:
12707 /* Detach eBPF program from kernel attach point. */
12708 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12709 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12710 if (ML_(safe_to_deref)(attr, ARG3)) {
12711 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12712 SET_STATUS_Failure(VKI_EBADF);
12713 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12714 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12715 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12716 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12717 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12718 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12719 SET_STATUS_Failure(VKI_EBADF);
12722 break;
12723 case VKI_BPF_PROG_TEST_RUN:
12724 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12725 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12726 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12727 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12728 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12729 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12730 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12731 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12732 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12733 if (ML_(safe_to_deref)(attr, ARG3)) {
12734 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12735 SET_STATUS_Failure(VKI_EBADF);
12736 break;
12738 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12739 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12740 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12742 break;
12743 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12744 /* Get info for eBPF map or program. Write info. */
12745 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12746 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12747 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12748 if (ML_(safe_to_deref)(attr, ARG3)) {
12749 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12750 SET_STATUS_Failure(VKI_EBADF);
12751 break;
12753 /* Get size of struct to write: is object a program or a map? */
12754 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12755 if (res)
12756 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12757 VG_MIN(attr->info.info_len, res));
12758 else
12759 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12760 VG_MIN(attr->info.info_len,
12761 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12762 sizeof(struct vki_bpf_map_info)),
12763 sizeof(struct vki_bpf_btf_info))));
12765 break;
12766 case VKI_BPF_PROG_QUERY:
12768 * Query list of eBPF program attached to cgroup.
12769 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12771 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12772 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12773 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12774 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12775 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12776 if (ML_(safe_to_deref)(attr, ARG3)) {
12777 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12778 SET_STATUS_Failure(VKI_EBADF);
12779 break;
12781 if (attr->query.prog_cnt > 0) {
12782 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12783 if (attr->query.prog_ids) {
12784 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12785 attr->query.prog_cnt * sizeof(__vki_u32));
12789 break;
12790 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12791 /* Open raw tracepoint. Read tracepoint name. */
12792 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12793 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12794 if (ML_(safe_to_deref)(attr, ARG3)) {
12795 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12796 "bpf", tid, False)) {
12797 SET_STATUS_Failure(VKI_EBADF);
12798 break;
12800 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12801 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
12802 "bpf(attr->raw_tracepoint.name)");
12804 break;
12805 case VKI_BPF_BTF_LOAD:
12806 /* Load BTF information about a program into the kernel. */
12807 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
12808 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
12809 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
12810 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
12811 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
12812 if (ML_(safe_to_deref)(attr, ARG3)) {
12813 /* Read BTF data. */
12814 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
12815 /* Possibly write up to btf_log_len into user space log buffer. */
12816 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
12817 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
12818 attr->btf_log_buf, attr->btf_log_size);
12820 break;
12821 case VKI_BPF_TASK_FD_QUERY:
12822 /* Get info about the task. Write collected info. */
12823 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
12824 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
12825 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
12826 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
12827 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
12828 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12829 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12830 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12831 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12832 if (ML_(safe_to_deref)(attr, ARG3)) {
12833 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
12834 SET_STATUS_Failure(VKI_EBADF);
12835 break;
12837 if (attr->task_fd_query.buf_len > 0) {
12838 /* Write task or perf event name. */
12839 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
12840 attr->task_fd_query.buf,
12841 attr->task_fd_query.buf_len);
12844 break;
12845 default:
12846 VG_(message)(Vg_DebugMsg,
12847 "FATAL: unhandled eBPF command %lu\n", ARG1);
12848 VG_(core_panic)("... bye!\n");
12849 break;
12853 POST(sys_bpf)
12855 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12856 UInt key_size, value_size;
12858 vg_assert(SUCCESS);
12860 switch (ARG1) {
12861 case VKI_BPF_PROG_GET_NEXT_ID:
12862 case VKI_BPF_MAP_GET_NEXT_ID:
12863 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12864 break;
12865 case VKI_BPF_MAP_UPDATE_ELEM:
12866 case VKI_BPF_MAP_DELETE_ELEM:
12867 case VKI_BPF_OBJ_PIN:
12868 case VKI_BPF_PROG_ATTACH:
12869 case VKI_BPF_PROG_DETACH:
12870 break;
12871 /* Following commands have bpf() return a file descriptor. */
12872 case VKI_BPF_MAP_CREATE:
12873 case VKI_BPF_OBJ_GET:
12874 case VKI_BPF_PROG_GET_FD_BY_ID:
12875 case VKI_BPF_MAP_GET_FD_BY_ID:
12876 case VKI_BPF_BTF_GET_FD_BY_ID:
12877 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12878 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12879 VG_(close)(RES);
12880 SET_STATUS_Failure(VKI_EMFILE);
12881 } else {
12882 if (VG_(clo_track_fds))
12883 ML_(record_fd_open_nameless)(tid, RES);
12885 break;
12887 * TODO: Is there a way to pass information between PRE and POST hooks?
12888 * To avoid querying again for the size of keys and values.
12890 case VKI_BPF_MAP_LOOKUP_ELEM:
12891 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12892 POST_MEM_WRITE(attr->value, value_size);
12893 break;
12894 case VKI_BPF_MAP_GET_NEXT_KEY:
12895 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12896 POST_MEM_WRITE(attr->next_key, key_size);
12897 break;
12898 case VKI_BPF_PROG_LOAD:
12899 /* Return a file descriptor for loaded program, write into log_buf. */
12900 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12901 VG_(close)(RES);
12902 SET_STATUS_Failure(VKI_EMFILE);
12903 } else {
12904 if (VG_(clo_track_fds))
12905 ML_(record_fd_open_nameless)(tid, RES);
12907 if (attr->log_level || attr->log_size || attr->log_buf)
12908 POST_MEM_WRITE(attr->log_buf, attr->log_size);
12909 break;
12910 case VKI_BPF_PROG_TEST_RUN:
12911 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
12912 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12913 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
12914 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
12915 break;
12916 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12917 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
12918 break;
12919 case VKI_BPF_PROG_QUERY:
12920 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12921 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12922 if (attr->query.prog_ids)
12923 POST_MEM_WRITE(attr->query.prog_ids,
12924 attr->query.prog_cnt * sizeof(__vki_u32));
12925 break;
12926 case VKI_BPF_BTF_LOAD:
12927 /* Return a file descriptor for BTF data, write into btf_log_buf. */
12928 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12929 VG_(close)(RES);
12930 SET_STATUS_Failure(VKI_EMFILE);
12931 } else {
12932 if (VG_(clo_track_fds))
12933 ML_(record_fd_open_nameless)(tid, RES);
12935 if (attr->btf_log_level)
12936 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
12937 break;
12938 case VKI_BPF_TASK_FD_QUERY:
12939 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
12940 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12941 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12942 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12943 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12944 break;
12945 default:
12946 VG_(message)(Vg_DebugMsg,
12947 "FATAL: unhandled eBPF command %lu\n", ARG1);
12948 VG_(core_panic)("... bye!\n");
12949 break;
12953 PRE(sys_copy_file_range)
12955 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
12956 ARG4, ARG5, ARG6);
12958 PRE_REG_READ6(vki_size_t, "copy_file_range",
12959 int, "fd_in",
12960 vki_loff_t *, "off_in",
12961 int, "fd_out",
12962 vki_loff_t *, "off_out",
12963 vki_size_t, "len",
12964 unsigned int, "flags");
12966 /* File descriptors are "specially" tracked by valgrind.
12967 valgrind itself uses some, so make sure someone didn't
12968 put in one of our own... */
12969 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
12970 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
12971 SET_STATUS_Failure( VKI_EBADF );
12972 } else {
12973 /* Now see if the offsets are defined. PRE_MEM_READ will
12974 double check it can dereference them. */
12975 if (ARG2 != 0)
12976 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
12977 if (ARG4 != 0)
12978 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
12982 PRE(sys_pkey_alloc)
12984 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
12986 PRE_REG_READ2(long, "pkey_alloc",
12987 unsigned long, "flags",
12988 unsigned long, "access_rights");
12990 /* The kernel says: pkey_alloc() is always safe to call regardless of
12991 whether or not the operating system supports protection keys. It can be
12992 used in lieu of any other mechanism for detecting pkey support and will
12993 simply fail with the error ENOSPC if the operating system has no pkey
12994 support.
12996 So we simply always return ENOSPC to signal memory protection keys are
12997 not supported under valgrind, unless there are unknown flags, then we
12998 return EINVAL. */
12999 unsigned long pkey_flags = ARG1;
13000 if (pkey_flags != 0)
13001 SET_STATUS_Failure( VKI_EINVAL );
13002 else
13003 SET_STATUS_Failure( VKI_ENOSPC );
13006 PRE(sys_pkey_free)
13008 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13010 PRE_REG_READ1(long, "pkey_free",
13011 unsigned long, "pkey");
13013 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13014 always an error. */
13015 SET_STATUS_Failure( VKI_EINVAL );
13018 PRE(sys_pkey_mprotect)
13020 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13021 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13022 PRE_REG_READ4(long, "pkey_mprotect",
13023 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13024 unsigned long, pkey);
13026 Addr addr = ARG1;
13027 SizeT len = ARG2;
13028 Int prot = ARG3;
13029 Int pkey = ARG4;
13031 /* Since pkey_alloc () can never succeed, see above, any pkey is
13032 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13033 if (pkey != -1)
13034 SET_STATUS_Failure( VKI_EINVAL );
13035 else
13036 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13038 ARG1 = addr;
13039 ARG2 = len;
13040 ARG3 = prot;
13043 POST(sys_pkey_mprotect)
13045 Addr addr = ARG1;
13046 SizeT len = ARG2;
13047 Int prot = ARG3;
13049 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13052 PRE(sys_io_uring_setup)
13054 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13055 ARG1, ARG2);
13056 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13057 struct vki_io_uring_params *, p);
13058 if (ARG2)
13059 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13060 offsetof(struct vki_io_uring_params, sq_off));
13063 POST(sys_io_uring_setup)
13065 vg_assert(SUCCESS);
13066 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13067 VG_(close)(RES);
13068 SET_STATUS_Failure( VKI_EMFILE );
13069 } else {
13070 if (VG_(clo_track_fds))
13071 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
13072 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13073 sizeof(struct vki_io_sqring_offsets) +
13074 sizeof(struct vki_io_cqring_offsets));
13078 PRE(sys_io_uring_enter)
13080 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13081 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13082 FMT_REGWORD "u )",
13083 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13084 PRE_REG_READ6(long, "io_uring_enter",
13085 unsigned int, fd, unsigned int, to_submit,
13086 unsigned int, min_complete, unsigned int, flags,
13087 const void *, sig, unsigned long, sigsz);
13088 if (ARG5)
13089 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13092 POST(sys_io_uring_enter)
13096 PRE(sys_io_uring_register)
13098 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13099 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13100 PRE_REG_READ4(long, "io_uring_register",
13101 unsigned int, fd, unsigned int, opcode,
13102 void *, arg, unsigned int, nr_args);
13103 switch (ARG2) {
13104 case VKI_IORING_REGISTER_BUFFERS:
13105 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13106 break;
13107 case VKI_IORING_UNREGISTER_BUFFERS:
13108 break;
13109 case VKI_IORING_REGISTER_FILES:
13110 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13111 break;
13112 case VKI_IORING_UNREGISTER_FILES:
13113 break;
13114 case VKI_IORING_REGISTER_EVENTFD:
13115 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13116 break;
13117 case VKI_IORING_UNREGISTER_EVENTFD:
13118 break;
13122 POST(sys_io_uring_register)
13126 #undef PRE
13127 #undef POST
13129 #endif // defined(VGO_linux)
13131 /*--------------------------------------------------------------------*/
13132 /*--- end ---*/
13133 /*--------------------------------------------------------------------*/