Support new faccessat2 linux syscall (439)
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob41849873e6ca7df94d3a1cb8ccfdc27b2860c632
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 /* Just check the events field, the data field is for user space and
2104 unused by the kernel. */
2105 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2106 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2107 sizeof(__vki_u32) );
2111 /* RES event records have been written (exclude padding). */
2112 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2113 SyscallStatus* status )
2115 vg_assert(SUCCESS);
2116 if (RES > 0) {
2117 Int i;
2118 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2119 for (i = 0; i < RES; i++) {
2120 /* Assume both events and data are set (data is user space only). */
2121 POST_FIELD_WRITE(events[i].events);
2122 POST_FIELD_WRITE(events[i].data);
2127 PRE(sys_epoll_wait)
2129 *flags |= SfMayBlock;
2130 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2131 SARG1, ARG2, SARG3, SARG4);
2132 PRE_REG_READ4(long, "epoll_wait",
2133 int, epfd, struct vki_epoll_event *, events,
2134 int, maxevents, int, timeout);
2135 /* Assume all (maxevents) events records should be (fully) writable. */
2136 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2138 POST(sys_epoll_wait)
2140 epoll_post_helper (tid, arrghs, status);
2143 PRE(sys_epoll_pwait)
2145 *flags |= SfMayBlock;
2146 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2147 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2148 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2149 PRE_REG_READ6(long, "epoll_pwait",
2150 int, epfd, struct vki_epoll_event *, events,
2151 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2152 vki_size_t, sigsetsize);
2153 /* Assume all (maxevents) events records should be (fully) writable. */
2154 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2155 if (ARG5)
2156 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2158 POST(sys_epoll_pwait)
2160 epoll_post_helper (tid, arrghs, status);
2163 PRE(sys_eventfd)
2165 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2166 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2168 POST(sys_eventfd)
2170 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2171 VG_(close)(RES);
2172 SET_STATUS_Failure( VKI_EMFILE );
2173 } else {
2174 if (VG_(clo_track_fds))
2175 ML_(record_fd_open_nameless) (tid, RES);
2179 PRE(sys_eventfd2)
2181 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2182 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2184 POST(sys_eventfd2)
2186 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2187 VG_(close)(RES);
2188 SET_STATUS_Failure( VKI_EMFILE );
2189 } else {
2190 if (VG_(clo_track_fds))
2191 ML_(record_fd_open_nameless) (tid, RES);
2195 PRE(sys_fallocate)
2197 *flags |= SfMayBlock;
2198 #if VG_WORDSIZE == 4
2199 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2200 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2201 PRE_REG_READ6(long, "fallocate",
2202 int, fd, int, mode,
2203 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2204 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2205 #elif VG_WORDSIZE == 8
2206 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2207 SARG1, SARG2, SARG3, SARG4);
2208 PRE_REG_READ4(long, "fallocate",
2209 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2210 #else
2211 # error Unexpected word size
2212 #endif
2213 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2214 SET_STATUS_Failure( VKI_EBADF );
2217 PRE(sys_prlimit64)
2219 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2220 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2221 PRE_REG_READ4(long, "prlimit64",
2222 vki_pid_t, pid, unsigned int, resource,
2223 const struct rlimit64 *, new_rlim,
2224 struct rlimit64 *, old_rlim);
2225 if (ARG3)
2226 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2227 if (ARG4)
2228 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2230 if (ARG3 &&
2231 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2232 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2233 SET_STATUS_Failure( VKI_EINVAL );
2235 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2236 switch (ARG2) {
2237 case VKI_RLIMIT_NOFILE:
2238 SET_STATUS_Success( 0 );
2239 if (ARG4) {
2240 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2241 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2243 if (ARG3) {
2244 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2245 > VG_(fd_hard_limit) ||
2246 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2247 != VG_(fd_hard_limit)) {
2248 SET_STATUS_Failure( VKI_EPERM );
2250 else {
2251 VG_(fd_soft_limit) =
2252 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2255 break;
2257 case VKI_RLIMIT_DATA:
2258 SET_STATUS_Success( 0 );
2259 if (ARG4) {
2260 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2261 VG_(client_rlimit_data).rlim_cur;
2262 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2263 VG_(client_rlimit_data).rlim_max;
2265 if (ARG3) {
2266 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2267 > VG_(client_rlimit_data).rlim_max ||
2268 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2269 > VG_(client_rlimit_data).rlim_max) {
2270 SET_STATUS_Failure( VKI_EPERM );
2272 else {
2273 VG_(client_rlimit_data).rlim_cur =
2274 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2275 VG_(client_rlimit_data).rlim_max =
2276 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2279 break;
2281 case VKI_RLIMIT_STACK:
2282 SET_STATUS_Success( 0 );
2283 if (ARG4) {
2284 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2285 VG_(client_rlimit_stack).rlim_cur;
2286 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2287 VG_(client_rlimit_stack).rlim_max;
2289 if (ARG3) {
2290 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2291 > VG_(client_rlimit_stack).rlim_max ||
2292 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2293 > VG_(client_rlimit_stack).rlim_max) {
2294 SET_STATUS_Failure( VKI_EPERM );
2296 else {
2297 VG_(threads)[tid].client_stack_szB =
2298 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2299 VG_(client_rlimit_stack).rlim_cur =
2300 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2301 VG_(client_rlimit_stack).rlim_max =
2302 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2305 break;
2310 POST(sys_prlimit64)
2312 if (ARG4)
2313 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2316 /* ---------------------------------------------------------------------
2317 tid-related wrappers
2318 ------------------------------------------------------------------ */
2320 PRE(sys_gettid)
2322 PRINT("sys_gettid ()");
2323 PRE_REG_READ0(long, "gettid");
2326 PRE(sys_set_tid_address)
2328 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2329 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2332 PRE(sys_tkill)
2334 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2335 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2336 if (!ML_(client_signal_OK)(ARG2)) {
2337 SET_STATUS_Failure( VKI_EINVAL );
2338 return;
2341 /* Check to see if this kill gave us a pending signal */
2342 *flags |= SfPollAfter;
2344 if (VG_(clo_trace_signals))
2345 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2346 SARG2, SARG1);
2348 /* If we're sending SIGKILL, check to see if the target is one of
2349 our threads and handle it specially. */
2350 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2351 SET_STATUS_Success(0);
2352 return;
2355 /* Ask to handle this syscall via the slow route, since that's the
2356 only one that sets tst->status to VgTs_WaitSys. If the result
2357 of doing the syscall is an immediate run of
2358 async_signalhandler() in m_signals, then we need the thread to
2359 be properly tidied away. I have the impression the previous
2360 version of this wrapper worked on x86/amd64 only because the
2361 kernel did not immediately deliver the async signal to this
2362 thread (on ppc it did, which broke the assertion re tst->status
2363 at the top of async_signalhandler()). */
2364 *flags |= SfMayBlock;
2366 POST(sys_tkill)
2368 if (VG_(clo_trace_signals))
2369 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2370 SARG2, SARG1);
2373 PRE(sys_tgkill)
2375 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2376 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2377 if (!ML_(client_signal_OK)(ARG3)) {
2378 SET_STATUS_Failure( VKI_EINVAL );
2379 return;
2382 /* Check to see if this kill gave us a pending signal */
2383 *flags |= SfPollAfter;
2385 if (VG_(clo_trace_signals))
2386 VG_(message)(Vg_DebugMsg,
2387 "tgkill: sending signal %ld to pid %ld/%ld\n",
2388 SARG3, SARG1, SARG2);
2390 /* If we're sending SIGKILL, check to see if the target is one of
2391 our threads and handle it specially. */
2392 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2393 SET_STATUS_Success(0);
2394 return;
2397 /* Ask to handle this syscall via the slow route, since that's the
2398 only one that sets tst->status to VgTs_WaitSys. If the result
2399 of doing the syscall is an immediate run of
2400 async_signalhandler() in m_signals, then we need the thread to
2401 be properly tidied away. I have the impression the previous
2402 version of this wrapper worked on x86/amd64 only because the
2403 kernel did not immediately deliver the async signal to this
2404 thread (on ppc it did, which broke the assertion re tst->status
2405 at the top of async_signalhandler()). */
2406 *flags |= SfMayBlock;
2408 POST(sys_tgkill)
2410 if (VG_(clo_trace_signals))
2411 VG_(message)(Vg_DebugMsg,
2412 "tgkill: sent signal %ld to pid %ld/%ld\n",
2413 SARG3, SARG1, SARG2);
2416 /* ---------------------------------------------------------------------
2417 fadvise64* wrappers
2418 ------------------------------------------------------------------ */
2420 PRE(sys_fadvise64)
2422 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2423 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2424 PRE_REG_READ5(long, "fadvise64",
2425 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2426 vki_size_t, len, int, advice);
2429 PRE(sys_fadvise64_64)
2431 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2432 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2433 PRE_REG_READ6(long, "fadvise64_64",
2434 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2435 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2438 /* ---------------------------------------------------------------------
2439 io_* wrappers
2440 ------------------------------------------------------------------ */
2442 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2443 // and this allows us to control exactly the code that gets run while
2444 // the padding is in place.
2446 PRE(sys_io_setup)
2448 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2449 PRE_REG_READ2(long, "io_setup",
2450 unsigned, nr_events, vki_aio_context_t *, ctxp);
2451 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2454 POST(sys_io_setup)
2456 SizeT size;
2457 struct vki_aio_ring *r;
2459 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2460 ARG1*sizeof(struct vki_io_event));
2461 r = *(struct vki_aio_ring **)(Addr)ARG2;
2462 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2464 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2465 VKI_PROT_READ | VKI_PROT_WRITE,
2466 VKI_MAP_ANONYMOUS, -1, 0 );
2468 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2471 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2472 // after the syscall. We must get 'size' from the aio_ring structure,
2473 // before the syscall, while the aio_ring structure still exists. (And we
2474 // know that we must look at the aio_ring structure because Tom inspected the
2475 // kernel and glibc sources to see what they do, yuk.)
2477 // XXX This segment can be implicitly unmapped when aio
2478 // file-descriptors are closed...
2479 PRE(sys_io_destroy)
2481 SizeT size = 0;
2483 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2484 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2486 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2487 // possible...
2488 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2489 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2490 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2491 r->nr*sizeof(struct vki_io_event));
2494 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2496 if (SUCCESS && RES == 0) {
2497 Bool d = VG_(am_notify_munmap)( ARG1, size );
2498 VG_TRACK( die_mem_munmap, ARG1, size );
2499 if (d)
2500 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2501 "PRE(sys_io_destroy)" );
2505 PRE(sys_io_getevents)
2507 *flags |= SfMayBlock;
2508 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2509 FMT_REGWORD "x )",
2510 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2511 PRE_REG_READ5(long, "io_getevents",
2512 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2513 struct io_event *, events,
2514 struct timespec *, timeout);
2515 if (ARG3 > 0)
2516 PRE_MEM_WRITE( "io_getevents(events)",
2517 ARG4, sizeof(struct vki_io_event)*ARG3 );
2518 if (ARG5 != 0)
2519 PRE_MEM_READ( "io_getevents(timeout)",
2520 ARG5, sizeof(struct vki_timespec));
2522 POST(sys_io_getevents)
2524 Int i;
2525 vg_assert(SUCCESS);
2526 if (RES > 0) {
2527 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2528 for (i = 0; i < RES; i++) {
2529 const struct vki_io_event *vev =
2530 ((struct vki_io_event *)(Addr)ARG4) + i;
2531 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2533 switch (cb->aio_lio_opcode) {
2534 case VKI_IOCB_CMD_PREAD:
2535 if (vev->result > 0)
2536 POST_MEM_WRITE( cb->aio_buf, vev->result );
2537 break;
2539 case VKI_IOCB_CMD_PWRITE:
2540 break;
2542 case VKI_IOCB_CMD_FSYNC:
2543 break;
2545 case VKI_IOCB_CMD_FDSYNC:
2546 break;
2548 case VKI_IOCB_CMD_PREADV:
2549 if (vev->result > 0) {
2550 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2551 Int remains = vev->result;
2552 Int j;
2554 for (j = 0; j < cb->aio_nbytes; j++) {
2555 Int nReadThisBuf = vec[j].iov_len;
2556 if (nReadThisBuf > remains) nReadThisBuf = remains;
2557 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2558 remains -= nReadThisBuf;
2559 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2562 break;
2564 case VKI_IOCB_CMD_PWRITEV:
2565 break;
2567 default:
2568 VG_(message)(Vg_DebugMsg,
2569 "Warning: unhandled io_getevents opcode: %u\n",
2570 cb->aio_lio_opcode);
2571 break;
2577 PRE(sys_io_submit)
2579 Int i, j;
2581 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2582 ARG1, SARG2, ARG3);
2583 PRE_REG_READ3(long, "io_submit",
2584 vki_aio_context_t, ctx_id, long, nr,
2585 struct iocb **, iocbpp);
2586 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2587 if (ARG3 != 0) {
2588 for (i = 0; i < ARG2; i++) {
2589 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2590 struct vki_iovec *iov;
2592 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2593 switch (cb->aio_lio_opcode) {
2594 case VKI_IOCB_CMD_PREAD:
2595 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2596 break;
2598 case VKI_IOCB_CMD_PWRITE:
2599 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2600 break;
2602 case VKI_IOCB_CMD_FSYNC:
2603 break;
2605 case VKI_IOCB_CMD_FDSYNC:
2606 break;
2608 case VKI_IOCB_CMD_PREADV:
2609 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2610 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2611 for (j = 0; j < cb->aio_nbytes; j++)
2612 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2613 break;
2615 case VKI_IOCB_CMD_PWRITEV:
2616 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2617 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2618 for (j = 0; j < cb->aio_nbytes; j++)
2619 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2620 break;
2622 default:
2623 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2624 cb->aio_lio_opcode);
2625 break;
2631 PRE(sys_io_cancel)
2633 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2634 (ULong)ARG1, ARG2, ARG3);
2635 PRE_REG_READ3(long, "io_cancel",
2636 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2637 struct io_event *, result);
2638 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2639 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2641 POST(sys_io_cancel)
2643 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2646 /* ---------------------------------------------------------------------
2647 *_mempolicy wrappers
2648 ------------------------------------------------------------------ */
2650 PRE(sys_mbind)
2652 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2653 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2654 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2655 PRE_REG_READ6(long, "mbind",
2656 unsigned long, start, unsigned long, len,
2657 unsigned long, policy, unsigned long *, nodemask,
2658 unsigned long, maxnode, unsigned, flags);
2659 if (ARG1 != 0)
2660 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2661 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2664 PRE(sys_set_mempolicy)
2666 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2667 SARG1, ARG2, ARG3);
2668 PRE_REG_READ3(long, "set_mempolicy",
2669 int, policy, unsigned long *, nodemask,
2670 unsigned long, maxnode);
2671 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2672 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2675 PRE(sys_get_mempolicy)
2677 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2678 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2679 ARG1, ARG2, ARG3, ARG4, ARG5);
2680 PRE_REG_READ5(long, "get_mempolicy",
2681 int *, policy, unsigned long *, nodemask,
2682 unsigned long, maxnode, unsigned long, addr,
2683 unsigned long, flags);
2684 if (ARG1 != 0)
2685 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2686 if (ARG2 != 0)
2687 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2688 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2690 POST(sys_get_mempolicy)
2692 if (ARG1 != 0)
2693 POST_MEM_WRITE( ARG1, sizeof(Int) );
2694 if (ARG2 != 0)
2695 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2698 /* ---------------------------------------------------------------------
2699 fanotify_* wrappers
2700 ------------------------------------------------------------------ */
2702 PRE(sys_fanotify_init)
2704 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2705 ARG1, ARG2);
2706 PRE_REG_READ2(long, "fanotify_init",
2707 unsigned int, flags, unsigned int, event_f_flags);
2710 POST(sys_fanotify_init)
2712 vg_assert(SUCCESS);
2713 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2714 VG_(close)(RES);
2715 SET_STATUS_Failure( VKI_EMFILE );
2716 } else {
2717 if (VG_(clo_track_fds))
2718 ML_(record_fd_open_nameless) (tid, RES);
2722 PRE(sys_fanotify_mark)
2724 #if VG_WORDSIZE == 4
2725 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2726 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2727 (HChar *)(Addr)ARG6);
2728 PRE_REG_READ6(long, "sys_fanotify_mark",
2729 int, fanotify_fd, unsigned int, flags,
2730 __vki_u32, mask0, __vki_u32, mask1,
2731 int, dfd, const char *, pathname);
2732 if (ARG6)
2733 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2734 #elif VG_WORDSIZE == 8
2735 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2736 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2737 PRE_REG_READ5(long, "sys_fanotify_mark",
2738 int, fanotify_fd, unsigned int, flags,
2739 __vki_u64, mask,
2740 int, dfd, const char *, pathname);
2741 if (ARG5)
2742 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2743 #else
2744 # error Unexpected word size
2745 #endif
2748 /* ---------------------------------------------------------------------
2749 inotify_* wrappers
2750 ------------------------------------------------------------------ */
2752 PRE(sys_inotify_init)
2754 PRINT("sys_inotify_init ( )");
2755 PRE_REG_READ0(long, "inotify_init");
2757 POST(sys_inotify_init)
2759 vg_assert(SUCCESS);
2760 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2761 VG_(close)(RES);
2762 SET_STATUS_Failure( VKI_EMFILE );
2763 } else {
2764 if (VG_(clo_track_fds))
2765 ML_(record_fd_open_nameless) (tid, RES);
2769 PRE(sys_inotify_init1)
2771 PRINT("sys_inotify_init ( %ld )", SARG1);
2772 PRE_REG_READ1(long, "inotify_init", int, flag);
2775 POST(sys_inotify_init1)
2777 vg_assert(SUCCESS);
2778 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2779 VG_(close)(RES);
2780 SET_STATUS_Failure( VKI_EMFILE );
2781 } else {
2782 if (VG_(clo_track_fds))
2783 ML_(record_fd_open_nameless) (tid, RES);
2787 PRE(sys_inotify_add_watch)
2789 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2790 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2791 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2792 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2795 PRE(sys_inotify_rm_watch)
2797 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2798 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2801 /* ---------------------------------------------------------------------
2802 mq_* wrappers
2803 ------------------------------------------------------------------ */
2805 PRE(sys_mq_open)
2807 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2808 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2809 PRE_REG_READ4(long, "mq_open",
2810 const char *, name, int, oflag, vki_mode_t, mode,
2811 struct mq_attr *, attr);
2812 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2813 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2814 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2815 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2816 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2817 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2818 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2821 POST(sys_mq_open)
2823 vg_assert(SUCCESS);
2824 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2825 VG_(close)(RES);
2826 SET_STATUS_Failure( VKI_EMFILE );
2827 } else {
2828 if (VG_(clo_track_fds))
2829 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2833 PRE(sys_mq_unlink)
2835 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2836 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2837 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2840 PRE(sys_mq_timedsend)
2842 *flags |= SfMayBlock;
2843 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2844 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2845 SARG1,ARG2,ARG3,ARG4,ARG5);
2846 PRE_REG_READ5(long, "mq_timedsend",
2847 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2848 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2849 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2850 SET_STATUS_Failure( VKI_EBADF );
2851 } else {
2852 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2853 if (ARG5 != 0)
2854 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2855 sizeof(struct vki_timespec) );
2859 PRE(sys_mq_timedsend_time64)
2861 *flags |= SfMayBlock;
2862 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2863 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2864 SARG1,ARG2,ARG3,ARG4,ARG5);
2865 PRE_REG_READ5(long, "mq_timedsend_time64",
2866 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2867 unsigned int, msg_prio,
2868 const struct vki_timespec64 *, abs_timeout);
2869 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2870 SET_STATUS_Failure( VKI_EBADF );
2871 } else {
2872 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2873 if (ARG5 != 0)
2874 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2878 PRE(sys_mq_timedreceive)
2880 *flags |= SfMayBlock;
2881 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2882 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2883 SARG1,ARG2,ARG3,ARG4,ARG5);
2884 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2885 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2886 unsigned int *, msg_prio,
2887 const struct timespec *, abs_timeout);
2888 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2889 SET_STATUS_Failure( VKI_EBADF );
2890 } else {
2891 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2892 if (ARG4 != 0)
2893 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2894 ARG4, sizeof(unsigned int) );
2895 if (ARG5 != 0)
2896 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2897 ARG5, sizeof(struct vki_timespec) );
2900 POST(sys_mq_timedreceive)
2902 POST_MEM_WRITE( ARG2, RES );
2903 if (ARG4 != 0)
2904 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2907 PRE(sys_mq_timedreceive_time64)
2909 *flags |= SfMayBlock;
2910 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2911 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2912 SARG1,ARG2,ARG3,ARG4,ARG5);
2913 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2914 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2915 unsigned int *, msg_prio,
2916 const struct vki_timespec64 *, abs_timeout);
2917 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2918 SET_STATUS_Failure( VKI_EBADF );
2919 } else {
2920 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2921 if (ARG4 != 0)
2922 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2923 ARG4, sizeof(unsigned int) );
2924 if (ARG5 != 0)
2925 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2929 POST(sys_mq_timedreceive_time64)
2931 POST_MEM_WRITE( ARG2, RES );
2932 if (ARG4 != 0)
2933 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2936 PRE(sys_mq_notify)
2938 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2939 PRE_REG_READ2(long, "mq_notify",
2940 vki_mqd_t, mqdes, const struct sigevent *, notification);
2941 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2942 SET_STATUS_Failure( VKI_EBADF );
2943 else if (ARG2 != 0)
2944 PRE_MEM_READ( "mq_notify(notification)",
2945 ARG2, sizeof(struct vki_sigevent) );
2948 PRE(sys_mq_getsetattr)
2950 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2951 SARG1, ARG2, ARG3 );
2952 PRE_REG_READ3(long, "mq_getsetattr",
2953 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2954 struct mq_attr *, omqstat);
2955 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2956 SET_STATUS_Failure( VKI_EBADF );
2957 } else {
2958 if (ARG2 != 0) {
2959 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2960 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2961 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2963 if (ARG3 != 0)
2964 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2965 sizeof(struct vki_mq_attr) );
2968 POST(sys_mq_getsetattr)
2970 if (ARG3 != 0)
2971 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2974 /* ---------------------------------------------------------------------
2975 clock_* wrappers
2976 ------------------------------------------------------------------ */
2978 PRE(sys_clock_settime)
2980 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2981 PRE_REG_READ2(long, "clock_settime",
2982 vki_clockid_t, clk_id, const struct timespec *, tp);
2983 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2986 PRE(sys_clock_settime64)
2988 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2989 PRE_REG_READ2(long, "clock_settime64",
2990 vki_clockid_t, clk_id, const struct timespec64 *, tp);
2991 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
2994 PRE(sys_clock_gettime)
2996 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2997 PRE_REG_READ2(long, "clock_gettime",
2998 vki_clockid_t, clk_id, struct timespec *, tp);
2999 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3001 POST(sys_clock_gettime)
3003 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3006 PRE(sys_clock_gettime64)
3008 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3009 PRE_REG_READ2(long, "clock_gettime64",
3010 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3011 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3012 sizeof(struct vki_timespec64) );
3014 POST(sys_clock_gettime64)
3016 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3019 PRE(sys_clock_getres)
3021 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3022 // Nb: we can't use "RES" as the param name because that's a macro
3023 // defined above!
3024 PRE_REG_READ2(long, "clock_getres",
3025 vki_clockid_t, clk_id, struct timespec *, res);
3026 if (ARG2 != 0)
3027 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3029 POST(sys_clock_getres)
3031 if (ARG2 != 0)
3032 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3035 PRE(sys_clock_getres_time64)
3037 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3038 // Nb: we can't use "RES" as the param name because that's a macro
3039 // defined above!
3040 PRE_REG_READ2(long, "clock_getres_time64",
3041 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3042 if (ARG2 != 0)
3043 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3044 sizeof(struct vki_timespec64) );
3046 POST(sys_clock_getres_time64)
3048 if (ARG2 != 0)
3049 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3052 PRE(sys_clock_nanosleep)
3054 *flags |= SfMayBlock|SfPostOnFail;
3055 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3056 FMT_REGWORD "x )",
3057 SARG1, SARG2, ARG3, ARG4);
3058 PRE_REG_READ4(int32_t, "clock_nanosleep",
3059 vki_clockid_t, clkid, int, flags,
3060 const struct timespec *, rqtp, struct timespec *, rmtp);
3061 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3062 if (ARG4 != 0)
3063 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3065 POST(sys_clock_nanosleep)
3067 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3068 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3071 PRE(sys_clock_nanosleep_time64)
3073 *flags |= SfMayBlock|SfPostOnFail;
3074 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3075 FMT_REGWORD "x )",
3076 SARG1, SARG2, ARG3, ARG4);
3077 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3078 vki_clockid_t, clkid, int, flags,
3079 const struct vki_timespec64 *, rqtp,
3080 struct vki_timespec64 *, rmtp);
3081 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3082 if (ARG4 != 0)
3083 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3084 sizeof(struct vki_timespec64) );
3086 POST(sys_clock_nanosleep_time64)
3088 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3089 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3092 /* ---------------------------------------------------------------------
3093 timer_* wrappers
3094 ------------------------------------------------------------------ */
3096 PRE(sys_timer_create)
3098 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3099 SARG1, ARG2, ARG3);
3100 PRE_REG_READ3(long, "timer_create",
3101 vki_clockid_t, clockid, struct sigevent *, evp,
3102 vki_timer_t *, timerid);
3103 if (ARG2 != 0) {
3104 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3105 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3106 sizeof(vki_sigval_t) );
3107 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3108 sizeof(int) );
3109 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3110 sizeof(int) );
3111 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3112 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3113 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3114 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3116 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3118 POST(sys_timer_create)
3120 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3123 PRE(sys_timer_settime)
3125 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3126 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3127 PRE_REG_READ4(long, "timer_settime",
3128 vki_timer_t, timerid, int, flags,
3129 const struct itimerspec *, value,
3130 struct itimerspec *, ovalue);
3131 PRE_MEM_READ( "timer_settime(value)", ARG3,
3132 sizeof(struct vki_itimerspec) );
3133 if (ARG4 != 0)
3134 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3135 sizeof(struct vki_itimerspec) );
3137 POST(sys_timer_settime)
3139 if (ARG4 != 0)
3140 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3143 PRE(sys_timer_settime64)
3145 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3146 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3147 PRE_REG_READ4(long, "timer_settime64",
3148 vki_timer_t, timerid, int, flags,
3149 const struct vki_itimerspec64 *, value,
3150 struct vki_itimerspec64 *, ovalue);
3151 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3152 sizeof(struct vki_itimerspec64) );
3153 if (ARG4 != 0)
3154 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3155 sizeof(struct vki_itimerspec64) );
3157 POST(sys_timer_settime64)
3159 if (ARG4 != 0)
3160 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3163 PRE(sys_timer_gettime)
3165 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3166 PRE_REG_READ2(long, "timer_gettime",
3167 vki_timer_t, timerid, struct itimerspec *, value);
3168 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3169 sizeof(struct vki_itimerspec));
3171 POST(sys_timer_gettime)
3173 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3176 PRE(sys_timer_gettime64)
3178 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3179 PRE_REG_READ2(long, "timer_gettime64",
3180 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3181 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3182 sizeof(struct vki_itimerspec64));
3184 POST(sys_timer_gettime64)
3186 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3189 PRE(sys_timer_getoverrun)
3191 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3192 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3195 PRE(sys_timer_delete)
3197 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3198 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3201 /* ---------------------------------------------------------------------
3202 timerfd* wrappers
3203 See also http://lwn.net/Articles/260172/ for an overview.
3204 See also /usr/src/linux/fs/timerfd.c for the implementation.
3205 ------------------------------------------------------------------ */
3207 /* Returns True if running on 2.6.22, else False (or False if
3208 cannot be determined). */
3209 static Bool linux_kernel_2_6_22(void)
3211 static Int result = -1;
3212 Int fd, read;
3213 HChar release[64]; // large enough
3214 SysRes res;
3216 if (result == -1) {
3217 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3218 if (sr_isError(res))
3219 return False;
3220 fd = sr_Res(res);
3221 read = VG_(read)(fd, release, sizeof(release) - 1);
3222 if (read < 0)
3223 return False;
3224 release[read] = 0;
3225 VG_(close)(fd);
3226 //VG_(printf)("kernel release = %s\n", release);
3227 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3228 && ! VG_(isdigit)(release[6]);
3230 vg_assert(result == 0 || result == 1);
3231 return result == 1;
3234 PRE(sys_timerfd_create)
3236 if (linux_kernel_2_6_22()) {
3237 /* 2.6.22 kernel: timerfd system call. */
3238 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3239 PRE_REG_READ3(long, "sys_timerfd",
3240 int, fd, int, clockid, const struct itimerspec *, tmr);
3241 PRE_MEM_READ("timerfd(tmr)", ARG3,
3242 sizeof(struct vki_itimerspec) );
3243 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3244 SET_STATUS_Failure( VKI_EBADF );
3245 } else {
3246 /* 2.6.24 and later kernels: timerfd_create system call. */
3247 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3248 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3251 POST(sys_timerfd_create)
3253 if (linux_kernel_2_6_22())
3255 /* 2.6.22 kernel: timerfd system call. */
3256 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3257 VG_(close)(RES);
3258 SET_STATUS_Failure( VKI_EMFILE );
3259 } else {
3260 if (VG_(clo_track_fds))
3261 ML_(record_fd_open_nameless) (tid, RES);
3264 else
3266 /* 2.6.24 and later kernels: timerfd_create system call. */
3267 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3268 VG_(close)(RES);
3269 SET_STATUS_Failure( VKI_EMFILE );
3270 } else {
3271 if (VG_(clo_track_fds))
3272 ML_(record_fd_open_nameless) (tid, RES);
3277 PRE(sys_timerfd_gettime)
3279 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3280 PRE_REG_READ2(long, "timerfd_gettime",
3281 int, ufd,
3282 struct vki_itimerspec*, otmr);
3283 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3284 SET_STATUS_Failure(VKI_EBADF);
3285 else
3286 PRE_MEM_WRITE("timerfd_gettime(result)",
3287 ARG2, sizeof(struct vki_itimerspec));
3289 POST(sys_timerfd_gettime)
3291 if (RES == 0)
3292 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3295 PRE(sys_timerfd_gettime64)
3297 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3298 PRE_REG_READ2(long, "timerfd_gettime64",
3299 int, ufd,
3300 struct vki_itimerspec64*, otmr);
3301 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3302 SET_STATUS_Failure(VKI_EBADF);
3303 else
3304 PRE_MEM_WRITE("timerfd_gettime64(result)",
3305 ARG2, sizeof(struct vki_itimerspec64));
3307 POST(sys_timerfd_gettime64)
3309 if (RES == 0)
3310 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3313 PRE(sys_timerfd_settime)
3315 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3316 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3317 PRE_REG_READ4(long, "timerfd_settime",
3318 int, ufd,
3319 int, flags,
3320 const struct vki_itimerspec*, utmr,
3321 struct vki_itimerspec*, otmr);
3322 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3323 SET_STATUS_Failure(VKI_EBADF);
3324 else
3326 PRE_MEM_READ("timerfd_settime(result)",
3327 ARG3, sizeof(struct vki_itimerspec));
3328 if (ARG4)
3330 PRE_MEM_WRITE("timerfd_settime(result)",
3331 ARG4, sizeof(struct vki_itimerspec));
3335 POST(sys_timerfd_settime)
3337 if (RES == 0 && ARG4 != 0)
3338 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3341 PRE(sys_timerfd_settime64)
3343 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3344 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3345 PRE_REG_READ4(long, "timerfd_settime64",
3346 int, ufd,
3347 int, flags,
3348 const struct vki_itimerspec64*, utmr,
3349 struct vki_itimerspec64*, otmr);
3350 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3351 SET_STATUS_Failure(VKI_EBADF);
3352 else
3354 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3355 if (ARG4)
3357 PRE_MEM_WRITE("timerfd_settime64(result)",
3358 ARG4, sizeof(struct vki_itimerspec64));
3362 POST(sys_timerfd_settime64)
3364 if (RES == 0 && ARG4 != 0)
3365 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3368 /* ---------------------------------------------------------------------
3369 capabilities wrappers
3370 ------------------------------------------------------------------ */
3372 PRE(sys_capget)
3374 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3375 PRE_REG_READ2(long, "capget",
3376 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3377 PRE_MEM_READ( "capget(header)", ARG1,
3378 sizeof(struct __vki_user_cap_header_struct) );
3379 if (ARG2 != (Addr)NULL)
3380 PRE_MEM_WRITE( "capget(data)", ARG2,
3381 sizeof(struct __vki_user_cap_data_struct) );
3383 POST(sys_capget)
3385 if (ARG2 != (Addr)NULL)
3386 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3389 PRE(sys_capset)
3391 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3392 PRE_REG_READ2(long, "capset",
3393 vki_cap_user_header_t, header,
3394 const vki_cap_user_data_t, data);
3395 PRE_MEM_READ( "capset(header)",
3396 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3397 PRE_MEM_READ( "capset(data)",
3398 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3401 /* ---------------------------------------------------------------------
3402 16-bit uid/gid/groups wrappers
3403 ------------------------------------------------------------------ */
3405 PRE(sys_getuid16)
3407 PRINT("sys_getuid16 ( )");
3408 PRE_REG_READ0(long, "getuid16");
3411 PRE(sys_setuid16)
3413 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3414 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3417 PRE(sys_getgid16)
3419 PRINT("sys_getgid16 ( )");
3420 PRE_REG_READ0(long, "getgid16");
3423 PRE(sys_setgid16)
3425 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3426 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3429 PRE(sys_geteuid16)
3431 PRINT("sys_geteuid16 ( )");
3432 PRE_REG_READ0(long, "geteuid16");
3435 PRE(sys_getegid16)
3437 PRINT("sys_getegid16 ( )");
3438 PRE_REG_READ0(long, "getegid16");
3441 PRE(sys_setreuid16)
3443 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3444 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3447 PRE(sys_setregid16)
3449 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3450 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3453 PRE(sys_getgroups16)
3455 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3456 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3457 if (ARG1 > 0)
3458 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3460 POST(sys_getgroups16)
3462 vg_assert(SUCCESS);
3463 if (ARG1 > 0 && RES > 0)
3464 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3467 PRE(sys_setgroups16)
3469 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3470 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3471 if (ARG1 > 0)
3472 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3475 /* ---------------------------------------------------------------------
3476 *chown16 wrappers
3477 ------------------------------------------------------------------ */
3479 PRE(sys_chown16)
3481 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3482 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3483 PRE_REG_READ3(long, "chown16",
3484 const char *, path,
3485 vki_old_uid_t, owner, vki_old_gid_t, group);
3486 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3489 PRE(sys_fchown16)
3491 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3492 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3493 PRE_REG_READ3(long, "fchown16",
3494 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3497 /* ---------------------------------------------------------------------
3498 *xattr wrappers
3499 ------------------------------------------------------------------ */
3501 PRE(sys_setxattr)
3503 *flags |= SfMayBlock;
3504 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3505 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3506 ARG4, SARG5);
3507 PRE_REG_READ5(long, "setxattr",
3508 char *, path, char *, name,
3509 void *, value, vki_size_t, size, int, flags);
3510 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3511 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3512 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3515 PRE(sys_lsetxattr)
3517 *flags |= SfMayBlock;
3518 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3519 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3520 ARG1, ARG2, ARG3, ARG4, SARG5);
3521 PRE_REG_READ5(long, "lsetxattr",
3522 char *, path, char *, name,
3523 void *, value, vki_size_t, size, int, flags);
3524 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3525 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3526 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3529 PRE(sys_fsetxattr)
3531 *flags |= SfMayBlock;
3532 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3533 FMT_REGWORD "u, %ld )",
3534 SARG1, ARG2, ARG3, ARG4, SARG5);
3535 PRE_REG_READ5(long, "fsetxattr",
3536 int, fd, char *, name, void *, value,
3537 vki_size_t, size, int, flags);
3538 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3539 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3542 PRE(sys_getxattr)
3544 *flags |= SfMayBlock;
3545 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3546 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3547 PRE_REG_READ4(ssize_t, "getxattr",
3548 char *, path, char *, name, void *, value, vki_size_t, size);
3549 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3550 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3551 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3553 POST(sys_getxattr)
3555 vg_assert(SUCCESS);
3556 if (RES > 0 && ARG3 != (Addr)NULL) {
3557 POST_MEM_WRITE( ARG3, RES );
3561 PRE(sys_lgetxattr)
3563 *flags |= SfMayBlock;
3564 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3565 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3566 PRE_REG_READ4(ssize_t, "lgetxattr",
3567 char *, path, char *, name, void *, value, vki_size_t, size);
3568 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3569 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3570 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3572 POST(sys_lgetxattr)
3574 vg_assert(SUCCESS);
3575 if (RES > 0 && ARG3 != (Addr)NULL) {
3576 POST_MEM_WRITE( ARG3, RES );
3580 PRE(sys_fgetxattr)
3582 *flags |= SfMayBlock;
3583 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3584 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3585 PRE_REG_READ4(ssize_t, "fgetxattr",
3586 int, fd, char *, name, void *, value, vki_size_t, size);
3587 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3588 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3590 POST(sys_fgetxattr)
3592 if (RES > 0 && ARG3 != (Addr)NULL)
3593 POST_MEM_WRITE( ARG3, RES );
3596 PRE(sys_listxattr)
3598 *flags |= SfMayBlock;
3599 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3600 ARG1, ARG2, (ULong)ARG3);
3601 PRE_REG_READ3(ssize_t, "listxattr",
3602 char *, path, char *, list, vki_size_t, size);
3603 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3604 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3606 POST(sys_listxattr)
3608 if (RES > 0 && ARG2 != (Addr)NULL)
3609 POST_MEM_WRITE( ARG2, RES );
3612 PRE(sys_llistxattr)
3614 *flags |= SfMayBlock;
3615 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3616 ARG1, ARG2, (ULong)ARG3);
3617 PRE_REG_READ3(ssize_t, "llistxattr",
3618 char *, path, char *, list, vki_size_t, size);
3619 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3620 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3622 POST(sys_llistxattr)
3624 if (RES > 0 && ARG2 != (Addr)NULL)
3625 POST_MEM_WRITE( ARG2, RES );
3628 PRE(sys_flistxattr)
3630 *flags |= SfMayBlock;
3631 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3632 SARG1, ARG2, ARG3);
3633 PRE_REG_READ3(ssize_t, "flistxattr",
3634 int, fd, char *, list, vki_size_t, size);
3635 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3637 POST(sys_flistxattr)
3639 if (RES > 0 && ARG2 != (Addr)NULL)
3640 POST_MEM_WRITE( ARG2, RES );
3643 PRE(sys_removexattr)
3645 *flags |= SfMayBlock;
3646 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3647 ARG1, ARG2);
3648 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3649 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3650 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3653 PRE(sys_lremovexattr)
3655 *flags |= SfMayBlock;
3656 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3657 ARG1, ARG2);
3658 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3659 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3660 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3663 PRE(sys_fremovexattr)
3665 *flags |= SfMayBlock;
3666 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3667 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3668 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3671 /* ---------------------------------------------------------------------
3672 sched_* wrappers
3673 ------------------------------------------------------------------ */
3675 PRE(sys_sched_setparam)
3677 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3678 PRE_REG_READ2(long, "sched_setparam",
3679 vki_pid_t, pid, struct sched_param *, p);
3680 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3682 POST(sys_sched_setparam)
3684 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3687 PRE(sys_sched_getparam)
3689 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3690 PRE_REG_READ2(long, "sched_getparam",
3691 vki_pid_t, pid, struct sched_param *, p);
3692 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3694 POST(sys_sched_getparam)
3696 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3699 PRE(sys_sched_setattr)
3701 struct vki_sched_attr *attr;
3702 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3703 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3704 PRE_REG_READ3(long, "sched_setattr",
3705 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3706 /* We need to be able to read at least the size field. */
3707 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3708 attr = (struct vki_sched_attr *)(Addr)ARG2;
3709 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3710 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3713 PRE(sys_sched_getattr)
3715 struct vki_sched_attr *attr;
3716 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3717 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3718 PRE_REG_READ4(long, "sched_getattr",
3719 vki_pid_t, pid, struct sched_attr *, p,
3720 unsigned int, size, unsigned int, flags);
3721 /* We need to be able to read at least the size field. */
3722 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3723 /* And the kernel needs to be able to write to the whole struct size. */
3724 attr = (struct vki_sched_attr *)(Addr)ARG2;
3725 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3726 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3728 POST(sys_sched_getattr)
3730 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3731 POST_MEM_WRITE( (Addr)attr, attr->size );
3734 PRE(sys_sched_getscheduler)
3736 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3737 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3740 PRE(sys_sched_setscheduler)
3742 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3743 SARG1, SARG2, ARG3);
3744 PRE_REG_READ3(long, "sched_setscheduler",
3745 vki_pid_t, pid, int, policy, struct sched_param *, p);
3746 if (ARG3 != 0)
3747 PRE_MEM_READ( "sched_setscheduler(p)",
3748 ARG3, sizeof(struct vki_sched_param));
3751 PRE(sys_sched_yield)
3753 *flags |= SfMayBlock;
3754 PRINT("sched_yield()");
3755 PRE_REG_READ0(long, "sys_sched_yield");
3758 PRE(sys_sched_get_priority_max)
3760 PRINT("sched_get_priority_max ( %ld )", SARG1);
3761 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3764 PRE(sys_sched_get_priority_min)
3766 PRINT("sched_get_priority_min ( %ld )", SARG1);
3767 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3770 PRE(sys_sched_rr_get_interval)
3772 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3773 PRE_REG_READ2(int, "sched_rr_get_interval",
3774 vki_pid_t, pid,
3775 struct vki_timespec *, tp);
3776 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3777 ARG2, sizeof(struct vki_timespec));
3780 POST(sys_sched_rr_get_interval)
3782 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3785 PRE(sys_sched_rr_get_interval_time64)
3787 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3788 SARG1, ARG2);
3789 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3790 vki_pid_t, pid,
3791 struct vki_timespec *, tp);
3792 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3793 ARG2, sizeof(struct vki_timespec64));
3796 POST(sys_sched_rr_get_interval_time64)
3798 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3801 PRE(sys_sched_setaffinity)
3803 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3804 SARG1, ARG2, ARG3);
3805 PRE_REG_READ3(long, "sched_setaffinity",
3806 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3807 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3810 PRE(sys_sched_getaffinity)
3812 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3813 SARG1, ARG2, ARG3);
3814 PRE_REG_READ3(long, "sched_getaffinity",
3815 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3816 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3818 POST(sys_sched_getaffinity)
3820 POST_MEM_WRITE(ARG3, ARG2);
3823 PRE(sys_unshare)
3825 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3826 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3829 PRE(sys_setns)
3831 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3832 PRE_REG_READ2(int, "setns",
3833 int, fd,
3834 int, nstype);
3835 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3836 SET_STATUS_Failure( VKI_EBADF );
3840 /* ---------------------------------------------------------------------
3841 miscellaneous wrappers
3842 ------------------------------------------------------------------ */
3844 PRE(sys_munlockall)
3846 *flags |= SfMayBlock;
3847 PRINT("sys_munlockall ( )");
3848 PRE_REG_READ0(long, "munlockall");
3851 // This has different signatures for different platforms.
3853 // x86: int sys_pipe(unsigned long __user *fildes);
3854 // AMD64: long sys_pipe(int *fildes);
3855 // ppc32: int sys_pipe(int __user *fildes);
3856 // ppc64: int sys_pipe(int __user *fildes);
3858 // The type of the argument is most important, and it is an array of 32 bit
3859 // values in all cases. (The return type differs across platforms, but it
3860 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3861 // was caused by using an array of 'unsigned long's, which didn't work on
3862 // AMD64.
3863 PRE(sys_pipe)
3865 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3866 PRE_REG_READ1(int, "pipe", int *, filedes);
3867 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3869 POST(sys_pipe)
3871 Int *p = (Int *)(Addr)ARG1;
3872 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3873 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3874 VG_(close)(p[0]);
3875 VG_(close)(p[1]);
3876 SET_STATUS_Failure( VKI_EMFILE );
3877 } else {
3878 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3879 if (VG_(clo_track_fds)) {
3880 ML_(record_fd_open_nameless)(tid, p[0]);
3881 ML_(record_fd_open_nameless)(tid, p[1]);
3886 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3887 there's a second arg containing flags to be applied to the new file
3888 descriptors. It hardly seems worth the effort to factor out the
3889 duplicated code, hence: */
3890 PRE(sys_pipe2)
3892 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3893 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3894 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3896 POST(sys_pipe2)
3898 Int *p = (Int *)(Addr)ARG1;
3899 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3900 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3901 VG_(close)(p[0]);
3902 VG_(close)(p[1]);
3903 SET_STATUS_Failure( VKI_EMFILE );
3904 } else {
3905 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3906 if (VG_(clo_track_fds)) {
3907 ML_(record_fd_open_nameless)(tid, p[0]);
3908 ML_(record_fd_open_nameless)(tid, p[1]);
3913 PRE(sys_dup3)
3915 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3916 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3917 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3918 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3919 SET_STATUS_Failure( VKI_EBADF );
3922 POST(sys_dup3)
3924 vg_assert(SUCCESS);
3925 if (VG_(clo_track_fds))
3926 ML_(record_fd_open_named)(tid, RES);
3929 PRE(sys_quotactl)
3931 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3932 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3933 PRE_REG_READ4(long, "quotactl",
3934 unsigned int, cmd, const char *, special, vki_qid_t, id,
3935 void *, addr);
3936 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3939 PRE(sys_waitid)
3941 *flags |= SfMayBlock;
3942 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3943 SARG1, SARG2, ARG3, SARG4, ARG5);
3944 PRE_REG_READ5(int32_t, "sys_waitid",
3945 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3946 int, options, struct vki_rusage *, ru);
3947 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3948 if (ARG5 != 0)
3949 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3951 POST(sys_waitid)
3953 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3954 if (ARG5 != 0)
3955 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3958 PRE(sys_sync_file_range)
3960 *flags |= SfMayBlock;
3961 #if VG_WORDSIZE == 4
3962 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3963 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3964 PRE_REG_READ6(long, "sync_file_range",
3965 int, fd,
3966 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3967 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3968 unsigned int, flags);
3969 #elif VG_WORDSIZE == 8
3970 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3971 SARG1, SARG2, SARG3, ARG4);
3972 PRE_REG_READ4(long, "sync_file_range",
3973 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3974 unsigned int, flags);
3975 #else
3976 # error Unexpected word size
3977 #endif
3978 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3979 SET_STATUS_Failure( VKI_EBADF );
3982 PRE(sys_sync_file_range2)
3984 *flags |= SfMayBlock;
3985 #if VG_WORDSIZE == 4
3986 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3987 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3988 PRE_REG_READ6(long, "sync_file_range2",
3989 int, fd, unsigned int, flags,
3990 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3991 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3992 #elif VG_WORDSIZE == 8
3993 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3994 SARG1, ARG2, SARG3, SARG4);
3995 PRE_REG_READ4(long, "sync_file_range2",
3996 int, fd, unsigned int, flags,
3997 vki_loff_t, offset, vki_loff_t, nbytes);
3998 #else
3999 # error Unexpected word size
4000 #endif
4001 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4002 SET_STATUS_Failure( VKI_EBADF );
4005 PRE(sys_stime)
4007 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4008 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4009 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4012 PRE(sys_perf_event_open)
4014 struct vki_perf_event_attr *attr;
4015 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4016 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4017 PRE_REG_READ5(long, "perf_event_open",
4018 struct vki_perf_event_attr *, attr,
4019 vki_pid_t, pid, int, cpu, int, group_fd,
4020 unsigned long, flags);
4021 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4022 PRE_MEM_READ( "perf_event_open(attr->size)",
4023 (Addr)&attr->size, sizeof(attr->size) );
4024 PRE_MEM_READ( "perf_event_open(attr)",
4025 (Addr)attr, attr->size );
4028 POST(sys_perf_event_open)
4030 vg_assert(SUCCESS);
4031 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4032 VG_(close)(RES);
4033 SET_STATUS_Failure( VKI_EMFILE );
4034 } else {
4035 if (VG_(clo_track_fds))
4036 ML_(record_fd_open_nameless)(tid, RES);
4040 PRE(sys_getcpu)
4042 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4043 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4044 PRE_REG_READ3(int, "getcpu",
4045 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4046 if (ARG1 != 0)
4047 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4048 if (ARG2 != 0)
4049 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4050 if (ARG3 != 0)
4051 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4054 POST(sys_getcpu)
4056 if (ARG1 != 0)
4057 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4058 if (ARG2 != 0)
4059 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4060 if (ARG3 != 0)
4061 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4064 PRE(sys_move_pages)
4066 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4067 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4068 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4069 PRE_REG_READ6(int, "move_pages",
4070 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4071 const int *, nodes, int *, status, int, flags);
4072 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4073 if (ARG4)
4074 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4075 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4078 POST(sys_move_pages)
4080 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4083 PRE(sys_getrandom)
4085 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4086 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4087 PRE_REG_READ3(int, "getrandom",
4088 char *, buf, vki_size_t, count, unsigned int, flags);
4089 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4092 POST(sys_getrandom)
4094 POST_MEM_WRITE( ARG1, ARG2 );
4097 PRE(sys_memfd_create)
4099 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4100 ARG1, ARG2);
4101 PRE_REG_READ2(int, "memfd_create",
4102 char *, uname, unsigned int, flags);
4103 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4106 POST(sys_memfd_create)
4108 vg_assert(SUCCESS);
4109 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4110 VG_(close)(RES);
4111 SET_STATUS_Failure( VKI_EMFILE );
4112 } else {
4113 if (VG_(clo_track_fds))
4114 ML_(record_fd_open_nameless)(tid, RES);
4118 PRE(sys_membarrier)
4120 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4121 PRE_REG_READ1(int, "membarrier", int, flags);
4124 PRE(sys_syncfs)
4126 *flags |= SfMayBlock;
4127 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4128 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4131 PRE(sys_statx)
4133 FUSE_COMPATIBLE_MAY_BLOCK();
4134 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4135 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4136 PRE_REG_READ5(long, "statx",
4137 int, dirfd, char *, filename, int, flags,
4138 unsigned int, mask, struct statx *, buf);
4139 // Work around Rust's dubious use of statx, as described here:
4140 // https://github.com/rust-lang/rust/blob/
4141 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4142 // src/libstd/sys/unix/fs.rs#L128-L142
4143 // in which it passes NULL for both filename and buf, and then looks at the
4144 // return value, so as to determine whether or not this syscall is supported.
4145 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4146 if (!both_filename_and_buf_are_null) {
4147 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4148 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4151 POST(sys_statx)
4153 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4156 /* ---------------------------------------------------------------------
4157 utime wrapper
4158 ------------------------------------------------------------------ */
4160 PRE(sys_utime)
4162 *flags |= SfMayBlock;
4163 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4164 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4165 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4166 if (ARG2 != 0)
4167 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4170 /* ---------------------------------------------------------------------
4171 lseek wrapper
4172 ------------------------------------------------------------------ */
4174 PRE(sys_lseek)
4176 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4177 ARG1, SARG2, ARG3);
4178 PRE_REG_READ3(vki_off_t, "lseek",
4179 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4182 /* ---------------------------------------------------------------------
4183 readahead wrapper
4184 ------------------------------------------------------------------ */
4186 PRE(sys_readahead)
4188 *flags |= SfMayBlock;
4189 #if VG_WORDSIZE == 4
4190 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4191 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4192 PRE_REG_READ4(vki_off_t, "readahead",
4193 int, fd, unsigned, MERGE64_FIRST(offset),
4194 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4195 #elif VG_WORDSIZE == 8
4196 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4197 PRE_REG_READ3(vki_off_t, "readahead",
4198 int, fd, vki_loff_t, offset, vki_size_t, count);
4199 #else
4200 # error Unexpected word size
4201 #endif
4202 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4203 SET_STATUS_Failure( VKI_EBADF );
4206 /* ---------------------------------------------------------------------
4207 sig* wrappers
4208 ------------------------------------------------------------------ */
4210 PRE(sys_sigpending)
4212 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4213 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4214 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4216 POST(sys_sigpending)
4218 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4221 // This syscall is not used on amd64/Linux -- it only provides
4222 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4223 // This wrapper is only suitable for 32-bit architectures.
4224 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4225 // conditional compilation like this?)
4226 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4227 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4228 || defined(VGP_nanomips_linux)
4229 PRE(sys_sigprocmask)
4231 vki_old_sigset_t* set;
4232 vki_old_sigset_t* oldset;
4233 vki_sigset_t bigger_set;
4234 vki_sigset_t bigger_oldset;
4236 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4237 PRE_REG_READ3(long, "sigprocmask",
4238 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4239 if (ARG2 != 0)
4240 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4241 if (ARG3 != 0)
4242 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4244 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4245 // vki_sigset_t params.
4246 set = (vki_old_sigset_t*)(Addr)ARG2;
4247 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4249 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4250 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4251 if (set)
4252 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4254 SET_STATUS_from_SysRes(
4255 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4256 set ? &bigger_set : NULL,
4257 oldset ? &bigger_oldset : NULL)
4260 if (oldset)
4261 *oldset = bigger_oldset.sig[0];
4263 if (SUCCESS)
4264 *flags |= SfPollAfter;
4266 POST(sys_sigprocmask)
4268 vg_assert(SUCCESS);
4269 if (RES == 0 && ARG3 != 0)
4270 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4273 /* Convert from non-RT to RT sigset_t's */
4274 static
4275 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4277 VG_(sigemptyset)(set);
4278 set->sig[0] = *oldset;
4280 PRE(sys_sigaction)
4282 vki_sigaction_toK_t new, *newp;
4283 vki_sigaction_fromK_t old, *oldp;
4285 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4286 PRE_REG_READ3(int, "sigaction",
4287 int, signum, const struct old_sigaction *, act,
4288 struct old_sigaction *, oldact);
4290 newp = oldp = NULL;
4292 if (ARG2 != 0) {
4293 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4294 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4295 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4296 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4297 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4298 && (sa->sa_flags & VKI_SA_RESTORER))
4299 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4302 if (ARG3 != 0) {
4303 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4304 oldp = &old;
4307 /* If the new or old sigaction is not NULL, but the structs
4308 aren't accessible then sigaction returns EFAULT and we cannot
4309 use either struct for our own bookkeeping. Just fail early. */
4310 if (ARG2 != 0
4311 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4312 sizeof(struct vki_old_sigaction))) {
4313 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4314 (void *)(Addr)ARG2);
4315 SET_STATUS_Failure ( VKI_EFAULT );
4316 } else if ((ARG3 != 0
4317 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4318 sizeof(struct vki_old_sigaction)))) {
4319 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4320 (void *)(Addr)ARG3);
4321 SET_STATUS_Failure ( VKI_EFAULT );
4322 } else {
4323 if (ARG2 != 0) {
4324 struct vki_old_sigaction *oldnew =
4325 (struct vki_old_sigaction *)(Addr)ARG2;
4327 new.ksa_handler = oldnew->ksa_handler;
4328 new.sa_flags = oldnew->sa_flags;
4329 new.sa_restorer = oldnew->sa_restorer;
4330 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4331 newp = &new;
4334 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4336 if (ARG3 != 0 && SUCCESS && RES == 0) {
4337 struct vki_old_sigaction *oldold =
4338 (struct vki_old_sigaction *)(Addr)ARG3;
4340 oldold->ksa_handler = oldp->ksa_handler;
4341 oldold->sa_flags = oldp->sa_flags;
4342 oldold->sa_restorer = oldp->sa_restorer;
4343 oldold->sa_mask = oldp->sa_mask.sig[0];
4347 POST(sys_sigaction)
4349 vg_assert(SUCCESS);
4350 if (RES == 0 && ARG3 != 0)
4351 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4353 #endif
4355 PRE(sys_signalfd)
4357 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4358 (ULong)ARG3);
4359 PRE_REG_READ3(long, "sys_signalfd",
4360 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4361 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4362 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4363 SET_STATUS_Failure( VKI_EBADF );
4365 POST(sys_signalfd)
4367 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4368 VG_(close)(RES);
4369 SET_STATUS_Failure( VKI_EMFILE );
4370 } else {
4371 if (VG_(clo_track_fds))
4372 ML_(record_fd_open_nameless) (tid, RES);
4376 PRE(sys_signalfd4)
4378 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4379 SARG1, ARG2, ARG3, SARG4);
4380 PRE_REG_READ4(long, "sys_signalfd4",
4381 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4382 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4383 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4384 SET_STATUS_Failure( VKI_EBADF );
4386 POST(sys_signalfd4)
4388 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4389 VG_(close)(RES);
4390 SET_STATUS_Failure( VKI_EMFILE );
4391 } else {
4392 if (VG_(clo_track_fds))
4393 ML_(record_fd_open_nameless) (tid, RES);
4398 /* ---------------------------------------------------------------------
4399 rt_sig* wrappers
4400 ------------------------------------------------------------------ */
4402 PRE(sys_rt_sigaction)
4404 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4405 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4406 PRE_REG_READ4(long, "rt_sigaction",
4407 int, signum, const struct sigaction *, act,
4408 struct sigaction *, oldact, vki_size_t, sigsetsize);
4410 if (ARG2 != 0) {
4411 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4412 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4413 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4414 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4415 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4416 && (sa->sa_flags & VKI_SA_RESTORER))
4417 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4419 if (ARG3 != 0)
4420 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4422 /* If the new or old sigaction is not NULL, but the structs
4423 aren't accessible then sigaction returns EFAULT and we cannot
4424 use either struct for our own bookkeeping. Just fail early. */
4425 if (ARG2 != 0
4426 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4427 sizeof(vki_sigaction_toK_t))) {
4428 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4429 (void *)(Addr)ARG2);
4430 SET_STATUS_Failure ( VKI_EFAULT );
4431 } else if ((ARG3 != 0
4432 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4433 sizeof(vki_sigaction_fromK_t)))) {
4434 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4435 (void *)(Addr)ARG3);
4436 SET_STATUS_Failure ( VKI_EFAULT );
4437 } else {
4439 // XXX: doesn't seem right to be calling do_sys_sigaction for
4440 // sys_rt_sigaction... perhaps this function should be renamed
4441 // VG_(do_sys_rt_sigaction)() --njn
4443 SET_STATUS_from_SysRes(
4444 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4445 (vki_sigaction_fromK_t *)(Addr)ARG3)
4449 POST(sys_rt_sigaction)
4451 vg_assert(SUCCESS);
4452 if (RES == 0 && ARG3 != 0)
4453 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4456 PRE(sys_rt_sigprocmask)
4458 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4459 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4460 PRE_REG_READ4(long, "rt_sigprocmask",
4461 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4462 vki_size_t, sigsetsize);
4463 if (ARG2 != 0)
4464 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4465 if (ARG3 != 0)
4466 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4468 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4469 // Since we want to use the set and oldset for bookkeeping we also want
4470 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4471 if (sizeof(vki_sigset_t) != ARG4)
4472 SET_STATUS_Failure( VKI_EINVAL );
4473 else if (ARG2 != 0
4474 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4475 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4476 (void *)(Addr)ARG2);
4477 SET_STATUS_Failure ( VKI_EFAULT );
4479 else if (ARG3 != 0
4480 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4481 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4482 (void *)(Addr)ARG3);
4483 SET_STATUS_Failure ( VKI_EFAULT );
4486 else {
4487 SET_STATUS_from_SysRes(
4488 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4489 (vki_sigset_t*) (Addr)ARG2,
4490 (vki_sigset_t*) (Addr)ARG3 )
4494 if (SUCCESS)
4495 *flags |= SfPollAfter;
4497 POST(sys_rt_sigprocmask)
4499 vg_assert(SUCCESS);
4500 if (RES == 0 && ARG3 != 0)
4501 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4504 PRE(sys_rt_sigpending)
4506 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4507 PRE_REG_READ2(long, "rt_sigpending",
4508 vki_sigset_t *, set, vki_size_t, sigsetsize);
4509 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4511 POST(sys_rt_sigpending)
4513 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4516 PRE(sys_rt_sigtimedwait)
4518 *flags |= SfMayBlock;
4519 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4520 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4521 ARG1, ARG2, ARG3, ARG4);
4522 PRE_REG_READ4(long, "rt_sigtimedwait",
4523 const vki_sigset_t *, set, vki_siginfo_t *, info,
4524 const struct timespec *, timeout, vki_size_t, sigsetsize);
4525 if (ARG1 != 0)
4526 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4527 if (ARG2 != 0)
4528 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4529 if (ARG3 != 0)
4530 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4531 ARG3, sizeof(struct vki_timespec) );
4533 POST(sys_rt_sigtimedwait)
4535 if (ARG2 != 0)
4536 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4539 PRE(sys_rt_sigtimedwait_time64)
4541 *flags |= SfMayBlock;
4542 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4543 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4544 ARG1, ARG2, ARG3, ARG4);
4545 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4546 const vki_sigset_t *, set, vki_siginfo_t *, info,
4547 const struct vki_timespec64 *, timeout,
4548 vki_size_t, sigsetsize);
4549 if (ARG1 != 0)
4550 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4551 if (ARG2 != 0)
4552 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4553 sizeof(vki_siginfo_t) );
4554 if (ARG3 != 0)
4555 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4557 POST(sys_rt_sigtimedwait_time64)
4559 if (ARG2 != 0)
4560 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4563 PRE(sys_rt_sigqueueinfo)
4565 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4566 SARG1, SARG2, ARG3);
4567 PRE_REG_READ3(long, "rt_sigqueueinfo",
4568 int, pid, int, sig, vki_siginfo_t *, uinfo);
4569 if (ARG2 != 0)
4570 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4572 POST(sys_rt_sigqueueinfo)
4574 if (!ML_(client_signal_OK)(ARG2))
4575 SET_STATUS_Failure( VKI_EINVAL );
4578 PRE(sys_rt_tgsigqueueinfo)
4580 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4581 SARG1, SARG2, SARG3, ARG4);
4582 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4583 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4584 if (ARG3 != 0)
4585 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4588 POST(sys_rt_tgsigqueueinfo)
4590 if (!ML_(client_signal_OK)(ARG3))
4591 SET_STATUS_Failure( VKI_EINVAL );
4594 // XXX: x86-specific? The kernel prototypes for the different archs are
4595 // hard to decipher.
4596 PRE(sys_rt_sigsuspend)
4598 /* The C library interface to sigsuspend just takes a pointer to
4599 a signal mask but this system call has two arguments - a pointer
4600 to the mask and the number of bytes used by it. The kernel insists
4601 on the size being equal to sizeof(sigset_t) however and will just
4602 return EINVAL if it isn't.
4604 *flags |= SfMayBlock;
4605 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4606 ARG1, ARG2 );
4607 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4608 if (ARG1 != (Addr)NULL) {
4609 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4610 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4611 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4612 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4613 be killable by VG_(nuke_all_threads_except).
4614 We thus silently ignore the user request to mask this signal.
4615 Note that this is similar to what is done for e.g.
4616 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4617 } else {
4618 SET_STATUS_Failure(VKI_EFAULT);
4623 /* ---------------------------------------------------------------------
4624 linux msg* wrapper helpers
4625 ------------------------------------------------------------------ */
4627 void
4628 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4629 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4631 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4632 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4633 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4634 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4637 void
4638 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4639 UWord arg0, UWord arg1, UWord arg2,
4640 UWord arg3, UWord arg4 )
4642 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4643 long msgtyp, int msgflg); */
4644 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4645 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4646 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4648 void
4649 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4650 UWord res,
4651 UWord arg0, UWord arg1, UWord arg2,
4652 UWord arg3, UWord arg4 )
4654 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4655 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4656 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4659 void
4660 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4661 UWord arg0, UWord arg1, UWord arg2 )
4663 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4664 switch (arg1 /* cmd */) {
4665 case VKI_IPC_INFO:
4666 case VKI_MSG_INFO:
4667 case VKI_IPC_INFO|VKI_IPC_64:
4668 case VKI_MSG_INFO|VKI_IPC_64:
4669 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4670 arg2, sizeof(struct vki_msginfo) );
4671 break;
4672 case VKI_IPC_STAT:
4673 case VKI_MSG_STAT:
4674 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4675 arg2, sizeof(struct vki_msqid_ds) );
4676 break;
4677 case VKI_IPC_STAT|VKI_IPC_64:
4678 case VKI_MSG_STAT|VKI_IPC_64:
4679 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4680 arg2, sizeof(struct vki_msqid64_ds) );
4681 break;
4682 case VKI_IPC_SET:
4683 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4684 arg2, sizeof(struct vki_msqid_ds) );
4685 break;
4686 case VKI_IPC_SET|VKI_IPC_64:
4687 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4688 arg2, sizeof(struct vki_msqid64_ds) );
4689 break;
4692 void
4693 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4694 UWord res,
4695 UWord arg0, UWord arg1, UWord arg2 )
4697 switch (arg1 /* cmd */) {
4698 case VKI_IPC_INFO:
4699 case VKI_MSG_INFO:
4700 case VKI_IPC_INFO|VKI_IPC_64:
4701 case VKI_MSG_INFO|VKI_IPC_64:
4702 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4703 break;
4704 case VKI_IPC_STAT:
4705 case VKI_MSG_STAT:
4706 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4707 break;
4708 case VKI_IPC_STAT|VKI_IPC_64:
4709 case VKI_MSG_STAT|VKI_IPC_64:
4710 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4711 break;
4715 /* ---------------------------------------------------------------------
4716 Generic handler for sys_ipc
4717 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4718 are either direct system calls, or are all implemented via sys_ipc.
4719 ------------------------------------------------------------------ */
4720 #ifdef __NR_ipc
4721 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4723 Addr* a_p = (Addr*)a;
4724 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4725 return *a_p;
4728 static Bool semctl_cmd_has_4args (UWord cmd)
4730 switch (cmd & ~VKI_IPC_64)
4732 case VKI_IPC_INFO:
4733 case VKI_SEM_INFO:
4734 case VKI_IPC_STAT:
4735 case VKI_SEM_STAT:
4736 case VKI_IPC_SET:
4737 case VKI_GETALL:
4738 case VKI_SETALL:
4739 return True;
4740 default:
4741 return False;
4745 PRE(sys_ipc)
4747 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4748 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4750 switch (ARG1 /* call */) {
4751 case VKI_SEMOP:
4752 PRE_REG_READ5(int, "ipc",
4753 vki_uint, call, int, first, int, second, int, third,
4754 void *, ptr);
4755 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4756 *flags |= SfMayBlock;
4757 break;
4758 case VKI_SEMGET:
4759 PRE_REG_READ4(int, "ipc",
4760 vki_uint, call, int, first, int, second, int, third);
4761 break;
4762 case VKI_SEMCTL:
4764 PRE_REG_READ5(int, "ipc",
4765 vki_uint, call, int, first, int, second, int, third,
4766 void *, ptr);
4767 UWord arg;
4768 if (semctl_cmd_has_4args(ARG4))
4769 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4770 else
4771 arg = 0;
4772 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4773 break;
4775 case VKI_SEMTIMEDOP:
4776 PRE_REG_READ6(int, "ipc",
4777 vki_uint, call, int, first, int, second, int, third,
4778 void *, ptr, long, fifth);
4779 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4780 *flags |= SfMayBlock;
4781 break;
4782 case VKI_MSGSND:
4783 PRE_REG_READ5(int, "ipc",
4784 vki_uint, call, int, first, int, second, int, third,
4785 void *, ptr);
4786 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4787 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4788 *flags |= SfMayBlock;
4789 break;
4790 case VKI_MSGRCV:
4792 PRE_REG_READ5(int, "ipc",
4793 vki_uint, call, int, first, int, second, int, third,
4794 void *, ptr);
4795 Addr msgp;
4796 Word msgtyp;
4798 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4799 "msgrcv(msgp)" );
4800 msgtyp = deref_Addr( tid,
4801 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4802 "msgrcv(msgp)" );
4804 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4806 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4807 *flags |= SfMayBlock;
4808 break;
4810 case VKI_MSGGET:
4811 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4812 break;
4813 case VKI_MSGCTL:
4814 PRE_REG_READ5(int, "ipc",
4815 vki_uint, call, int, first, int, second, int, third,
4816 void *, ptr);
4817 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4818 break;
4819 case VKI_SHMAT:
4821 PRE_REG_READ5(int, "ipc",
4822 vki_uint, call, int, first, int, second, int, third,
4823 void *, ptr);
4824 UWord w;
4825 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4826 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4827 if (w == 0)
4828 SET_STATUS_Failure( VKI_EINVAL );
4829 else
4830 ARG5 = w;
4831 break;
4833 case VKI_SHMDT:
4834 PRE_REG_READ5(int, "ipc",
4835 vki_uint, call, int, first, int, second, int, third,
4836 void *, ptr);
4837 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4838 SET_STATUS_Failure( VKI_EINVAL );
4839 break;
4840 case VKI_SHMGET:
4841 PRE_REG_READ4(int, "ipc",
4842 vki_uint, call, int, first, int, second, int, third);
4843 if (ARG4 & VKI_SHM_HUGETLB) {
4844 static Bool warning_given = False;
4845 ARG4 &= ~VKI_SHM_HUGETLB;
4846 if (!warning_given) {
4847 warning_given = True;
4848 VG_(umsg)(
4849 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4852 break;
4853 case VKI_SHMCTL: /* IPCOP_shmctl */
4854 PRE_REG_READ5(int, "ipc",
4855 vki_uint, call, int, first, int, second, int, third,
4856 void *, ptr);
4857 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4858 break;
4859 default:
4860 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4861 VG_(core_panic)("... bye!\n");
4862 break; /*NOTREACHED*/
4866 POST(sys_ipc)
4868 vg_assert(SUCCESS);
4869 switch (ARG1 /* call */) {
4870 case VKI_SEMOP:
4871 case VKI_SEMGET:
4872 break;
4873 case VKI_SEMCTL:
4875 UWord arg;
4876 if (semctl_cmd_has_4args(ARG4))
4877 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4878 else
4879 arg = 0;
4880 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4881 break;
4883 case VKI_SEMTIMEDOP:
4884 case VKI_MSGSND:
4885 break;
4886 case VKI_MSGRCV:
4888 Addr msgp;
4889 Word msgtyp;
4891 msgp = deref_Addr( tid,
4892 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4893 "msgrcv(msgp)" );
4894 msgtyp = deref_Addr( tid,
4895 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4896 "msgrcv(msgp)" );
4898 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4899 break;
4901 case VKI_MSGGET:
4902 break;
4903 case VKI_MSGCTL:
4904 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4905 break;
4906 case VKI_SHMAT:
4908 Addr addr;
4910 /* force readability. before the syscall it is
4911 * indeed uninitialized, as can be seen in
4912 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4913 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4915 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4916 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4917 break;
4919 case VKI_SHMDT:
4920 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4921 break;
4922 case VKI_SHMGET:
4923 break;
4924 case VKI_SHMCTL:
4925 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4926 break;
4927 default:
4928 VG_(message)(Vg_DebugMsg,
4929 "FATAL: unhandled syscall(ipc) %lu\n",
4930 ARG1 );
4931 VG_(core_panic)("... bye!\n");
4932 break; /*NOTREACHED*/
4935 #endif
4937 PRE(sys_semget)
4939 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4940 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4943 PRE(sys_semop)
4945 *flags |= SfMayBlock;
4946 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4947 SARG1, ARG2, ARG3);
4948 PRE_REG_READ3(long, "semop",
4949 int, semid, struct sembuf *, sops, unsigned, nsoops);
4950 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4953 PRE(sys_semctl)
4955 switch (ARG3 & ~VKI_IPC_64) {
4956 case VKI_IPC_INFO:
4957 case VKI_SEM_INFO:
4958 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4959 SARG3, ARG4);
4960 PRE_REG_READ4(long, "semctl",
4961 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4962 break;
4963 case VKI_IPC_STAT:
4964 case VKI_SEM_STAT:
4965 case VKI_IPC_SET:
4966 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4967 SARG3, ARG4);
4968 PRE_REG_READ4(long, "semctl",
4969 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4970 break;
4971 case VKI_GETALL:
4972 case VKI_SETALL:
4973 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4974 SARG3, ARG4);
4975 PRE_REG_READ4(long, "semctl",
4976 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4977 break;
4978 default:
4979 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4980 PRE_REG_READ3(long, "semctl",
4981 int, semid, int, semnum, int, cmd);
4982 break;
4984 #ifdef VGP_amd64_linux
4985 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4986 #else
4987 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4988 #endif
4991 POST(sys_semctl)
4993 #ifdef VGP_amd64_linux
4994 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4995 #else
4996 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4997 #endif
5000 PRE(sys_semtimedop)
5002 *flags |= SfMayBlock;
5003 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5004 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5005 PRE_REG_READ4(long, "semtimedop",
5006 int, semid, struct sembuf *, sops, unsigned, nsoops,
5007 struct timespec *, timeout);
5008 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5011 PRE(sys_semtimedop_time64)
5013 *flags |= SfMayBlock;
5014 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5015 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5016 PRE_REG_READ4(long, "semtimedop_time64",
5017 int, semid, struct sembuf *, sops, unsigned, nsoops,
5018 struct vki_timespec64 *, timeout);
5019 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5020 ARG2 * sizeof(struct vki_sembuf) );
5021 if (ARG3 != 0)
5022 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5025 PRE(sys_msgget)
5027 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5028 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5031 PRE(sys_msgsnd)
5033 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5034 SARG1, ARG2, ARG3, SARG4);
5035 PRE_REG_READ4(long, "msgsnd",
5036 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5037 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5038 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5039 *flags |= SfMayBlock;
5042 PRE(sys_msgrcv)
5044 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5045 SARG1, ARG2, ARG3, SARG4, SARG5);
5046 PRE_REG_READ5(long, "msgrcv",
5047 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5048 long, msgytp, int, msgflg);
5049 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5050 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5051 *flags |= SfMayBlock;
5053 POST(sys_msgrcv)
5055 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5058 PRE(sys_msgctl)
5060 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5061 PRE_REG_READ3(long, "msgctl",
5062 int, msqid, int, cmd, struct msqid_ds *, buf);
5063 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5066 POST(sys_msgctl)
5068 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5071 PRE(sys_shmget)
5073 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5074 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5075 if (ARG3 & VKI_SHM_HUGETLB) {
5076 static Bool warning_given = False;
5077 ARG3 &= ~VKI_SHM_HUGETLB;
5078 if (!warning_given) {
5079 warning_given = True;
5080 VG_(umsg)(
5081 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5086 PRE(sys_shmat)
5088 UWord arg2tmp;
5089 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5090 PRE_REG_READ3(long, "shmat",
5091 int, shmid, const void *, shmaddr, int, shmflg);
5092 #if defined(VGP_arm_linux)
5093 /* Round the attach address down to an VKI_SHMLBA boundary if the
5094 client requested rounding. See #222545. This is necessary only
5095 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5096 other linux targets it is the same as the page size. */
5097 if (ARG3 & VKI_SHM_RND)
5098 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5099 #endif
5100 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5101 if (arg2tmp == 0)
5102 SET_STATUS_Failure( VKI_EINVAL );
5103 else
5104 ARG2 = arg2tmp; // used in POST
5107 POST(sys_shmat)
5109 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5112 PRE(sys_shmdt)
5114 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5115 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5116 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5117 SET_STATUS_Failure( VKI_EINVAL );
5120 POST(sys_shmdt)
5122 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5125 PRE(sys_shmctl)
5127 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5128 PRE_REG_READ3(long, "shmctl",
5129 int, shmid, int, cmd, struct shmid_ds *, buf);
5130 #ifdef VGP_amd64_linux
5131 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5132 #else
5133 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5134 #endif
5137 POST(sys_shmctl)
5139 #ifdef VGP_amd64_linux
5140 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5141 #else
5142 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5143 #endif
5147 /* ---------------------------------------------------------------------
5148 Generic handler for sys_socketcall
5149 Depending on the platform, some socket related syscalls (e.g. socketpair,
5150 socket, bind, ...)
5151 are either direct system calls, or are all implemented via sys_socketcall.
5152 ------------------------------------------------------------------ */
5153 #ifdef __NR_socketcall
5154 PRE(sys_socketcall)
5156 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5157 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5158 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5159 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5160 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5161 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5163 // call PRE_MEM_READ and check for EFAULT result.
5164 #define PRE_MEM_READ_ef(msg, arg, size) \
5166 PRE_MEM_READ( msg, arg, size); \
5167 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5168 SET_STATUS_Failure( VKI_EFAULT ); \
5169 break; \
5173 *flags |= SfMayBlock;
5174 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5175 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5177 switch (ARG1 /* request */) {
5179 case VKI_SYS_SOCKETPAIR:
5180 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5181 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5182 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5183 break;
5185 case VKI_SYS_SOCKET:
5186 /* int socket(int domain, int type, int protocol); */
5187 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5188 break;
5190 case VKI_SYS_BIND:
5191 /* int bind(int sockfd, struct sockaddr *my_addr,
5192 int addrlen); */
5193 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5194 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5195 break;
5197 case VKI_SYS_LISTEN:
5198 /* int listen(int s, int backlog); */
5199 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5200 break;
5202 case VKI_SYS_ACCEPT:
5203 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5204 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5205 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5206 break;
5208 case VKI_SYS_ACCEPT4:
5209 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5210 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5211 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5212 break;
5214 case VKI_SYS_SENDTO:
5215 /* int sendto(int s, const void *msg, int len,
5216 unsigned int flags,
5217 const struct sockaddr *to, int tolen); */
5218 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5219 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5220 ARG2_3, ARG2_4, ARG2_5 );
5221 break;
5223 case VKI_SYS_SEND:
5224 /* int send(int s, const void *msg, size_t len, int flags); */
5225 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5226 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5227 break;
5229 case VKI_SYS_RECVFROM:
5230 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5231 struct sockaddr *from, int *fromlen); */
5232 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5233 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5234 ARG2_3, ARG2_4, ARG2_5 );
5235 break;
5237 case VKI_SYS_RECV:
5238 /* int recv(int s, void *buf, int len, unsigned int flags); */
5239 /* man 2 recv says:
5240 The recv call is normally used only on a connected socket
5241 (see connect(2)) and is identical to recvfrom with a NULL
5242 from parameter.
5244 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5245 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5246 break;
5248 case VKI_SYS_CONNECT:
5249 /* int connect(int sockfd,
5250 struct sockaddr *serv_addr, int addrlen ); */
5251 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5252 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5253 break;
5255 case VKI_SYS_SETSOCKOPT:
5256 /* int setsockopt(int s, int level, int optname,
5257 const void *optval, int optlen); */
5258 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5259 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5260 ARG2_3, ARG2_4 );
5261 break;
5263 case VKI_SYS_GETSOCKOPT:
5264 /* int getsockopt(int s, int level, int optname,
5265 void *optval, socklen_t *optlen); */
5266 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5267 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5268 ARG2_3, ARG2_4 );
5269 break;
5271 case VKI_SYS_GETSOCKNAME:
5272 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5273 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5274 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5275 break;
5277 case VKI_SYS_GETPEERNAME:
5278 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5279 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5280 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5281 break;
5283 case VKI_SYS_SHUTDOWN:
5284 /* int shutdown(int s, int how); */
5285 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5286 break;
5288 case VKI_SYS_SENDMSG:
5289 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5290 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5291 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5292 (struct vki_msghdr *)(Addr)ARG2_1 );
5293 break;
5295 case VKI_SYS_RECVMSG:
5296 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5297 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5298 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5299 (struct vki_msghdr *)(Addr)ARG2_1 );
5300 break;
5302 case VKI_SYS_RECVMMSG:
5303 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5304 struct timespec *timeout); */
5305 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5306 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5307 ARG2_4 );
5308 break;
5310 case VKI_SYS_SENDMMSG:
5311 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5312 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5313 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5314 break;
5316 default:
5317 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5318 SET_STATUS_Failure( VKI_EINVAL );
5319 break;
5321 # undef ARG2_0
5322 # undef ARG2_1
5323 # undef ARG2_2
5324 # undef ARG2_3
5325 # undef ARG2_4
5326 # undef ARG2_5
5329 POST(sys_socketcall)
5331 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5332 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5333 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5334 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5335 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5336 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5338 SysRes r;
5339 vg_assert(SUCCESS);
5340 switch (ARG1 /* request */) {
5342 case VKI_SYS_SOCKETPAIR:
5343 r = ML_(generic_POST_sys_socketpair)(
5344 tid, VG_(mk_SysRes_Success)(RES),
5345 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5347 SET_STATUS_from_SysRes(r);
5348 break;
5350 case VKI_SYS_SOCKET:
5351 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5352 SET_STATUS_from_SysRes(r);
5353 break;
5355 case VKI_SYS_BIND:
5356 /* int bind(int sockfd, struct sockaddr *my_addr,
5357 int addrlen); */
5358 break;
5360 case VKI_SYS_LISTEN:
5361 /* int listen(int s, int backlog); */
5362 break;
5364 case VKI_SYS_ACCEPT:
5365 case VKI_SYS_ACCEPT4:
5366 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5367 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5368 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5369 ARG2_0, ARG2_1, ARG2_2 );
5370 SET_STATUS_from_SysRes(r);
5371 break;
5373 case VKI_SYS_SENDTO:
5374 break;
5376 case VKI_SYS_SEND:
5377 break;
5379 case VKI_SYS_RECVFROM:
5380 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5381 ARG2_0, ARG2_1, ARG2_2,
5382 ARG2_3, ARG2_4, ARG2_5 );
5383 break;
5385 case VKI_SYS_RECV:
5386 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5387 break;
5389 case VKI_SYS_CONNECT:
5390 break;
5392 case VKI_SYS_SETSOCKOPT:
5393 break;
5395 case VKI_SYS_GETSOCKOPT:
5396 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5397 ARG2_0, ARG2_1,
5398 ARG2_2, ARG2_3, ARG2_4 );
5399 break;
5401 case VKI_SYS_GETSOCKNAME:
5402 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5403 ARG2_0, ARG2_1, ARG2_2 );
5404 break;
5406 case VKI_SYS_GETPEERNAME:
5407 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5408 ARG2_0, ARG2_1, ARG2_2 );
5409 break;
5411 case VKI_SYS_SHUTDOWN:
5412 break;
5414 case VKI_SYS_SENDMSG:
5415 break;
5417 case VKI_SYS_RECVMSG:
5418 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5419 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5420 break;
5422 case VKI_SYS_RECVMMSG:
5423 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5424 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5425 break;
5427 case VKI_SYS_SENDMMSG:
5428 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5429 break;
5431 default:
5432 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5433 VG_(core_panic)("... bye!\n");
5434 break; /*NOTREACHED*/
5436 # undef ARG2_0
5437 # undef ARG2_1
5438 # undef ARG2_2
5439 # undef ARG2_3
5440 # undef ARG2_4
5441 # undef ARG2_5
5443 #endif
5445 PRE(sys_socket)
5447 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5448 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5450 POST(sys_socket)
5452 SysRes r;
5453 vg_assert(SUCCESS);
5454 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5455 SET_STATUS_from_SysRes(r);
5458 PRE(sys_setsockopt)
5460 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5461 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5462 PRE_REG_READ5(long, "setsockopt",
5463 int, s, int, level, int, optname,
5464 const void *, optval, unsigned, optlen); // socklen_t
5465 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5468 PRE(sys_getsockopt)
5470 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5471 SARG1, SARG2, SARG3, ARG4, SARG5);
5472 PRE_REG_READ5(long, "getsockopt",
5473 int, s, int, level, int, optname,
5474 void *, optval, int, *optlen);
5475 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5477 POST(sys_getsockopt)
5479 vg_assert(SUCCESS);
5480 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5481 ARG1,ARG2,ARG3,ARG4,ARG5);
5484 PRE(sys_connect)
5486 *flags |= SfMayBlock;
5487 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5488 PRE_REG_READ3(long, "connect",
5489 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5490 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5493 PRE(sys_accept)
5495 *flags |= SfMayBlock;
5496 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5497 SARG1, ARG2, ARG3);
5498 PRE_REG_READ3(long, "accept",
5499 int, s, struct sockaddr *, addr, int *, addrlen);
5500 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5502 POST(sys_accept)
5504 SysRes r;
5505 vg_assert(SUCCESS);
5506 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5507 ARG1,ARG2,ARG3);
5508 SET_STATUS_from_SysRes(r);
5511 PRE(sys_accept4)
5513 *flags |= SfMayBlock;
5514 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5515 SARG1, ARG2, ARG3, SARG4);
5516 PRE_REG_READ4(long, "accept4",
5517 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5518 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5520 POST(sys_accept4)
5522 SysRes r;
5523 vg_assert(SUCCESS);
5524 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5525 ARG1,ARG2,ARG3);
5526 SET_STATUS_from_SysRes(r);
5529 PRE(sys_send)
5531 *flags |= SfMayBlock;
5532 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5533 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5534 PRE_REG_READ4(long, "send",
5535 int, s, const void *, msg, vki_size_t, len,
5536 int, flags);
5538 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5541 PRE(sys_sendto)
5543 *flags |= SfMayBlock;
5544 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5545 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5546 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5547 PRE_REG_READ6(long, "sendto",
5548 int, s, const void *, msg, vki_size_t, len,
5549 unsigned int, flags,
5550 const struct sockaddr *, to, int, tolen);
5551 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5554 PRE (sys_recv)
5556 *flags |= SfMayBlock;
5557 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5558 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5559 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5560 unsigned int, flags);
5561 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5564 POST (sys_recv)
5566 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5569 PRE(sys_recvfrom)
5571 *flags |= SfMayBlock;
5572 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5573 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5574 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5575 PRE_REG_READ6(long, "recvfrom",
5576 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5577 struct sockaddr *, from, int *, fromlen);
5578 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5580 POST(sys_recvfrom)
5582 vg_assert(SUCCESS);
5583 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5584 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5587 PRE(sys_sendmsg)
5589 *flags |= SfMayBlock;
5590 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5591 SARG1, ARG2, ARG3);
5592 PRE_REG_READ3(long, "sendmsg",
5593 int, s, const struct msghdr *, msg, unsigned int, flags);
5594 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5597 PRE(sys_recvmsg)
5599 *flags |= SfMayBlock;
5600 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5601 SARG1, ARG2, ARG3);
5602 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5603 unsigned int, flags);
5604 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5606 POST(sys_recvmsg)
5608 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5609 RES);
5612 PRE(sys_shutdown)
5614 *flags |= SfMayBlock;
5615 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5616 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5619 PRE(sys_bind)
5621 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5622 PRE_REG_READ3(long, "bind",
5623 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5624 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5627 PRE(sys_listen)
5629 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5630 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5633 PRE(sys_getsockname)
5635 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5636 SARG1, ARG2, ARG3);
5637 PRE_REG_READ3(long, "getsockname",
5638 int, s, struct sockaddr *, name, int *, namelen);
5639 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5641 POST(sys_getsockname)
5643 vg_assert(SUCCESS);
5644 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5645 ARG1,ARG2,ARG3);
5648 PRE(sys_getpeername)
5650 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5651 SARG1, ARG2, ARG3);
5652 PRE_REG_READ3(long, "getpeername",
5653 int, s, struct sockaddr *, name, int *, namelen);
5654 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5656 POST(sys_getpeername)
5658 vg_assert(SUCCESS);
5659 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5660 ARG1,ARG2,ARG3);
5663 PRE(sys_socketpair)
5665 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5666 SARG3, ARG4);
5667 PRE_REG_READ4(long, "socketpair",
5668 int, d, int, type, int, protocol, int*, sv);
5669 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5671 POST(sys_socketpair)
5673 vg_assert(SUCCESS);
5674 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5675 ARG1,ARG2,ARG3,ARG4);
5679 /* ---------------------------------------------------------------------
5680 *at wrappers
5681 ------------------------------------------------------------------ */
5683 PRE(sys_openat)
5685 HChar name[30]; // large enough
5686 SysRes sres;
5688 if (ARG3 & VKI_O_CREAT) {
5689 // 4-arg version
5690 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5691 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5692 PRE_REG_READ4(long, "openat",
5693 int, dfd, const char *, filename, int, flags, int, mode);
5694 } else {
5695 // 3-arg version
5696 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5697 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5698 PRE_REG_READ3(long, "openat",
5699 int, dfd, const char *, filename, int, flags);
5702 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5704 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5705 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5706 be sure only to compare the bottom 32 bits. */
5707 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5708 && *(Char *)(Addr)ARG2 != '/'
5709 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5710 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5711 SET_STATUS_Failure( VKI_EBADF );
5713 /* Handle the case where the open is of /proc/self/cmdline or
5714 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5715 fake file we cooked up at startup (in m_main). Also, seek the
5716 cloned fd back to the start. */
5718 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5719 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5720 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5721 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5722 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5723 SET_STATUS_from_SysRes( sres );
5724 if (!sr_isError(sres)) {
5725 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5726 if (off < 0)
5727 SET_STATUS_Failure( VKI_EMFILE );
5729 return;
5732 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5734 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5735 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5736 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5737 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5738 sres = VG_(dup)( VG_(cl_auxv_fd) );
5739 SET_STATUS_from_SysRes( sres );
5740 if (!sr_isError(sres)) {
5741 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5742 if (off < 0)
5743 SET_STATUS_Failure( VKI_EMFILE );
5745 return;
5748 /* Otherwise handle normally */
5749 *flags |= SfMayBlock;
5752 POST(sys_openat)
5754 vg_assert(SUCCESS);
5755 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5756 VG_(close)(RES);
5757 SET_STATUS_Failure( VKI_EMFILE );
5758 } else {
5759 if (VG_(clo_track_fds))
5760 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5764 PRE(sys_mkdirat)
5766 *flags |= SfMayBlock;
5767 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5768 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5769 PRE_REG_READ3(long, "mkdirat",
5770 int, dfd, const char *, pathname, int, mode);
5771 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5774 PRE(sys_mknodat)
5776 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5777 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5778 PRE_REG_READ4(long, "mknodat",
5779 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5780 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5783 PRE(sys_fchownat)
5785 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5786 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5787 PRE_REG_READ4(long, "fchownat",
5788 int, dfd, const char *, path,
5789 vki_uid_t, owner, vki_gid_t, group);
5790 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5793 PRE(sys_futimesat)
5795 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5796 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5797 PRE_REG_READ3(long, "futimesat",
5798 int, dfd, char *, filename, struct timeval *, tvp);
5799 if (ARG2 != 0)
5800 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5801 if (ARG3 != 0)
5802 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5805 PRE(sys_utimensat)
5807 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5808 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5809 PRE_REG_READ4(long, "utimensat",
5810 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5811 if (ARG2 != 0)
5812 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5813 if (ARG3 != 0) {
5814 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5815 then the tv_sec field is ignored. */
5816 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5817 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5818 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5819 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5820 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5821 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5822 if (times[0].tv_nsec != VKI_UTIME_NOW
5823 && times[0].tv_nsec != VKI_UTIME_OMIT)
5824 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5825 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5826 if (times[1].tv_nsec != VKI_UTIME_NOW
5827 && times[1].tv_nsec != VKI_UTIME_OMIT)
5828 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5829 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5834 PRE(sys_utimensat_time64)
5836 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5837 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5838 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5839 PRE_REG_READ4(long, "utimensat_time64",
5840 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5841 if (ARG2 != 0)
5842 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5843 if (ARG3 != 0) {
5844 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5845 then the tv_sec field is ignored. */
5846 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5847 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5848 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5849 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5850 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5851 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5852 if (times[0].tv_nsec != VKI_UTIME_NOW
5853 && times[0].tv_nsec != VKI_UTIME_OMIT)
5854 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5855 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5856 if (times[1].tv_nsec != VKI_UTIME_NOW
5857 && times[1].tv_nsec != VKI_UTIME_OMIT)
5858 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5859 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5864 #if !defined(VGP_nanomips_linux)
5865 PRE(sys_newfstatat)
5867 FUSE_COMPATIBLE_MAY_BLOCK();
5868 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5869 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5870 PRE_REG_READ3(long, "fstatat",
5871 int, dfd, char *, file_name, struct stat *, buf);
5872 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5873 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5876 POST(sys_newfstatat)
5878 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5880 #endif
5882 PRE(sys_unlinkat)
5884 *flags |= SfMayBlock;
5885 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5886 (HChar*)(Addr)ARG2);
5887 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5888 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5891 PRE(sys_renameat)
5893 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5894 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5895 ARG4, (HChar*)(Addr)ARG4);
5896 PRE_REG_READ4(long, "renameat",
5897 int, olddfd, const char *, oldpath,
5898 int, newdfd, const char *, newpath);
5899 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5900 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5903 PRE(sys_renameat2)
5905 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5906 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5907 ARG4, (HChar*)(Addr)ARG4, ARG5);
5908 PRE_REG_READ5(long, "renameat2",
5909 int, olddfd, const char *, oldpath,
5910 int, newdfd, const char *, newpath,
5911 unsigned int, flags);
5912 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5913 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5916 PRE(sys_linkat)
5918 *flags |= SfMayBlock;
5919 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5920 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5921 (HChar*)(Addr)ARG4, SARG5);
5922 PRE_REG_READ5(long, "linkat",
5923 int, olddfd, const char *, oldpath,
5924 int, newdfd, const char *, newpath,
5925 int, flags);
5926 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5927 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5930 PRE(sys_symlinkat)
5932 *flags |= SfMayBlock;
5933 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5934 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5935 PRE_REG_READ3(long, "symlinkat",
5936 const char *, oldpath, int, newdfd, const char *, newpath);
5937 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5938 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5941 PRE(sys_readlinkat)
5943 HChar name[30]; // large enough
5944 Word saved = SYSNO;
5946 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5947 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5948 PRE_REG_READ4(long, "readlinkat",
5949 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5950 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5951 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5954 * Handle the case where readlinkat is looking at /proc/self/exe or
5955 * /proc/<pid>/exe.
5957 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5958 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5959 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5960 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5961 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5962 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5963 ARG3, ARG4));
5964 } else {
5965 /* Normal case */
5966 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5969 if (SUCCESS && RES > 0)
5970 POST_MEM_WRITE( ARG3, RES );
5973 PRE(sys_fchmodat)
5975 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5976 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5977 PRE_REG_READ3(long, "fchmodat",
5978 int, dfd, const char *, path, vki_mode_t, mode);
5979 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5982 PRE(sys_faccessat)
5984 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5985 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5986 PRE_REG_READ3(long, "faccessat",
5987 int, dfd, const char *, pathname, int, mode);
5988 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5991 PRE(sys_faccessat2)
5993 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5994 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5995 PRE_REG_READ4(long, "faccessat2",
5996 int, dfd, const char *, pathname, int, mode, int, flags);
5997 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6000 PRE(sys_name_to_handle_at)
6002 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6003 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6004 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6005 PRE_REG_READ5(int, "name_to_handle_at",
6006 int, dfd, const char *, name,
6007 struct vki_file_handle *, handle,
6008 int *, mnt_id, int, flag);
6009 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6010 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6011 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6012 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6013 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6015 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6018 POST(sys_name_to_handle_at)
6020 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6021 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6022 POST_MEM_WRITE( ARG4, sizeof(int) );
6025 PRE(sys_open_by_handle_at)
6027 *flags |= SfMayBlock;
6028 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6029 ARG2, SARG3);
6030 PRE_REG_READ3(int, "open_by_handle_at",
6031 int, mountdirfd,
6032 struct vki_file_handle *, handle,
6033 int, flags);
6034 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6035 sizeof(struct vki_file_handle) +
6036 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6039 POST(sys_open_by_handle_at)
6041 vg_assert(SUCCESS);
6042 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6043 VG_(close)(RES);
6044 SET_STATUS_Failure( VKI_EMFILE );
6045 } else {
6046 if (VG_(clo_track_fds))
6047 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6051 /* ---------------------------------------------------------------------
6052 p{read,write}v wrappers
6053 ------------------------------------------------------------------ */
6054 /* This handles the common part of the PRE macro for preadv and preadv2. */
6055 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6056 Int fd, Addr vector, Int count, const char *str)
6058 struct vki_iovec * vec;
6059 Int i;
6060 /* safe size for the "preadv/preadv2(vector[i])" string */
6061 char tmp[30];
6063 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6064 SET_STATUS_Failure( VKI_EBADF );
6065 } else if (count > 0) {
6066 VG_(strcpy) (tmp, str);
6067 VG_(strcat) (tmp, "(vector)");
6068 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6070 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6071 count * sizeof(struct vki_iovec))) {
6072 vec = (struct vki_iovec *)(Addr)vector;
6073 for (i = 0; i < count; i++) {
6074 /* Note: building such a dynamic error string is *not*
6075 a pattern to follow. See bug 417075. */
6076 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6077 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6083 /* This handles the common part of the POST macro for preadv and preadv2. */
6084 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6086 vg_assert(SUCCESS);
6087 if (RES > 0) {
6088 Int i;
6089 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6090 Int remains = RES;
6092 /* RES holds the number of bytes read. */
6093 for (i = 0; i < count; i++) {
6094 Int nReadThisBuf = vec[i].iov_len;
6095 if (nReadThisBuf > remains) nReadThisBuf = remains;
6096 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6097 remains -= nReadThisBuf;
6098 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6103 PRE(sys_preadv)
6105 *flags |= SfMayBlock;
6106 const char *str = "preadv";
6107 #if VG_WORDSIZE == 4
6108 /* Note that the offset argument here is in lo+hi order on both
6109 big and little endian platforms... */
6110 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6111 "u, %lld )",
6112 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6113 PRE_REG_READ5(ssize_t, "preadv",
6114 unsigned long, fd, const struct iovec *, vector,
6115 unsigned long, count, vki_u32, offset_low,
6116 vki_u32, offset_high);
6117 #elif VG_WORDSIZE == 8
6118 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6119 PRE_REG_READ4(ssize_t, "preadv",
6120 unsigned long, fd, const struct iovec *, vector,
6121 unsigned long, count, Word, offset);
6122 #else
6123 # error Unexpected word size
6124 #endif
6125 Int fd = ARG1;
6126 Addr vector = ARG2;
6127 Int count = ARG3;
6129 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6133 POST(sys_preadv)
6135 Addr vector = ARG2;
6136 Int count = ARG3;
6138 handle_post_sys_preadv(tid, status, vector, count);
6141 PRE(sys_preadv2)
6143 *flags |= SfMayBlock;
6144 const char *str = "preadv2";
6145 #if VG_WORDSIZE == 4
6146 /* Note that the offset argument here is in lo+hi order on both
6147 big and little endian platforms... */
6148 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6149 "u, %lld, %" FMT_REGWORD "u )",
6150 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6151 PRE_REG_READ6(ssize_t, "preadv2",
6152 unsigned long, fd, const struct iovec *, vector,
6153 unsigned long, count, vki_u32, offset_low,
6154 vki_u32, offset_high, unsigned long, flags);
6155 #elif VG_WORDSIZE == 8
6156 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6157 PRE_REG_READ5(ssize_t, "preadv2",
6158 unsigned long, fd, const struct iovec *, vector,
6159 unsigned long, count, Word, offset, unsigned long, flags);
6160 #else
6161 # error Unexpected word size
6162 #endif
6163 Int fd = ARG1;
6164 Addr vector = ARG2;
6165 Int count = ARG3;
6167 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6170 POST(sys_preadv2)
6172 Addr vector = ARG2;
6173 Int count = ARG3;
6175 handle_post_sys_preadv(tid, status, vector, count);
6178 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6179 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6180 Int fd, Addr vector, Int count, const char *str)
6182 Int i;
6183 struct vki_iovec * vec;
6184 /* safe size for the "preadv/preadv2(vector[i])" string */
6185 char tmp[30];
6187 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6188 SET_STATUS_Failure( VKI_EBADF );
6189 } else if (count > 0) {
6190 VG_(strcpy) (tmp, str);
6191 VG_(strcat) (tmp, "(vector)");
6192 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6193 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6194 count * sizeof(struct vki_iovec))) {
6195 vec = (struct vki_iovec *)(Addr)vector;
6196 for (i = 0; i < count; i++) {
6197 /* Note: building such a dynamic error string is *not*
6198 a pattern to follow. See bug 417075. */
6199 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6200 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6206 PRE(sys_pwritev)
6208 *flags |= SfMayBlock;
6209 const char *str = "pwritev";
6210 #if VG_WORDSIZE == 4
6211 /* Note that the offset argument here is in lo+hi order on both
6212 big and little endian platforms... */
6213 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6214 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6215 PRE_REG_READ5(ssize_t, "pwritev",
6216 unsigned long, fd, const struct iovec *, vector,
6217 unsigned long, count, vki_u32, offset_low,
6218 vki_u32, offset_high);
6219 #elif VG_WORDSIZE == 8
6220 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6221 PRE_REG_READ4(ssize_t, "pwritev",
6222 unsigned long, fd, const struct iovec *, vector,
6223 unsigned long, count, Word, offset);
6224 #else
6225 # error Unexpected word size
6226 #endif
6227 Int fd = ARG1;
6228 Addr vector = ARG2;
6229 Int count = ARG3;
6231 handle_sys_pwritev(tid, status, fd, vector, count, str);
6234 PRE(sys_pwritev2)
6236 *flags |= SfMayBlock;
6237 const char *str = "pwritev2";
6238 #if VG_WORDSIZE == 4
6239 /* Note that the offset argument here is in lo+hi order on both
6240 big and little endian platforms... */
6241 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6242 "u, %lld, %" FMT_REGWORD "u )",
6243 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6244 PRE_REG_READ6(ssize_t, "pwritev2",
6245 unsigned long, fd, const struct iovec *, vector,
6246 unsigned long, count, vki_u32, offset_low,
6247 vki_u32, offset_high, unsigned long, flags);
6248 #elif VG_WORDSIZE == 8
6249 /* Note offset_high isn't actually used? */
6250 PRE_REG_READ6(ssize_t, "pwritev2",
6251 unsigned long, fd, const struct iovec *, vector,
6252 unsigned long, count, Word, offset,
6253 Word, offset_high, unsigned long, flags);
6254 #else
6255 # error Unexpected word size
6256 #endif
6257 Int fd = ARG1;
6258 Addr vector = ARG2;
6259 Int count = ARG3;
6261 handle_sys_pwritev(tid, status, fd, vector, count, str);
6264 /* ---------------------------------------------------------------------
6265 process_vm_{read,write}v wrappers
6266 ------------------------------------------------------------------ */
6268 PRE(sys_process_vm_readv)
6270 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6271 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6272 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6273 PRE_REG_READ6(ssize_t, "process_vm_readv",
6274 vki_pid_t, pid,
6275 const struct iovec *, lvec,
6276 unsigned long, liovcnt,
6277 const struct iovec *, rvec,
6278 unsigned long, riovcnt,
6279 unsigned long, flags);
6280 PRE_MEM_READ( "process_vm_readv(lvec)",
6281 ARG2, ARG3 * sizeof(struct vki_iovec) );
6282 PRE_MEM_READ( "process_vm_readv(rvec)",
6283 ARG4, ARG5 * sizeof(struct vki_iovec) );
6284 if (ARG2 != 0
6285 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6286 sizeof(struct vki_iovec) * ARG3)) {
6287 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6288 UInt i;
6289 for (i = 0; i < ARG3; i++)
6290 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6291 (Addr)vec[i].iov_base, vec[i].iov_len );
6295 POST(sys_process_vm_readv)
6297 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6298 UInt remains = RES;
6299 UInt i;
6300 for (i = 0; i < ARG3; i++) {
6301 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6302 vec[i].iov_len : remains;
6303 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6304 remains -= nReadThisBuf;
6308 PRE(sys_process_vm_writev)
6310 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6311 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6312 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6313 PRE_REG_READ6(ssize_t, "process_vm_writev",
6314 vki_pid_t, pid,
6315 const struct iovec *, lvec,
6316 unsigned long, liovcnt,
6317 const struct iovec *, rvec,
6318 unsigned long, riovcnt,
6319 unsigned long, flags);
6320 PRE_MEM_READ( "process_vm_writev(lvec)",
6321 ARG2, ARG3 * sizeof(struct vki_iovec) );
6322 PRE_MEM_READ( "process_vm_writev(rvec)",
6323 ARG4, ARG5 * sizeof(struct vki_iovec) );
6324 if (ARG2 != 0
6325 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6326 sizeof(struct vki_iovec) * ARG3)) {
6327 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6328 UInt i;
6329 for (i = 0; i < ARG3; i++)
6330 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6331 (Addr)vec[i].iov_base, vec[i].iov_len );
6335 /* ---------------------------------------------------------------------
6336 {send,recv}mmsg wrappers
6337 ------------------------------------------------------------------ */
6339 PRE(sys_sendmmsg)
6341 *flags |= SfMayBlock;
6342 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6343 SARG3, SARG4);
6344 PRE_REG_READ4(long, "sendmmsg",
6345 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6346 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6349 POST(sys_sendmmsg)
6351 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6354 PRE(sys_recvmmsg)
6356 *flags |= SfMayBlock;
6357 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6358 FMT_REGWORD "x )",
6359 SARG1, ARG2, SARG3, SARG4, ARG5);
6360 PRE_REG_READ5(long, "recvmmsg",
6361 int, s, struct mmsghdr *, mmsg, int, vlen,
6362 int, flags, struct timespec *, timeout);
6363 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6366 POST(sys_recvmmsg)
6368 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6371 PRE(sys_recvmmsg_time64)
6373 *flags |= SfMayBlock;
6374 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6375 FMT_REGWORD "x )",
6376 SARG1, ARG2, SARG3, SARG4, ARG5);
6377 PRE_REG_READ5(long, "recvmmsg_time64",
6378 int, s, struct mmsghdr *, mmsg, int, vlen,
6379 int, flags, struct vki_timespec64 *, timeout);
6380 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6381 HChar name[40]; // large enough
6382 UInt i;
6383 for (i = 0; i < ARG3; i++) {
6384 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6385 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6386 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6387 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6389 if (ARG5)
6390 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6393 POST(sys_recvmmsg_time64)
6395 /* ARG5 isn't actually used, so just use the generic POST. */
6396 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6399 /* ---------------------------------------------------------------------
6400 key retention service wrappers
6401 ------------------------------------------------------------------ */
6403 PRE(sys_request_key)
6405 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6406 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6407 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6408 PRE_REG_READ4(long, "request_key",
6409 const char *, type, const char *, description,
6410 const char *, callout_info, vki_key_serial_t, keyring);
6411 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6412 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6413 if (ARG3 != (UWord)NULL)
6414 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6417 PRE(sys_add_key)
6419 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6420 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6421 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6422 PRE_REG_READ5(long, "add_key",
6423 const char *, type, const char *, description,
6424 const void *, payload, vki_size_t, plen,
6425 vki_key_serial_t, keyring);
6426 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6427 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6428 if (ARG3 != (UWord)NULL)
6429 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6432 PRE(sys_keyctl)
6434 switch (ARG1 /* option */) {
6435 case VKI_KEYCTL_GET_KEYRING_ID:
6436 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6437 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6438 int, option, vki_key_serial_t, id, int, create);
6439 break;
6440 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6441 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6442 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6443 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6444 int, option, const char *, name);
6445 if (ARG2 != (UWord)NULL)
6446 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6447 break;
6448 case VKI_KEYCTL_UPDATE:
6449 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6450 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6451 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6452 int, option, vki_key_serial_t, key,
6453 const void *, payload, vki_size_t, plen);
6454 if (ARG3 != (UWord)NULL)
6455 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6456 break;
6457 case VKI_KEYCTL_REVOKE:
6458 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6459 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6460 int, option, vki_key_serial_t, id);
6461 break;
6462 case VKI_KEYCTL_CHOWN:
6463 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6464 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6465 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6466 int, option, vki_key_serial_t, id,
6467 vki_uid_t, uid, vki_gid_t, gid);
6468 break;
6469 case VKI_KEYCTL_SETPERM:
6470 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6471 SARG2, ARG3);
6472 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6473 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6474 break;
6475 case VKI_KEYCTL_DESCRIBE:
6476 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6477 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6478 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6479 int, option, vki_key_serial_t, id,
6480 char *, buffer, vki_size_t, buflen);
6481 if (ARG3 != (UWord)NULL)
6482 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6483 break;
6484 case VKI_KEYCTL_CLEAR:
6485 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6486 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6487 int, option, vki_key_serial_t, keyring);
6488 break;
6489 case VKI_KEYCTL_LINK:
6490 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6491 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6492 vki_key_serial_t, keyring, vki_key_serial_t, key);
6493 break;
6494 case VKI_KEYCTL_UNLINK:
6495 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6496 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6497 vki_key_serial_t, keyring, vki_key_serial_t, key);
6498 break;
6499 case VKI_KEYCTL_SEARCH:
6500 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6501 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6502 ARG4, (HChar*)(Addr)ARG4, SARG5);
6503 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6504 int, option, vki_key_serial_t, keyring,
6505 const char *, type, const char *, description,
6506 vki_key_serial_t, destring);
6507 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6508 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6509 break;
6510 case VKI_KEYCTL_READ:
6511 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6512 "u )", SARG2, ARG3, ARG4);
6513 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6514 int, option, vki_key_serial_t, keyring,
6515 char *, buffer, vki_size_t, buflen);
6516 if (ARG3 != (UWord)NULL)
6517 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6518 break;
6519 case VKI_KEYCTL_INSTANTIATE:
6520 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6521 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6522 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6523 int, option, vki_key_serial_t, key,
6524 char *, payload, vki_size_t, plen,
6525 vki_key_serial_t, keyring);
6526 if (ARG3 != (UWord)NULL)
6527 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6528 break;
6529 case VKI_KEYCTL_NEGATE:
6530 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6531 SARG2, ARG3, SARG4);
6532 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6533 int, option, vki_key_serial_t, key,
6534 unsigned, timeout, vki_key_serial_t, keyring);
6535 break;
6536 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6537 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6538 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6539 int, option, int, reqkey_defl);
6540 break;
6541 case VKI_KEYCTL_SET_TIMEOUT:
6542 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6543 SARG2, ARG3);
6544 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6545 int, option, vki_key_serial_t, key, unsigned, timeout);
6546 break;
6547 case VKI_KEYCTL_ASSUME_AUTHORITY:
6548 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6549 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6550 int, option, vki_key_serial_t, key);
6551 break;
6552 default:
6553 PRINT("sys_keyctl ( %ld ) ", SARG1);
6554 PRE_REG_READ1(long, "keyctl", int, option);
6555 break;
6559 POST(sys_keyctl)
6561 vg_assert(SUCCESS);
6562 switch (ARG1 /* option */) {
6563 case VKI_KEYCTL_DESCRIBE:
6564 case VKI_KEYCTL_READ:
6565 if (RES > ARG4)
6566 POST_MEM_WRITE(ARG3, ARG4);
6567 else
6568 POST_MEM_WRITE(ARG3, RES);
6569 break;
6570 default:
6571 break;
6575 /* ---------------------------------------------------------------------
6576 ioprio_ wrappers
6577 ------------------------------------------------------------------ */
6579 PRE(sys_ioprio_set)
6581 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6582 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6585 PRE(sys_ioprio_get)
6587 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6588 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6591 /* ---------------------------------------------------------------------
6592 _module wrappers
6593 ------------------------------------------------------------------ */
6595 PRE(sys_init_module)
6597 *flags |= SfMayBlock;
6598 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6599 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6600 PRE_REG_READ3(long, "init_module",
6601 void *, umod, unsigned long, len, const char *, uargs);
6602 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6603 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6606 PRE(sys_finit_module)
6608 *flags |= SfMayBlock;
6610 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6611 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6612 PRE_REG_READ3(long, "finit_module",
6613 int, fd, const char *, params, int, flags);
6614 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6617 PRE(sys_delete_module)
6619 *flags |= SfMayBlock;
6620 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6621 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6622 PRE_REG_READ2(long, "delete_module",
6623 const char *, name_user, unsigned int, flags);
6624 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6627 /* ---------------------------------------------------------------------
6628 splice wrappers
6629 ------------------------------------------------------------------ */
6631 PRE(sys_splice)
6633 *flags |= SfMayBlock;
6634 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6635 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6636 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6637 PRE_REG_READ6(vki_ssize_t, "splice",
6638 int, fd_in, vki_loff_t *, off_in,
6639 int, fd_out, vki_loff_t *, off_out,
6640 vki_size_t, len, unsigned int, flags);
6641 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6642 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6643 SET_STATUS_Failure( VKI_EBADF );
6644 } else {
6645 if (ARG2 != 0)
6646 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6647 if (ARG4 != 0)
6648 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6652 PRE(sys_tee)
6654 *flags |= SfMayBlock;
6655 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6656 SARG1, SARG2, ARG3, ARG4);
6657 PRE_REG_READ4(vki_ssize_t, "tee",
6658 int, fd_in, int, fd_out,
6659 vki_size_t, len, unsigned int, flags);
6660 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6661 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6662 SET_STATUS_Failure( VKI_EBADF );
6666 PRE(sys_vmsplice)
6668 Int fdfl;
6669 *flags |= SfMayBlock;
6670 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6671 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6672 PRE_REG_READ4(vki_ssize_t, "splice",
6673 int, fd, struct vki_iovec *, iov,
6674 unsigned long, nr_segs, unsigned int, flags);
6675 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6676 SET_STATUS_Failure( VKI_EBADF );
6677 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6678 SET_STATUS_Failure( VKI_EBADF );
6679 } else {
6680 const struct vki_iovec *iov;
6681 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6682 for (iov = (struct vki_iovec *)(Addr)ARG2;
6683 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6685 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6686 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6687 PRE_MEM_WRITE( "vmsplice(iov[...])",
6688 (Addr)iov->iov_base, iov->iov_len );
6689 else
6690 PRE_MEM_READ( "vmsplice(iov[...])",
6691 (Addr)iov->iov_base, iov->iov_len );
6697 POST(sys_vmsplice)
6699 vg_assert(SUCCESS);
6700 if (RES > 0) {
6701 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6702 vg_assert(fdfl >= 0);
6703 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6705 const struct vki_iovec *iov;
6706 for (iov = (struct vki_iovec *)(Addr)ARG2;
6707 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6709 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6715 /* ---------------------------------------------------------------------
6716 oprofile-related wrappers
6717 ------------------------------------------------------------------ */
6719 #if defined(VGP_x86_linux)
6720 PRE(sys_lookup_dcookie)
6722 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6723 MERGE64(ARG1,ARG2), ARG3, ARG4);
6724 PRE_REG_READ4(long, "lookup_dcookie",
6725 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6726 char *, buf, vki_size_t, len);
6727 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6729 POST(sys_lookup_dcookie)
6731 vg_assert(SUCCESS);
6732 if (ARG3 != (Addr)NULL)
6733 POST_MEM_WRITE( ARG3, RES);
6735 #endif
6737 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6738 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6739 PRE(sys_lookup_dcookie)
6741 *flags |= SfMayBlock;
6742 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6743 PRE_REG_READ3(int, "lookup_dcookie",
6744 unsigned long long, cookie, char *, buf, vki_size_t, len);
6746 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6749 POST(sys_lookup_dcookie)
6751 vg_assert(SUCCESS);
6752 if (ARG2 != (Addr)NULL)
6753 POST_MEM_WRITE( ARG2, RES );
6755 #endif
6757 /* ---------------------------------------------------------------------
6758 fcntl wrappers
6759 ------------------------------------------------------------------ */
6761 PRE(sys_fcntl)
6763 switch (ARG2) {
6764 // These ones ignore ARG3.
6765 case VKI_F_GETFD:
6766 case VKI_F_GETFL:
6767 case VKI_F_GETOWN:
6768 case VKI_F_GETSIG:
6769 case VKI_F_GETLEASE:
6770 case VKI_F_GETPIPE_SZ:
6771 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6772 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6773 break;
6775 // These ones use ARG3 as "arg".
6776 case VKI_F_DUPFD:
6777 case VKI_F_DUPFD_CLOEXEC:
6778 case VKI_F_SETFD:
6779 case VKI_F_SETFL:
6780 case VKI_F_SETLEASE:
6781 case VKI_F_NOTIFY:
6782 case VKI_F_SETOWN:
6783 case VKI_F_SETSIG:
6784 case VKI_F_SETPIPE_SZ:
6785 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6786 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6787 PRE_REG_READ3(long, "fcntl",
6788 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6789 break;
6791 // These ones use ARG3 as "lock".
6792 case VKI_F_GETLK:
6793 case VKI_F_SETLK:
6794 case VKI_F_SETLKW:
6795 case VKI_F_OFD_GETLK:
6796 case VKI_F_OFD_SETLK:
6797 case VKI_F_OFD_SETLKW:
6798 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6799 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6800 PRE_REG_READ3(long, "fcntl",
6801 unsigned int, fd, unsigned int, cmd,
6802 struct vki_flock *, lock);
6804 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6805 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6806 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6807 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6808 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6809 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6810 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6813 break;
6815 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6816 case VKI_F_GETLK64:
6817 case VKI_F_SETLK64:
6818 case VKI_F_SETLKW64:
6819 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6820 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6821 PRE_REG_READ3(long, "fcntl",
6822 unsigned int, fd, unsigned int, cmd,
6823 struct flock64 *, lock);
6825 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6826 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6827 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6828 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6829 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6830 if (ARG2 == VKI_F_GETLK64) {
6831 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6834 break;
6835 # endif
6837 case VKI_F_SETOWN_EX:
6838 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6839 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6840 PRE_REG_READ3(long, "fcntl",
6841 unsigned int, fd, unsigned int, cmd,
6842 struct vki_f_owner_ex *, arg);
6843 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6844 break;
6846 case VKI_F_GETOWN_EX:
6847 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6848 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6849 PRE_REG_READ3(long, "fcntl",
6850 unsigned int, fd, unsigned int, cmd,
6851 struct vki_f_owner_ex *, arg);
6852 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6853 break;
6855 default:
6856 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6857 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6858 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6859 ARG2);
6860 SET_STATUS_Failure( VKI_EINVAL );
6861 break;
6864 # if defined(VGP_x86_linux)
6865 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6866 # else
6867 if (ARG2 == VKI_F_SETLKW)
6868 # endif
6869 *flags |= SfMayBlock;
6872 POST(sys_fcntl)
6874 vg_assert(SUCCESS);
6875 if (ARG2 == VKI_F_DUPFD) {
6876 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6877 VG_(close)(RES);
6878 SET_STATUS_Failure( VKI_EMFILE );
6879 } else {
6880 if (VG_(clo_track_fds))
6881 ML_(record_fd_open_named)(tid, RES);
6884 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6885 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6886 VG_(close)(RES);
6887 SET_STATUS_Failure( VKI_EMFILE );
6888 } else {
6889 if (VG_(clo_track_fds))
6890 ML_(record_fd_open_named)(tid, RES);
6892 } else if (ARG2 == VKI_F_GETOWN_EX) {
6893 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6894 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6895 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6896 POST_FIELD_WRITE(lock->l_pid);
6897 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6898 } else if (ARG2 == VKI_F_GETLK64) {
6899 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6900 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6901 # endif
6905 // XXX: wrapper only suitable for 32-bit systems
6906 PRE(sys_fcntl64)
6908 switch (ARG2) {
6909 // These ones ignore ARG3.
6910 case VKI_F_GETFD:
6911 case VKI_F_GETFL:
6912 case VKI_F_GETOWN:
6913 case VKI_F_SETOWN:
6914 case VKI_F_GETSIG:
6915 case VKI_F_SETSIG:
6916 case VKI_F_GETLEASE:
6917 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6918 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6919 break;
6921 // These ones use ARG3 as "arg".
6922 case VKI_F_DUPFD:
6923 case VKI_F_DUPFD_CLOEXEC:
6924 case VKI_F_SETFD:
6925 case VKI_F_SETFL:
6926 case VKI_F_SETLEASE:
6927 case VKI_F_NOTIFY:
6928 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6929 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6930 PRE_REG_READ3(long, "fcntl64",
6931 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6932 break;
6934 // These ones use ARG3 as "lock".
6935 case VKI_F_GETLK:
6936 case VKI_F_SETLK:
6937 case VKI_F_SETLKW:
6938 # if defined(VGP_x86_linux)
6939 case VKI_F_GETLK64:
6940 case VKI_F_SETLK64:
6941 case VKI_F_SETLKW64:
6942 # endif
6943 case VKI_F_OFD_GETLK:
6944 case VKI_F_OFD_SETLK:
6945 case VKI_F_OFD_SETLKW:
6946 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6947 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6948 PRE_REG_READ3(long, "fcntl64",
6949 unsigned int, fd, unsigned int, cmd,
6950 struct flock64 *, lock);
6951 break;
6953 case VKI_F_SETOWN_EX:
6954 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6955 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6956 PRE_REG_READ3(long, "fcntl",
6957 unsigned int, fd, unsigned int, cmd,
6958 struct vki_f_owner_ex *, arg);
6959 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6960 break;
6962 case VKI_F_GETOWN_EX:
6963 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6964 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6965 PRE_REG_READ3(long, "fcntl",
6966 unsigned int, fd, unsigned int, cmd,
6967 struct vki_f_owner_ex *, arg);
6968 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6969 break;
6972 # if defined(VGP_x86_linux)
6973 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6974 # else
6975 if (ARG2 == VKI_F_SETLKW)
6976 # endif
6977 *flags |= SfMayBlock;
6980 POST(sys_fcntl64)
6982 vg_assert(SUCCESS);
6983 if (ARG2 == VKI_F_DUPFD) {
6984 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6985 VG_(close)(RES);
6986 SET_STATUS_Failure( VKI_EMFILE );
6987 } else {
6988 if (VG_(clo_track_fds))
6989 ML_(record_fd_open_named)(tid, RES);
6992 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6993 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6994 VG_(close)(RES);
6995 SET_STATUS_Failure( VKI_EMFILE );
6996 } else {
6997 if (VG_(clo_track_fds))
6998 ML_(record_fd_open_named)(tid, RES);
7000 } else if (ARG2 == VKI_F_GETOWN_EX) {
7001 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7005 /* ---------------------------------------------------------------------
7006 ioctl wrappers
7007 ------------------------------------------------------------------ */
7009 struct vg_drm_version_info {
7010 struct vki_drm_version data;
7011 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7014 PRE(sys_ioctl)
7016 *flags |= SfMayBlock;
7018 ARG2 = (UInt)ARG2;
7020 // We first handle the ones that don't use ARG3 (even as a
7021 // scalar/non-pointer argument).
7022 switch (ARG2 /* request */) {
7024 /* asm-generic/ioctls.h */
7025 case VKI_FIOCLEX:
7026 case VKI_FIONCLEX:
7027 case VKI_TIOCNOTTY:
7029 /* linux perf_event ioctls */
7030 case VKI_PERF_EVENT_IOC_ENABLE:
7031 case VKI_PERF_EVENT_IOC_DISABLE:
7033 /* linux/soundcard interface (ALSA) */
7034 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7035 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7036 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7037 case VKI_SNDRV_PCM_IOCTL_RESET:
7038 case VKI_SNDRV_PCM_IOCTL_START:
7039 case VKI_SNDRV_PCM_IOCTL_DROP:
7040 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7041 case VKI_SNDRV_PCM_IOCTL_RESUME:
7042 case VKI_SNDRV_PCM_IOCTL_XRUN:
7043 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7044 case VKI_SNDRV_TIMER_IOCTL_START:
7045 case VKI_SNDRV_TIMER_IOCTL_STOP:
7046 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7047 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7049 /* SCSI no operand */
7050 case VKI_SCSI_IOCTL_DOORLOCK:
7051 case VKI_SCSI_IOCTL_DOORUNLOCK:
7053 /* CDROM stuff. */
7054 case VKI_CDROM_DISC_STATUS:
7055 case VKI_CDROMSTOP:
7057 /* DVD stuff */
7058 case VKI_DVD_READ_STRUCT:
7060 /* KVM ioctls that don't check for a numeric value as parameter */
7061 case VKI_KVM_S390_ENABLE_SIE:
7062 case VKI_KVM_CREATE_IRQCHIP:
7063 case VKI_KVM_S390_INITIAL_RESET:
7064 case VKI_KVM_KVMCLOCK_CTRL:
7066 /* vhost without parameter */
7067 case VKI_VHOST_SET_OWNER:
7068 case VKI_VHOST_RESET_OWNER:
7070 /* User input device creation */
7071 case VKI_UI_DEV_CREATE:
7072 case VKI_UI_DEV_DESTROY:
7074 /* InfiniBand */
7075 case VKI_IB_USER_MAD_ENABLE_PKEY:
7077 /* Lustre */
7078 case VKI_LL_IOC_GROUP_LOCK:
7079 case VKI_LL_IOC_GROUP_UNLOCK:
7081 /* V4L2 */
7082 case VKI_V4L2_LOG_STATUS:
7084 /* Mesa */
7085 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7087 /* DVB */
7088 case VKI_DMX_STOP:
7089 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7090 PRE_REG_READ2(long, "ioctl",
7091 unsigned int, fd, unsigned int, request);
7092 return;
7094 default:
7095 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7096 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7097 PRE_REG_READ3(long, "ioctl",
7098 unsigned int, fd, unsigned int, request, unsigned long, arg);
7099 break;
7102 // We now handle those that do look at ARG3 (and unknown ones fall into
7103 // this category). Nb: some of these may well belong in the
7104 // doesn't-use-ARG3 switch above.
7105 switch (ARG2 /* request */) {
7107 case VKI_ION_IOC_ALLOC: {
7108 struct vki_ion_allocation_data* data
7109 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7110 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7111 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7112 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7113 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7114 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7115 break;
7117 case VKI_ION_IOC_MAP: {
7118 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7119 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7120 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7121 break;
7123 case VKI_ION_IOC_IMPORT: {
7124 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7125 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7126 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7127 break;
7130 case VKI_SYNC_IOC_MERGE: {
7131 struct vki_sync_merge_data* data =
7132 (struct vki_sync_merge_data*)(Addr)ARG3;
7133 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7134 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7135 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7136 break;
7139 case VKI_TCSETS:
7140 case VKI_TCSETSW:
7141 case VKI_TCSETSF:
7142 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7143 break;
7144 case VKI_TCGETS:
7145 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7146 break;
7147 case VKI_TCSETA:
7148 case VKI_TCSETAW:
7149 case VKI_TCSETAF:
7150 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7151 break;
7152 case VKI_TCGETA:
7153 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7154 break;
7155 case VKI_TCSBRK:
7156 case VKI_TCXONC:
7157 case VKI_TCSBRKP:
7158 case VKI_TCFLSH:
7159 case VKI_TIOCSIG:
7160 /* These just take an int by value */
7161 break;
7162 case VKI_TIOCGWINSZ:
7163 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7164 break;
7165 case VKI_TIOCSWINSZ:
7166 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7167 break;
7168 case VKI_TIOCMBIS:
7169 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7170 break;
7171 case VKI_TIOCMBIC:
7172 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7173 break;
7174 case VKI_TIOCMSET:
7175 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7176 break;
7177 case VKI_TIOCMGET:
7178 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7179 break;
7180 case VKI_TIOCLINUX:
7181 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7182 if (*(char *)(Addr)ARG3 == 11) {
7183 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7185 break;
7186 case VKI_TIOCGPGRP:
7187 /* Get process group ID for foreground processing group. */
7188 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7189 break;
7190 case VKI_TIOCSPGRP:
7191 /* Set a process group ID? */
7192 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7193 break;
7194 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7195 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7196 break;
7197 case VKI_TIOCSCTTY:
7198 /* Just takes an int value. */
7199 break;
7200 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7201 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7202 break;
7203 case VKI_FIONBIO:
7204 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7205 break;
7206 case VKI_FIOASYNC:
7207 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7208 break;
7209 case VKI_FIONREAD: /* identical to SIOCINQ */
7210 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7211 break;
7212 case VKI_FIOQSIZE:
7213 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7214 break;
7216 case VKI_TIOCSERGETLSR:
7217 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7218 break;
7219 case VKI_TIOCGICOUNT:
7220 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7221 sizeof(struct vki_serial_icounter_struct) );
7222 break;
7224 case VKI_SG_SET_COMMAND_Q:
7225 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7226 break;
7227 case VKI_SG_IO:
7228 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7230 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7231 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7232 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7233 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7234 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7237 break;
7238 case VKI_SG_GET_SCSI_ID:
7239 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7240 break;
7241 case VKI_SG_SET_RESERVED_SIZE:
7242 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7243 break;
7244 case VKI_SG_SET_TIMEOUT:
7245 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7246 break;
7247 case VKI_SG_GET_RESERVED_SIZE:
7248 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7249 break;
7250 case VKI_SG_GET_TIMEOUT:
7251 break;
7252 case VKI_SG_GET_VERSION_NUM:
7253 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7254 break;
7255 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7256 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7257 break;
7258 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7259 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7260 break;
7262 case VKI_IIOCGETCPS:
7263 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7264 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7265 break;
7266 case VKI_IIOCNETGPN:
7267 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7268 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7269 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7270 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7271 sizeof(vki_isdn_net_ioctl_phone) );
7272 break;
7274 /* These all use struct ifreq AFAIK */
7275 case VKI_SIOCGIFINDEX: /* get iface index */
7276 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7277 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7278 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7279 break;
7280 case VKI_SIOCGIFFLAGS: /* get flags */
7281 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7282 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7283 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7284 break;
7285 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7286 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7287 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7288 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7289 break;
7290 case VKI_SIOCGIFMTU: /* get MTU size */
7291 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7292 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7293 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7294 break;
7295 case VKI_SIOCGIFADDR: /* get PA address */
7296 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7297 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7298 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7299 break;
7300 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7301 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7302 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7303 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7304 break;
7305 case VKI_SIOCGIFMETRIC: /* get metric */
7306 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7307 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7308 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7309 break;
7310 case VKI_SIOCGIFMAP: /* Get device parameters */
7311 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7312 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7313 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7314 break;
7315 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7316 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7317 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7318 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7319 break;
7320 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7321 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7322 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7323 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7324 break;
7325 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7326 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7327 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7328 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7329 break;
7330 case VKI_SIOCGIFNAME: /* get iface name */
7331 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7332 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7333 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7334 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7335 break;
7337 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7338 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7339 // The kernel will have to look at ifr_data to determine which operation
7340 // to perform.
7341 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7342 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7344 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7346 // Is this correct? Is ifr_name *always* looked at?
7347 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7348 (Addr)ir->vki_ifr_name );
7350 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7351 // the whole structure is defined. So in this case, just check it's
7352 // accessible.
7353 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7354 case VKI_ETHTOOL_GSET:
7355 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7356 (Addr)ir, sizeof(struct vki_ifreq) );
7357 break;
7358 default:
7359 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7360 (Addr)ir, sizeof(struct vki_ifreq) );
7361 break;
7364 // Now perform the relevant pre-action for the operation.
7365 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7366 case VKI_ETHTOOL_GSET:
7367 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7368 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7369 break;
7370 case VKI_ETHTOOL_SSET:
7371 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7372 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7373 break;
7374 case VKI_ETHTOOL_GDRVINFO:
7375 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7376 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7377 break;
7378 case VKI_ETHTOOL_GREGS:
7379 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7380 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7381 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7382 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7383 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7384 break;
7385 case VKI_ETHTOOL_GWOL:
7386 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7387 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7388 break;
7389 case VKI_ETHTOOL_SWOL:
7390 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7391 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7392 break;
7393 case VKI_ETHTOOL_GMSGLVL:
7394 case VKI_ETHTOOL_GLINK:
7395 case VKI_ETHTOOL_GRXCSUM:
7396 case VKI_ETHTOOL_GSG:
7397 case VKI_ETHTOOL_GTSO:
7398 case VKI_ETHTOOL_GUFO:
7399 case VKI_ETHTOOL_GGSO:
7400 case VKI_ETHTOOL_GFLAGS:
7401 case VKI_ETHTOOL_GGRO:
7402 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7403 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7404 break;
7405 case VKI_ETHTOOL_SMSGLVL:
7406 case VKI_ETHTOOL_SRXCSUM:
7407 case VKI_ETHTOOL_SSG:
7408 case VKI_ETHTOOL_STSO:
7409 case VKI_ETHTOOL_SUFO:
7410 case VKI_ETHTOOL_SGSO:
7411 case VKI_ETHTOOL_SFLAGS:
7412 case VKI_ETHTOOL_SGRO:
7413 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7414 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7415 break;
7416 case VKI_ETHTOOL_NWAY_RST:
7417 break;
7418 case VKI_ETHTOOL_GRINGPARAM:
7419 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7420 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7421 break;
7422 case VKI_ETHTOOL_SRINGPARAM:
7423 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7424 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7425 break;
7426 case VKI_ETHTOOL_TEST:
7427 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7428 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7429 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7430 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7431 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7432 break;
7433 case VKI_ETHTOOL_PHYS_ID:
7434 break;
7435 case VKI_ETHTOOL_GPERMADDR:
7436 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7437 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7438 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7439 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7440 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7441 break;
7442 case VKI_ETHTOOL_RESET:
7443 break;
7444 case VKI_ETHTOOL_GSSET_INFO:
7445 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7446 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7447 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7448 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7449 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7450 break;
7451 case VKI_ETHTOOL_GFEATURES:
7452 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7453 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7454 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7455 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7456 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7457 break;
7458 case VKI_ETHTOOL_SFEATURES:
7459 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7460 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7461 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7462 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7463 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7464 break;
7465 case VKI_ETHTOOL_GCHANNELS:
7466 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7467 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7468 break;
7469 case VKI_ETHTOOL_SCHANNELS:
7470 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7471 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7472 break;
7473 case VKI_ETHTOOL_GET_TS_INFO:
7474 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7475 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7476 break;
7478 break;
7479 } /* case VKI_SIOCETHTOOL */
7481 case VKI_SIOCGMIIPHY: /* get hardware entry */
7482 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7483 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7484 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7485 break;
7486 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7487 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7488 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7489 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7490 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7491 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7492 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7493 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7494 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7495 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7496 sizeof(struct vki_ifreq));
7497 break;
7498 case VKI_SIOCGIFCONF: /* get iface list */
7499 /* WAS:
7500 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7501 KERNEL_DO_SYSCALL(tid,RES);
7502 if (!VG_(is_kerror)(RES) && RES == 0)
7503 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7505 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7506 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7507 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7508 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7509 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7510 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7511 if ( ARG3 ) {
7512 // TODO len must be readable and writable
7513 // buf pointer only needs to be readable
7514 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7515 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7516 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7518 break;
7519 case VKI_SIOCGSTAMP:
7520 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7521 break;
7522 case VKI_SIOCGSTAMPNS:
7523 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7524 break;
7525 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7526 the number of bytes currently in that socket's send buffer.
7527 It writes this value as an int to the memory location
7528 indicated by the third argument of ioctl(2). */
7529 case VKI_SIOCOUTQ:
7530 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7531 break;
7532 case VKI_SIOCGRARP: /* get RARP table entry */
7533 case VKI_SIOCGARP: /* get ARP table entry */
7534 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7535 break;
7537 case VKI_SIOCSIFFLAGS: /* set flags */
7538 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7539 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7540 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7541 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7542 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7543 break;
7544 case VKI_SIOCSIFMAP: /* Set device parameters */
7545 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7546 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7547 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7548 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7549 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7550 break;
7551 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7552 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7553 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7554 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7555 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7556 sizeof(struct vki_hwtstamp_config) );
7557 break;
7558 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7559 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7560 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7561 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7562 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7563 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7564 break;
7565 case VKI_SIOCSIFADDR: /* set PA address */
7566 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7567 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7568 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7569 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7570 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7571 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7572 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7573 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7574 break;
7575 case VKI_SIOCSIFMETRIC: /* set metric */
7576 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7577 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7578 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7579 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7580 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7581 break;
7582 case VKI_SIOCSIFMTU: /* set MTU size */
7583 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7584 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7585 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7586 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7587 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7588 break;
7589 case VKI_SIOCSIFHWADDR: /* set hardware address */
7590 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7591 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7592 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7593 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7594 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7595 break;
7596 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7597 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7598 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7599 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7600 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7601 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7602 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7603 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7604 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7605 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7606 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7607 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7608 break;
7609 /* Routing table calls. */
7610 case VKI_SIOCADDRT: /* add routing table entry */
7611 case VKI_SIOCDELRT: /* delete routing table entry */
7612 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7613 sizeof(struct vki_rtentry));
7614 break;
7616 /* tun/tap related ioctls */
7617 case VKI_TUNSETNOCSUM:
7618 case VKI_TUNSETDEBUG:
7619 break;
7620 case VKI_TUNSETIFF:
7621 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7622 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7623 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7624 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7625 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7626 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7627 break;
7628 case VKI_TUNSETPERSIST:
7629 case VKI_TUNSETOWNER:
7630 case VKI_TUNSETLINK:
7631 case VKI_TUNSETGROUP:
7632 break;
7633 case VKI_TUNGETFEATURES:
7634 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7635 break;
7636 case VKI_TUNSETOFFLOAD:
7637 break;
7638 case VKI_TUNGETIFF:
7639 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7640 break;
7641 case VKI_TUNGETSNDBUF:
7642 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7643 break;
7644 case VKI_TUNSETSNDBUF:
7645 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7646 break;
7647 case VKI_TUNGETVNETHDRSZ:
7648 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7649 break;
7650 case VKI_TUNSETVNETHDRSZ:
7651 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7652 break;
7653 case VKI_TUNSETQUEUE:
7654 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7655 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7656 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7657 break;
7658 case VKI_TUNSETIFINDEX:
7659 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7660 break;
7662 /* RARP cache control calls. */
7663 case VKI_SIOCDRARP: /* delete RARP table entry */
7664 case VKI_SIOCSRARP: /* set RARP table entry */
7665 /* ARP cache control calls. */
7666 case VKI_SIOCSARP: /* set ARP table entry */
7667 case VKI_SIOCDARP: /* delete ARP table entry */
7668 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7669 break;
7671 case VKI_SIOCGPGRP:
7672 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7673 break;
7674 case VKI_SIOCSPGRP:
7675 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7676 //tst->sys_flags &= ~SfMayBlock;
7677 break;
7679 case VKI_SIOCATMARK:
7680 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7681 break;
7683 /* linux/soundcard interface (OSS) */
7684 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7685 case VKI_SNDCTL_SEQ_GETINCOUNT:
7686 case VKI_SNDCTL_SEQ_PERCMODE:
7687 case VKI_SNDCTL_SEQ_TESTMIDI:
7688 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7689 case VKI_SNDCTL_SEQ_NRSYNTHS:
7690 case VKI_SNDCTL_SEQ_NRMIDIS:
7691 case VKI_SNDCTL_SEQ_GETTIME:
7692 case VKI_SNDCTL_DSP_GETBLKSIZE:
7693 case VKI_SNDCTL_DSP_GETFMTS:
7694 case VKI_SNDCTL_DSP_GETTRIGGER:
7695 case VKI_SNDCTL_DSP_GETODELAY:
7696 case VKI_SNDCTL_DSP_GETSPDIF:
7697 case VKI_SNDCTL_DSP_GETCAPS:
7698 case VKI_SOUND_PCM_READ_RATE:
7699 case VKI_SOUND_PCM_READ_CHANNELS:
7700 case VKI_SOUND_PCM_READ_BITS:
7701 case VKI_SOUND_PCM_READ_FILTER:
7702 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7703 ARG3, sizeof(int));
7704 break;
7705 case VKI_SNDCTL_SEQ_CTRLRATE:
7706 case VKI_SNDCTL_DSP_SPEED:
7707 case VKI_SNDCTL_DSP_STEREO:
7708 case VKI_SNDCTL_DSP_CHANNELS:
7709 case VKI_SOUND_PCM_WRITE_FILTER:
7710 case VKI_SNDCTL_DSP_SUBDIVIDE:
7711 case VKI_SNDCTL_DSP_SETFRAGMENT:
7712 case VKI_SNDCTL_DSP_SETFMT:
7713 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7714 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7715 case VKI_SNDCTL_TMR_TIMEBASE:
7716 case VKI_SNDCTL_TMR_TEMPO:
7717 case VKI_SNDCTL_TMR_SOURCE:
7718 case VKI_SNDCTL_MIDI_PRETIME:
7719 case VKI_SNDCTL_MIDI_MPUMODE:
7720 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7721 ARG3, sizeof(int));
7722 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7723 ARG3, sizeof(int));
7724 break;
7725 case VKI_SNDCTL_DSP_GETOSPACE:
7726 case VKI_SNDCTL_DSP_GETISPACE:
7727 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7728 ARG3, sizeof(vki_audio_buf_info));
7729 break;
7730 case VKI_SNDCTL_DSP_NONBLOCK:
7731 break;
7732 case VKI_SNDCTL_DSP_SETTRIGGER:
7733 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7734 ARG3, sizeof(int));
7735 break;
7737 case VKI_SNDCTL_DSP_POST:
7738 case VKI_SNDCTL_DSP_RESET:
7739 case VKI_SNDCTL_DSP_SYNC:
7740 case VKI_SNDCTL_DSP_SETSYNCRO:
7741 case VKI_SNDCTL_DSP_SETDUPLEX:
7742 break;
7744 /* linux/soundcard interface (ALSA) */
7745 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7746 case VKI_SNDRV_PCM_IOCTL_LINK:
7747 /* these just take an int by value */
7748 break;
7749 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7750 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7751 break;
7752 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7753 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7754 break;
7755 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7756 struct vki_snd_ctl_elem_list *data =
7757 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7758 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7759 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7760 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7761 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7762 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7763 if (data->pids) {
7764 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7766 break;
7768 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7769 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7770 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7771 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7772 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7773 break;
7775 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7776 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7777 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7778 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7779 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7780 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7781 break;
7784 /* Real Time Clock (/dev/rtc) ioctls */
7785 case VKI_RTC_UIE_ON:
7786 case VKI_RTC_UIE_OFF:
7787 case VKI_RTC_AIE_ON:
7788 case VKI_RTC_AIE_OFF:
7789 case VKI_RTC_PIE_ON:
7790 case VKI_RTC_PIE_OFF:
7791 case VKI_RTC_IRQP_SET:
7792 break;
7793 case VKI_RTC_RD_TIME:
7794 case VKI_RTC_ALM_READ:
7795 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7796 ARG3, sizeof(struct vki_rtc_time));
7797 break;
7798 case VKI_RTC_ALM_SET:
7799 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7800 break;
7801 case VKI_RTC_IRQP_READ:
7802 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7803 break;
7805 /* Block devices */
7806 case VKI_BLKROSET:
7807 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7808 break;
7809 case VKI_BLKROGET:
7810 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7811 break;
7812 case VKI_BLKGETSIZE:
7813 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7814 break;
7815 case VKI_BLKFLSBUF:
7816 break;
7817 case VKI_BLKRASET:
7818 break;
7819 case VKI_BLKRAGET:
7820 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7821 break;
7822 case VKI_BLKFRASET:
7823 break;
7824 case VKI_BLKFRAGET:
7825 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7826 break;
7827 case VKI_BLKSECTGET:
7828 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7829 break;
7830 case VKI_BLKSSZGET:
7831 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7832 break;
7833 case VKI_BLKBSZGET:
7834 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7835 break;
7836 case VKI_BLKBSZSET:
7837 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7838 break;
7839 case VKI_BLKGETSIZE64:
7840 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7841 break;
7842 case VKI_BLKPBSZGET:
7843 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7844 break;
7845 case VKI_BLKIOMIN:
7846 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7847 break;
7848 case VKI_BLKIOOPT:
7849 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7850 break;
7851 case VKI_BLKALIGNOFF:
7852 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7853 break;
7854 case VKI_BLKDISCARDZEROES:
7855 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7856 break;
7857 case VKI_BLKREPORTZONE:
7858 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7859 sizeof(struct vki_blk_zone_report));
7860 break;
7861 case VKI_BLKRESETZONE:
7862 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7863 sizeof(struct vki_blk_zone_range));
7864 break;
7866 /* Hard disks */
7867 case VKI_HDIO_GETGEO: /* 0x0301 */
7868 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7869 break;
7870 case VKI_HDIO_GET_DMA: /* 0x030b */
7871 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7872 break;
7873 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7874 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7875 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7876 break;
7878 /* SCSI */
7879 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7880 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7881 break;
7882 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7883 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7884 break;
7886 /* CD ROM stuff (??) */
7887 case VKI_CDROM_GET_MCN:
7888 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7889 sizeof(struct vki_cdrom_mcn) );
7890 break;
7891 case VKI_CDROM_SEND_PACKET:
7892 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7893 sizeof(struct vki_cdrom_generic_command));
7894 break;
7895 case VKI_CDROMSUBCHNL:
7896 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7897 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7898 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7899 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7900 sizeof(struct vki_cdrom_subchnl));
7901 break;
7902 case VKI_CDROMREADMODE1: /*0x530d*/
7903 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7904 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7905 break;
7906 case VKI_CDROMREADMODE2: /*0x530c*/
7907 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7908 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7909 break;
7910 case VKI_CDROMREADTOCHDR:
7911 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7912 sizeof(struct vki_cdrom_tochdr));
7913 break;
7914 case VKI_CDROMREADTOCENTRY:
7915 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7916 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7917 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7918 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7919 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7920 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7921 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7922 sizeof(struct vki_cdrom_tocentry));
7923 break;
7924 case VKI_CDROMMULTISESSION: /* 0x5310 */
7925 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7926 sizeof(struct vki_cdrom_multisession));
7927 break;
7928 case VKI_CDROMVOLREAD: /* 0x5313 */
7929 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7930 sizeof(struct vki_cdrom_volctrl));
7931 break;
7932 case VKI_CDROMREADRAW: /* 0x5314 */
7933 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7934 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7935 break;
7936 case VKI_CDROMREADAUDIO: /* 0x530e */
7937 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7938 sizeof (struct vki_cdrom_read_audio));
7939 if ( ARG3 ) {
7940 /* ToDo: don't do any of the following if the structure is invalid */
7941 struct vki_cdrom_read_audio *cra =
7942 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7943 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7944 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7946 break;
7947 case VKI_CDROMPLAYMSF:
7948 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7949 break;
7950 /* The following two are probably bogus (should check args
7951 for readability). JRS 20021117 */
7952 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7953 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7954 break;
7955 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7956 break;
7958 case VKI_FIGETBSZ:
7959 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7960 break;
7961 case VKI_FIBMAP:
7962 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7963 break;
7965 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7966 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7967 sizeof(struct vki_fb_var_screeninfo));
7968 break;
7969 case VKI_FBIOPUT_VSCREENINFO:
7970 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7971 sizeof(struct vki_fb_var_screeninfo));
7972 break;
7973 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7974 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7975 sizeof(struct vki_fb_fix_screeninfo));
7976 break;
7977 case VKI_FBIOPAN_DISPLAY:
7978 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7979 sizeof(struct vki_fb_var_screeninfo));
7981 break;
7982 case VKI_PPCLAIM:
7983 case VKI_PPEXCL:
7984 case VKI_PPYIELD:
7985 case VKI_PPRELEASE:
7986 break;
7987 case VKI_PPSETMODE:
7988 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7989 break;
7990 case VKI_PPGETMODE:
7991 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7992 break;
7993 case VKI_PPSETPHASE:
7994 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7995 break;
7996 case VKI_PPGETPHASE:
7997 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7998 break;
7999 case VKI_PPGETMODES:
8000 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8001 break;
8002 case VKI_PPSETFLAGS:
8003 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8004 break;
8005 case VKI_PPGETFLAGS:
8006 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8007 break;
8008 case VKI_PPRSTATUS:
8009 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8010 break;
8011 case VKI_PPRDATA:
8012 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8013 break;
8014 case VKI_PPRCONTROL:
8015 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8016 break;
8017 case VKI_PPWDATA:
8018 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8019 break;
8020 case VKI_PPWCONTROL:
8021 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8022 break;
8023 case VKI_PPFCONTROL:
8024 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8025 break;
8026 case VKI_PPDATADIR:
8027 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8028 break;
8029 case VKI_PPNEGOT:
8030 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8031 break;
8032 case VKI_PPWCTLONIRQ:
8033 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8034 break;
8035 case VKI_PPCLRIRQ:
8036 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8037 break;
8038 case VKI_PPSETTIME:
8039 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8040 break;
8041 case VKI_PPGETTIME:
8042 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8043 break;
8045 case VKI_GIO_FONT:
8046 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8047 break;
8048 case VKI_PIO_FONT:
8049 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8050 break;
8052 case VKI_GIO_FONTX:
8053 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8054 if ( ARG3 ) {
8055 /* ToDo: don't do any of the following if the structure is invalid */
8056 struct vki_consolefontdesc *cfd =
8057 (struct vki_consolefontdesc *)(Addr)ARG3;
8058 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8059 32 * cfd->charcount );
8061 break;
8062 case VKI_PIO_FONTX:
8063 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8064 if ( ARG3 ) {
8065 /* ToDo: don't do any of the following if the structure is invalid */
8066 struct vki_consolefontdesc *cfd =
8067 (struct vki_consolefontdesc *)(Addr)ARG3;
8068 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8069 32 * cfd->charcount );
8071 break;
8073 case VKI_PIO_FONTRESET:
8074 break;
8076 case VKI_GIO_CMAP:
8077 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8078 break;
8079 case VKI_PIO_CMAP:
8080 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8081 break;
8083 case VKI_KIOCSOUND:
8084 case VKI_KDMKTONE:
8085 break;
8087 case VKI_KDGETLED:
8088 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8089 break;
8090 case VKI_KDSETLED:
8091 break;
8093 case VKI_KDGKBTYPE:
8094 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8095 break;
8097 case VKI_KDADDIO:
8098 case VKI_KDDELIO:
8099 case VKI_KDENABIO:
8100 case VKI_KDDISABIO:
8101 break;
8103 case VKI_KDSETMODE:
8104 break;
8105 case VKI_KDGETMODE:
8106 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8107 break;
8109 case VKI_KDMAPDISP:
8110 case VKI_KDUNMAPDISP:
8111 break;
8113 case VKI_GIO_SCRNMAP:
8114 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8115 break;
8116 case VKI_PIO_SCRNMAP:
8117 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8118 break;
8119 case VKI_GIO_UNISCRNMAP:
8120 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8121 VKI_E_TABSZ * sizeof(unsigned short) );
8122 break;
8123 case VKI_PIO_UNISCRNMAP:
8124 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8125 VKI_E_TABSZ * sizeof(unsigned short) );
8126 break;
8128 case VKI_GIO_UNIMAP:
8129 if ( ARG3 ) {
8130 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8131 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8132 sizeof(unsigned short));
8133 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8134 sizeof(struct vki_unipair *));
8135 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8136 desc->entry_ct * sizeof(struct vki_unipair));
8138 break;
8139 case VKI_PIO_UNIMAP:
8140 if ( ARG3 ) {
8141 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8142 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8143 sizeof(unsigned short) );
8144 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8145 sizeof(struct vki_unipair *) );
8146 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8147 desc->entry_ct * sizeof(struct vki_unipair) );
8149 break;
8150 case VKI_PIO_UNIMAPCLR:
8151 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8152 break;
8154 case VKI_KDGKBMODE:
8155 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8156 break;
8157 case VKI_KDSKBMODE:
8158 break;
8160 case VKI_KDGKBMETA:
8161 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8162 break;
8163 case VKI_KDSKBMETA:
8164 break;
8166 case VKI_KDGKBLED:
8167 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8168 break;
8169 case VKI_KDSKBLED:
8170 break;
8172 case VKI_KDGKBENT:
8173 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8174 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8175 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8176 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8177 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8178 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8179 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8180 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8181 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8182 break;
8183 case VKI_KDSKBENT:
8184 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8185 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8186 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8187 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8188 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8189 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8190 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8191 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8192 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8193 break;
8195 case VKI_KDGKBSENT:
8196 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8197 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8198 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8199 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8200 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8201 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8202 break;
8203 case VKI_KDSKBSENT:
8204 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8205 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8206 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8207 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8208 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8209 break;
8211 case VKI_KDGKBDIACR:
8212 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8213 break;
8214 case VKI_KDSKBDIACR:
8215 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8216 break;
8218 case VKI_KDGETKEYCODE:
8219 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8220 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8221 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8222 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8223 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8224 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8225 break;
8226 case VKI_KDSETKEYCODE:
8227 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8228 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8229 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8230 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8231 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8232 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8233 break;
8235 case VKI_KDSIGACCEPT:
8236 break;
8238 case VKI_KDKBDREP:
8239 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8240 break;
8242 case VKI_KDFONTOP:
8243 if ( ARG3 ) {
8244 struct vki_console_font_op *op =
8245 (struct vki_console_font_op *) (Addr)ARG3;
8246 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8247 sizeof(struct vki_console_font_op) );
8248 switch ( op->op ) {
8249 case VKI_KD_FONT_OP_SET:
8250 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8251 (Addr)op->data,
8252 (op->width + 7) / 8 * 32 * op->charcount );
8253 break;
8254 case VKI_KD_FONT_OP_GET:
8255 if ( op->data )
8256 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8257 (Addr)op->data,
8258 (op->width + 7) / 8 * 32 * op->charcount );
8259 break;
8260 case VKI_KD_FONT_OP_SET_DEFAULT:
8261 if ( op->data )
8262 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8263 (Addr)op->data );
8264 break;
8265 case VKI_KD_FONT_OP_COPY:
8266 break;
8269 break;
8271 case VKI_VT_OPENQRY:
8272 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8273 break;
8274 case VKI_VT_GETMODE:
8275 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8276 break;
8277 case VKI_VT_SETMODE:
8278 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8279 break;
8280 case VKI_VT_GETSTATE:
8281 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8282 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8283 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8284 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8285 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8286 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8287 break;
8288 case VKI_VT_RELDISP:
8289 case VKI_VT_ACTIVATE:
8290 case VKI_VT_WAITACTIVE:
8291 case VKI_VT_DISALLOCATE:
8292 break;
8293 case VKI_VT_RESIZE:
8294 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8295 break;
8296 case VKI_VT_RESIZEX:
8297 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8298 break;
8299 case VKI_VT_LOCKSWITCH:
8300 case VKI_VT_UNLOCKSWITCH:
8301 break;
8303 case VKI_USBDEVFS_CONTROL:
8304 if ( ARG3 ) {
8305 struct vki_usbdevfs_ctrltransfer *vkuc =
8306 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8307 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8308 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8309 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8310 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8311 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8312 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8313 if (vkuc->bRequestType & 0x80)
8314 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8315 else
8316 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8318 break;
8319 case VKI_USBDEVFS_BULK:
8320 if ( ARG3 ) {
8321 struct vki_usbdevfs_bulktransfer *vkub =
8322 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8323 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8324 if (vkub->ep & 0x80)
8325 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8326 else
8327 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8329 break;
8330 case VKI_USBDEVFS_GETDRIVER:
8331 if ( ARG3 ) {
8332 struct vki_usbdevfs_getdriver *vkugd =
8333 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8334 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8336 break;
8337 case VKI_USBDEVFS_SUBMITURB:
8338 if ( ARG3 ) {
8339 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8341 /* Not the whole struct needs to be initialized */
8342 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8343 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8344 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8345 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8346 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8347 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8348 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8349 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8350 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8351 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8352 if (vkusp->bRequestType & 0x80)
8353 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8354 else
8355 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8356 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8357 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8358 int total_length = 0;
8359 int i;
8360 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8361 for(i=0; i<vkuu->number_of_packets; i++) {
8362 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8363 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));
8364 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8365 total_length += vkuu->iso_frame_desc[i].length;
8367 if (vkuu->endpoint & 0x80)
8368 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8369 else
8370 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8371 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8372 } else {
8373 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8374 if (vkuu->endpoint & 0x80)
8375 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8376 else
8377 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8378 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8381 break;
8382 case VKI_USBDEVFS_DISCARDURB:
8383 break;
8384 case VKI_USBDEVFS_REAPURB:
8385 if ( ARG3 ) {
8386 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8388 break;
8389 case VKI_USBDEVFS_REAPURBNDELAY:
8390 if ( ARG3 ) {
8391 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8393 break;
8394 case VKI_USBDEVFS_CONNECTINFO:
8395 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8396 break;
8397 case VKI_USBDEVFS_IOCTL:
8398 if ( ARG3 ) {
8399 struct vki_usbdevfs_ioctl *vkui =
8400 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8401 UInt dir2, size2;
8402 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8403 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8404 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8405 if (size2 > 0) {
8406 if (dir2 & _VKI_IOC_WRITE)
8407 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8408 else if (dir2 & _VKI_IOC_READ)
8409 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8412 break;
8413 case VKI_USBDEVFS_RESET:
8414 break;
8416 /* I2C (/dev/i2c-*) ioctls */
8417 case VKI_I2C_SLAVE:
8418 case VKI_I2C_SLAVE_FORCE:
8419 case VKI_I2C_TENBIT:
8420 case VKI_I2C_PEC:
8421 break;
8422 case VKI_I2C_FUNCS:
8423 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8424 break;
8425 case VKI_I2C_RDWR:
8426 if ( ARG3 ) {
8427 struct vki_i2c_rdwr_ioctl_data *vkui =
8428 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8429 UInt i;
8430 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8431 for (i=0; i < vkui->nmsgs; i++) {
8432 struct vki_i2c_msg *msg = vkui->msgs + i;
8433 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8434 if (msg->flags & VKI_I2C_M_RD)
8435 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8436 else
8437 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8440 break;
8441 case VKI_I2C_SMBUS:
8442 if ( ARG3 ) {
8443 struct vki_i2c_smbus_ioctl_data *vkis
8444 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8445 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8446 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8447 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8448 (Addr)&vkis->size, sizeof(vkis->size));
8449 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8450 (Addr)&vkis->command, sizeof(vkis->command));
8451 /* i2c_smbus_write_quick hides its value in read_write, so
8452 this variable can have a different meaning */
8453 /* to make matters worse i2c_smbus_write_byte stores its
8454 value in command */
8455 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8456 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8457 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8458 /* the rest uses the byte array to store the data,
8459 some the first byte for size */
8460 UInt size;
8461 switch(vkis->size) {
8462 case VKI_I2C_SMBUS_BYTE_DATA:
8463 size = 1;
8464 break;
8465 case VKI_I2C_SMBUS_WORD_DATA:
8466 case VKI_I2C_SMBUS_PROC_CALL:
8467 size = 2;
8468 break;
8469 case VKI_I2C_SMBUS_BLOCK_DATA:
8470 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8471 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8472 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8473 size = 1 + vkis->data->block[0];
8474 break;
8475 default:
8476 size = 0;
8479 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8480 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8481 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8482 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8483 ".i2c_smbus_ioctl_data.data",
8484 (Addr)&vkis->data->block[0], size);
8485 else
8486 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8487 "i2c_smbus_ioctl_data.data",
8488 (Addr)&vkis->data->block[0], size);
8491 break;
8493 /* Wireless extensions ioctls */
8494 case VKI_SIOCSIWCOMMIT:
8495 case VKI_SIOCSIWNWID:
8496 case VKI_SIOCSIWFREQ:
8497 case VKI_SIOCSIWMODE:
8498 case VKI_SIOCSIWSENS:
8499 case VKI_SIOCSIWRANGE:
8500 case VKI_SIOCSIWPRIV:
8501 case VKI_SIOCSIWSTATS:
8502 case VKI_SIOCSIWSPY:
8503 case VKI_SIOCSIWTHRSPY:
8504 case VKI_SIOCSIWAP:
8505 case VKI_SIOCSIWSCAN:
8506 case VKI_SIOCSIWESSID:
8507 case VKI_SIOCSIWRATE:
8508 case VKI_SIOCSIWNICKN:
8509 case VKI_SIOCSIWRTS:
8510 case VKI_SIOCSIWFRAG:
8511 case VKI_SIOCSIWTXPOW:
8512 case VKI_SIOCSIWRETRY:
8513 case VKI_SIOCSIWENCODE:
8514 case VKI_SIOCSIWPOWER:
8515 case VKI_SIOCSIWGENIE:
8516 case VKI_SIOCSIWMLME:
8517 case VKI_SIOCSIWAUTH:
8518 case VKI_SIOCSIWENCODEEXT:
8519 case VKI_SIOCSIWPMKSA:
8520 break;
8521 case VKI_SIOCGIWNAME:
8522 if (ARG3) {
8523 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8524 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8525 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8527 break;
8528 case VKI_SIOCGIWNWID:
8529 case VKI_SIOCGIWSENS:
8530 case VKI_SIOCGIWRATE:
8531 case VKI_SIOCGIWRTS:
8532 case VKI_SIOCGIWFRAG:
8533 case VKI_SIOCGIWTXPOW:
8534 case VKI_SIOCGIWRETRY:
8535 case VKI_SIOCGIWPOWER:
8536 case VKI_SIOCGIWAUTH:
8537 if (ARG3) {
8538 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8539 "RETRY|PARAM|AUTH])",
8540 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8541 sizeof(struct vki_iw_param));
8543 break;
8544 case VKI_SIOCGIWFREQ:
8545 if (ARG3) {
8546 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8547 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8548 sizeof(struct vki_iw_freq));
8550 break;
8551 case VKI_SIOCGIWMODE:
8552 if (ARG3) {
8553 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8554 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8555 sizeof(__vki_u32));
8557 break;
8558 case VKI_SIOCGIWRANGE:
8559 case VKI_SIOCGIWPRIV:
8560 case VKI_SIOCGIWSTATS:
8561 case VKI_SIOCGIWSPY:
8562 case VKI_SIOCGIWTHRSPY:
8563 case VKI_SIOCGIWAPLIST:
8564 case VKI_SIOCGIWSCAN:
8565 case VKI_SIOCGIWESSID:
8566 case VKI_SIOCGIWNICKN:
8567 case VKI_SIOCGIWENCODE:
8568 case VKI_SIOCGIWGENIE:
8569 case VKI_SIOCGIWENCODEEXT:
8570 if (ARG3) {
8571 struct vki_iw_point* point;
8572 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8573 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8574 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8575 (Addr)point->pointer, point->length);
8577 break;
8578 case VKI_SIOCGIWAP:
8579 if (ARG3) {
8580 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8581 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8582 sizeof(struct vki_sockaddr));
8584 break;
8586 /* User input device creation */
8587 case VKI_UI_SET_EVBIT:
8588 case VKI_UI_SET_KEYBIT:
8589 case VKI_UI_SET_RELBIT:
8590 case VKI_UI_SET_ABSBIT:
8591 case VKI_UI_SET_MSCBIT:
8592 case VKI_UI_SET_LEDBIT:
8593 case VKI_UI_SET_SNDBIT:
8594 case VKI_UI_SET_FFBIT:
8595 case VKI_UI_SET_SWBIT:
8596 case VKI_UI_SET_PROPBIT:
8597 /* These just take an int by value */
8598 break;
8600 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8601 || defined(VGPV_mips32_linux_android) \
8602 || defined(VGPV_arm64_linux_android)
8603 /* ashmem */
8604 case VKI_ASHMEM_GET_SIZE:
8605 case VKI_ASHMEM_SET_SIZE:
8606 case VKI_ASHMEM_GET_PROT_MASK:
8607 case VKI_ASHMEM_SET_PROT_MASK:
8608 case VKI_ASHMEM_GET_PIN_STATUS:
8609 case VKI_ASHMEM_PURGE_ALL_CACHES:
8610 break;
8611 case VKI_ASHMEM_GET_NAME:
8612 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8613 break;
8614 case VKI_ASHMEM_SET_NAME:
8615 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8616 break;
8617 case VKI_ASHMEM_PIN:
8618 case VKI_ASHMEM_UNPIN:
8619 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8620 ARG3, sizeof(struct vki_ashmem_pin) );
8621 break;
8623 /* binder */
8624 case VKI_BINDER_WRITE_READ:
8625 if (ARG3) {
8626 struct vki_binder_write_read* bwr
8627 = (struct vki_binder_write_read*)(Addr)ARG3;
8629 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8630 bwr->write_buffer);
8631 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8632 bwr->write_size);
8633 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8634 bwr->write_consumed);
8635 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8636 bwr->read_buffer);
8637 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8638 bwr->read_size);
8639 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8640 bwr->read_consumed);
8642 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8643 bwr->write_consumed);
8644 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8645 bwr->read_consumed);
8647 if (bwr->read_size)
8648 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8649 (Addr)bwr->read_buffer, bwr->read_size);
8650 if (bwr->write_size)
8651 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8652 (Addr)bwr->write_buffer, bwr->write_size);
8654 break;
8656 case VKI_BINDER_SET_IDLE_TIMEOUT:
8657 case VKI_BINDER_SET_MAX_THREADS:
8658 case VKI_BINDER_SET_IDLE_PRIORITY:
8659 case VKI_BINDER_SET_CONTEXT_MGR:
8660 case VKI_BINDER_THREAD_EXIT:
8661 break;
8662 case VKI_BINDER_VERSION:
8663 if (ARG3) {
8664 struct vki_binder_version* bv =
8665 (struct vki_binder_version*)(Addr)ARG3;
8666 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8668 break;
8669 # endif /* defined(VGPV_*_linux_android) */
8671 case VKI_HCIGETDEVLIST:
8672 if (ARG3) {
8673 struct vki_hci_dev_list_req* dlr =
8674 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8675 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8676 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8677 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8678 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8679 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8681 break;
8683 case VKI_HCIINQUIRY:
8684 if (ARG3) {
8685 struct vki_hci_inquiry_req* ir =
8686 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8687 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8688 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8689 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8690 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8691 ir->num_rsp * sizeof(struct vki_inquiry_info));
8693 break;
8695 case VKI_DRM_IOCTL_VERSION:
8696 if (ARG3) {
8697 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8698 struct vg_drm_version_info* info;
8699 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8700 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8701 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8702 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8703 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8704 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8705 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8706 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8707 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8708 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8709 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8710 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8711 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8712 // To ensure we VG_(free) info even when syscall fails:
8713 *flags |= SfPostOnFail;
8714 info->data = *data;
8715 info->orig = data;
8716 ARG3 = (Addr)&info->data;
8718 break;
8719 case VKI_DRM_IOCTL_GET_UNIQUE:
8720 if (ARG3) {
8721 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8722 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8723 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8724 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8726 break;
8727 case VKI_DRM_IOCTL_GET_MAGIC:
8728 if (ARG3) {
8729 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8730 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8732 break;
8733 case VKI_DRM_IOCTL_WAIT_VBLANK:
8734 if (ARG3) {
8735 union vki_drm_wait_vblank *data =
8736 (union vki_drm_wait_vblank *)(Addr)ARG3;
8737 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8738 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8739 /* XXX: It seems request.signal isn't used */
8740 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8742 break;
8743 case VKI_DRM_IOCTL_GEM_CLOSE:
8744 if (ARG3) {
8745 struct vki_drm_gem_close *data =
8746 (struct vki_drm_gem_close *)(Addr)ARG3;
8747 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8749 break;
8750 case VKI_DRM_IOCTL_GEM_FLINK:
8751 if (ARG3) {
8752 struct vki_drm_gem_flink *data =
8753 (struct vki_drm_gem_flink *)(Addr)ARG3;
8754 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8755 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8757 break;
8758 case VKI_DRM_IOCTL_GEM_OPEN:
8759 if (ARG3) {
8760 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8761 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8762 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8763 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8765 break;
8766 case VKI_DRM_IOCTL_I915_GETPARAM:
8767 if (ARG3) {
8768 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8769 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8770 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8772 break;
8773 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8774 if (ARG3) {
8775 struct vki_drm_i915_gem_busy *data =
8776 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8777 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8778 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8780 break;
8781 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8782 if (ARG3) {
8783 struct vki_drm_i915_gem_create *data =
8784 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8785 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8786 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8788 break;
8789 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8790 if (ARG3) {
8791 struct vki_drm_i915_gem_pread *data =
8792 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8793 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8794 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8795 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8796 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8797 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8799 break;
8800 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8801 if (ARG3) {
8802 struct vki_drm_i915_gem_pwrite *data =
8803 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8804 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8805 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8806 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8807 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8808 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8809 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8810 * interleaved vertex attributes may have a wide stride with uninitialized data between
8811 * consecutive vertices) */
8813 break;
8814 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8815 if (ARG3) {
8816 struct vki_drm_i915_gem_mmap_v1 *data =
8817 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8818 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8819 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8820 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8821 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8823 break;
8824 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8825 if (ARG3) {
8826 struct vki_drm_i915_gem_mmap *data =
8827 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8828 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8829 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8830 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8831 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8832 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8834 break;
8835 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8836 if (ARG3) {
8837 struct vki_drm_i915_gem_mmap_gtt *data =
8838 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8839 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8840 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8842 break;
8843 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8844 if (ARG3) {
8845 struct vki_drm_i915_gem_set_domain *data =
8846 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8847 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8848 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8849 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8851 break;
8852 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8853 if (ARG3) {
8854 struct vki_drm_i915_gem_set_tiling *data =
8855 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8856 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8857 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8858 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8859 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8861 break;
8862 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8863 if (ARG3) {
8864 struct vki_drm_i915_gem_get_tiling *data =
8865 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8866 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8867 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8868 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8870 break;
8871 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8872 if (ARG3) {
8873 struct vki_drm_i915_gem_get_aperture *data =
8874 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8875 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8876 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8878 break;
8880 /* KVM ioctls that check for a numeric value as parameter */
8881 case VKI_KVM_GET_API_VERSION:
8882 case VKI_KVM_CREATE_VM:
8883 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8884 case VKI_KVM_CHECK_EXTENSION:
8885 case VKI_KVM_SET_TSS_ADDR:
8886 case VKI_KVM_CREATE_VCPU:
8887 case VKI_KVM_RUN:
8888 break;
8890 case VKI_KVM_S390_MEM_OP: {
8891 struct vki_kvm_s390_mem_op *args =
8892 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8893 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8894 sizeof(struct vki_kvm_s390_mem_op));
8895 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8896 break;
8897 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8898 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8899 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8900 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8902 break;
8905 #ifdef ENABLE_XEN
8906 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8907 SyscallArgs harrghs;
8908 struct vki_xen_privcmd_hypercall *args =
8909 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8911 if (!args)
8912 break;
8914 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8915 harrghs.sysno = args->op;
8916 harrghs.arg1 = args->arg[0];
8917 harrghs.arg2 = args->arg[1];
8918 harrghs.arg3 = args->arg[2];
8919 harrghs.arg4 = args->arg[3];
8920 harrghs.arg5 = args->arg[4];
8921 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8923 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8925 /* HACK. arg8 is used to return the number of hypercall
8926 * arguments actually consumed! */
8927 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8928 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8930 break;
8933 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8934 struct vki_xen_privcmd_mmap *args =
8935 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8936 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8937 (Addr)&args->num, sizeof(args->num));
8938 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8939 (Addr)&args->dom, sizeof(args->dom));
8940 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8941 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8942 break;
8944 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8945 struct vki_xen_privcmd_mmapbatch *args =
8946 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8947 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8948 (Addr)&args->num, sizeof(args->num));
8949 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8950 (Addr)&args->dom, sizeof(args->dom));
8951 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8952 (Addr)&args->addr, sizeof(args->addr));
8953 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8954 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8955 break;
8957 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8958 struct vki_xen_privcmd_mmapbatch_v2 *args =
8959 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8960 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8961 (Addr)&args->num, sizeof(args->num));
8962 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8963 (Addr)&args->dom, sizeof(args->dom));
8964 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8965 (Addr)&args->addr, sizeof(args->addr));
8966 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8967 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8968 break;
8971 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8972 struct vki_xen_ioctl_evtchn_bind_virq *args =
8973 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8974 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8975 (Addr)&args->virq, sizeof(args->virq));
8977 break;
8978 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8979 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8980 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8981 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8982 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8983 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8984 (Addr)&args->remote_port, sizeof(args->remote_port));
8986 break;
8987 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8988 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8989 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8990 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8991 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8993 break;
8994 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8995 struct vki_xen_ioctl_evtchn_unbind *args =
8996 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8997 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8998 (Addr)&args->port, sizeof(args->port));
9000 break;
9001 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9002 struct vki_xen_ioctl_evtchn_notify *args =
9003 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9004 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9005 (Addr)&args->port, sizeof(args->port));
9007 break;
9008 case VKI_XEN_IOCTL_EVTCHN_RESET:
9009 /* No input*/
9010 break;
9011 #endif
9013 /* Lustre */
9014 case VKI_OBD_IOC_FID2PATH: {
9015 struct vki_getinfo_fid2path *gf =
9016 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9017 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9018 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9019 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9020 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9021 break;
9024 case VKI_LL_IOC_PATH2FID:
9025 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9026 break;
9028 case VKI_LL_IOC_GETPARENT: {
9029 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9030 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9031 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9032 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9033 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9034 break;
9037 /* V4L2 */
9038 case VKI_V4L2_QUERYCAP: {
9039 struct vki_v4l2_capability *data =
9040 (struct vki_v4l2_capability *)(Addr)ARG3;
9041 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9042 break;
9044 case VKI_V4L2_ENUM_FMT: {
9045 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9046 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9047 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9048 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9049 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9050 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9051 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9052 break;
9054 case VKI_V4L2_G_FMT: {
9055 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9056 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9057 switch (data->type) {
9058 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9059 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9060 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9061 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9062 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9063 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9064 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9065 break;
9066 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9067 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9068 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9069 break;
9070 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9071 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9072 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9073 break;
9074 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9075 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9076 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9077 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9078 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9079 if (data->fmt.win.clipcount && data->fmt.win.clips)
9080 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9081 (Addr)data->fmt.win.clips,
9082 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9083 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9084 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9085 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9086 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9087 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9088 break;
9089 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9090 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9091 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9092 break;
9093 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9094 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9095 break;
9097 break;
9099 case VKI_V4L2_S_FMT: {
9100 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9101 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9102 switch (data->type) {
9103 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9104 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9105 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9106 (Addr)&data->type + sizeof(data->type),
9107 sizeof(*data) - sizeof(data->type));
9108 break;
9109 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9110 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9111 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9112 break;
9113 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9114 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9115 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9116 break;
9117 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9118 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9119 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9120 if (data->fmt.win.clipcount && data->fmt.win.clips)
9121 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9122 (Addr)data->fmt.win.clips,
9123 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9124 if (data->fmt.win.bitmap)
9125 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9126 (Addr)data->fmt.win.bitmap,
9127 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9128 break;
9129 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9130 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9131 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9132 break;
9133 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9134 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9135 break;
9137 break;
9139 case VKI_V4L2_TRY_FMT: {
9140 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9141 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9142 switch (data->type) {
9143 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9144 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9145 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9146 (Addr)&data->type + sizeof(data->type),
9147 sizeof(*data) - sizeof(data->type));
9148 break;
9149 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9150 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9151 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9152 break;
9153 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9154 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9155 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9156 break;
9157 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9158 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9159 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9160 if (data->fmt.win.clipcount && data->fmt.win.clips)
9161 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9162 (Addr)data->fmt.win.clips,
9163 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9164 if (data->fmt.win.bitmap)
9165 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9166 (Addr)data->fmt.win.bitmap,
9167 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9168 break;
9169 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9170 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9171 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9172 break;
9173 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9174 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9175 break;
9177 break;
9179 case VKI_V4L2_REQBUFS: {
9180 struct vki_v4l2_requestbuffers *data =
9181 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9182 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9183 break;
9185 case VKI_V4L2_QUERYBUF: {
9186 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9187 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9188 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9189 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9190 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9191 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9192 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9193 unsigned i;
9195 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9196 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9197 for (i = 0; i < data->length; i++) {
9198 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9199 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9200 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9201 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9202 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9204 } else {
9205 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9206 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9208 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9209 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9210 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9211 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9212 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9213 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9214 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9215 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9216 break;
9218 case VKI_V4L2_G_FBUF: {
9219 struct vki_v4l2_framebuffer *data =
9220 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9221 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9222 break;
9224 case VKI_V4L2_S_FBUF: {
9225 struct vki_v4l2_framebuffer *data =
9226 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9227 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9228 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9229 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9231 break;
9233 case VKI_V4L2_OVERLAY: {
9234 int *data = (int *)(Addr)ARG3;
9235 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9236 break;
9238 case VKI_V4L2_QBUF: {
9239 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9240 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9241 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9242 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9243 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9245 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9246 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9247 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9248 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9249 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9250 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9251 if (is_output) {
9252 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9253 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9255 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9256 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9257 unsigned i;
9259 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9260 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9261 for (i = 0; i < data->length; i++) {
9262 if (is_output) {
9263 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9264 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9266 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9267 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9268 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9269 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9270 else
9271 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9272 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9274 } else {
9275 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9276 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9277 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9278 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9279 else
9280 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9281 if (is_output) {
9282 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9283 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9286 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9287 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9288 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9290 break;
9292 case VKI_V4L2_EXPBUF: {
9293 struct vki_v4l2_exportbuffer *data =
9294 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9295 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9296 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9297 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9298 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9299 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9300 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9301 break;
9303 case VKI_V4L2_DQBUF: {
9304 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9305 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9306 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9307 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9308 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9309 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9310 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9311 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9312 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9313 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9314 unsigned i;
9316 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9317 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9318 for (i = 0; i < data->length; i++) {
9319 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9320 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9321 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9322 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9323 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9325 } else {
9326 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9327 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9328 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9329 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9331 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9332 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9333 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9334 break;
9336 case VKI_V4L2_STREAMON: {
9337 int *data = (int *)(Addr)ARG3;
9338 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9339 break;
9341 case VKI_V4L2_STREAMOFF: {
9342 int *data = (int *)(Addr)ARG3;
9343 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9344 break;
9346 case VKI_V4L2_G_PARM: {
9347 struct vki_v4l2_streamparm *data =
9348 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9349 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9350 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9351 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9352 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9354 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9355 if (is_output) {
9356 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9357 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9358 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9359 } else {
9360 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9361 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9362 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9364 break;
9366 case VKI_V4L2_S_PARM: {
9367 struct vki_v4l2_streamparm *data =
9368 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9369 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9370 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9371 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9372 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9374 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9375 if (is_output)
9376 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9377 else
9378 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9379 break;
9381 case VKI_V4L2_G_STD: {
9382 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9383 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9384 break;
9386 case VKI_V4L2_S_STD: {
9387 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9388 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9389 break;
9391 case VKI_V4L2_ENUMSTD: {
9392 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9393 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9394 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9395 break;
9397 case VKI_V4L2_ENUMINPUT: {
9398 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9399 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9400 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9401 break;
9403 case VKI_V4L2_G_CTRL: {
9404 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9405 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9406 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9407 break;
9409 case VKI_V4L2_S_CTRL: {
9410 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9411 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9412 break;
9414 case VKI_V4L2_G_TUNER: {
9415 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9416 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9417 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9418 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9419 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9420 break;
9422 case VKI_V4L2_S_TUNER: {
9423 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9424 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9425 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9426 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9427 break;
9429 case VKI_V4L2_G_AUDIO: {
9430 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9431 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9432 sizeof(*data) - sizeof(data->reserved));
9433 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9434 break;
9436 case VKI_V4L2_S_AUDIO: {
9437 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9438 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9439 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9440 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9441 break;
9443 case VKI_V4L2_QUERYCTRL: {
9444 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9445 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9446 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9447 sizeof(*data) - sizeof(data->id));
9448 break;
9450 case VKI_V4L2_QUERYMENU: {
9451 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9452 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9453 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9454 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9455 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9456 break;
9458 case VKI_V4L2_G_INPUT: {
9459 int *data = (int *)(Addr)ARG3;
9460 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9461 break;
9463 case VKI_V4L2_S_INPUT: {
9464 int *data = (int *)(Addr)ARG3;
9465 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9466 break;
9468 case VKI_V4L2_G_EDID: {
9469 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9470 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9471 if (data->blocks && data->edid)
9472 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9473 break;
9475 case VKI_V4L2_S_EDID: {
9476 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9477 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9478 if (data->blocks && data->edid)
9479 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9480 break;
9482 case VKI_V4L2_G_OUTPUT: {
9483 int *data = (int *)(Addr)ARG3;
9484 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9485 break;
9487 case VKI_V4L2_S_OUTPUT: {
9488 int *data = (int *)(Addr)ARG3;
9489 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9490 break;
9492 case VKI_V4L2_ENUMOUTPUT: {
9493 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9494 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9495 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9496 break;
9498 case VKI_V4L2_G_AUDOUT: {
9499 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9500 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9501 sizeof(*data) - sizeof(data->reserved));
9502 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9503 break;
9505 case VKI_V4L2_S_AUDOUT: {
9506 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9507 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9508 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9509 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9510 break;
9512 case VKI_V4L2_G_MODULATOR: {
9513 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9514 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9515 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9516 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9517 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9518 break;
9520 case VKI_V4L2_S_MODULATOR: {
9521 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9522 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9523 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9524 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9525 break;
9527 case VKI_V4L2_G_FREQUENCY: {
9528 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9529 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9530 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9531 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9532 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9533 break;
9535 case VKI_V4L2_S_FREQUENCY: {
9536 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9537 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9538 break;
9540 case VKI_V4L2_CROPCAP: {
9541 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9542 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9543 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9544 break;
9546 case VKI_V4L2_G_CROP: {
9547 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9548 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9549 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9550 break;
9552 case VKI_V4L2_S_CROP: {
9553 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9554 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9555 break;
9557 case VKI_V4L2_G_JPEGCOMP: {
9558 struct vki_v4l2_jpegcompression *data =
9559 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9560 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9561 break;
9563 case VKI_V4L2_S_JPEGCOMP: {
9564 struct vki_v4l2_jpegcompression *data =
9565 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9566 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9567 break;
9569 case VKI_V4L2_QUERYSTD: {
9570 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9571 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9572 break;
9574 case VKI_V4L2_ENUMAUDIO: {
9575 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9576 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9577 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9578 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9579 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9580 break;
9582 case VKI_V4L2_ENUMAUDOUT: {
9583 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9584 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9585 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9586 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9587 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9588 break;
9590 case VKI_V4L2_G_PRIORITY: {
9591 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9592 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9593 break;
9595 case VKI_V4L2_S_PRIORITY: {
9596 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9597 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9598 break;
9600 case VKI_V4L2_G_SLICED_VBI_CAP: {
9601 struct vki_v4l2_sliced_vbi_cap *data =
9602 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9603 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9604 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9605 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9606 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9607 break;
9609 case VKI_V4L2_G_EXT_CTRLS: {
9610 struct vki_v4l2_ext_controls *data =
9611 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9612 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9613 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9614 if (data->count) {
9615 unsigned i;
9617 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9618 for (i = 0; i < data->count; i++) {
9619 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9620 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9621 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9622 if (data->controls[i].size) {
9623 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9624 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9625 (Addr)data->controls[i].ptr, data->controls[i].size);
9626 } else {
9627 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9628 data->controls[i].value64);
9632 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9633 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9634 break;
9636 case VKI_V4L2_S_EXT_CTRLS: {
9637 struct vki_v4l2_ext_controls *data =
9638 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9639 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9640 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9641 if (data->count) {
9642 unsigned i;
9644 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9645 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9646 data->count * sizeof(data->controls[0]));
9647 for (i = 0; i < data->count; i++) {
9648 if (data->controls[i].size) {
9649 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9650 (Addr)data->controls[i].ptr, data->controls[i].size);
9654 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9655 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9656 break;
9658 case VKI_V4L2_TRY_EXT_CTRLS: {
9659 struct vki_v4l2_ext_controls *data =
9660 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9661 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9662 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9663 if (data->count) {
9664 unsigned i;
9666 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9667 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9668 data->count * sizeof(data->controls[0]));
9669 for (i = 0; i < data->count; i++) {
9670 if (data->controls[i].size) {
9671 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9672 (Addr)data->controls[i].ptr, data->controls[i].size);
9676 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9677 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9678 break;
9680 case VKI_V4L2_ENUM_FRAMESIZES: {
9681 struct vki_v4l2_frmsizeenum *data =
9682 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9683 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9684 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9685 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9686 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9687 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9688 break;
9690 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9691 struct vki_v4l2_frmivalenum *data =
9692 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9693 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9694 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9695 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9696 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9697 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9698 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9699 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9700 break;
9702 case VKI_V4L2_G_ENC_INDEX: {
9703 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9704 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9705 break;
9707 case VKI_V4L2_ENCODER_CMD: {
9708 struct vki_v4l2_encoder_cmd *data =
9709 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9710 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9711 break;
9713 case VKI_V4L2_TRY_ENCODER_CMD: {
9714 struct vki_v4l2_encoder_cmd *data =
9715 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9716 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9717 break;
9719 case VKI_V4L2_DBG_S_REGISTER: {
9720 struct vki_v4l2_dbg_register *data =
9721 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9722 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9723 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9724 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9725 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9726 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9727 break;
9729 case VKI_V4L2_DBG_G_REGISTER: {
9730 struct vki_v4l2_dbg_register *data =
9731 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9732 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9733 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9734 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9735 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9736 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9737 break;
9739 case VKI_V4L2_S_HW_FREQ_SEEK: {
9740 struct vki_v4l2_hw_freq_seek *data =
9741 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9742 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9743 break;
9745 case VKI_V4L2_S_DV_TIMINGS: {
9746 struct vki_v4l2_dv_timings *data =
9747 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9748 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9749 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9750 break;
9752 case VKI_V4L2_G_DV_TIMINGS: {
9753 struct vki_v4l2_dv_timings *data =
9754 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9755 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9756 break;
9758 case VKI_V4L2_DQEVENT: {
9759 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9760 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9761 break;
9763 case VKI_V4L2_SUBSCRIBE_EVENT: {
9764 struct vki_v4l2_event_subscription *data =
9765 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9766 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9767 break;
9769 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9770 struct vki_v4l2_event_subscription *data =
9771 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9772 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9773 break;
9775 case VKI_V4L2_CREATE_BUFS: {
9776 struct vki_v4l2_create_buffers *data =
9777 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9778 struct vki_v4l2_format *fmt = &data->format;
9779 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9780 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9781 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9782 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9783 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9784 switch (fmt->type) {
9785 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9786 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9787 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9788 break;
9789 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9790 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9791 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9792 break;
9793 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9794 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9795 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9796 break;
9797 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9798 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9799 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9800 break;
9801 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9802 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9803 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9804 break;
9805 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9806 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9807 break;
9809 break;
9811 case VKI_V4L2_PREPARE_BUF: {
9812 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9813 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9814 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9815 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9816 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9817 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9818 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9819 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9820 unsigned i;
9822 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9823 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9824 for (i = 0; i < data->length; i++) {
9825 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9828 break;
9830 case VKI_V4L2_G_SELECTION: {
9831 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9832 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9833 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9834 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9835 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9836 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9837 break;
9839 case VKI_V4L2_S_SELECTION: {
9840 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9841 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9842 break;
9844 case VKI_V4L2_DECODER_CMD: {
9845 struct vki_v4l2_decoder_cmd *data =
9846 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9847 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9848 break;
9850 case VKI_V4L2_TRY_DECODER_CMD: {
9851 struct vki_v4l2_decoder_cmd *data =
9852 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9853 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9854 break;
9856 case VKI_V4L2_ENUM_DV_TIMINGS: {
9857 struct vki_v4l2_enum_dv_timings *data =
9858 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9859 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9860 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9861 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9862 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9863 break;
9865 case VKI_V4L2_QUERY_DV_TIMINGS: {
9866 struct vki_v4l2_dv_timings *data =
9867 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9868 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9869 break;
9871 case VKI_V4L2_DV_TIMINGS_CAP: {
9872 struct vki_v4l2_dv_timings_cap *data =
9873 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9874 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9875 break;
9877 case VKI_V4L2_ENUM_FREQ_BANDS: {
9878 struct vki_v4l2_frequency_band *data =
9879 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9880 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9881 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9882 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9883 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9884 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9885 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9886 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9887 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9888 break;
9890 case VKI_V4L2_DBG_G_CHIP_INFO: {
9891 struct vki_v4l2_dbg_chip_info *data =
9892 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9893 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9894 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9895 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9896 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9897 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9898 break;
9900 case VKI_V4L2_QUERY_EXT_CTRL: {
9901 struct vki_v4l2_query_ext_ctrl *data =
9902 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9903 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9904 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9905 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9906 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9907 break;
9909 case VKI_V4L2_SUBDEV_G_FMT: {
9910 struct vki_v4l2_subdev_format *data =
9911 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9912 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9913 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9914 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9915 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9916 break;
9918 case VKI_V4L2_SUBDEV_S_FMT: {
9919 struct vki_v4l2_subdev_format *data =
9920 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9921 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9922 break;
9924 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9925 struct vki_v4l2_subdev_frame_interval *data =
9926 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9927 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9928 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9929 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9930 break;
9932 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9933 struct vki_v4l2_subdev_frame_interval *data =
9934 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9935 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9936 break;
9938 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9939 struct vki_v4l2_subdev_mbus_code_enum *data =
9940 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9941 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9942 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9943 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9944 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9945 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9946 break;
9948 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9949 struct vki_v4l2_subdev_frame_size_enum *data =
9950 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9951 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9952 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9953 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9954 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9955 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9956 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9957 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9958 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9959 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9960 break;
9962 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9963 struct vki_v4l2_subdev_frame_interval_enum *data =
9964 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9965 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9966 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9967 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9968 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9969 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9970 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9971 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9972 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9973 break;
9975 case VKI_V4L2_SUBDEV_G_CROP: {
9976 struct vki_v4l2_subdev_crop *data =
9977 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9978 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9979 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9980 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9981 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9982 break;
9984 case VKI_V4L2_SUBDEV_S_CROP: {
9985 struct vki_v4l2_subdev_crop *data =
9986 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9987 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9988 break;
9990 case VKI_V4L2_SUBDEV_G_SELECTION: {
9991 struct vki_v4l2_subdev_selection *data =
9992 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9993 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9994 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9995 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9996 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9997 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9998 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9999 break;
10001 case VKI_V4L2_SUBDEV_S_SELECTION: {
10002 struct vki_v4l2_subdev_selection *data =
10003 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10004 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10005 break;
10007 case VKI_MEDIA_IOC_DEVICE_INFO: {
10008 struct vki_media_device_info *data =
10009 (struct vki_media_device_info *)(Addr)ARG3;
10010 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10011 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10012 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10013 break;
10015 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10016 struct vki_media_entity_desc *data =
10017 (struct vki_media_entity_desc *)(Addr)ARG3;
10018 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10019 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10020 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10021 break;
10023 case VKI_MEDIA_IOC_ENUM_LINKS: {
10024 struct vki_media_links_enum *data =
10025 (struct vki_media_links_enum *)(Addr)ARG3;
10026 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10027 break;
10029 case VKI_MEDIA_IOC_SETUP_LINK: {
10030 struct vki_media_link_desc *data =
10031 (struct vki_media_link_desc *)(Addr)ARG3;
10032 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10033 break;
10036 /* Serial */
10037 case VKI_TIOCGSERIAL: {
10038 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10039 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10040 break;
10042 case VKI_TIOCSSERIAL: {
10043 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10044 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10045 break;
10048 case VKI_PERF_EVENT_IOC_RESET:
10049 case VKI_PERF_EVENT_IOC_REFRESH:
10050 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10051 case VKI_PERF_EVENT_IOC_SET_BPF:
10052 /* These take scalar arguments, so already handled above */
10053 break;
10055 case VKI_PERF_EVENT_IOC_PERIOD:
10056 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10057 break;
10059 case VKI_PERF_EVENT_IOC_SET_FILTER:
10060 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10061 break;
10063 case VKI_PERF_EVENT_IOC_ID:
10064 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10065 break;
10067 /* Pulse Per Second (PPS) */
10068 case VKI_PPS_GETPARAMS: {
10069 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10070 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10071 break;
10073 case VKI_PPS_SETPARAMS: {
10074 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10075 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10076 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10077 data->assert_off_tu.sec);
10078 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10079 data->assert_off_tu.nsec);
10080 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10081 data->clear_off_tu.sec);
10082 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10083 data->clear_off_tu.nsec);
10084 break;
10086 case VKI_PPS_GETCAP:
10087 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10088 break;
10089 case VKI_PPS_FETCH: {
10090 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10091 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10092 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10093 break;
10095 case VKI_PPS_KC_BIND: {
10096 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10097 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10098 break;
10101 /* PTP Hardware Clock */
10102 case VKI_PTP_CLOCK_GETCAPS: {
10103 struct vki_ptp_clock_caps *data =
10104 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10105 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10106 break;
10108 case VKI_PTP_EXTTS_REQUEST: {
10109 struct vki_ptp_extts_request *data =
10110 (struct vki_ptp_extts_request *)(Addr)ARG3;
10111 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10112 break;
10114 case VKI_PTP_PEROUT_REQUEST: {
10115 struct vki_ptp_perout_request *data =
10116 (struct vki_ptp_perout_request *)(Addr)ARG3;
10117 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10118 break;
10120 case VKI_PTP_ENABLE_PPS:
10121 break;
10122 case VKI_PTP_SYS_OFFSET: {
10123 struct vki_ptp_sys_offset *data =
10124 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10125 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10126 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10127 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10128 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10129 break;
10131 case VKI_PTP_PIN_GETFUNC: {
10132 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10133 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10134 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10135 break;
10137 case VKI_PTP_PIN_SETFUNC: {
10138 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10139 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10140 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10141 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10142 break;
10144 case VKI_PTP_SYS_OFFSET_PRECISE: {
10145 struct vki_ptp_sys_offset_precise *data =
10146 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10147 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10148 break;
10150 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10151 struct vki_ptp_sys_offset_extended *data =
10152 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10153 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10154 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10155 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10156 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10157 3 * data->n_samples * sizeof(data->ts[0][0]));
10158 break;
10161 default:
10162 /* EVIOC* are variable length and return size written on success */
10163 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10164 case VKI_EVIOCGNAME(0):
10165 case VKI_EVIOCGPHYS(0):
10166 case VKI_EVIOCGUNIQ(0):
10167 case VKI_EVIOCGKEY(0):
10168 case VKI_EVIOCGLED(0):
10169 case VKI_EVIOCGSND(0):
10170 case VKI_EVIOCGSW(0):
10171 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10172 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10173 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10174 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10175 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10176 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10177 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10178 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10179 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10180 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10181 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10182 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10183 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10184 break;
10185 default:
10186 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10187 break;
10189 break;
10193 POST(sys_ioctl)
10195 ARG2 = (UInt)ARG2;
10197 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10199 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10201 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10202 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10203 VG_(clo_kernel_variant))) {
10205 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10206 /* What's going on here: there appear to be a bunch of ioctls
10207 of the form 0xC01C67xx which are undocumented, and if
10208 unhandled give rise to a vast number of false positives in
10209 Memcheck.
10211 The "normal" interpretation of an ioctl of this form would
10212 be that the 3rd arg is a pointer to an area of size 0x1C
10213 (28 bytes) which is filled in by the kernel. Hence you
10214 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10215 But it doesn't.
10217 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10218 One interpretation of this is that ARG3 really does point
10219 to a 28 byte struct, but inside that are pointers to other
10220 areas also filled in by the kernel. If these happen to be
10221 allocated just back up the stack then the 256 byte paint
10222 might cover them too, somewhat indiscriminately.
10224 By printing out ARG3 and also the 28 bytes that it points
10225 at, it's possible to guess that the 7 word structure has
10226 this form
10228 0 1 2 3 4 5 6
10229 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10231 Unfortunately that doesn't seem to work for some reason,
10232 so stay with the blunt-instrument approach for the time
10233 being.
10235 if (1) {
10236 /* blunt-instrument approach */
10237 POST_MEM_WRITE(ARG3, 256);
10238 } else {
10239 /* be a bit more sophisticated */
10240 POST_MEM_WRITE(ARG3, 28);
10241 UInt* word = (UInt*)(Addr)ARG3;
10242 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10243 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10244 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10245 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10247 goto post_sys_ioctl__out;
10250 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10252 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10253 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10254 VG_(clo_kernel_variant))) {
10255 if (ARG2 == 0xC00C0902) {
10256 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10257 goto post_sys_ioctl__out;
10260 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10262 /* --- END special IOCTL handlers for specific Android hardware --- */
10264 /* --- normal handling --- */
10265 switch (ARG2 /* request */) {
10267 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10268 this is pretty poor given that there's no pre-handling to check
10269 that writable areas are addressable. */
10270 case VKI_ION_IOC_ALLOC: {
10271 struct vki_ion_allocation_data* data
10272 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10273 POST_FIELD_WRITE(data->handle);
10274 break;
10276 case VKI_ION_IOC_MAP: {
10277 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10278 POST_FIELD_WRITE(data->fd);
10279 break;
10281 case VKI_ION_IOC_FREE: // is this necessary?
10282 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10283 break;
10284 case VKI_ION_IOC_SHARE:
10285 break;
10286 case VKI_ION_IOC_IMPORT: {
10287 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10288 POST_FIELD_WRITE(data->handle);
10289 break;
10291 case VKI_ION_IOC_SYNC:
10292 break;
10293 case VKI_ION_IOC_CUSTOM: // is this necessary?
10294 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10295 break;
10297 case VKI_SYNC_IOC_MERGE: {
10298 struct vki_sync_merge_data* data =
10299 (struct vki_sync_merge_data*)(Addr)ARG3;
10300 POST_FIELD_WRITE(data->fence);
10301 break;
10304 case VKI_TCSETS:
10305 case VKI_TCSETSW:
10306 case VKI_TCSETSF:
10307 case VKI_IB_USER_MAD_ENABLE_PKEY:
10308 break;
10309 case VKI_TCGETS:
10310 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10311 break;
10312 case VKI_TCSETA:
10313 case VKI_TCSETAW:
10314 case VKI_TCSETAF:
10315 break;
10316 case VKI_TCGETA:
10317 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10318 break;
10319 case VKI_TCSBRK:
10320 case VKI_TCXONC:
10321 case VKI_TCSBRKP:
10322 case VKI_TCFLSH:
10323 case VKI_TIOCSIG:
10324 break;
10325 case VKI_TIOCGWINSZ:
10326 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10327 break;
10328 case VKI_TIOCSWINSZ:
10329 case VKI_TIOCMBIS:
10330 case VKI_TIOCMBIC:
10331 case VKI_TIOCMSET:
10332 break;
10333 case VKI_TIOCMGET:
10334 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10335 break;
10336 case VKI_TIOCLINUX:
10337 POST_MEM_WRITE( ARG3, sizeof(char *) );
10338 break;
10339 case VKI_TIOCGPGRP:
10340 /* Get process group ID for foreground processing group. */
10341 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10342 break;
10343 case VKI_TIOCSPGRP:
10344 /* Set a process group ID? */
10345 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10346 break;
10347 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10348 POST_MEM_WRITE( ARG3, sizeof(int));
10349 break;
10350 case VKI_TIOCSCTTY:
10351 break;
10352 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10353 break;
10354 case VKI_FIONBIO:
10355 break;
10356 case VKI_FIONCLEX:
10357 break;
10358 case VKI_FIOCLEX:
10359 break;
10360 case VKI_TIOCNOTTY:
10361 break;
10362 case VKI_FIOASYNC:
10363 break;
10364 case VKI_FIONREAD: /* identical to SIOCINQ */
10365 POST_MEM_WRITE( ARG3, sizeof(int) );
10366 break;
10367 case VKI_FIOQSIZE:
10368 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10369 break;
10371 case VKI_TIOCSERGETLSR:
10372 POST_MEM_WRITE( ARG3, sizeof(int) );
10373 break;
10374 case VKI_TIOCGICOUNT:
10375 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10376 break;
10378 case VKI_SG_SET_COMMAND_Q:
10379 break;
10380 case VKI_SG_IO:
10382 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10383 if ( sgio->sbp ) {
10384 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10386 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10387 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10388 int transferred = sgio->dxfer_len - sgio->resid;
10389 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10392 break;
10393 case VKI_SG_GET_SCSI_ID:
10394 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10395 break;
10396 case VKI_SG_SET_RESERVED_SIZE:
10397 break;
10398 case VKI_SG_SET_TIMEOUT:
10399 break;
10400 case VKI_SG_GET_RESERVED_SIZE:
10401 POST_MEM_WRITE(ARG3, sizeof(int));
10402 break;
10403 case VKI_SG_GET_TIMEOUT:
10404 break;
10405 case VKI_SG_GET_VERSION_NUM:
10406 POST_MEM_WRITE(ARG3, sizeof(int));
10407 break;
10408 case VKI_SG_EMULATED_HOST:
10409 POST_MEM_WRITE(ARG3, sizeof(int));
10410 break;
10411 case VKI_SG_GET_SG_TABLESIZE:
10412 POST_MEM_WRITE(ARG3, sizeof(int));
10413 break;
10415 case VKI_IIOCGETCPS:
10416 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10417 break;
10418 case VKI_IIOCNETGPN:
10419 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10420 break;
10422 /* These all use struct ifreq AFAIK */
10423 case VKI_SIOCGIFINDEX: /* get iface index */
10424 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10425 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10426 break;
10427 case VKI_SIOCGIFFLAGS: /* get flags */
10428 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10429 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10430 break;
10431 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10432 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10433 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10434 break;
10435 case VKI_SIOCGIFMTU: /* get MTU size */
10436 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10437 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10438 break;
10439 case VKI_SIOCGIFADDR: /* get PA address */
10440 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10441 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10442 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10443 POST_MEM_WRITE(
10444 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10445 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10446 break;
10447 case VKI_SIOCGIFMETRIC: /* get metric */
10448 POST_MEM_WRITE(
10449 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10450 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10451 break;
10452 case VKI_SIOCGIFMAP: /* Get device parameters */
10453 POST_MEM_WRITE(
10454 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10455 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10456 break;
10457 break;
10458 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10459 POST_MEM_WRITE(
10460 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10461 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10462 break;
10463 case VKI_SIOCGIFNAME: /* get iface name */
10464 POST_MEM_WRITE(
10465 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10466 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10467 break;
10468 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10469 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10470 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10471 case VKI_ETHTOOL_GSET:
10472 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10473 break;
10474 case VKI_ETHTOOL_SSET:
10475 break;
10476 case VKI_ETHTOOL_GDRVINFO:
10477 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10478 break;
10479 case VKI_ETHTOOL_GREGS:
10480 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10481 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10482 break;
10483 case VKI_ETHTOOL_GWOL:
10484 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10485 break;
10486 case VKI_ETHTOOL_SWOL:
10487 break;
10488 case VKI_ETHTOOL_GMSGLVL:
10489 case VKI_ETHTOOL_GLINK:
10490 case VKI_ETHTOOL_GRXCSUM:
10491 case VKI_ETHTOOL_GSG:
10492 case VKI_ETHTOOL_GTSO:
10493 case VKI_ETHTOOL_GUFO:
10494 case VKI_ETHTOOL_GGSO:
10495 case VKI_ETHTOOL_GFLAGS:
10496 case VKI_ETHTOOL_GGRO:
10497 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10498 break;
10499 case VKI_ETHTOOL_SMSGLVL:
10500 case VKI_ETHTOOL_SRXCSUM:
10501 case VKI_ETHTOOL_SSG:
10502 case VKI_ETHTOOL_STSO:
10503 case VKI_ETHTOOL_SUFO:
10504 case VKI_ETHTOOL_SGSO:
10505 case VKI_ETHTOOL_SFLAGS:
10506 case VKI_ETHTOOL_SGRO:
10507 break;
10508 case VKI_ETHTOOL_NWAY_RST:
10509 break;
10510 case VKI_ETHTOOL_GRINGPARAM:
10511 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10512 break;
10513 case VKI_ETHTOOL_SRINGPARAM:
10514 break;
10515 case VKI_ETHTOOL_TEST:
10516 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10517 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10518 break;
10519 case VKI_ETHTOOL_PHYS_ID:
10520 break;
10521 case VKI_ETHTOOL_GPERMADDR:
10522 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10523 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10524 break;
10525 case VKI_ETHTOOL_RESET:
10526 break;
10527 case VKI_ETHTOOL_GSSET_INFO:
10528 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10529 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10530 break;
10531 case VKI_ETHTOOL_GFEATURES:
10532 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10533 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10534 break;
10535 case VKI_ETHTOOL_SFEATURES:
10536 break;
10537 case VKI_ETHTOOL_GCHANNELS:
10538 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10539 break;
10540 case VKI_ETHTOOL_SCHANNELS:
10541 break;
10542 case VKI_ETHTOOL_GET_TS_INFO:
10543 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10544 break;
10546 break;
10548 case VKI_SIOCGMIIPHY: /* get hardware entry */
10549 POST_MEM_WRITE(
10550 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10551 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10552 break;
10553 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10554 POST_MEM_WRITE(
10555 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10556 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10557 break;
10559 /* tun/tap related ioctls */
10560 case VKI_TUNSETIFF:
10561 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10562 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10563 break;
10564 case VKI_TUNGETFEATURES:
10565 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10566 break;
10567 case VKI_TUNGETIFF:
10568 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10569 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10570 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10571 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10572 break;
10573 case VKI_TUNGETSNDBUF:
10574 POST_MEM_WRITE( ARG3, sizeof(int) );
10575 break;
10576 case VKI_TUNGETVNETHDRSZ:
10577 POST_MEM_WRITE( ARG3, sizeof(int) );
10578 break;
10580 case VKI_SIOCGIFCONF: /* get iface list */
10581 /* WAS:
10582 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10583 KERNEL_DO_SYSCALL(tid,RES);
10584 if (!VG_(is_kerror)(RES) && RES == 0)
10585 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10587 if (RES == 0 && ARG3 ) {
10588 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10589 if (ifc->vki_ifc_buf != NULL)
10590 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10592 break;
10593 case VKI_SIOCGSTAMP:
10594 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10595 break;
10596 case VKI_SIOCGSTAMPNS:
10597 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10598 break;
10599 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10600 the number of bytes currently in that socket's send buffer.
10601 It writes this value as an int to the memory location
10602 indicated by the third argument of ioctl(2). */
10603 case VKI_SIOCOUTQ:
10604 POST_MEM_WRITE(ARG3, sizeof(int));
10605 break;
10606 case VKI_SIOCGRARP: /* get RARP table entry */
10607 case VKI_SIOCGARP: /* get ARP table entry */
10608 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10609 break;
10611 case VKI_SIOCSIFFLAGS: /* set flags */
10612 case VKI_SIOCSIFMAP: /* Set device parameters */
10613 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10614 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10615 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10616 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10617 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10618 case VKI_SIOCSIFMETRIC: /* set metric */
10619 case VKI_SIOCSIFADDR: /* set PA address */
10620 case VKI_SIOCSIFMTU: /* set MTU size */
10621 case VKI_SIOCSIFHWADDR: /* set hardware address */
10622 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10623 break;
10624 /* Routing table calls. */
10625 case VKI_SIOCADDRT: /* add routing table entry */
10626 case VKI_SIOCDELRT: /* delete routing table entry */
10627 break;
10629 /* RARP cache control calls. */
10630 case VKI_SIOCDRARP: /* delete RARP table entry */
10631 case VKI_SIOCSRARP: /* set RARP table entry */
10632 /* ARP cache control calls. */
10633 case VKI_SIOCSARP: /* set ARP table entry */
10634 case VKI_SIOCDARP: /* delete ARP table entry */
10635 break;
10637 case VKI_SIOCGPGRP:
10638 POST_MEM_WRITE(ARG3, sizeof(int));
10639 break;
10640 case VKI_SIOCSPGRP:
10641 break;
10643 case VKI_SIOCATMARK:
10644 POST_MEM_WRITE(ARG3, sizeof(int));
10645 break;
10647 /* linux/soundcard interface (OSS) */
10648 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10649 case VKI_SNDCTL_SEQ_GETINCOUNT:
10650 case VKI_SNDCTL_SEQ_PERCMODE:
10651 case VKI_SNDCTL_SEQ_TESTMIDI:
10652 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10653 case VKI_SNDCTL_SEQ_NRSYNTHS:
10654 case VKI_SNDCTL_SEQ_NRMIDIS:
10655 case VKI_SNDCTL_SEQ_GETTIME:
10656 case VKI_SNDCTL_DSP_GETBLKSIZE:
10657 case VKI_SNDCTL_DSP_GETFMTS:
10658 case VKI_SNDCTL_DSP_SETFMT:
10659 case VKI_SNDCTL_DSP_GETTRIGGER:
10660 case VKI_SNDCTL_DSP_GETODELAY:
10661 case VKI_SNDCTL_DSP_GETSPDIF:
10662 case VKI_SNDCTL_DSP_GETCAPS:
10663 case VKI_SOUND_PCM_READ_RATE:
10664 case VKI_SOUND_PCM_READ_CHANNELS:
10665 case VKI_SOUND_PCM_READ_BITS:
10666 case VKI_SOUND_PCM_READ_FILTER:
10667 POST_MEM_WRITE(ARG3, sizeof(int));
10668 break;
10669 case VKI_SNDCTL_SEQ_CTRLRATE:
10670 case VKI_SNDCTL_DSP_SPEED:
10671 case VKI_SNDCTL_DSP_STEREO:
10672 case VKI_SNDCTL_DSP_CHANNELS:
10673 case VKI_SOUND_PCM_WRITE_FILTER:
10674 case VKI_SNDCTL_DSP_SUBDIVIDE:
10675 case VKI_SNDCTL_DSP_SETFRAGMENT:
10676 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10677 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10678 case VKI_SNDCTL_TMR_TIMEBASE:
10679 case VKI_SNDCTL_TMR_TEMPO:
10680 case VKI_SNDCTL_TMR_SOURCE:
10681 case VKI_SNDCTL_MIDI_PRETIME:
10682 case VKI_SNDCTL_MIDI_MPUMODE:
10683 break;
10684 case VKI_SNDCTL_DSP_GETOSPACE:
10685 case VKI_SNDCTL_DSP_GETISPACE:
10686 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10687 break;
10688 case VKI_SNDCTL_DSP_NONBLOCK:
10689 break;
10690 case VKI_SNDCTL_DSP_SETTRIGGER:
10691 break;
10693 case VKI_SNDCTL_DSP_POST:
10694 case VKI_SNDCTL_DSP_RESET:
10695 case VKI_SNDCTL_DSP_SYNC:
10696 case VKI_SNDCTL_DSP_SETSYNCRO:
10697 case VKI_SNDCTL_DSP_SETDUPLEX:
10698 break;
10700 /* linux/soundcard interface (ALSA) */
10701 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10702 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10703 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10704 case VKI_SNDRV_PCM_IOCTL_RESET:
10705 case VKI_SNDRV_PCM_IOCTL_START:
10706 case VKI_SNDRV_PCM_IOCTL_DROP:
10707 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10708 case VKI_SNDRV_PCM_IOCTL_RESUME:
10709 case VKI_SNDRV_PCM_IOCTL_XRUN:
10710 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10711 case VKI_SNDRV_TIMER_IOCTL_START:
10712 case VKI_SNDRV_TIMER_IOCTL_STOP:
10713 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10714 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10715 break;
10717 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10718 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10719 break;
10721 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10722 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10723 break;
10724 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10725 struct vki_snd_ctl_elem_list *data =
10726 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10727 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10728 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10729 if (data->pids) {
10730 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10732 break;
10734 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10735 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10736 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10737 break;
10739 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10740 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10741 break;
10743 /* SCSI no operand */
10744 case VKI_SCSI_IOCTL_DOORLOCK:
10745 case VKI_SCSI_IOCTL_DOORUNLOCK:
10746 break;
10748 /* Real Time Clock (/dev/rtc) ioctls */
10749 case VKI_RTC_UIE_ON:
10750 case VKI_RTC_UIE_OFF:
10751 case VKI_RTC_AIE_ON:
10752 case VKI_RTC_AIE_OFF:
10753 case VKI_RTC_PIE_ON:
10754 case VKI_RTC_PIE_OFF:
10755 case VKI_RTC_IRQP_SET:
10756 break;
10757 case VKI_RTC_RD_TIME:
10758 case VKI_RTC_ALM_READ:
10759 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10760 break;
10761 case VKI_RTC_ALM_SET:
10762 break;
10763 case VKI_RTC_IRQP_READ:
10764 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10765 break;
10767 /* Block devices */
10768 case VKI_BLKROSET:
10769 break;
10770 case VKI_BLKROGET:
10771 POST_MEM_WRITE(ARG3, sizeof(int));
10772 break;
10773 case VKI_BLKGETSIZE:
10774 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10775 break;
10776 case VKI_BLKFLSBUF:
10777 break;
10778 case VKI_BLKRASET:
10779 break;
10780 case VKI_BLKRAGET:
10781 POST_MEM_WRITE(ARG3, sizeof(long));
10782 break;
10783 case VKI_BLKFRASET:
10784 break;
10785 case VKI_BLKFRAGET:
10786 POST_MEM_WRITE(ARG3, sizeof(long));
10787 break;
10788 case VKI_BLKSECTGET:
10789 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10790 break;
10791 case VKI_BLKSSZGET:
10792 POST_MEM_WRITE(ARG3, sizeof(int));
10793 break;
10794 case VKI_BLKBSZGET:
10795 POST_MEM_WRITE(ARG3, sizeof(int));
10796 break;
10797 case VKI_BLKBSZSET:
10798 break;
10799 case VKI_BLKGETSIZE64:
10800 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10801 break;
10802 case VKI_BLKPBSZGET:
10803 POST_MEM_WRITE(ARG3, sizeof(int));
10804 break;
10805 case VKI_BLKIOMIN:
10806 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10807 break;
10808 case VKI_BLKIOOPT:
10809 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10810 break;
10811 case VKI_BLKALIGNOFF:
10812 POST_MEM_WRITE(ARG3, sizeof(int));
10813 break;
10814 case VKI_BLKDISCARDZEROES:
10815 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10816 break;
10817 case VKI_BLKREPORTZONE: {
10818 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10820 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10821 break;
10823 case VKI_BLKRESETZONE:
10824 break;
10826 /* Hard disks */
10827 case VKI_HDIO_GETGEO: /* 0x0301 */
10828 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10829 break;
10830 case VKI_HDIO_GET_DMA: /* 0x030b */
10831 POST_MEM_WRITE(ARG3, sizeof(long));
10832 break;
10833 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10834 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10835 break;
10837 /* SCSI */
10838 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10839 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10840 break;
10841 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10842 POST_MEM_WRITE(ARG3, sizeof(int));
10843 break;
10845 /* CD ROM stuff (??) */
10846 case VKI_CDROM_DISC_STATUS:
10847 case VKI_CDROMSTOP:
10848 break;
10849 case VKI_CDROMSUBCHNL:
10850 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10851 break;
10852 case VKI_CDROMREADTOCHDR:
10853 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10854 break;
10855 case VKI_CDROMREADTOCENTRY:
10856 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10857 break;
10858 case VKI_CDROMMULTISESSION:
10859 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10860 break;
10861 case VKI_CDROMVOLREAD:
10862 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10863 break;
10864 case VKI_CDROMREADMODE1:
10865 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10866 break;
10867 case VKI_CDROMREADMODE2:
10868 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10869 break;
10870 case VKI_CDROMREADRAW:
10871 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10872 break;
10873 case VKI_CDROMREADAUDIO:
10875 struct vki_cdrom_read_audio *cra =
10876 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10877 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10878 break;
10881 case VKI_CDROMPLAYMSF:
10882 break;
10883 /* The following two are probably bogus (should check args
10884 for readability). JRS 20021117 */
10885 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10886 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10887 break;
10888 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10889 break;
10891 /* DVD stuff */
10892 case VKI_DVD_READ_STRUCT:
10893 break;
10895 case VKI_FIGETBSZ:
10896 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10897 break;
10898 case VKI_FIBMAP:
10899 POST_MEM_WRITE(ARG3, sizeof(int));
10900 break;
10902 case VKI_FBIOGET_VSCREENINFO: //0x4600
10903 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10904 break;
10905 case VKI_FBIOGET_FSCREENINFO: //0x4602
10906 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10907 break;
10909 case VKI_PPCLAIM:
10910 case VKI_PPEXCL:
10911 case VKI_PPYIELD:
10912 case VKI_PPRELEASE:
10913 case VKI_PPSETMODE:
10914 case VKI_PPSETPHASE:
10915 case VKI_PPSETFLAGS:
10916 case VKI_PPWDATA:
10917 case VKI_PPWCONTROL:
10918 case VKI_PPFCONTROL:
10919 case VKI_PPDATADIR:
10920 case VKI_PPNEGOT:
10921 case VKI_PPWCTLONIRQ:
10922 case VKI_PPSETTIME:
10923 break;
10924 case VKI_PPGETMODE:
10925 POST_MEM_WRITE( ARG3, sizeof(int) );
10926 break;
10927 case VKI_PPGETPHASE:
10928 POST_MEM_WRITE( ARG3, sizeof(int) );
10929 break;
10930 case VKI_PPGETMODES:
10931 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10932 break;
10933 case VKI_PPGETFLAGS:
10934 POST_MEM_WRITE( ARG3, sizeof(int) );
10935 break;
10936 case VKI_PPRSTATUS:
10937 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10938 break;
10939 case VKI_PPRDATA:
10940 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10941 break;
10942 case VKI_PPRCONTROL:
10943 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10944 break;
10945 case VKI_PPCLRIRQ:
10946 POST_MEM_WRITE( ARG3, sizeof(int) );
10947 break;
10948 case VKI_PPGETTIME:
10949 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10950 break;
10952 case VKI_GIO_FONT:
10953 POST_MEM_WRITE( ARG3, 32 * 256 );
10954 break;
10955 case VKI_PIO_FONT:
10956 break;
10958 case VKI_GIO_FONTX:
10959 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10960 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10961 break;
10962 case VKI_PIO_FONTX:
10963 break;
10965 case VKI_PIO_FONTRESET:
10966 break;
10968 case VKI_GIO_CMAP:
10969 POST_MEM_WRITE( ARG3, 16 * 3 );
10970 break;
10971 case VKI_PIO_CMAP:
10972 break;
10974 case VKI_KIOCSOUND:
10975 case VKI_KDMKTONE:
10976 break;
10978 case VKI_KDGETLED:
10979 POST_MEM_WRITE( ARG3, sizeof(char) );
10980 break;
10981 case VKI_KDSETLED:
10982 break;
10984 case VKI_KDGKBTYPE:
10985 POST_MEM_WRITE( ARG3, sizeof(char) );
10986 break;
10988 case VKI_KDADDIO:
10989 case VKI_KDDELIO:
10990 case VKI_KDENABIO:
10991 case VKI_KDDISABIO:
10992 break;
10994 case VKI_KDSETMODE:
10995 break;
10996 case VKI_KDGETMODE:
10997 POST_MEM_WRITE( ARG3, sizeof(int) );
10998 break;
11000 case VKI_KDMAPDISP:
11001 case VKI_KDUNMAPDISP:
11002 break;
11004 case VKI_GIO_SCRNMAP:
11005 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11006 break;
11007 case VKI_PIO_SCRNMAP:
11008 break;
11009 case VKI_GIO_UNISCRNMAP:
11010 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11011 break;
11012 case VKI_PIO_UNISCRNMAP:
11013 break;
11015 case VKI_GIO_UNIMAP:
11016 if ( ARG3 ) {
11017 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11018 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11019 POST_MEM_WRITE( (Addr)desc->entries,
11020 desc->entry_ct * sizeof(struct vki_unipair) );
11022 break;
11023 case VKI_PIO_UNIMAP:
11024 break;
11025 case VKI_PIO_UNIMAPCLR:
11026 break;
11028 case VKI_KDGKBMODE:
11029 POST_MEM_WRITE( ARG3, sizeof(int) );
11030 break;
11031 case VKI_KDSKBMODE:
11032 break;
11034 case VKI_KDGKBMETA:
11035 POST_MEM_WRITE( ARG3, sizeof(int) );
11036 break;
11037 case VKI_KDSKBMETA:
11038 break;
11040 case VKI_KDGKBLED:
11041 POST_MEM_WRITE( ARG3, sizeof(char) );
11042 break;
11043 case VKI_KDSKBLED:
11044 break;
11046 case VKI_KDGKBENT:
11047 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11048 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11049 break;
11050 case VKI_KDSKBENT:
11051 break;
11053 case VKI_KDGKBSENT:
11054 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11055 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11056 break;
11057 case VKI_KDSKBSENT:
11058 break;
11060 case VKI_KDGKBDIACR:
11061 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11062 break;
11063 case VKI_KDSKBDIACR:
11064 break;
11066 case VKI_KDGETKEYCODE:
11067 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11068 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11069 break;
11070 case VKI_KDSETKEYCODE:
11071 break;
11073 case VKI_KDSIGACCEPT:
11074 break;
11076 case VKI_KDKBDREP:
11077 break;
11079 case VKI_KDFONTOP:
11080 if ( ARG3 ) {
11081 struct vki_console_font_op *op =
11082 (struct vki_console_font_op *) (Addr)ARG3;
11083 switch ( op->op ) {
11084 case VKI_KD_FONT_OP_SET:
11085 break;
11086 case VKI_KD_FONT_OP_GET:
11087 if ( op->data )
11088 POST_MEM_WRITE( (Addr) op->data,
11089 (op->width + 7) / 8 * 32 * op->charcount );
11090 break;
11091 case VKI_KD_FONT_OP_SET_DEFAULT:
11092 break;
11093 case VKI_KD_FONT_OP_COPY:
11094 break;
11096 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11098 break;
11100 case VKI_VT_OPENQRY:
11101 POST_MEM_WRITE( ARG3, sizeof(int) );
11102 break;
11103 case VKI_VT_GETMODE:
11104 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11105 break;
11106 case VKI_VT_SETMODE:
11107 break;
11108 case VKI_VT_GETSTATE:
11109 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11110 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11111 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11112 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11113 break;
11114 case VKI_VT_RELDISP:
11115 case VKI_VT_ACTIVATE:
11116 case VKI_VT_WAITACTIVE:
11117 case VKI_VT_DISALLOCATE:
11118 break;
11119 case VKI_VT_RESIZE:
11120 break;
11121 case VKI_VT_RESIZEX:
11122 break;
11123 case VKI_VT_LOCKSWITCH:
11124 case VKI_VT_UNLOCKSWITCH:
11125 break;
11127 case VKI_USBDEVFS_CONTROL:
11128 if ( ARG3 ) {
11129 struct vki_usbdevfs_ctrltransfer *vkuc =
11130 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11131 if (vkuc->bRequestType & 0x80)
11132 POST_MEM_WRITE((Addr)vkuc->data, RES);
11134 break;
11135 case VKI_USBDEVFS_BULK:
11136 if ( ARG3 ) {
11137 struct vki_usbdevfs_bulktransfer *vkub =
11138 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11139 if (vkub->ep & 0x80)
11140 POST_MEM_WRITE((Addr)vkub->data, RES);
11142 break;
11143 case VKI_USBDEVFS_GETDRIVER:
11144 if ( ARG3 ) {
11145 struct vki_usbdevfs_getdriver *vkugd =
11146 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11147 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11149 break;
11150 case VKI_USBDEVFS_REAPURB:
11151 case VKI_USBDEVFS_REAPURBNDELAY:
11152 if ( ARG3 ) {
11153 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11154 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11155 if (!*vkuu)
11156 break;
11157 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11158 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11159 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11160 if (vkusp->bRequestType & 0x80)
11161 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11162 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11163 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11164 char *bp = (*vkuu)->buffer;
11165 int i;
11166 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11167 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11168 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11169 if ((*vkuu)->endpoint & 0x80)
11170 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11171 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11173 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11174 } else {
11175 if ((*vkuu)->endpoint & 0x80)
11176 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11177 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11180 break;
11181 case VKI_USBDEVFS_CONNECTINFO:
11182 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11183 break;
11184 case VKI_USBDEVFS_IOCTL:
11185 if ( ARG3 ) {
11186 struct vki_usbdevfs_ioctl *vkui =
11187 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11188 UInt dir2, size2;
11189 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11190 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11191 if (size2 > 0) {
11192 if (dir2 & _VKI_IOC_READ)
11193 POST_MEM_WRITE((Addr)vkui->data, size2);
11196 break;
11198 /* I2C (/dev/i2c-*) ioctls */
11199 case VKI_I2C_SLAVE:
11200 case VKI_I2C_SLAVE_FORCE:
11201 case VKI_I2C_TENBIT:
11202 case VKI_I2C_PEC:
11203 break;
11204 case VKI_I2C_FUNCS:
11205 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11206 break;
11207 case VKI_I2C_RDWR:
11208 if ( ARG3 ) {
11209 struct vki_i2c_rdwr_ioctl_data *vkui =
11210 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11211 UInt i;
11212 for (i=0; i < vkui->nmsgs; i++) {
11213 struct vki_i2c_msg *msg = vkui->msgs + i;
11214 if (msg->flags & VKI_I2C_M_RD)
11215 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11218 break;
11219 case VKI_I2C_SMBUS:
11220 if ( ARG3 ) {
11221 struct vki_i2c_smbus_ioctl_data *vkis
11222 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11223 /* i2c_smbus_write_quick hides its value in read_write, so
11224 this variable can have a different meaning */
11225 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11226 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11227 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11228 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11229 UInt size;
11230 switch(vkis->size) {
11231 case VKI_I2C_SMBUS_BYTE:
11232 case VKI_I2C_SMBUS_BYTE_DATA:
11233 size = 1;
11234 break;
11235 case VKI_I2C_SMBUS_WORD_DATA:
11236 case VKI_I2C_SMBUS_PROC_CALL:
11237 size = 2;
11238 break;
11239 case VKI_I2C_SMBUS_BLOCK_DATA:
11240 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11241 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11242 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11243 size = 1 + vkis->data->block[0];
11244 break;
11245 default:
11246 size = 0;
11248 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11252 break;
11254 /* Wireless extensions ioctls */
11255 case VKI_SIOCSIWCOMMIT:
11256 case VKI_SIOCSIWNWID:
11257 case VKI_SIOCSIWFREQ:
11258 case VKI_SIOCSIWMODE:
11259 case VKI_SIOCSIWSENS:
11260 case VKI_SIOCSIWRANGE:
11261 case VKI_SIOCSIWPRIV:
11262 case VKI_SIOCSIWSTATS:
11263 case VKI_SIOCSIWSPY:
11264 case VKI_SIOCSIWTHRSPY:
11265 case VKI_SIOCSIWAP:
11266 case VKI_SIOCSIWSCAN:
11267 case VKI_SIOCSIWESSID:
11268 case VKI_SIOCSIWRATE:
11269 case VKI_SIOCSIWNICKN:
11270 case VKI_SIOCSIWRTS:
11271 case VKI_SIOCSIWFRAG:
11272 case VKI_SIOCSIWTXPOW:
11273 case VKI_SIOCSIWRETRY:
11274 case VKI_SIOCSIWENCODE:
11275 case VKI_SIOCSIWPOWER:
11276 case VKI_SIOCSIWGENIE:
11277 case VKI_SIOCSIWMLME:
11278 case VKI_SIOCSIWAUTH:
11279 case VKI_SIOCSIWENCODEEXT:
11280 case VKI_SIOCSIWPMKSA:
11281 break;
11282 case VKI_SIOCGIWNAME:
11283 if (ARG3) {
11284 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11285 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11287 break;
11288 case VKI_SIOCGIWNWID:
11289 case VKI_SIOCGIWSENS:
11290 case VKI_SIOCGIWRATE:
11291 case VKI_SIOCGIWRTS:
11292 case VKI_SIOCGIWFRAG:
11293 case VKI_SIOCGIWTXPOW:
11294 case VKI_SIOCGIWRETRY:
11295 case VKI_SIOCGIWPOWER:
11296 case VKI_SIOCGIWAUTH:
11297 if (ARG3) {
11298 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11299 sizeof(struct vki_iw_param));
11301 break;
11302 case VKI_SIOCGIWFREQ:
11303 if (ARG3) {
11304 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11305 sizeof(struct vki_iw_freq));
11307 break;
11308 case VKI_SIOCGIWMODE:
11309 if (ARG3) {
11310 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11311 sizeof(__vki_u32));
11313 break;
11314 case VKI_SIOCGIWRANGE:
11315 case VKI_SIOCGIWPRIV:
11316 case VKI_SIOCGIWSTATS:
11317 case VKI_SIOCGIWSPY:
11318 case VKI_SIOCGIWTHRSPY:
11319 case VKI_SIOCGIWAPLIST:
11320 case VKI_SIOCGIWSCAN:
11321 case VKI_SIOCGIWESSID:
11322 case VKI_SIOCGIWNICKN:
11323 case VKI_SIOCGIWENCODE:
11324 case VKI_SIOCGIWGENIE:
11325 case VKI_SIOCGIWENCODEEXT:
11326 if (ARG3) {
11327 struct vki_iw_point* point;
11328 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11329 POST_MEM_WRITE((Addr)point->pointer, point->length);
11331 break;
11332 case VKI_SIOCGIWAP:
11333 if (ARG3) {
11334 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11335 sizeof(struct vki_sockaddr));
11337 break;
11339 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11340 || defined(VGPV_mips32_linux_android) \
11341 || defined(VGPV_arm64_linux_android)
11342 /* ashmem */
11343 case VKI_ASHMEM_GET_SIZE:
11344 case VKI_ASHMEM_SET_SIZE:
11345 case VKI_ASHMEM_GET_PROT_MASK:
11346 case VKI_ASHMEM_SET_PROT_MASK:
11347 case VKI_ASHMEM_GET_PIN_STATUS:
11348 case VKI_ASHMEM_PURGE_ALL_CACHES:
11349 case VKI_ASHMEM_SET_NAME:
11350 case VKI_ASHMEM_PIN:
11351 case VKI_ASHMEM_UNPIN:
11352 break;
11353 case VKI_ASHMEM_GET_NAME:
11354 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11355 break;
11357 /* binder */
11358 case VKI_BINDER_WRITE_READ:
11359 if (ARG3) {
11360 struct vki_binder_write_read* bwr
11361 = (struct vki_binder_write_read*)(Addr)ARG3;
11362 POST_FIELD_WRITE(bwr->write_consumed);
11363 POST_FIELD_WRITE(bwr->read_consumed);
11365 if (bwr->read_size)
11366 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11368 break;
11370 case VKI_BINDER_SET_IDLE_TIMEOUT:
11371 case VKI_BINDER_SET_MAX_THREADS:
11372 case VKI_BINDER_SET_IDLE_PRIORITY:
11373 case VKI_BINDER_SET_CONTEXT_MGR:
11374 case VKI_BINDER_THREAD_EXIT:
11375 break;
11376 case VKI_BINDER_VERSION:
11377 if (ARG3) {
11378 struct vki_binder_version* bv =
11379 (struct vki_binder_version*)(Addr)ARG3;
11380 POST_FIELD_WRITE(bv->protocol_version);
11382 break;
11383 # endif /* defined(VGPV_*_linux_android) */
11385 case VKI_HCIGETDEVLIST:
11386 if (ARG3) {
11387 struct vki_hci_dev_list_req* dlr =
11388 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11389 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11390 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11392 break;
11394 case VKI_HCIINQUIRY:
11395 if (ARG3) {
11396 struct vki_hci_inquiry_req* ir =
11397 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11398 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11399 ir->num_rsp * sizeof(struct vki_inquiry_info));
11401 break;
11403 case VKI_DRM_IOCTL_VERSION:
11404 if (ARG3) {
11405 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11406 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11407 const vki_size_t orig_name_len = info->orig->name_len;
11408 const vki_size_t orig_date_len = info->orig->date_len;
11409 const vki_size_t orig_desc_len = info->orig->desc_len;
11410 *info->orig = info->data;
11411 ARG3 = (Addr)info->orig;
11412 data = info->orig;
11413 VG_(free)(info);
11414 if (SUCCESS) {
11415 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11416 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11417 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11418 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11419 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11420 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11421 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11422 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11423 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11426 break;
11427 case VKI_DRM_IOCTL_GET_UNIQUE:
11428 if (ARG3) {
11429 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11430 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11432 break;
11433 case VKI_DRM_IOCTL_GET_MAGIC:
11434 if (ARG3) {
11435 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11436 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11438 break;
11439 case VKI_DRM_IOCTL_WAIT_VBLANK:
11440 if (ARG3) {
11441 union vki_drm_wait_vblank *data =
11442 (union vki_drm_wait_vblank *)(Addr)ARG3;
11443 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11445 break;
11446 case VKI_DRM_IOCTL_GEM_FLINK:
11447 if (ARG3) {
11448 struct vki_drm_gem_flink *data =
11449 (struct vki_drm_gem_flink *)(Addr)ARG3;
11450 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11452 break;
11453 case VKI_DRM_IOCTL_GEM_OPEN:
11454 if (ARG3) {
11455 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11456 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11457 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11459 break;
11460 case VKI_DRM_IOCTL_I915_GETPARAM:
11461 if (ARG3) {
11462 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11463 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11465 break;
11466 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11467 if (ARG3) {
11468 struct vki_drm_i915_gem_busy *data =
11469 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11470 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11472 break;
11473 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11474 if (ARG3) {
11475 struct vki_drm_i915_gem_create *data =
11476 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11477 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11479 break;
11480 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11481 if (ARG3) {
11482 struct vki_drm_i915_gem_pread *data =
11483 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11484 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11486 break;
11487 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11488 if (ARG3) {
11489 struct vki_drm_i915_gem_mmap_v1 *data =
11490 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11491 Addr addr = data->addr_ptr;
11492 SizeT size = data->size;
11493 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11494 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11495 ML_(notify_core_and_tool_of_mmap)(addr, size,
11496 VKI_PROT_READ | VKI_PROT_WRITE,
11497 VKI_MAP_ANONYMOUS, -1, 0 );
11498 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11500 break;
11501 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11502 if (ARG3) {
11503 struct vki_drm_i915_gem_mmap *data =
11504 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11505 Addr addr = data->addr_ptr;
11506 SizeT size = data->size;
11507 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11508 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11509 ML_(notify_core_and_tool_of_mmap)(addr, size,
11510 VKI_PROT_READ | VKI_PROT_WRITE,
11511 VKI_MAP_ANONYMOUS, -1, 0 );
11512 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11514 break;
11515 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11516 if (ARG3) {
11517 struct vki_drm_i915_gem_mmap_gtt *data =
11518 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11519 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11521 break;
11522 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11523 if (ARG3) {
11524 struct vki_drm_i915_gem_set_tiling *data =
11525 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11526 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11527 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11528 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11530 break;
11531 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11532 if (ARG3) {
11533 struct vki_drm_i915_gem_get_tiling *data =
11534 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11535 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11536 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11538 break;
11539 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11540 if (ARG3) {
11541 struct vki_drm_i915_gem_get_aperture *data =
11542 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11543 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11544 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11546 break;
11548 /* KVM ioctls that only write the system call return value */
11549 case VKI_KVM_GET_API_VERSION:
11550 case VKI_KVM_CREATE_VM:
11551 case VKI_KVM_CHECK_EXTENSION:
11552 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11553 case VKI_KVM_S390_ENABLE_SIE:
11554 case VKI_KVM_CREATE_VCPU:
11555 case VKI_KVM_SET_TSS_ADDR:
11556 case VKI_KVM_CREATE_IRQCHIP:
11557 case VKI_KVM_RUN:
11558 case VKI_KVM_S390_INITIAL_RESET:
11559 case VKI_KVM_KVMCLOCK_CTRL:
11560 break;
11562 case VKI_KVM_S390_MEM_OP: {
11563 struct vki_kvm_s390_mem_op *args =
11564 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11565 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11566 break;
11567 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11568 POST_MEM_WRITE((Addr)args->buf, args->size);
11570 break;
11572 #ifdef ENABLE_XEN
11573 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11574 SyscallArgs harrghs;
11575 struct vki_xen_privcmd_hypercall *args =
11576 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11578 if (!args)
11579 break;
11581 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11582 harrghs.sysno = args->op;
11583 harrghs.arg1 = args->arg[0];
11584 harrghs.arg2 = args->arg[1];
11585 harrghs.arg3 = args->arg[2];
11586 harrghs.arg4 = args->arg[3];
11587 harrghs.arg5 = args->arg[4];
11588 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11590 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11592 break;
11594 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11595 break;
11596 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11597 struct vki_xen_privcmd_mmapbatch *args =
11598 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11599 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11601 break;
11602 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11603 struct vki_xen_privcmd_mmapbatch_v2 *args =
11604 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11605 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11607 break;
11609 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11610 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11611 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11612 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11613 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11614 case VKI_XEN_IOCTL_EVTCHN_RESET:
11615 /* No output */
11616 break;
11617 #endif
11619 /* Lustre */
11620 case VKI_OBD_IOC_FID2PATH: {
11621 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11622 POST_FIELD_WRITE(args->gf_recno);
11623 POST_FIELD_WRITE(args->gf_linkno);
11624 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11625 break;
11628 case VKI_LL_IOC_PATH2FID:
11629 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11630 break;
11632 case VKI_LL_IOC_GETPARENT: {
11633 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11634 POST_FIELD_WRITE(gp->gp_fid);
11635 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11636 break;
11639 /* V4L2 */
11640 case VKI_V4L2_S_FMT:
11641 case VKI_V4L2_TRY_FMT:
11642 case VKI_V4L2_REQBUFS:
11643 case VKI_V4L2_OVERLAY:
11644 case VKI_V4L2_STREAMON:
11645 case VKI_V4L2_STREAMOFF:
11646 case VKI_V4L2_S_PARM:
11647 case VKI_V4L2_S_STD:
11648 case VKI_V4L2_S_FREQUENCY:
11649 case VKI_V4L2_S_CTRL:
11650 case VKI_V4L2_S_TUNER:
11651 case VKI_V4L2_S_AUDIO:
11652 case VKI_V4L2_S_INPUT:
11653 case VKI_V4L2_S_EDID:
11654 case VKI_V4L2_S_OUTPUT:
11655 case VKI_V4L2_S_AUDOUT:
11656 case VKI_V4L2_S_MODULATOR:
11657 case VKI_V4L2_S_JPEGCOMP:
11658 case VKI_V4L2_S_CROP:
11659 case VKI_V4L2_S_PRIORITY:
11660 case VKI_V4L2_S_HW_FREQ_SEEK:
11661 case VKI_V4L2_S_DV_TIMINGS:
11662 case VKI_V4L2_SUBSCRIBE_EVENT:
11663 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11664 case VKI_V4L2_PREPARE_BUF:
11665 break;
11666 case VKI_V4L2_QUERYCAP: {
11667 struct vki_v4l2_capability *data =
11668 (struct vki_v4l2_capability *)(Addr)ARG3;
11669 POST_MEM_WRITE((Addr)data, sizeof(*data));
11670 break;
11672 case VKI_V4L2_ENUM_FMT: {
11673 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11674 POST_FIELD_WRITE(data->flags);
11675 POST_FIELD_WRITE(data->description);
11676 POST_FIELD_WRITE(data->pixelformat);
11677 POST_FIELD_WRITE(data->reserved);
11678 break;
11680 case VKI_V4L2_G_FMT: {
11681 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11682 switch (data->type) {
11683 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11684 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11685 POST_FIELD_WRITE(data->fmt.pix);
11686 break;
11687 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11688 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11689 POST_FIELD_WRITE(data->fmt.vbi);
11690 break;
11691 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11692 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11693 POST_FIELD_WRITE(data->fmt.sliced);
11694 break;
11695 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11696 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11697 POST_FIELD_WRITE(data->fmt.win);
11698 break;
11699 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11700 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11701 POST_FIELD_WRITE(data->fmt.pix_mp);
11702 break;
11703 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11704 POST_FIELD_WRITE(data->fmt.sdr);
11705 break;
11707 break;
11709 case VKI_V4L2_QUERYBUF: {
11710 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11711 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11712 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11713 unsigned i;
11715 for (i = 0; i < data->length; i++) {
11716 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11717 POST_FIELD_WRITE(data->m.planes[i].length);
11718 POST_FIELD_WRITE(data->m.planes[i].m);
11719 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11720 POST_FIELD_WRITE(data->m.planes[i].reserved);
11722 } else {
11723 POST_FIELD_WRITE(data->m);
11724 POST_FIELD_WRITE(data->length);
11726 POST_FIELD_WRITE(data->bytesused);
11727 POST_FIELD_WRITE(data->flags);
11728 POST_FIELD_WRITE(data->field);
11729 POST_FIELD_WRITE(data->timestamp);
11730 POST_FIELD_WRITE(data->timecode);
11731 POST_FIELD_WRITE(data->sequence);
11732 POST_FIELD_WRITE(data->memory);
11733 POST_FIELD_WRITE(data->sequence);
11734 break;
11736 case VKI_V4L2_G_FBUF: {
11737 struct vki_v4l2_framebuffer *data =
11738 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11739 POST_MEM_WRITE((Addr)data, sizeof(*data));
11740 break;
11742 case VKI_V4L2_S_FBUF: {
11743 struct vki_v4l2_framebuffer *data =
11744 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11745 POST_FIELD_WRITE(data->capability);
11746 POST_FIELD_WRITE(data->flags);
11747 POST_FIELD_WRITE(data->fmt);
11748 break;
11750 case VKI_V4L2_QBUF: {
11751 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11753 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11754 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11755 unsigned i;
11757 for (i = 0; i < data->length; i++) {
11758 POST_FIELD_WRITE(data->m.planes[i].length);
11759 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11760 POST_FIELD_WRITE(data->m.planes[i].m);
11762 } else {
11763 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11764 POST_FIELD_WRITE(data->m);
11765 POST_FIELD_WRITE(data->length);
11767 break;
11769 case VKI_V4L2_EXPBUF: {
11770 struct vki_v4l2_exportbuffer *data =
11771 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11772 POST_FIELD_WRITE(data->fd);
11773 break;
11775 case VKI_V4L2_DQBUF: {
11776 struct vki_v4l2_buffer *data =
11777 (struct vki_v4l2_buffer *)(Addr)ARG3;
11778 POST_FIELD_WRITE(data->index);
11779 POST_FIELD_WRITE(data->bytesused);
11780 POST_FIELD_WRITE(data->field);
11781 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11782 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11783 unsigned i;
11785 for (i = 0; i < data->length; i++) {
11786 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11787 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11788 POST_FIELD_WRITE(data->m.planes[i].length);
11789 POST_FIELD_WRITE(data->m.planes[i].m);
11791 } else {
11792 POST_FIELD_WRITE(data->m);
11793 POST_FIELD_WRITE(data->length);
11794 POST_FIELD_WRITE(data->bytesused);
11795 POST_FIELD_WRITE(data->field);
11797 POST_FIELD_WRITE(data->timestamp);
11798 POST_FIELD_WRITE(data->timecode);
11799 POST_FIELD_WRITE(data->sequence);
11800 break;
11802 case VKI_V4L2_G_PARM: {
11803 struct vki_v4l2_streamparm *data =
11804 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11805 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11806 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11807 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11808 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11810 if (is_output)
11811 POST_MEM_WRITE((Addr)&data->parm.output,
11812 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11813 else
11814 POST_MEM_WRITE((Addr)&data->parm.capture,
11815 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11816 break;
11818 case VKI_V4L2_G_STD: {
11819 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11820 POST_MEM_WRITE((Addr)data, sizeof(*data));
11821 break;
11823 case VKI_V4L2_ENUMSTD: {
11824 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11825 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11826 break;
11828 case VKI_V4L2_ENUMINPUT: {
11829 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11830 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11831 break;
11833 case VKI_V4L2_G_CTRL: {
11834 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11835 POST_FIELD_WRITE(data->value);
11836 break;
11838 case VKI_V4L2_G_TUNER: {
11839 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11840 POST_MEM_WRITE((Addr)data->name,
11841 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11842 break;
11844 case VKI_V4L2_G_AUDIO: {
11845 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11846 POST_MEM_WRITE((Addr)data,
11847 sizeof(*data) - sizeof(data->reserved));
11848 break;
11850 case VKI_V4L2_QUERYCTRL: {
11851 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11852 POST_MEM_WRITE((Addr)&data->type,
11853 sizeof(*data) - sizeof(data->id));
11854 break;
11856 case VKI_V4L2_QUERYMENU: {
11857 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11858 POST_MEM_WRITE((Addr)data->name,
11859 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11860 break;
11862 case VKI_V4L2_G_INPUT: {
11863 int *data = (int *)(Addr)ARG3;
11864 POST_MEM_WRITE((Addr)data, sizeof(*data));
11865 break;
11867 case VKI_V4L2_G_EDID: {
11868 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11869 if (data->blocks && data->edid)
11870 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11871 break;
11873 case VKI_V4L2_G_OUTPUT: {
11874 int *data = (int *)(Addr)ARG3;
11875 POST_MEM_WRITE((Addr)data, sizeof(*data));
11876 break;
11878 case VKI_V4L2_ENUMOUTPUT: {
11879 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11880 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11881 break;
11883 case VKI_V4L2_G_AUDOUT: {
11884 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11885 POST_MEM_WRITE((Addr)data,
11886 sizeof(*data) - sizeof(data->reserved));
11887 break;
11889 case VKI_V4L2_G_MODULATOR: {
11890 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11891 POST_MEM_WRITE((Addr)data->name,
11892 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11893 break;
11895 case VKI_V4L2_G_FREQUENCY: {
11896 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11897 POST_FIELD_WRITE(data->type);
11898 POST_FIELD_WRITE(data->frequency);
11899 break;
11901 case VKI_V4L2_CROPCAP: {
11902 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11903 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11904 break;
11906 case VKI_V4L2_G_CROP: {
11907 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11908 POST_FIELD_WRITE(data->c);
11909 break;
11911 case VKI_V4L2_G_JPEGCOMP: {
11912 struct vki_v4l2_jpegcompression *data =
11913 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11914 POST_MEM_WRITE((Addr)data, sizeof(*data));
11915 break;
11917 case VKI_V4L2_QUERYSTD: {
11918 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11919 POST_MEM_WRITE((Addr)data, sizeof(*data));
11920 break;
11922 case VKI_V4L2_ENUMAUDIO: {
11923 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11924 POST_MEM_WRITE((Addr)data->name,
11925 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11926 break;
11928 case VKI_V4L2_ENUMAUDOUT: {
11929 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11930 POST_MEM_WRITE((Addr)data->name,
11931 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11932 break;
11934 case VKI_V4L2_G_PRIORITY: {
11935 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11936 POST_MEM_WRITE((Addr)data, sizeof(*data));
11937 break;
11939 case VKI_V4L2_G_SLICED_VBI_CAP: {
11940 struct vki_v4l2_sliced_vbi_cap *data =
11941 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11942 POST_MEM_WRITE((Addr)data,
11943 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11944 break;
11946 case VKI_V4L2_G_EXT_CTRLS: {
11947 struct vki_v4l2_ext_controls *data =
11948 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11949 if (data->count) {
11950 unsigned i;
11952 for (i = 0; i < data->count; i++) {
11953 if (data->controls[i].size)
11954 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11955 else
11956 POST_FIELD_WRITE(data->controls[i].value64);
11959 POST_FIELD_WRITE(data->error_idx);
11960 break;
11962 case VKI_V4L2_S_EXT_CTRLS: {
11963 struct vki_v4l2_ext_controls *data =
11964 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11965 POST_FIELD_WRITE(data->error_idx);
11966 break;
11968 case VKI_V4L2_TRY_EXT_CTRLS: {
11969 struct vki_v4l2_ext_controls *data =
11970 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11971 POST_FIELD_WRITE(data->error_idx);
11972 break;
11974 case VKI_V4L2_ENUM_FRAMESIZES: {
11975 struct vki_v4l2_frmsizeenum *data =
11976 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11977 POST_FIELD_WRITE(data->type);
11978 POST_FIELD_WRITE(data->stepwise);
11979 break;
11981 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11982 struct vki_v4l2_frmivalenum *data =
11983 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11984 POST_FIELD_WRITE(data->type);
11985 POST_FIELD_WRITE(data->stepwise);
11986 break;
11988 case VKI_V4L2_G_ENC_INDEX: {
11989 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11990 POST_MEM_WRITE((Addr)data, sizeof(*data));
11991 break;
11993 case VKI_V4L2_ENCODER_CMD: {
11994 struct vki_v4l2_encoder_cmd *data =
11995 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11996 POST_FIELD_WRITE(data->flags);
11997 break;
11999 case VKI_V4L2_TRY_ENCODER_CMD: {
12000 struct vki_v4l2_encoder_cmd *data =
12001 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12002 POST_FIELD_WRITE(data->flags);
12003 break;
12005 case VKI_V4L2_DBG_S_REGISTER: {
12006 struct vki_v4l2_dbg_register *data =
12007 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12008 POST_FIELD_WRITE(data->size);
12009 break;
12011 case VKI_V4L2_DBG_G_REGISTER: {
12012 struct vki_v4l2_dbg_register *data =
12013 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12014 POST_FIELD_WRITE(data->val);
12015 POST_FIELD_WRITE(data->size);
12016 break;
12018 case VKI_V4L2_G_DV_TIMINGS: {
12019 struct vki_v4l2_dv_timings *data =
12020 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12021 POST_MEM_WRITE((Addr)data, sizeof(*data));
12022 break;
12024 case VKI_V4L2_DQEVENT: {
12025 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12026 POST_MEM_WRITE((Addr)data, sizeof(*data));
12027 break;
12029 case VKI_V4L2_CREATE_BUFS: {
12030 struct vki_v4l2_create_buffers *data =
12031 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12032 POST_FIELD_WRITE(data->index);
12033 break;
12035 case VKI_V4L2_G_SELECTION: {
12036 struct vki_v4l2_selection *data =
12037 (struct vki_v4l2_selection *)(Addr)ARG3;
12038 POST_FIELD_WRITE(data->r);
12039 break;
12041 case VKI_V4L2_S_SELECTION: {
12042 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12043 POST_FIELD_WRITE(data->r);
12044 break;
12046 case VKI_V4L2_DECODER_CMD: {
12047 struct vki_v4l2_decoder_cmd *data =
12048 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12049 POST_FIELD_WRITE(data->flags);
12050 break;
12052 case VKI_V4L2_TRY_DECODER_CMD: {
12053 struct vki_v4l2_decoder_cmd *data =
12054 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12055 POST_FIELD_WRITE(data->flags);
12056 break;
12058 case VKI_V4L2_ENUM_DV_TIMINGS: {
12059 struct vki_v4l2_enum_dv_timings *data =
12060 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12061 POST_FIELD_WRITE(data->timings);
12062 break;
12064 case VKI_V4L2_QUERY_DV_TIMINGS: {
12065 struct vki_v4l2_dv_timings *data =
12066 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12067 POST_MEM_WRITE((Addr)data, sizeof(*data));
12068 break;
12070 case VKI_V4L2_DV_TIMINGS_CAP: {
12071 struct vki_v4l2_dv_timings_cap *data =
12072 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12073 POST_MEM_WRITE((Addr)data, sizeof(*data));
12074 break;
12076 case VKI_V4L2_ENUM_FREQ_BANDS: {
12077 struct vki_v4l2_frequency_band *data =
12078 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12079 POST_FIELD_WRITE(data->capability);
12080 POST_FIELD_WRITE(data->rangelow);
12081 POST_FIELD_WRITE(data->rangehigh);
12082 POST_FIELD_WRITE(data->modulation);
12083 break;
12085 case VKI_V4L2_DBG_G_CHIP_INFO: {
12086 struct vki_v4l2_dbg_chip_info *data =
12087 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12088 POST_FIELD_WRITE(data->name);
12089 POST_FIELD_WRITE(data->flags);
12090 break;
12092 case VKI_V4L2_QUERY_EXT_CTRL: {
12093 struct vki_v4l2_query_ext_ctrl *data =
12094 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12095 POST_MEM_WRITE((Addr)&data->type,
12096 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12097 break;
12100 case VKI_V4L2_SUBDEV_S_FMT:
12101 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12102 case VKI_V4L2_SUBDEV_S_CROP:
12103 case VKI_V4L2_SUBDEV_S_SELECTION:
12104 break;
12106 case VKI_V4L2_SUBDEV_G_FMT: {
12107 struct vki_v4l2_subdev_format *data =
12108 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12109 POST_FIELD_WRITE(data->format);
12110 break;
12112 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12113 struct vki_v4l2_subdev_frame_interval *data =
12114 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12115 POST_FIELD_WRITE(data->interval);
12116 break;
12118 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12119 struct vki_v4l2_subdev_mbus_code_enum *data =
12120 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12121 POST_FIELD_WRITE(data->code);
12122 break;
12124 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12125 struct vki_v4l2_subdev_frame_size_enum *data =
12126 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12127 POST_FIELD_WRITE(data->min_width);
12128 POST_FIELD_WRITE(data->min_height);
12129 POST_FIELD_WRITE(data->max_width);
12130 POST_FIELD_WRITE(data->max_height);
12131 break;
12133 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12134 struct vki_v4l2_subdev_frame_interval_enum *data =
12135 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12136 POST_FIELD_WRITE(data->interval);
12137 break;
12139 case VKI_V4L2_SUBDEV_G_CROP: {
12140 struct vki_v4l2_subdev_crop *data =
12141 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12142 POST_FIELD_WRITE(data->rect);
12143 break;
12145 case VKI_V4L2_SUBDEV_G_SELECTION: {
12146 struct vki_v4l2_subdev_selection *data =
12147 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12148 POST_FIELD_WRITE(data->r);
12149 break;
12151 case VKI_MEDIA_IOC_DEVICE_INFO: {
12152 struct vki_media_device_info *data =
12153 (struct vki_media_device_info *)(Addr)ARG3;
12154 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12155 break;
12157 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12158 struct vki_media_entity_desc *data =
12159 (struct vki_media_entity_desc *)(Addr)ARG3;
12160 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12161 break;
12163 case VKI_MEDIA_IOC_ENUM_LINKS:
12165 * This ioctl does write to the provided pointers, but it's not
12166 * possible to deduce the size of the array those pointers point to.
12168 break;
12169 case VKI_MEDIA_IOC_SETUP_LINK:
12170 break;
12172 /* Serial */
12173 case VKI_TIOCGSERIAL: {
12174 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12175 POST_MEM_WRITE((Addr)data, sizeof(*data));
12176 break;
12178 case VKI_TIOCSSERIAL:
12179 break;
12181 case VKI_PERF_EVENT_IOC_ENABLE:
12182 case VKI_PERF_EVENT_IOC_DISABLE:
12183 case VKI_PERF_EVENT_IOC_REFRESH:
12184 case VKI_PERF_EVENT_IOC_RESET:
12185 case VKI_PERF_EVENT_IOC_PERIOD:
12186 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12187 case VKI_PERF_EVENT_IOC_SET_FILTER:
12188 case VKI_PERF_EVENT_IOC_SET_BPF:
12189 break;
12191 case VKI_PERF_EVENT_IOC_ID:
12192 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12193 break;
12195 /* Pulse Per Second (PPS) */
12196 case VKI_PPS_GETPARAMS: {
12197 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12198 POST_MEM_WRITE((Addr)data, sizeof(*data));
12199 break;
12201 case VKI_PPS_GETCAP:
12202 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12203 break;
12204 case VKI_PPS_FETCH: {
12205 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12206 POST_FIELD_WRITE(data->info);
12207 break;
12209 case VKI_PPS_SETPARAMS:
12210 case VKI_PPS_KC_BIND:
12211 break;
12213 /* PTP Hardware Clock */
12214 case VKI_PTP_CLOCK_GETCAPS: {
12215 struct vki_ptp_clock_caps *data =
12216 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12217 POST_MEM_WRITE((Addr)data, sizeof(*data));
12218 break;
12220 case VKI_PTP_SYS_OFFSET: {
12221 struct vki_ptp_sys_offset *data =
12222 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12223 POST_MEM_WRITE((Addr)data->ts,
12224 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12225 break;
12227 case VKI_PTP_PIN_GETFUNC: {
12228 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12229 POST_MEM_WRITE((Addr)data, sizeof(*data));
12230 break;
12232 case VKI_PTP_SYS_OFFSET_PRECISE: {
12233 struct vki_ptp_sys_offset_precise *data =
12234 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12235 POST_MEM_WRITE((Addr)data, sizeof(*data));
12236 break;
12238 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12239 struct vki_ptp_sys_offset_extended *data =
12240 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12241 POST_MEM_WRITE((Addr)data->ts,
12242 3 * data->n_samples * sizeof(data->ts[0][0]));
12243 break;
12245 case VKI_PTP_EXTTS_REQUEST:
12246 case VKI_PTP_PEROUT_REQUEST:
12247 case VKI_PTP_ENABLE_PPS:
12248 case VKI_PTP_PIN_SETFUNC:
12249 break;
12251 default:
12252 /* EVIOC* are variable length and return size written on success */
12253 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12254 case VKI_EVIOCGNAME(0):
12255 case VKI_EVIOCGPHYS(0):
12256 case VKI_EVIOCGUNIQ(0):
12257 case VKI_EVIOCGKEY(0):
12258 case VKI_EVIOCGLED(0):
12259 case VKI_EVIOCGSND(0):
12260 case VKI_EVIOCGSW(0):
12261 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12262 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12263 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12264 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12265 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12266 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12267 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12268 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12269 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12270 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12271 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12272 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12273 if (RES > 0)
12274 POST_MEM_WRITE(ARG3, RES);
12275 break;
12276 default:
12277 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12278 break;
12280 break;
12283 post_sys_ioctl__out:
12284 {} /* keep C compilers happy */
12287 /* ---------------------------------------------------------------------
12288 socketcall wrapper helpers
12289 ------------------------------------------------------------------ */
12291 void
12292 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12293 UWord arg0, UWord arg1, UWord arg2,
12294 UWord arg3, UWord arg4 )
12296 /* int getsockopt(int s, int level, int optname,
12297 void *optval, socklen_t *optlen); */
12298 Addr optval_p = arg3;
12299 Addr optlen_p = arg4;
12300 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12301 if (optval_p != (Addr)NULL) {
12302 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12303 "socketcall.getsockopt(optval)",
12304 "socketcall.getsockopt(optlen)" );
12305 if (arg1 == VKI_SOL_SCTP &&
12306 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12307 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12309 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12310 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12311 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12312 (Addr)ga->addrs, address_bytes );
12317 void
12318 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12319 SysRes res,
12320 UWord arg0, UWord arg1, UWord arg2,
12321 UWord arg3, UWord arg4 )
12323 Addr optval_p = arg3;
12324 Addr optlen_p = arg4;
12325 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12326 if (optval_p != (Addr)NULL) {
12327 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12328 "socketcall.getsockopt(optlen_out)" );
12329 if (arg1 == VKI_SOL_SCTP &&
12330 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12331 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12333 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12334 struct vki_sockaddr *a = ga->addrs;
12335 int i;
12336 for (i = 0; i < ga->addr_num; i++) {
12337 int sl = 0;
12338 if (a->sa_family == VKI_AF_INET)
12339 sl = sizeof(struct vki_sockaddr_in);
12340 else if (a->sa_family == VKI_AF_INET6)
12341 sl = sizeof(struct vki_sockaddr_in6);
12342 else {
12343 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12344 "address type %d\n", a->sa_family);
12346 a = (struct vki_sockaddr*)((char*)a + sl);
12348 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12353 void
12354 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12355 UWord arg0, UWord arg1, UWord arg2,
12356 UWord arg3, UWord arg4 )
12358 /* int setsockopt(int s, int level, int optname,
12359 const void *optval, socklen_t optlen); */
12360 Addr optval_p = arg3;
12361 if (optval_p != (Addr)NULL) {
12363 * OK, let's handle at least some setsockopt levels and options
12364 * ourselves, so we don't get false claims of references to
12365 * uninitialized memory (such as padding in structures) and *do*
12366 * check what pointers in the argument point to.
12368 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12370 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12373 * struct sock_fprog has a 16-bit count of instructions,
12374 * followed by a pointer to an array of those instructions.
12375 * There's padding between those two elements.
12377 * So that we don't bogusly complain about the padding bytes,
12378 * we just report that we read len and and filter.
12380 * We then make sure that what filter points to is valid.
12382 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12383 (Addr)&fp->len, sizeof(fp->len) );
12384 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12385 (Addr)&fp->filter, sizeof(fp->filter) );
12387 /* len * sizeof (*filter) */
12388 if (fp->filter != NULL)
12390 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12391 (Addr)(fp->filter),
12392 fp->len * sizeof(*fp->filter) );
12395 else
12397 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12398 arg3, /* optval */
12399 arg4 /* optlen */ );
12404 void
12405 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12406 UWord arg1, UWord arg2, UWord arg3,
12407 UWord arg4, UWord arg5 )
12409 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12410 HChar name[40]; // large enough
12411 UInt i;
12412 for (i = 0; i < arg3; i++) {
12413 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12414 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12415 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12416 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12418 if (arg5)
12419 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12422 void
12423 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12424 UWord arg1, UWord arg2, UWord arg3,
12425 UWord arg4, UWord arg5 )
12427 if (res > 0) {
12428 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12429 HChar name[32]; // large enough
12430 UInt i;
12431 for (i = 0; i < res; i++) {
12432 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12433 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12434 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12439 void
12440 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12441 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12443 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12444 HChar name[40]; // large enough
12445 UInt i;
12446 for (i = 0; i < arg3; i++) {
12447 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12448 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12449 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12450 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12454 void
12455 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12456 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12458 if (res > 0) {
12459 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12460 UInt i;
12461 for (i = 0; i < res; i++) {
12462 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12467 /* ---------------------------------------------------------------------
12468 ptrace wrapper helpers
12469 ------------------------------------------------------------------ */
12471 void
12472 ML_(linux_POST_traceme) ( ThreadId tid )
12474 ThreadState *tst = VG_(get_ThreadState)(tid);
12475 tst->ptrace = VKI_PT_PTRACED;
12478 void
12479 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12481 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12483 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12484 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12485 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12486 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12487 (Addr) iov->iov_base, iov->iov_len);
12491 void
12492 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12494 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12496 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12497 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12498 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12499 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12500 (Addr) iov->iov_base, iov->iov_len);
12504 void
12505 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12507 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12509 /* XXX: The actual amount of data written by the kernel might be
12510 less than iov_len, depending on the regset (arg3). */
12511 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12514 PRE(sys_kcmp)
12516 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12517 SARG1, SARG2, SARG3, ARG4, ARG5);
12518 switch (ARG3) {
12519 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12520 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12521 /* Most of the comparison types don't look at |idx1| or
12522 |idx2|. */
12523 PRE_REG_READ3(long, "kcmp",
12524 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12525 break;
12526 case VKI_KCMP_FILE:
12527 default:
12528 PRE_REG_READ5(long, "kcmp",
12529 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12530 unsigned long, idx1, unsigned long, idx2);
12531 break;
12535 /* ---------------------------------------------------------------------
12536 bpf wrappers
12537 ------------------------------------------------------------------ */
12539 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12541 HChar path[32], buf[1024]; /* large enough */
12542 SysRes sres;
12543 HChar *comp;
12544 Int proc_fd;
12546 *key_size = 0;
12547 *value_size = 0;
12549 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12550 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12551 if (sr_isError(sres))
12552 return False;
12553 proc_fd = sr_Res(sres);
12555 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12556 return False;
12557 VG_(close)(proc_fd);
12559 comp = VG_(strstr)(buf, "key_size:");
12560 if (comp)
12561 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12563 comp = VG_(strstr)(buf, "value_size:");
12564 if (comp)
12565 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12567 return (*key_size && *value_size);
12571 * From a file descriptor for an eBPF object, try to determine the size of the
12572 * struct that will be written, i.e. determine if object is a map or a program.
12573 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12574 * search for strings "prog_type" or "map_type".
12576 static UInt bpf_obj_get_info_size(Int fd)
12578 HChar path[32], buf[1024]; /* large enough */
12579 SysRes sres;
12580 Int proc_fd;
12582 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12583 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12584 if (sr_isError(sres))
12585 return 0;
12586 proc_fd = sr_Res(sres);
12588 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12589 return 0;
12590 VG_(close)(proc_fd);
12592 if (VG_(strstr)(buf, "prog_type:"))
12593 return sizeof(struct vki_bpf_prog_info);
12595 if (VG_(strstr)(buf, "map_type:"))
12596 return sizeof(struct vki_bpf_map_info);
12598 return 0;
12601 PRE(sys_bpf)
12603 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12604 UInt res, key_size, value_size;
12606 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12607 (Word)ARG1, ARG2, ARG3);
12608 PRE_REG_READ3(long, "bpf",
12609 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12610 switch (ARG1) {
12611 case VKI_BPF_PROG_GET_NEXT_ID:
12612 case VKI_BPF_MAP_GET_NEXT_ID:
12613 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12614 break;
12615 case VKI_BPF_PROG_GET_FD_BY_ID:
12616 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12617 break;
12618 case VKI_BPF_MAP_GET_FD_BY_ID:
12619 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12620 break;
12621 case VKI_BPF_BTF_GET_FD_BY_ID:
12622 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12623 break;
12624 case VKI_BPF_MAP_CREATE:
12625 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12626 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12627 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12628 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12629 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12630 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12631 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12632 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12633 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12634 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12635 switch (attr->map_type) {
12636 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12637 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12638 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12639 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12640 SET_STATUS_Failure(VKI_EBADF);
12641 break;
12642 case VKI_BPF_MAP_TYPE_ARRAY:
12643 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12644 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12645 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12646 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12647 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12648 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12649 SET_STATUS_Failure(VKI_EBADF);
12650 break;
12654 break;
12655 case VKI_BPF_MAP_TYPE_UNSPEC:
12656 case VKI_BPF_MAP_TYPE_HASH:
12657 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12658 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12659 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12660 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12661 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12662 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12663 case VKI_BPF_MAP_TYPE_LRU_HASH:
12664 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12665 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12666 case VKI_BPF_MAP_TYPE_DEVMAP:
12667 case VKI_BPF_MAP_TYPE_SOCKMAP:
12668 case VKI_BPF_MAP_TYPE_CPUMAP:
12669 case VKI_BPF_MAP_TYPE_XSKMAP:
12670 case VKI_BPF_MAP_TYPE_SOCKHASH:
12671 default:
12672 break;
12674 break;
12675 case VKI_BPF_MAP_LOOKUP_ELEM:
12676 /* Perform a lookup on an eBPF map. Read key, write value. */
12677 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12678 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12679 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12680 if (ML_(safe_to_deref)(attr, ARG3)) {
12681 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12682 SET_STATUS_Failure(VKI_EBADF);
12683 break;
12685 /* Get size of key and value for this map. */
12686 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12687 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12688 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12691 break;
12692 case VKI_BPF_MAP_UPDATE_ELEM:
12693 /* Add or update a map element in kernel. Read key, read value. */
12694 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12695 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12696 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12697 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12698 if (ML_(safe_to_deref)(attr, ARG3)) {
12699 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12700 SET_STATUS_Failure(VKI_EBADF);
12701 break;
12703 /* Get size of key and value for this map. */
12704 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12705 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12706 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12709 break;
12710 case VKI_BPF_MAP_DELETE_ELEM:
12711 /* Delete a map element in kernel. Read key from user space. */
12712 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12713 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12714 if (ML_(safe_to_deref)(attr, ARG3)) {
12715 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12716 SET_STATUS_Failure(VKI_EBADF);
12717 break;
12719 /* Get size of key for this map. */
12720 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12721 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12723 break;
12724 case VKI_BPF_MAP_GET_NEXT_KEY:
12725 /* From a key, get next key for the map. Read key, write next key. */
12726 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12727 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12728 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12729 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12730 if (ML_(safe_to_deref)(attr, ARG3)) {
12731 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12732 SET_STATUS_Failure(VKI_EBADF);
12733 break;
12735 /* Get size of key for this map. */
12736 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12737 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12738 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12741 break;
12742 case VKI_BPF_PROG_LOAD:
12743 /* Load a program into the kernel from an array of instructions. */
12744 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12745 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12746 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12747 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12748 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12749 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12750 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12751 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12752 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12753 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12754 if (ML_(safe_to_deref)(attr, ARG3)) {
12755 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12756 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12757 /* Read instructions, license, program name. */
12758 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12759 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12760 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12761 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12762 /* Possibly write up to log_len into user space log buffer. */
12763 if (attr->log_level || attr->log_size || attr->log_buf)
12764 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12766 break;
12767 case VKI_BPF_OBJ_PIN:
12768 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12769 /* fall through */
12770 case VKI_BPF_OBJ_GET:
12771 /* Get pinned eBPF program or map. Read path name. */
12772 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12773 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12774 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12775 if (ML_(safe_to_deref)(attr, ARG3)) {
12776 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12777 SET_STATUS_Failure(VKI_EBADF);
12778 break;
12780 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12782 break;
12783 case VKI_BPF_PROG_ATTACH:
12784 case VKI_BPF_PROG_DETACH:
12785 /* Detach eBPF program from kernel attach point. */
12786 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12787 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12788 if (ML_(safe_to_deref)(attr, ARG3)) {
12789 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12790 SET_STATUS_Failure(VKI_EBADF);
12791 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12792 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12793 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12794 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12795 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12796 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12797 SET_STATUS_Failure(VKI_EBADF);
12800 break;
12801 case VKI_BPF_PROG_TEST_RUN:
12802 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12803 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12804 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12805 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12806 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12807 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12808 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12809 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12810 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12811 if (ML_(safe_to_deref)(attr, ARG3)) {
12812 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12813 SET_STATUS_Failure(VKI_EBADF);
12814 break;
12816 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12817 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12818 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12820 break;
12821 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12822 /* Get info for eBPF map or program. Write info. */
12823 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12824 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12825 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12826 if (ML_(safe_to_deref)(attr, ARG3)) {
12827 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12828 SET_STATUS_Failure(VKI_EBADF);
12829 break;
12831 /* Get size of struct to write: is object a program or a map? */
12832 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12833 if (res)
12834 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12835 VG_MIN(attr->info.info_len, res));
12836 else
12837 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12838 VG_MIN(attr->info.info_len,
12839 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12840 sizeof(struct vki_bpf_map_info)),
12841 sizeof(struct vki_bpf_btf_info))));
12843 break;
12844 case VKI_BPF_PROG_QUERY:
12846 * Query list of eBPF program attached to cgroup.
12847 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12849 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12850 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12851 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12852 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12853 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12854 if (ML_(safe_to_deref)(attr, ARG3)) {
12855 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12856 SET_STATUS_Failure(VKI_EBADF);
12857 break;
12859 if (attr->query.prog_cnt > 0) {
12860 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12861 if (attr->query.prog_ids) {
12862 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12863 attr->query.prog_cnt * sizeof(__vki_u32));
12867 break;
12868 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12869 /* Open raw tracepoint. Read tracepoint name. */
12870 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12871 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12872 if (ML_(safe_to_deref)(attr, ARG3)) {
12873 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12874 "bpf", tid, False)) {
12875 SET_STATUS_Failure(VKI_EBADF);
12876 break;
12878 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12879 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
12880 "bpf(attr->raw_tracepoint.name)");
12882 break;
12883 case VKI_BPF_BTF_LOAD:
12884 /* Load BTF information about a program into the kernel. */
12885 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
12886 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
12887 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
12888 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
12889 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
12890 if (ML_(safe_to_deref)(attr, ARG3)) {
12891 /* Read BTF data. */
12892 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
12893 /* Possibly write up to btf_log_len into user space log buffer. */
12894 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
12895 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
12896 attr->btf_log_buf, attr->btf_log_size);
12898 break;
12899 case VKI_BPF_TASK_FD_QUERY:
12900 /* Get info about the task. Write collected info. */
12901 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
12902 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
12903 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
12904 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
12905 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
12906 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12907 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12908 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12909 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12910 if (ML_(safe_to_deref)(attr, ARG3)) {
12911 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
12912 SET_STATUS_Failure(VKI_EBADF);
12913 break;
12915 if (attr->task_fd_query.buf_len > 0) {
12916 /* Write task or perf event name. */
12917 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
12918 attr->task_fd_query.buf,
12919 attr->task_fd_query.buf_len);
12922 break;
12923 default:
12924 VG_(message)(Vg_DebugMsg,
12925 "FATAL: unhandled eBPF command %lu\n", ARG1);
12926 VG_(core_panic)("... bye!\n");
12927 break;
12931 POST(sys_bpf)
12933 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12934 UInt key_size, value_size;
12936 vg_assert(SUCCESS);
12938 switch (ARG1) {
12939 case VKI_BPF_PROG_GET_NEXT_ID:
12940 case VKI_BPF_MAP_GET_NEXT_ID:
12941 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12942 break;
12943 case VKI_BPF_MAP_UPDATE_ELEM:
12944 case VKI_BPF_MAP_DELETE_ELEM:
12945 case VKI_BPF_OBJ_PIN:
12946 case VKI_BPF_PROG_ATTACH:
12947 case VKI_BPF_PROG_DETACH:
12948 break;
12949 /* Following commands have bpf() return a file descriptor. */
12950 case VKI_BPF_MAP_CREATE:
12951 case VKI_BPF_OBJ_GET:
12952 case VKI_BPF_PROG_GET_FD_BY_ID:
12953 case VKI_BPF_MAP_GET_FD_BY_ID:
12954 case VKI_BPF_BTF_GET_FD_BY_ID:
12955 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12956 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12957 VG_(close)(RES);
12958 SET_STATUS_Failure(VKI_EMFILE);
12959 } else {
12960 if (VG_(clo_track_fds))
12961 ML_(record_fd_open_nameless)(tid, RES);
12963 break;
12965 * TODO: Is there a way to pass information between PRE and POST hooks?
12966 * To avoid querying again for the size of keys and values.
12968 case VKI_BPF_MAP_LOOKUP_ELEM:
12969 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12970 POST_MEM_WRITE(attr->value, value_size);
12971 break;
12972 case VKI_BPF_MAP_GET_NEXT_KEY:
12973 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12974 POST_MEM_WRITE(attr->next_key, key_size);
12975 break;
12976 case VKI_BPF_PROG_LOAD:
12977 /* Return a file descriptor for loaded program, write into log_buf. */
12978 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12979 VG_(close)(RES);
12980 SET_STATUS_Failure(VKI_EMFILE);
12981 } else {
12982 if (VG_(clo_track_fds))
12983 ML_(record_fd_open_nameless)(tid, RES);
12985 if (attr->log_level || attr->log_size || attr->log_buf)
12986 POST_MEM_WRITE(attr->log_buf, attr->log_size);
12987 break;
12988 case VKI_BPF_PROG_TEST_RUN:
12989 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
12990 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12991 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
12992 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
12993 break;
12994 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12995 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
12996 break;
12997 case VKI_BPF_PROG_QUERY:
12998 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12999 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13000 if (attr->query.prog_ids)
13001 POST_MEM_WRITE(attr->query.prog_ids,
13002 attr->query.prog_cnt * sizeof(__vki_u32));
13003 break;
13004 case VKI_BPF_BTF_LOAD:
13005 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13006 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13007 VG_(close)(RES);
13008 SET_STATUS_Failure(VKI_EMFILE);
13009 } else {
13010 if (VG_(clo_track_fds))
13011 ML_(record_fd_open_nameless)(tid, RES);
13013 if (attr->btf_log_level)
13014 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13015 break;
13016 case VKI_BPF_TASK_FD_QUERY:
13017 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13018 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13019 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13020 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13021 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13022 break;
13023 default:
13024 VG_(message)(Vg_DebugMsg,
13025 "FATAL: unhandled eBPF command %lu\n", ARG1);
13026 VG_(core_panic)("... bye!\n");
13027 break;
13031 PRE(sys_copy_file_range)
13033 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13034 ARG4, ARG5, ARG6);
13036 PRE_REG_READ6(vki_size_t, "copy_file_range",
13037 int, "fd_in",
13038 vki_loff_t *, "off_in",
13039 int, "fd_out",
13040 vki_loff_t *, "off_out",
13041 vki_size_t, "len",
13042 unsigned int, "flags");
13044 /* File descriptors are "specially" tracked by valgrind.
13045 valgrind itself uses some, so make sure someone didn't
13046 put in one of our own... */
13047 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13048 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13049 SET_STATUS_Failure( VKI_EBADF );
13050 } else {
13051 /* Now see if the offsets are defined. PRE_MEM_READ will
13052 double check it can dereference them. */
13053 if (ARG2 != 0)
13054 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13055 if (ARG4 != 0)
13056 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13060 PRE(sys_pkey_alloc)
13062 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13064 PRE_REG_READ2(long, "pkey_alloc",
13065 unsigned long, "flags",
13066 unsigned long, "access_rights");
13068 /* The kernel says: pkey_alloc() is always safe to call regardless of
13069 whether or not the operating system supports protection keys. It can be
13070 used in lieu of any other mechanism for detecting pkey support and will
13071 simply fail with the error ENOSPC if the operating system has no pkey
13072 support.
13074 So we simply always return ENOSPC to signal memory protection keys are
13075 not supported under valgrind, unless there are unknown flags, then we
13076 return EINVAL. */
13077 unsigned long pkey_flags = ARG1;
13078 if (pkey_flags != 0)
13079 SET_STATUS_Failure( VKI_EINVAL );
13080 else
13081 SET_STATUS_Failure( VKI_ENOSPC );
13084 PRE(sys_pkey_free)
13086 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13088 PRE_REG_READ1(long, "pkey_free",
13089 unsigned long, "pkey");
13091 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13092 always an error. */
13093 SET_STATUS_Failure( VKI_EINVAL );
13096 PRE(sys_pkey_mprotect)
13098 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13099 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13100 PRE_REG_READ4(long, "pkey_mprotect",
13101 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13102 unsigned long, pkey);
13104 Addr addr = ARG1;
13105 SizeT len = ARG2;
13106 Int prot = ARG3;
13107 Int pkey = ARG4;
13109 /* Since pkey_alloc () can never succeed, see above, any pkey is
13110 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13111 if (pkey != -1)
13112 SET_STATUS_Failure( VKI_EINVAL );
13113 else
13114 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13116 ARG1 = addr;
13117 ARG2 = len;
13118 ARG3 = prot;
13121 POST(sys_pkey_mprotect)
13123 Addr addr = ARG1;
13124 SizeT len = ARG2;
13125 Int prot = ARG3;
13127 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13130 PRE(sys_io_uring_setup)
13132 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13133 ARG1, ARG2);
13134 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13135 struct vki_io_uring_params *, p);
13136 if (ARG2)
13137 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13138 offsetof(struct vki_io_uring_params, sq_off));
13141 POST(sys_io_uring_setup)
13143 vg_assert(SUCCESS);
13144 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13145 VG_(close)(RES);
13146 SET_STATUS_Failure( VKI_EMFILE );
13147 } else {
13148 if (VG_(clo_track_fds))
13149 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
13150 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13151 sizeof(struct vki_io_sqring_offsets) +
13152 sizeof(struct vki_io_cqring_offsets));
13156 PRE(sys_io_uring_enter)
13158 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13159 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13160 FMT_REGWORD "u )",
13161 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13162 PRE_REG_READ6(long, "io_uring_enter",
13163 unsigned int, fd, unsigned int, to_submit,
13164 unsigned int, min_complete, unsigned int, flags,
13165 const void *, sig, unsigned long, sigsz);
13166 if (ARG5)
13167 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13170 POST(sys_io_uring_enter)
13174 PRE(sys_io_uring_register)
13176 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13177 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13178 PRE_REG_READ4(long, "io_uring_register",
13179 unsigned int, fd, unsigned int, opcode,
13180 void *, arg, unsigned int, nr_args);
13181 switch (ARG2) {
13182 case VKI_IORING_REGISTER_BUFFERS:
13183 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13184 break;
13185 case VKI_IORING_UNREGISTER_BUFFERS:
13186 break;
13187 case VKI_IORING_REGISTER_FILES:
13188 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13189 break;
13190 case VKI_IORING_UNREGISTER_FILES:
13191 break;
13192 case VKI_IORING_REGISTER_EVENTFD:
13193 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13194 break;
13195 case VKI_IORING_UNREGISTER_EVENTFD:
13196 break;
13200 POST(sys_io_uring_register)
13204 PRE(sys_execveat)
13206 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13207 PRE_REG_READ5(vki_off_t, "execveat",
13208 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13209 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13211 #if !defined(__NR_execveat)
13212 SET_STATUS_Failure(VKI_ENOSYS);
13213 return;
13214 #endif
13216 char *path = (char*) ARG2;
13217 Addr arg_2 = ARG3;
13218 Addr arg_3 = ARG4;
13219 const HChar *buf;
13220 HChar *abs_path = NULL;
13221 Bool check_at_symlink = False;
13222 Bool check_pathptr = True;
13224 if (ML_(safe_to_deref) (path, 1)) {
13225 /* If pathname is absolute, we'll ignore dirfd
13226 * and just pass the pathname, try to determine
13227 * the absolute path otherwise. */
13228 if (path[0] != '/') {
13229 /* Check dirfd is a valid fd. */
13230 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13231 SET_STATUS_Failure( VKI_EBADF );
13232 return;
13234 /* If pathname is empty and AT_EMPTY_PATH is
13235 set then dirfd describes the whole path. */
13236 if (path[0] == '\0') {
13237 if (ARG5 & VKI_AT_EMPTY_PATH) {
13238 if (VG_(resolve_filename)(ARG1, &buf)) {
13239 VG_(strcpy)(path, buf);
13240 check_pathptr = False;
13244 else if (ARG1 == VKI_AT_FDCWD) {
13245 check_at_symlink = True;
13246 } else
13247 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13248 check_at_symlink = True;
13249 else if (VG_(resolve_filename)(ARG1, &buf)) {
13250 abs_path = VG_(malloc)("execveat",
13251 (VG_(strlen)(buf) + 1
13252 + VG_(strlen)(path) + 1));
13253 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13254 path = abs_path;
13255 check_pathptr = False;
13257 else
13258 path = NULL;
13259 if (check_at_symlink) {
13260 struct vg_stat statbuf;
13261 SysRes statres;
13263 statres = VG_(stat)(path, &statbuf);
13264 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13265 SET_STATUS_Failure( VKI_ELOOP );
13266 return;
13270 } else {
13271 SET_STATUS_Failure(VKI_EFAULT);
13272 return;
13275 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, 1,
13276 check_pathptr);
13278 /* The exec failed, we keep running... cleanup. */
13279 VG_(free)(abs_path);
13285 #undef PRE
13286 #undef POST
13288 #endif // defined(VGO_linux)
13290 /*--------------------------------------------------------------------*/
13291 /*--- end ---*/
13292 /*--------------------------------------------------------------------*/