sys_statx: don't complain if both |filename| and |buf| are NULL.
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob96c309e280f888659718573c3e5be71af4b0b8c2
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_r2 = 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) {
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 cloneflags &= ~VKI_CLONE_VM;
919 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
921 case 0: /* plain fork */
922 SET_STATUS_from_SysRes(
923 ML_(do_fork_clone)(tid,
924 cloneflags, /* flags */
925 (Int*)(Addr)ARG3, /* parent_tidptr */
926 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
927 (Addr)ARG_CHILD_STACK));
928 break;
930 default:
931 /* should we just ENOSYS? */
932 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
933 "x\n", ARG_FLAGS);
934 VG_(message)(Vg_UserMsg, "\n");
935 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
936 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
937 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
938 VG_(unimplemented)
939 ("Valgrind does not support general clone().");
942 if (SUCCESS) {
943 if (ARG_FLAGS & VKI_CLONE_PARENT_SETTID)
944 POST_MEM_WRITE(ARG3, sizeof(Int));
945 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
946 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
948 /* Thread creation was successful; let the child have the chance
949 to run */
950 *flags |= SfYieldAfter;
953 #undef ARG_CHILD_TIDPTR
954 #undef PRA_CHILD_TIDPTR
955 #undef ARG_TLS
956 #undef PRA_TLS
957 #undef ARG_FLAGS
958 #undef PRA_FLAGS
959 #undef ARG_CHILD_STACK
960 #undef PRA_CHILD_STACK
963 /* ---------------------------------------------------------------------
964 *mount wrappers
965 ------------------------------------------------------------------ */
967 PRE(sys_mount)
969 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
970 // We are conservative and check everything, except the memory pointed to
971 // by 'data'.
972 *flags |= SfMayBlock;
973 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
974 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
975 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
976 (HChar*)(Addr)ARG3, ARG4, ARG5);
977 PRE_REG_READ5(long, "mount",
978 char *, source, char *, target, char *, type,
979 unsigned long, flags, void *, data);
980 if (ARG1)
981 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
982 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
983 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
986 PRE(sys_oldumount)
988 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
989 PRE_REG_READ1(long, "umount", char *, path);
990 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
993 PRE(sys_umount)
995 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
996 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
997 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1000 /* Not actually wrapped by GLibc but does things with the system
1001 * mounts so it is put here.
1003 PRE(sys_pivot_root)
1005 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1006 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1007 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1008 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1012 /* ---------------------------------------------------------------------
1013 16- and 32-bit uid/gid wrappers
1014 ------------------------------------------------------------------ */
1016 PRE(sys_setfsuid16)
1018 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1019 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1022 PRE(sys_setfsuid)
1024 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1025 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1028 PRE(sys_setfsgid16)
1030 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1031 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1034 PRE(sys_setfsgid)
1036 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1037 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1040 PRE(sys_setresuid16)
1042 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1043 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1044 PRE_REG_READ3(long, "setresuid16",
1045 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1048 PRE(sys_setresuid)
1050 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1051 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1052 PRE_REG_READ3(long, "setresuid",
1053 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1056 PRE(sys_getresuid16)
1058 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1059 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1060 PRE_REG_READ3(long, "getresuid16",
1061 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1062 vki_old_uid_t *, suid);
1063 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1064 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1065 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1067 POST(sys_getresuid16)
1069 vg_assert(SUCCESS);
1070 if (RES == 0) {
1071 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1072 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1073 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1077 PRE(sys_getresuid)
1079 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1080 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1081 PRE_REG_READ3(long, "getresuid",
1082 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1083 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1084 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1085 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1087 POST(sys_getresuid)
1089 vg_assert(SUCCESS);
1090 if (RES == 0) {
1091 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1092 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1093 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1097 PRE(sys_setresgid16)
1099 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1100 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1101 PRE_REG_READ3(long, "setresgid16",
1102 vki_old_gid_t, rgid,
1103 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1106 PRE(sys_setresgid)
1108 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1109 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1110 PRE_REG_READ3(long, "setresgid",
1111 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1114 PRE(sys_getresgid16)
1116 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1117 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1118 PRE_REG_READ3(long, "getresgid16",
1119 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1120 vki_old_gid_t *, sgid);
1121 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1122 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1123 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1125 POST(sys_getresgid16)
1127 vg_assert(SUCCESS);
1128 if (RES == 0) {
1129 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1130 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1131 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1135 PRE(sys_getresgid)
1137 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1138 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1139 PRE_REG_READ3(long, "getresgid",
1140 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1141 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1142 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1143 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1145 POST(sys_getresgid)
1147 vg_assert(SUCCESS);
1148 if (RES == 0) {
1149 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1150 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1151 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1155 /* ---------------------------------------------------------------------
1156 miscellaneous wrappers
1157 ------------------------------------------------------------------ */
1159 PRE(sys_exit_group)
1161 ThreadId t;
1162 ThreadState* tst;
1164 PRINT("exit_group( %ld )", SARG1);
1165 PRE_REG_READ1(void, "exit_group", int, status);
1167 tst = VG_(get_ThreadState)(tid);
1168 /* A little complex; find all the threads with the same threadgroup
1169 as this one (including this one), and mark them to exit */
1170 /* It is unclear how one can get a threadgroup in this process which
1171 is not the threadgroup of the calling thread:
1172 The assignments to threadgroups are:
1173 = 0; /// scheduler.c os_state_clear
1174 = getpid(); /// scheduler.c in child after fork
1175 = getpid(); /// this file, in thread_wrapper
1176 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1177 copying the thread group of the thread doing clone
1178 So, the only case where the threadgroup might be different to the getpid
1179 value is in the child, just after fork. But then the fork syscall is
1180 still going on, the forked thread has had no chance yet to make this
1181 syscall. */
1182 for (t = 1; t < VG_N_THREADS; t++) {
1183 if ( /* not alive */
1184 VG_(threads)[t].status == VgTs_Empty
1186 /* not our group */
1187 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1189 continue;
1190 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1191 the exitreason. */
1192 VG_(threads)[t].os_state.exitcode = ARG1;
1195 /* Indicate in all other threads that the process is exiting.
1196 Then wait using VG_(reap_threads) for these threads to disappear.
1198 Can this give a deadlock if another thread is calling exit in parallel
1199 and would then wait for this thread to disappear ?
1200 The answer is no:
1201 Other threads are either blocked in a syscall or have yielded the CPU.
1203 A thread that has yielded the CPU is trying to get the big lock in
1204 VG_(scheduler). This thread will get the CPU thanks to the call
1205 to VG_(reap_threads). The scheduler will then check for signals,
1206 kill the process if this is a fatal signal, and otherwise prepare
1207 the thread for handling this signal. After this preparation, if
1208 the thread status is VG_(is_exiting), the scheduler exits the thread.
1209 So, a thread that has yielded the CPU does not have a chance to
1210 call exit => no deadlock for this thread.
1212 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1213 to all threads blocked in a syscall.
1214 The syscall will be interrupted, and the control will go to the
1215 scheduler. The scheduler will then return, as the thread is in
1216 exiting state. */
1218 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1219 VG_(reap_threads)(tid);
1220 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1221 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1222 is the thread calling exit_group and so its registers must be considered
1223 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1225 /* We have to claim the syscall already succeeded. */
1226 SET_STATUS_Success(0);
1229 PRE(sys_llseek)
1231 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1232 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1233 ARG1, ARG2, ARG3, ARG4, ARG5);
1234 PRE_REG_READ5(long, "llseek",
1235 unsigned int, fd, unsigned long, offset_high,
1236 unsigned long, offset_low, vki_loff_t *, result,
1237 unsigned int, whence);
1238 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1239 SET_STATUS_Failure( VKI_EBADF );
1240 else
1241 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1243 POST(sys_llseek)
1245 vg_assert(SUCCESS);
1246 if (RES == 0)
1247 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1250 PRE(sys_adjtimex)
1252 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1253 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1254 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1256 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1257 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1259 #define ADJX(bits,field) \
1260 if (tx->modes & (bits)) \
1261 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1262 (Addr)&tx->field, sizeof(tx->field))
1264 if (tx->modes & VKI_ADJ_ADJTIME) {
1265 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1266 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1267 } else {
1268 ADJX(VKI_ADJ_OFFSET, offset);
1269 ADJX(VKI_ADJ_FREQUENCY, freq);
1270 ADJX(VKI_ADJ_MAXERROR, maxerror);
1271 ADJX(VKI_ADJ_ESTERROR, esterror);
1272 ADJX(VKI_ADJ_STATUS, status);
1273 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1274 ADJX(VKI_ADJ_TICK, tick);
1276 #undef ADJX
1279 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1282 POST(sys_adjtimex)
1284 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1287 PRE(sys_clock_adjtime)
1289 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1290 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1291 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1292 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1294 #define ADJX(bits,field) \
1295 if (tx->modes & (bits)) \
1296 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1297 (Addr)&tx->field, sizeof(tx->field))
1299 if (tx->modes & VKI_ADJ_ADJTIME) {
1300 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1301 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1302 } else {
1303 ADJX(VKI_ADJ_OFFSET, offset);
1304 ADJX(VKI_ADJ_FREQUENCY, freq);
1305 ADJX(VKI_ADJ_MAXERROR, maxerror);
1306 ADJX(VKI_ADJ_ESTERROR, esterror);
1307 ADJX(VKI_ADJ_STATUS, status);
1308 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1309 ADJX(VKI_ADJ_TICK, tick);
1311 #undef ADJX
1313 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1316 POST(sys_clock_adjtime)
1318 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1321 PRE(sys_ioperm)
1323 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1324 ARG1, ARG2, SARG3 );
1325 PRE_REG_READ3(long, "ioperm",
1326 unsigned long, from, unsigned long, num, int, turn_on);
1329 PRE(sys_syslog)
1331 *flags |= SfMayBlock;
1332 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1333 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1334 switch (ARG1) {
1335 // The kernel uses magic numbers here, rather than named constants,
1336 // therefore so do we.
1337 case 2: case 3: case 4:
1338 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1339 break;
1340 default:
1341 break;
1344 POST(sys_syslog)
1346 switch (ARG1) {
1347 case 2: case 3: case 4:
1348 POST_MEM_WRITE( ARG2, ARG3 );
1349 break;
1350 default:
1351 break;
1355 PRE(sys_vhangup)
1357 PRINT("sys_vhangup ( )");
1358 PRE_REG_READ0(long, "vhangup");
1361 PRE(sys_sysinfo)
1363 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1364 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1365 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1367 POST(sys_sysinfo)
1369 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1372 PRE(sys_personality)
1374 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1375 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1378 PRE(sys_sysctl)
1380 struct __vki_sysctl_args *args;
1381 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1382 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1383 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1384 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1385 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1386 VKI_PROT_READ)) {
1387 SET_STATUS_Failure( VKI_EFAULT );
1388 return;
1391 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1392 if (args->newval != NULL)
1393 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1394 if (args->oldlenp != NULL) {
1395 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1396 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1399 POST(sys_sysctl)
1401 struct __vki_sysctl_args *args;
1402 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1403 if (args->oldlenp != NULL) {
1404 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1405 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1409 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1410 const char *attr_name)
1412 const HChar *step_str = (const HChar *)str;
1413 SizeT len;
1414 UInt i;
1417 * The name can be up to maxlen bytes long, including the terminating null
1418 * byte. So do not check more than maxlen bytes.
1420 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1421 len = VG_(strnlen)((const HChar *)str, maxlen);
1422 if (len < maxlen)
1423 PRE_MEM_RASCIIZ(attr_name, str);
1424 else
1425 PRE_MEM_READ(attr_name, str, maxlen);
1426 } else {
1428 * Do it the slow way, one byte at a time, while checking for terminating
1429 * '\0'.
1431 for (i = 0; i < maxlen; i++) {
1432 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1433 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1434 break;
1439 PRE(sys_prctl)
1441 *flags |= SfMayBlock;
1442 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1443 switch (ARG1) {
1444 case VKI_PR_SET_PDEATHSIG:
1445 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1446 break;
1447 case VKI_PR_GET_PDEATHSIG:
1448 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1449 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1450 break;
1451 case VKI_PR_GET_DUMPABLE:
1452 PRE_REG_READ1(int, "prctl", int, option);
1453 break;
1454 case VKI_PR_SET_DUMPABLE:
1455 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1456 break;
1457 case VKI_PR_GET_UNALIGN:
1458 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1459 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1460 break;
1461 case VKI_PR_SET_UNALIGN:
1462 PRE_REG_READ2(int, "prctl", int, option, int, value);
1463 break;
1464 case VKI_PR_GET_KEEPCAPS:
1465 PRE_REG_READ1(int, "prctl", int, option);
1466 break;
1467 case VKI_PR_SET_KEEPCAPS:
1468 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1469 break;
1470 case VKI_PR_GET_FPEMU:
1471 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1472 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1473 break;
1474 case VKI_PR_SET_FPEMU:
1475 PRE_REG_READ2(int, "prctl", int, option, int, value);
1476 break;
1477 case VKI_PR_GET_FPEXC:
1478 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1479 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1480 break;
1481 case VKI_PR_SET_FPEXC:
1482 PRE_REG_READ2(int, "prctl", int, option, int, value);
1483 break;
1484 case VKI_PR_GET_TIMING:
1485 PRE_REG_READ1(int, "prctl", int, option);
1486 break;
1487 case VKI_PR_SET_TIMING:
1488 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1489 break;
1490 case VKI_PR_SET_NAME:
1491 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1492 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1493 break;
1494 case VKI_PR_GET_NAME:
1495 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1496 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1497 break;
1498 case VKI_PR_GET_ENDIAN:
1499 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1500 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1501 break;
1502 case VKI_PR_SET_ENDIAN:
1503 PRE_REG_READ2(int, "prctl", int, option, int, value);
1504 break;
1505 case VKI_PR_SET_PTRACER:
1506 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1507 break;
1508 case VKI_PR_SET_SECCOMP:
1509 /* This is a bit feeble in that it uses |option| before checking
1510 it, but at least both sides of the conditional check it. */
1511 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1512 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1513 if (ARG3) {
1514 /* Should check that ARG3 points at a valid struct sock_fprog.
1515 Sounds complex; hence be lame. */
1516 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1517 ARG3, 1 );
1519 } else {
1520 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1522 break;
1523 default:
1524 PRE_REG_READ5(long, "prctl",
1525 int, option, unsigned long, arg2, unsigned long, arg3,
1526 unsigned long, arg4, unsigned long, arg5);
1527 break;
1530 POST(sys_prctl)
1532 switch (ARG1) {
1533 case VKI_PR_GET_PDEATHSIG:
1534 POST_MEM_WRITE(ARG2, sizeof(Int));
1535 break;
1536 case VKI_PR_GET_UNALIGN:
1537 POST_MEM_WRITE(ARG2, sizeof(Int));
1538 break;
1539 case VKI_PR_GET_FPEMU:
1540 POST_MEM_WRITE(ARG2, sizeof(Int));
1541 break;
1542 case VKI_PR_GET_FPEXC:
1543 POST_MEM_WRITE(ARG2, sizeof(Int));
1544 break;
1545 case VKI_PR_GET_NAME:
1546 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1547 break;
1548 case VKI_PR_GET_ENDIAN:
1549 POST_MEM_WRITE(ARG2, sizeof(Int));
1550 break;
1551 case VKI_PR_SET_NAME:
1553 const HChar* new_name = (const HChar*) (Addr)ARG2;
1554 if (new_name) { // Paranoia
1555 ThreadState* tst = VG_(get_ThreadState)(tid);
1556 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1558 /* Don't bother reusing the memory. This is a rare event. */
1559 tst->thread_name =
1560 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1561 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1564 break;
1568 PRE(sys_sendfile)
1570 *flags |= SfMayBlock;
1571 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1572 SARG1, SARG2, ARG3, ARG4);
1573 PRE_REG_READ4(ssize_t, "sendfile",
1574 int, out_fd, int, in_fd, vki_off_t *, offset,
1575 vki_size_t, count);
1576 if (ARG3 != 0)
1577 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1579 POST(sys_sendfile)
1581 if (ARG3 != 0 ) {
1582 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1586 PRE(sys_sendfile64)
1588 *flags |= SfMayBlock;
1589 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1590 SARG1, SARG2, ARG3, ARG4);
1591 PRE_REG_READ4(ssize_t, "sendfile64",
1592 int, out_fd, int, in_fd, vki_loff_t *, offset,
1593 vki_size_t, count);
1594 if (ARG3 != 0)
1595 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1597 POST(sys_sendfile64)
1599 if (ARG3 != 0 ) {
1600 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1604 PRE(sys_futex)
1607 arg param used by ops
1609 ARG1 - u32 *futex all
1610 ARG2 - int op
1611 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1612 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1613 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1614 ARG6 - int val3 CMP_REQUEUE
1616 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1617 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1618 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1619 case VKI_FUTEX_CMP_REQUEUE:
1620 case VKI_FUTEX_WAKE_OP:
1621 case VKI_FUTEX_CMP_REQUEUE_PI:
1622 PRE_REG_READ6(long, "futex",
1623 vki_u32 *, futex, int, op, int, val,
1624 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1625 break;
1626 case VKI_FUTEX_REQUEUE:
1627 case VKI_FUTEX_WAIT_REQUEUE_PI:
1628 PRE_REG_READ5(long, "futex",
1629 vki_u32 *, futex, int, op, int, val,
1630 struct timespec *, utime, vki_u32 *, uaddr2);
1631 break;
1632 case VKI_FUTEX_WAIT_BITSET:
1633 /* Check that the address at least begins in client-accessible area. */
1634 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1635 SET_STATUS_Failure( VKI_EFAULT );
1636 return;
1638 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1639 PRE_REG_READ4(long, "futex",
1640 vki_u32 *, futex, int, op, int, val,
1641 struct timespec *, utime);
1642 } else {
1643 /* Note argument 5 is unused, but argument 6 is used.
1644 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1645 PRE_REG_READ4(long, "futex",
1646 vki_u32 *, futex, int, op, int, val,
1647 struct timespec *, utime);
1648 if (VG_(tdict).track_pre_reg_read)
1649 PRA6("futex",int,val3);
1651 break;
1652 case VKI_FUTEX_WAKE_BITSET:
1653 PRE_REG_READ3(long, "futex",
1654 vki_u32 *, futex, int, op, int, val);
1655 if (VG_(tdict).track_pre_reg_read) {
1656 PRA6("futex", int, val3);
1658 break;
1659 case VKI_FUTEX_WAIT:
1660 case VKI_FUTEX_LOCK_PI:
1661 PRE_REG_READ4(long, "futex",
1662 vki_u32 *, futex, int, op, int, val,
1663 struct timespec *, utime);
1664 break;
1665 case VKI_FUTEX_WAKE:
1666 case VKI_FUTEX_FD:
1667 PRE_REG_READ3(long, "futex",
1668 vki_u32 *, futex, int, op, int, val);
1669 break;
1670 case VKI_FUTEX_TRYLOCK_PI:
1671 case VKI_FUTEX_UNLOCK_PI:
1672 default:
1673 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1674 break;
1677 *flags |= SfMayBlock;
1679 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1680 case VKI_FUTEX_WAIT:
1681 case VKI_FUTEX_LOCK_PI:
1682 case VKI_FUTEX_WAIT_BITSET:
1683 case VKI_FUTEX_WAIT_REQUEUE_PI:
1684 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1685 if (ARG4 != 0)
1686 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1687 break;
1689 case VKI_FUTEX_REQUEUE:
1690 case VKI_FUTEX_CMP_REQUEUE:
1691 case VKI_FUTEX_CMP_REQUEUE_PI:
1692 case VKI_FUTEX_WAKE_OP:
1693 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1694 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1695 break;
1697 case VKI_FUTEX_FD:
1698 case VKI_FUTEX_TRYLOCK_PI:
1699 case VKI_FUTEX_UNLOCK_PI:
1700 case VKI_FUTEX_WAKE:
1701 case VKI_FUTEX_WAKE_BITSET:
1702 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1703 break;
1705 default:
1706 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1707 break;
1710 POST(sys_futex)
1712 vg_assert(SUCCESS);
1713 POST_MEM_WRITE( ARG1, sizeof(int) );
1714 if (ARG2 == VKI_FUTEX_FD) {
1715 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1716 VG_(close)(RES);
1717 SET_STATUS_Failure( VKI_EMFILE );
1718 } else {
1719 if (VG_(clo_track_fds))
1720 ML_(record_fd_open_nameless)(tid, RES);
1725 PRE(sys_set_robust_list)
1727 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1728 FMT_REGWORD "u )", ARG1, ARG2);
1729 PRE_REG_READ2(long, "set_robust_list",
1730 struct vki_robust_list_head *, head, vki_size_t, len);
1732 /* Just check the robust_list_head structure is readable - don't
1733 try and chase the list as the kernel will only read it when
1734 the thread exits so the current contents is irrelevant. */
1735 if (ARG1 != 0)
1736 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1739 PRE(sys_get_robust_list)
1741 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1742 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1743 PRE_REG_READ3(long, "get_robust_list",
1744 int, pid,
1745 struct vki_robust_list_head **, head_ptr,
1746 vki_size_t *, len_ptr);
1747 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1748 ARG2, sizeof(struct vki_robust_list_head *));
1749 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1750 ARG3, sizeof(struct vki_size_t *));
1752 POST(sys_get_robust_list)
1754 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1755 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1758 struct pselect_sized_sigset {
1759 const vki_sigset_t *ss;
1760 vki_size_t ss_len;
1762 struct pselect_adjusted_sigset {
1763 struct pselect_sized_sigset ss; /* The actual syscall arg */
1764 vki_sigset_t adjusted_ss;
1767 PRE(sys_pselect6)
1769 *flags |= SfMayBlock | SfPostOnFail;
1770 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1771 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1772 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1773 PRE_REG_READ6(long, "pselect6",
1774 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1775 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1776 void *, sig);
1777 // XXX: this possibly understates how much memory is read.
1778 if (ARG2 != 0)
1779 PRE_MEM_READ( "pselect6(readfds)",
1780 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1781 if (ARG3 != 0)
1782 PRE_MEM_READ( "pselect6(writefds)",
1783 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1784 if (ARG4 != 0)
1785 PRE_MEM_READ( "pselect6(exceptfds)",
1786 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1787 if (ARG5 != 0)
1788 PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1789 if (ARG6 != 0) {
1790 const struct pselect_sized_sigset *pss =
1791 (struct pselect_sized_sigset *)(Addr)ARG6;
1792 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1793 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1794 ARG6 = 1; /* Something recognisable to POST() hook. */
1795 } else {
1796 struct pselect_adjusted_sigset *pas;
1797 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1798 ARG6 = (Addr)pas;
1799 pas->ss.ss = (void *)1;
1800 pas->ss.ss_len = pss->ss_len;
1801 if (pss->ss_len == sizeof(*pss->ss)) {
1802 if (pss->ss == NULL) {
1803 pas->ss.ss = NULL;
1804 } else {
1805 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1806 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1807 pas->adjusted_ss = *pss->ss;
1808 pas->ss.ss = &pas->adjusted_ss;
1809 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1816 POST(sys_pselect6)
1818 if (ARG6 != 0 && ARG6 != 1) {
1819 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1823 PRE(sys_ppoll)
1825 UInt i;
1826 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1827 *flags |= SfMayBlock | SfPostOnFail;
1828 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1829 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1830 ARG1, ARG2, ARG3, ARG4, ARG5);
1831 PRE_REG_READ5(long, "ppoll",
1832 struct vki_pollfd *, ufds, unsigned int, nfds,
1833 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1834 vki_size_t, sigsetsize);
1836 for (i = 0; i < ARG2; i++) {
1837 PRE_MEM_READ( "ppoll(ufds.fd)",
1838 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1839 PRE_MEM_READ( "ppoll(ufds.events)",
1840 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1841 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1842 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1845 if (ARG3)
1846 PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1847 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1848 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1849 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1850 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
1851 ARG4 = 1; /* Something recognisable to POST() hook. */
1852 } else {
1853 vki_sigset_t *vg_sigmask =
1854 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
1855 ARG4 = (Addr)vg_sigmask;
1856 *vg_sigmask = *guest_sigmask;
1857 VG_(sanitize_client_sigmask)(vg_sigmask);
1862 POST(sys_ppoll)
1864 vg_assert(SUCCESS || FAILURE);
1865 if (SUCCESS && (RES >= 0)) {
1866 UInt i;
1867 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1868 for (i = 0; i < ARG2; i++)
1869 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1871 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
1872 VG_(free)((vki_sigset_t *) (Addr)ARG4);
1877 /* ---------------------------------------------------------------------
1878 epoll_* wrappers
1879 ------------------------------------------------------------------ */
1881 PRE(sys_epoll_create)
1883 PRINT("sys_epoll_create ( %ld )", SARG1);
1884 PRE_REG_READ1(long, "epoll_create", int, size);
1886 POST(sys_epoll_create)
1888 vg_assert(SUCCESS);
1889 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
1890 VG_(close)(RES);
1891 SET_STATUS_Failure( VKI_EMFILE );
1892 } else {
1893 if (VG_(clo_track_fds))
1894 ML_(record_fd_open_nameless) (tid, RES);
1898 PRE(sys_epoll_create1)
1900 PRINT("sys_epoll_create1 ( %ld )", SARG1);
1901 PRE_REG_READ1(long, "epoll_create1", int, flags);
1903 POST(sys_epoll_create1)
1905 vg_assert(SUCCESS);
1906 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1907 VG_(close)(RES);
1908 SET_STATUS_Failure( VKI_EMFILE );
1909 } else {
1910 if (VG_(clo_track_fds))
1911 ML_(record_fd_open_nameless) (tid, RES);
1915 PRE(sys_epoll_ctl)
1917 static const HChar* epoll_ctl_s[3] = {
1918 "EPOLL_CTL_ADD",
1919 "EPOLL_CTL_DEL",
1920 "EPOLL_CTL_MOD"
1922 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
1923 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
1924 PRE_REG_READ4(long, "epoll_ctl",
1925 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1926 if (ARG2 != VKI_EPOLL_CTL_DEL)
1927 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
1930 PRE(sys_epoll_wait)
1932 *flags |= SfMayBlock;
1933 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
1934 SARG1, ARG2, SARG3, SARG4);
1935 PRE_REG_READ4(long, "epoll_wait",
1936 int, epfd, struct vki_epoll_event *, events,
1937 int, maxevents, int, timeout);
1938 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1940 POST(sys_epoll_wait)
1942 vg_assert(SUCCESS);
1943 if (RES > 0)
1944 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1947 PRE(sys_epoll_pwait)
1949 *flags |= SfMayBlock;
1950 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
1951 FMT_REGWORD "x, %" FMT_REGWORD "u )",
1952 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
1953 PRE_REG_READ6(long, "epoll_pwait",
1954 int, epfd, struct vki_epoll_event *, events,
1955 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1956 vki_size_t, sigsetsize);
1957 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1958 if (ARG5)
1959 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1961 POST(sys_epoll_pwait)
1963 vg_assert(SUCCESS);
1964 if (RES > 0)
1965 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1968 PRE(sys_eventfd)
1970 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
1971 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1973 POST(sys_eventfd)
1975 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1976 VG_(close)(RES);
1977 SET_STATUS_Failure( VKI_EMFILE );
1978 } else {
1979 if (VG_(clo_track_fds))
1980 ML_(record_fd_open_nameless) (tid, RES);
1984 PRE(sys_eventfd2)
1986 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
1987 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1989 POST(sys_eventfd2)
1991 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1992 VG_(close)(RES);
1993 SET_STATUS_Failure( VKI_EMFILE );
1994 } else {
1995 if (VG_(clo_track_fds))
1996 ML_(record_fd_open_nameless) (tid, RES);
2000 PRE(sys_fallocate)
2002 *flags |= SfMayBlock;
2003 #if VG_WORDSIZE == 4
2004 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2005 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2006 PRE_REG_READ6(long, "fallocate",
2007 int, fd, int, mode,
2008 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2009 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2010 #elif VG_WORDSIZE == 8
2011 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2012 SARG1, SARG2, SARG3, SARG4);
2013 PRE_REG_READ4(long, "fallocate",
2014 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2015 #else
2016 # error Unexpected word size
2017 #endif
2018 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2019 SET_STATUS_Failure( VKI_EBADF );
2022 PRE(sys_prlimit64)
2024 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2025 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2026 PRE_REG_READ4(long, "prlimit64",
2027 vki_pid_t, pid, unsigned int, resource,
2028 const struct rlimit64 *, new_rlim,
2029 struct rlimit64 *, old_rlim);
2030 if (ARG3)
2031 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2032 if (ARG4)
2033 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2035 if (ARG3 &&
2036 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2037 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2038 SET_STATUS_Failure( VKI_EINVAL );
2040 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2041 switch (ARG2) {
2042 case VKI_RLIMIT_NOFILE:
2043 SET_STATUS_Success( 0 );
2044 if (ARG4) {
2045 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2046 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2048 if (ARG3) {
2049 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2050 > VG_(fd_hard_limit) ||
2051 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2052 != VG_(fd_hard_limit)) {
2053 SET_STATUS_Failure( VKI_EPERM );
2055 else {
2056 VG_(fd_soft_limit) =
2057 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2060 break;
2062 case VKI_RLIMIT_DATA:
2063 SET_STATUS_Success( 0 );
2064 if (ARG4) {
2065 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2066 VG_(client_rlimit_data).rlim_cur;
2067 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2068 VG_(client_rlimit_data).rlim_max;
2070 if (ARG3) {
2071 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2072 > VG_(client_rlimit_data).rlim_max ||
2073 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2074 > VG_(client_rlimit_data).rlim_max) {
2075 SET_STATUS_Failure( VKI_EPERM );
2077 else {
2078 VG_(client_rlimit_data).rlim_cur =
2079 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2080 VG_(client_rlimit_data).rlim_max =
2081 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2084 break;
2086 case VKI_RLIMIT_STACK:
2087 SET_STATUS_Success( 0 );
2088 if (ARG4) {
2089 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2090 VG_(client_rlimit_stack).rlim_cur;
2091 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2092 VG_(client_rlimit_stack).rlim_max;
2094 if (ARG3) {
2095 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2096 > VG_(client_rlimit_stack).rlim_max ||
2097 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2098 > VG_(client_rlimit_stack).rlim_max) {
2099 SET_STATUS_Failure( VKI_EPERM );
2101 else {
2102 VG_(threads)[tid].client_stack_szB =
2103 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2104 VG_(client_rlimit_stack).rlim_cur =
2105 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2106 VG_(client_rlimit_stack).rlim_max =
2107 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2110 break;
2115 POST(sys_prlimit64)
2117 if (ARG4)
2118 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2121 /* ---------------------------------------------------------------------
2122 tid-related wrappers
2123 ------------------------------------------------------------------ */
2125 PRE(sys_gettid)
2127 PRINT("sys_gettid ()");
2128 PRE_REG_READ0(long, "gettid");
2131 PRE(sys_set_tid_address)
2133 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2134 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2137 PRE(sys_tkill)
2139 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2140 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2141 if (!ML_(client_signal_OK)(ARG2)) {
2142 SET_STATUS_Failure( VKI_EINVAL );
2143 return;
2146 /* Check to see if this kill gave us a pending signal */
2147 *flags |= SfPollAfter;
2149 if (VG_(clo_trace_signals))
2150 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2151 SARG2, SARG1);
2153 /* If we're sending SIGKILL, check to see if the target is one of
2154 our threads and handle it specially. */
2155 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2156 SET_STATUS_Success(0);
2157 return;
2160 /* Ask to handle this syscall via the slow route, since that's the
2161 only one that sets tst->status to VgTs_WaitSys. If the result
2162 of doing the syscall is an immediate run of
2163 async_signalhandler() in m_signals, then we need the thread to
2164 be properly tidied away. I have the impression the previous
2165 version of this wrapper worked on x86/amd64 only because the
2166 kernel did not immediately deliver the async signal to this
2167 thread (on ppc it did, which broke the assertion re tst->status
2168 at the top of async_signalhandler()). */
2169 *flags |= SfMayBlock;
2171 POST(sys_tkill)
2173 if (VG_(clo_trace_signals))
2174 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2175 SARG2, SARG1);
2178 PRE(sys_tgkill)
2180 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2181 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2182 if (!ML_(client_signal_OK)(ARG3)) {
2183 SET_STATUS_Failure( VKI_EINVAL );
2184 return;
2187 /* Check to see if this kill gave us a pending signal */
2188 *flags |= SfPollAfter;
2190 if (VG_(clo_trace_signals))
2191 VG_(message)(Vg_DebugMsg,
2192 "tgkill: sending signal %ld to pid %ld/%ld\n",
2193 SARG3, SARG1, SARG2);
2195 /* If we're sending SIGKILL, check to see if the target is one of
2196 our threads and handle it specially. */
2197 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2198 SET_STATUS_Success(0);
2199 return;
2202 /* Ask to handle this syscall via the slow route, since that's the
2203 only one that sets tst->status to VgTs_WaitSys. If the result
2204 of doing the syscall is an immediate run of
2205 async_signalhandler() in m_signals, then we need the thread to
2206 be properly tidied away. I have the impression the previous
2207 version of this wrapper worked on x86/amd64 only because the
2208 kernel did not immediately deliver the async signal to this
2209 thread (on ppc it did, which broke the assertion re tst->status
2210 at the top of async_signalhandler()). */
2211 *flags |= SfMayBlock;
2213 POST(sys_tgkill)
2215 if (VG_(clo_trace_signals))
2216 VG_(message)(Vg_DebugMsg,
2217 "tgkill: sent signal %ld to pid %ld/%ld\n",
2218 SARG3, SARG1, SARG2);
2221 /* ---------------------------------------------------------------------
2222 fadvise64* wrappers
2223 ------------------------------------------------------------------ */
2225 PRE(sys_fadvise64)
2227 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2228 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2229 PRE_REG_READ5(long, "fadvise64",
2230 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2231 vki_size_t, len, int, advice);
2234 PRE(sys_fadvise64_64)
2236 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2237 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2238 PRE_REG_READ6(long, "fadvise64_64",
2239 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2240 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2243 /* ---------------------------------------------------------------------
2244 io_* wrappers
2245 ------------------------------------------------------------------ */
2247 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2248 // and this allows us to control exactly the code that gets run while
2249 // the padding is in place.
2251 PRE(sys_io_setup)
2253 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2254 PRE_REG_READ2(long, "io_setup",
2255 unsigned, nr_events, vki_aio_context_t *, ctxp);
2256 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2259 POST(sys_io_setup)
2261 SizeT size;
2262 struct vki_aio_ring *r;
2264 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2265 ARG1*sizeof(struct vki_io_event));
2266 r = *(struct vki_aio_ring **)(Addr)ARG2;
2267 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2269 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2270 VKI_PROT_READ | VKI_PROT_WRITE,
2271 VKI_MAP_ANONYMOUS, -1, 0 );
2273 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2276 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2277 // after the syscall. We must get 'size' from the aio_ring structure,
2278 // before the syscall, while the aio_ring structure still exists. (And we
2279 // know that we must look at the aio_ring structure because Tom inspected the
2280 // kernel and glibc sources to see what they do, yuk.)
2282 // XXX This segment can be implicitly unmapped when aio
2283 // file-descriptors are closed...
2284 PRE(sys_io_destroy)
2286 SizeT size = 0;
2288 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2289 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2291 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2292 // possible...
2293 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2294 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2295 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2296 r->nr*sizeof(struct vki_io_event));
2299 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2301 if (SUCCESS && RES == 0) {
2302 Bool d = VG_(am_notify_munmap)( ARG1, size );
2303 VG_TRACK( die_mem_munmap, ARG1, size );
2304 if (d)
2305 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2306 "PRE(sys_io_destroy)" );
2310 PRE(sys_io_getevents)
2312 *flags |= SfMayBlock;
2313 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2314 FMT_REGWORD "x )",
2315 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2316 PRE_REG_READ5(long, "io_getevents",
2317 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2318 struct io_event *, events,
2319 struct timespec *, timeout);
2320 if (ARG3 > 0)
2321 PRE_MEM_WRITE( "io_getevents(events)",
2322 ARG4, sizeof(struct vki_io_event)*ARG3 );
2323 if (ARG5 != 0)
2324 PRE_MEM_READ( "io_getevents(timeout)",
2325 ARG5, sizeof(struct vki_timespec));
2327 POST(sys_io_getevents)
2329 Int i;
2330 vg_assert(SUCCESS);
2331 if (RES > 0) {
2332 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2333 for (i = 0; i < RES; i++) {
2334 const struct vki_io_event *vev =
2335 ((struct vki_io_event *)(Addr)ARG4) + i;
2336 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2338 switch (cb->aio_lio_opcode) {
2339 case VKI_IOCB_CMD_PREAD:
2340 if (vev->result > 0)
2341 POST_MEM_WRITE( cb->aio_buf, vev->result );
2342 break;
2344 case VKI_IOCB_CMD_PWRITE:
2345 break;
2347 case VKI_IOCB_CMD_FSYNC:
2348 break;
2350 case VKI_IOCB_CMD_FDSYNC:
2351 break;
2353 case VKI_IOCB_CMD_PREADV:
2354 if (vev->result > 0) {
2355 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2356 Int remains = vev->result;
2357 Int j;
2359 for (j = 0; j < cb->aio_nbytes; j++) {
2360 Int nReadThisBuf = vec[j].iov_len;
2361 if (nReadThisBuf > remains) nReadThisBuf = remains;
2362 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2363 remains -= nReadThisBuf;
2364 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2367 break;
2369 case VKI_IOCB_CMD_PWRITEV:
2370 break;
2372 default:
2373 VG_(message)(Vg_DebugMsg,
2374 "Warning: unhandled io_getevents opcode: %u\n",
2375 cb->aio_lio_opcode);
2376 break;
2382 PRE(sys_io_submit)
2384 Int i, j;
2386 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2387 ARG1, SARG2, ARG3);
2388 PRE_REG_READ3(long, "io_submit",
2389 vki_aio_context_t, ctx_id, long, nr,
2390 struct iocb **, iocbpp);
2391 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2392 if (ARG3 != 0) {
2393 for (i = 0; i < ARG2; i++) {
2394 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2395 struct vki_iovec *iov;
2397 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2398 switch (cb->aio_lio_opcode) {
2399 case VKI_IOCB_CMD_PREAD:
2400 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2401 break;
2403 case VKI_IOCB_CMD_PWRITE:
2404 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2405 break;
2407 case VKI_IOCB_CMD_FSYNC:
2408 break;
2410 case VKI_IOCB_CMD_FDSYNC:
2411 break;
2413 case VKI_IOCB_CMD_PREADV:
2414 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2415 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2416 for (j = 0; j < cb->aio_nbytes; j++)
2417 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2418 break;
2420 case VKI_IOCB_CMD_PWRITEV:
2421 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2422 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2423 for (j = 0; j < cb->aio_nbytes; j++)
2424 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2425 break;
2427 default:
2428 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2429 cb->aio_lio_opcode);
2430 break;
2436 PRE(sys_io_cancel)
2438 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2439 (ULong)ARG1, ARG2, ARG3);
2440 PRE_REG_READ3(long, "io_cancel",
2441 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2442 struct io_event *, result);
2443 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2444 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2446 POST(sys_io_cancel)
2448 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2451 /* ---------------------------------------------------------------------
2452 *_mempolicy wrappers
2453 ------------------------------------------------------------------ */
2455 PRE(sys_mbind)
2457 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2458 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2459 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2460 PRE_REG_READ6(long, "mbind",
2461 unsigned long, start, unsigned long, len,
2462 unsigned long, policy, unsigned long *, nodemask,
2463 unsigned long, maxnode, unsigned, flags);
2464 if (ARG1 != 0)
2465 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2466 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2469 PRE(sys_set_mempolicy)
2471 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2472 SARG1, ARG2, ARG3);
2473 PRE_REG_READ3(long, "set_mempolicy",
2474 int, policy, unsigned long *, nodemask,
2475 unsigned long, maxnode);
2476 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2477 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2480 PRE(sys_get_mempolicy)
2482 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2483 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2484 ARG1, ARG2, ARG3, ARG4, ARG5);
2485 PRE_REG_READ5(long, "get_mempolicy",
2486 int *, policy, unsigned long *, nodemask,
2487 unsigned long, maxnode, unsigned long, addr,
2488 unsigned long, flags);
2489 if (ARG1 != 0)
2490 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2491 if (ARG2 != 0)
2492 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2493 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2495 POST(sys_get_mempolicy)
2497 if (ARG1 != 0)
2498 POST_MEM_WRITE( ARG1, sizeof(Int) );
2499 if (ARG2 != 0)
2500 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2503 /* ---------------------------------------------------------------------
2504 fanotify_* wrappers
2505 ------------------------------------------------------------------ */
2507 PRE(sys_fanotify_init)
2509 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2510 ARG1, ARG2);
2511 PRE_REG_READ2(long, "fanotify_init",
2512 unsigned int, flags, unsigned int, event_f_flags);
2515 POST(sys_fanotify_init)
2517 vg_assert(SUCCESS);
2518 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2519 VG_(close)(RES);
2520 SET_STATUS_Failure( VKI_EMFILE );
2521 } else {
2522 if (VG_(clo_track_fds))
2523 ML_(record_fd_open_nameless) (tid, RES);
2527 PRE(sys_fanotify_mark)
2529 #if VG_WORDSIZE == 4
2530 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2531 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2532 (HChar *)(Addr)ARG6);
2533 PRE_REG_READ6(long, "sys_fanotify_mark",
2534 int, fanotify_fd, unsigned int, flags,
2535 __vki_u32, mask0, __vki_u32, mask1,
2536 int, dfd, const char *, pathname);
2537 if (ARG6)
2538 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2539 #elif VG_WORDSIZE == 8
2540 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2541 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2542 PRE_REG_READ5(long, "sys_fanotify_mark",
2543 int, fanotify_fd, unsigned int, flags,
2544 __vki_u64, mask,
2545 int, dfd, const char *, pathname);
2546 if (ARG5)
2547 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2548 #else
2549 # error Unexpected word size
2550 #endif
2553 /* ---------------------------------------------------------------------
2554 inotify_* wrappers
2555 ------------------------------------------------------------------ */
2557 PRE(sys_inotify_init)
2559 PRINT("sys_inotify_init ( )");
2560 PRE_REG_READ0(long, "inotify_init");
2562 POST(sys_inotify_init)
2564 vg_assert(SUCCESS);
2565 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2566 VG_(close)(RES);
2567 SET_STATUS_Failure( VKI_EMFILE );
2568 } else {
2569 if (VG_(clo_track_fds))
2570 ML_(record_fd_open_nameless) (tid, RES);
2574 PRE(sys_inotify_init1)
2576 PRINT("sys_inotify_init ( %ld )", SARG1);
2577 PRE_REG_READ1(long, "inotify_init", int, flag);
2580 POST(sys_inotify_init1)
2582 vg_assert(SUCCESS);
2583 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2584 VG_(close)(RES);
2585 SET_STATUS_Failure( VKI_EMFILE );
2586 } else {
2587 if (VG_(clo_track_fds))
2588 ML_(record_fd_open_nameless) (tid, RES);
2592 PRE(sys_inotify_add_watch)
2594 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2595 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2596 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2597 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2600 PRE(sys_inotify_rm_watch)
2602 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2603 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2606 /* ---------------------------------------------------------------------
2607 mq_* wrappers
2608 ------------------------------------------------------------------ */
2610 PRE(sys_mq_open)
2612 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2613 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2614 PRE_REG_READ4(long, "mq_open",
2615 const char *, name, int, oflag, vki_mode_t, mode,
2616 struct mq_attr *, attr);
2617 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2618 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2619 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2620 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2621 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2622 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2623 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2626 POST(sys_mq_open)
2628 vg_assert(SUCCESS);
2629 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2630 VG_(close)(RES);
2631 SET_STATUS_Failure( VKI_EMFILE );
2632 } else {
2633 if (VG_(clo_track_fds))
2634 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2638 PRE(sys_mq_unlink)
2640 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2641 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2642 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2645 PRE(sys_mq_timedsend)
2647 *flags |= SfMayBlock;
2648 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2649 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2650 SARG1,ARG2,ARG3,ARG4,ARG5);
2651 PRE_REG_READ5(long, "mq_timedsend",
2652 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2653 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2654 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2655 SET_STATUS_Failure( VKI_EBADF );
2656 } else {
2657 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2658 if (ARG5 != 0)
2659 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2660 sizeof(struct vki_timespec) );
2664 PRE(sys_mq_timedreceive)
2666 *flags |= SfMayBlock;
2667 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2668 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2669 SARG1,ARG2,ARG3,ARG4,ARG5);
2670 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2671 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2672 unsigned int *, msg_prio,
2673 const struct timespec *, abs_timeout);
2674 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2675 SET_STATUS_Failure( VKI_EBADF );
2676 } else {
2677 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2678 if (ARG4 != 0)
2679 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2680 ARG4, sizeof(unsigned int) );
2681 if (ARG5 != 0)
2682 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2683 ARG5, sizeof(struct vki_timespec) );
2686 POST(sys_mq_timedreceive)
2688 POST_MEM_WRITE( ARG2, RES );
2689 if (ARG4 != 0)
2690 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2693 PRE(sys_mq_notify)
2695 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2696 PRE_REG_READ2(long, "mq_notify",
2697 vki_mqd_t, mqdes, const struct sigevent *, notification);
2698 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2699 SET_STATUS_Failure( VKI_EBADF );
2700 else if (ARG2 != 0)
2701 PRE_MEM_READ( "mq_notify(notification)",
2702 ARG2, sizeof(struct vki_sigevent) );
2705 PRE(sys_mq_getsetattr)
2707 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2708 SARG1, ARG2, ARG3 );
2709 PRE_REG_READ3(long, "mq_getsetattr",
2710 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2711 struct mq_attr *, omqstat);
2712 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2713 SET_STATUS_Failure( VKI_EBADF );
2714 } else {
2715 if (ARG2 != 0) {
2716 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2717 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2718 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2720 if (ARG3 != 0)
2721 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2722 sizeof(struct vki_mq_attr) );
2725 POST(sys_mq_getsetattr)
2727 if (ARG3 != 0)
2728 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2731 /* ---------------------------------------------------------------------
2732 clock_* wrappers
2733 ------------------------------------------------------------------ */
2735 PRE(sys_clock_settime)
2737 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2738 PRE_REG_READ2(long, "clock_settime",
2739 vki_clockid_t, clk_id, const struct timespec *, tp);
2740 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2743 PRE(sys_clock_gettime)
2745 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2746 PRE_REG_READ2(long, "clock_gettime",
2747 vki_clockid_t, clk_id, struct timespec *, tp);
2748 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2750 POST(sys_clock_gettime)
2752 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2755 PRE(sys_clock_getres)
2757 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2758 // Nb: we can't use "RES" as the param name because that's a macro
2759 // defined above!
2760 PRE_REG_READ2(long, "clock_getres",
2761 vki_clockid_t, clk_id, struct timespec *, res);
2762 if (ARG2 != 0)
2763 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2765 POST(sys_clock_getres)
2767 if (ARG2 != 0)
2768 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2771 PRE(sys_clock_nanosleep)
2773 *flags |= SfMayBlock|SfPostOnFail;
2774 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
2775 FMT_REGWORD "x )",
2776 SARG1, SARG2, ARG3, ARG4);
2777 PRE_REG_READ4(int32_t, "clock_nanosleep",
2778 vki_clockid_t, clkid, int, flags,
2779 const struct timespec *, rqtp, struct timespec *, rmtp);
2780 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2781 if (ARG4 != 0)
2782 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2784 POST(sys_clock_nanosleep)
2786 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
2787 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2790 /* ---------------------------------------------------------------------
2791 timer_* wrappers
2792 ------------------------------------------------------------------ */
2794 PRE(sys_timer_create)
2796 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2797 SARG1, ARG2, ARG3);
2798 PRE_REG_READ3(long, "timer_create",
2799 vki_clockid_t, clockid, struct sigevent *, evp,
2800 vki_timer_t *, timerid);
2801 if (ARG2 != 0) {
2802 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
2803 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2804 sizeof(vki_sigval_t) );
2805 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2806 sizeof(int) );
2807 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2808 sizeof(int) );
2809 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2810 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
2811 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2812 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2814 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2816 POST(sys_timer_create)
2818 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2821 PRE(sys_timer_settime)
2823 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
2824 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
2825 PRE_REG_READ4(long, "timer_settime",
2826 vki_timer_t, timerid, int, flags,
2827 const struct itimerspec *, value,
2828 struct itimerspec *, ovalue);
2829 PRE_MEM_READ( "timer_settime(value)", ARG3,
2830 sizeof(struct vki_itimerspec) );
2831 if (ARG4 != 0)
2832 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2833 sizeof(struct vki_itimerspec) );
2835 POST(sys_timer_settime)
2837 if (ARG4 != 0)
2838 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2841 PRE(sys_timer_gettime)
2843 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2844 PRE_REG_READ2(long, "timer_gettime",
2845 vki_timer_t, timerid, struct itimerspec *, value);
2846 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2847 sizeof(struct vki_itimerspec));
2849 POST(sys_timer_gettime)
2851 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2854 PRE(sys_timer_getoverrun)
2856 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
2857 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2860 PRE(sys_timer_delete)
2862 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
2863 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2866 /* ---------------------------------------------------------------------
2867 timerfd* wrappers
2868 See also http://lwn.net/Articles/260172/ for an overview.
2869 See also /usr/src/linux/fs/timerfd.c for the implementation.
2870 ------------------------------------------------------------------ */
2872 /* Returns True if running on 2.6.22, else False (or False if
2873 cannot be determined). */
2874 static Bool linux_kernel_2_6_22(void)
2876 static Int result = -1;
2877 Int fd, read;
2878 HChar release[64]; // large enough
2879 SysRes res;
2881 if (result == -1) {
2882 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
2883 if (sr_isError(res))
2884 return False;
2885 fd = sr_Res(res);
2886 read = VG_(read)(fd, release, sizeof(release) - 1);
2887 if (read < 0)
2888 return False;
2889 release[read] = 0;
2890 VG_(close)(fd);
2891 //VG_(printf)("kernel release = %s\n", release);
2892 result = VG_(strncmp)(release, "2.6.22", 6) == 0
2893 && ! VG_(isdigit)(release[6]);
2895 vg_assert(result == 0 || result == 1);
2896 return result == 1;
2899 PRE(sys_timerfd_create)
2901 if (linux_kernel_2_6_22()) {
2902 /* 2.6.22 kernel: timerfd system call. */
2903 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
2904 PRE_REG_READ3(long, "sys_timerfd",
2905 int, fd, int, clockid, const struct itimerspec *, tmr);
2906 PRE_MEM_READ("timerfd(tmr)", ARG3,
2907 sizeof(struct vki_itimerspec) );
2908 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
2909 SET_STATUS_Failure( VKI_EBADF );
2910 } else {
2911 /* 2.6.24 and later kernels: timerfd_create system call. */
2912 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
2913 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2916 POST(sys_timerfd_create)
2918 if (linux_kernel_2_6_22())
2920 /* 2.6.22 kernel: timerfd system call. */
2921 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2922 VG_(close)(RES);
2923 SET_STATUS_Failure( VKI_EMFILE );
2924 } else {
2925 if (VG_(clo_track_fds))
2926 ML_(record_fd_open_nameless) (tid, RES);
2929 else
2931 /* 2.6.24 and later kernels: timerfd_create system call. */
2932 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2933 VG_(close)(RES);
2934 SET_STATUS_Failure( VKI_EMFILE );
2935 } else {
2936 if (VG_(clo_track_fds))
2937 ML_(record_fd_open_nameless) (tid, RES);
2942 PRE(sys_timerfd_gettime)
2944 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2945 PRE_REG_READ2(long, "timerfd_gettime",
2946 int, ufd,
2947 struct vki_itimerspec*, otmr);
2948 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2949 SET_STATUS_Failure(VKI_EBADF);
2950 else
2951 PRE_MEM_WRITE("timerfd_gettime(result)",
2952 ARG2, sizeof(struct vki_itimerspec));
2954 POST(sys_timerfd_gettime)
2956 if (RES == 0)
2957 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2960 PRE(sys_timerfd_settime)
2962 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
2963 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
2964 PRE_REG_READ4(long, "timerfd_settime",
2965 int, ufd,
2966 int, flags,
2967 const struct vki_itimerspec*, utmr,
2968 struct vki_itimerspec*, otmr);
2969 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2970 SET_STATUS_Failure(VKI_EBADF);
2971 else
2973 PRE_MEM_READ("timerfd_settime(result)",
2974 ARG3, sizeof(struct vki_itimerspec));
2975 if (ARG4)
2977 PRE_MEM_WRITE("timerfd_settime(result)",
2978 ARG4, sizeof(struct vki_itimerspec));
2982 POST(sys_timerfd_settime)
2984 if (RES == 0 && ARG4 != 0)
2985 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
2988 /* ---------------------------------------------------------------------
2989 capabilities wrappers
2990 ------------------------------------------------------------------ */
2992 PRE(sys_capget)
2994 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
2995 PRE_REG_READ2(long, "capget",
2996 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2997 PRE_MEM_READ( "capget(header)", ARG1,
2998 sizeof(struct __vki_user_cap_header_struct) );
2999 if (ARG2 != (Addr)NULL)
3000 PRE_MEM_WRITE( "capget(data)", ARG2,
3001 sizeof(struct __vki_user_cap_data_struct) );
3003 POST(sys_capget)
3005 if (ARG2 != (Addr)NULL)
3006 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3009 PRE(sys_capset)
3011 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3012 PRE_REG_READ2(long, "capset",
3013 vki_cap_user_header_t, header,
3014 const vki_cap_user_data_t, data);
3015 PRE_MEM_READ( "capset(header)",
3016 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3017 PRE_MEM_READ( "capset(data)",
3018 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3021 /* ---------------------------------------------------------------------
3022 16-bit uid/gid/groups wrappers
3023 ------------------------------------------------------------------ */
3025 PRE(sys_getuid16)
3027 PRINT("sys_getuid16 ( )");
3028 PRE_REG_READ0(long, "getuid16");
3031 PRE(sys_setuid16)
3033 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3034 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3037 PRE(sys_getgid16)
3039 PRINT("sys_getgid16 ( )");
3040 PRE_REG_READ0(long, "getgid16");
3043 PRE(sys_setgid16)
3045 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3046 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3049 PRE(sys_geteuid16)
3051 PRINT("sys_geteuid16 ( )");
3052 PRE_REG_READ0(long, "geteuid16");
3055 PRE(sys_getegid16)
3057 PRINT("sys_getegid16 ( )");
3058 PRE_REG_READ0(long, "getegid16");
3061 PRE(sys_setreuid16)
3063 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3064 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3067 PRE(sys_setregid16)
3069 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3070 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3073 PRE(sys_getgroups16)
3075 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3076 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3077 if (ARG1 > 0)
3078 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3080 POST(sys_getgroups16)
3082 vg_assert(SUCCESS);
3083 if (ARG1 > 0 && RES > 0)
3084 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3087 PRE(sys_setgroups16)
3089 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3090 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3091 if (ARG1 > 0)
3092 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3095 /* ---------------------------------------------------------------------
3096 *chown16 wrappers
3097 ------------------------------------------------------------------ */
3099 PRE(sys_chown16)
3101 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3102 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3103 PRE_REG_READ3(long, "chown16",
3104 const char *, path,
3105 vki_old_uid_t, owner, vki_old_gid_t, group);
3106 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3109 PRE(sys_fchown16)
3111 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3112 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3113 PRE_REG_READ3(long, "fchown16",
3114 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3117 /* ---------------------------------------------------------------------
3118 *xattr wrappers
3119 ------------------------------------------------------------------ */
3121 PRE(sys_setxattr)
3123 *flags |= SfMayBlock;
3124 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3125 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3126 ARG4, SARG5);
3127 PRE_REG_READ5(long, "setxattr",
3128 char *, path, char *, name,
3129 void *, value, vki_size_t, size, int, flags);
3130 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3131 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3132 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3135 PRE(sys_lsetxattr)
3137 *flags |= SfMayBlock;
3138 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3139 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3140 ARG1, ARG2, ARG3, ARG4, SARG5);
3141 PRE_REG_READ5(long, "lsetxattr",
3142 char *, path, char *, name,
3143 void *, value, vki_size_t, size, int, flags);
3144 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3145 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3146 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3149 PRE(sys_fsetxattr)
3151 *flags |= SfMayBlock;
3152 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3153 FMT_REGWORD "u, %ld )",
3154 SARG1, ARG2, ARG3, ARG4, SARG5);
3155 PRE_REG_READ5(long, "fsetxattr",
3156 int, fd, char *, name, void *, value,
3157 vki_size_t, size, int, flags);
3158 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3159 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3162 PRE(sys_getxattr)
3164 *flags |= SfMayBlock;
3165 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3166 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3167 PRE_REG_READ4(ssize_t, "getxattr",
3168 char *, path, char *, name, void *, value, vki_size_t, size);
3169 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3170 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3171 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3173 POST(sys_getxattr)
3175 vg_assert(SUCCESS);
3176 if (RES > 0 && ARG3 != (Addr)NULL) {
3177 POST_MEM_WRITE( ARG3, RES );
3181 PRE(sys_lgetxattr)
3183 *flags |= SfMayBlock;
3184 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3185 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3186 PRE_REG_READ4(ssize_t, "lgetxattr",
3187 char *, path, char *, name, void *, value, vki_size_t, size);
3188 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3189 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3190 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3192 POST(sys_lgetxattr)
3194 vg_assert(SUCCESS);
3195 if (RES > 0 && ARG3 != (Addr)NULL) {
3196 POST_MEM_WRITE( ARG3, RES );
3200 PRE(sys_fgetxattr)
3202 *flags |= SfMayBlock;
3203 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3204 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3205 PRE_REG_READ4(ssize_t, "fgetxattr",
3206 int, fd, char *, name, void *, value, vki_size_t, size);
3207 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3208 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3210 POST(sys_fgetxattr)
3212 if (RES > 0 && ARG3 != (Addr)NULL)
3213 POST_MEM_WRITE( ARG3, RES );
3216 PRE(sys_listxattr)
3218 *flags |= SfMayBlock;
3219 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3220 ARG1, ARG2, (ULong)ARG3);
3221 PRE_REG_READ3(ssize_t, "listxattr",
3222 char *, path, char *, list, vki_size_t, size);
3223 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3224 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3226 POST(sys_listxattr)
3228 if (RES > 0 && ARG2 != (Addr)NULL)
3229 POST_MEM_WRITE( ARG2, RES );
3232 PRE(sys_llistxattr)
3234 *flags |= SfMayBlock;
3235 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3236 ARG1, ARG2, (ULong)ARG3);
3237 PRE_REG_READ3(ssize_t, "llistxattr",
3238 char *, path, char *, list, vki_size_t, size);
3239 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3240 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3242 POST(sys_llistxattr)
3244 if (RES > 0 && ARG2 != (Addr)NULL)
3245 POST_MEM_WRITE( ARG2, RES );
3248 PRE(sys_flistxattr)
3250 *flags |= SfMayBlock;
3251 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3252 SARG1, ARG2, ARG3);
3253 PRE_REG_READ3(ssize_t, "flistxattr",
3254 int, fd, char *, list, vki_size_t, size);
3255 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3257 POST(sys_flistxattr)
3259 if (RES > 0 && ARG2 != (Addr)NULL)
3260 POST_MEM_WRITE( ARG2, RES );
3263 PRE(sys_removexattr)
3265 *flags |= SfMayBlock;
3266 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3267 ARG1, ARG2);
3268 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3269 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3270 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3273 PRE(sys_lremovexattr)
3275 *flags |= SfMayBlock;
3276 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3277 ARG1, ARG2);
3278 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3279 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3280 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3283 PRE(sys_fremovexattr)
3285 *flags |= SfMayBlock;
3286 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3287 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3288 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3291 /* ---------------------------------------------------------------------
3292 sched_* wrappers
3293 ------------------------------------------------------------------ */
3295 PRE(sys_sched_setparam)
3297 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3298 PRE_REG_READ2(long, "sched_setparam",
3299 vki_pid_t, pid, struct sched_param *, p);
3300 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3302 POST(sys_sched_setparam)
3304 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3307 PRE(sys_sched_getparam)
3309 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3310 PRE_REG_READ2(long, "sched_getparam",
3311 vki_pid_t, pid, struct sched_param *, p);
3312 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3314 POST(sys_sched_getparam)
3316 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3319 PRE(sys_sched_getscheduler)
3321 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3322 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3325 PRE(sys_sched_setscheduler)
3327 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3328 SARG1, SARG2, ARG3);
3329 PRE_REG_READ3(long, "sched_setscheduler",
3330 vki_pid_t, pid, int, policy, struct sched_param *, p);
3331 if (ARG3 != 0)
3332 PRE_MEM_READ( "sched_setscheduler(p)",
3333 ARG3, sizeof(struct vki_sched_param));
3336 PRE(sys_sched_yield)
3338 *flags |= SfMayBlock;
3339 PRINT("sched_yield()");
3340 PRE_REG_READ0(long, "sys_sched_yield");
3343 PRE(sys_sched_get_priority_max)
3345 PRINT("sched_get_priority_max ( %ld )", SARG1);
3346 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3349 PRE(sys_sched_get_priority_min)
3351 PRINT("sched_get_priority_min ( %ld )", SARG1);
3352 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3355 PRE(sys_sched_rr_get_interval)
3357 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3358 PRE_REG_READ2(int, "sched_rr_get_interval",
3359 vki_pid_t, pid,
3360 struct vki_timespec *, tp);
3361 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3362 ARG2, sizeof(struct vki_timespec));
3365 POST(sys_sched_rr_get_interval)
3367 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3370 PRE(sys_sched_setaffinity)
3372 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3373 SARG1, ARG2, ARG3);
3374 PRE_REG_READ3(long, "sched_setaffinity",
3375 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3376 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3379 PRE(sys_sched_getaffinity)
3381 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3382 SARG1, ARG2, ARG3);
3383 PRE_REG_READ3(long, "sched_getaffinity",
3384 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3385 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3387 POST(sys_sched_getaffinity)
3389 POST_MEM_WRITE(ARG3, ARG2);
3392 PRE(sys_unshare)
3394 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3395 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3398 /* ---------------------------------------------------------------------
3399 miscellaneous wrappers
3400 ------------------------------------------------------------------ */
3402 PRE(sys_munlockall)
3404 *flags |= SfMayBlock;
3405 PRINT("sys_munlockall ( )");
3406 PRE_REG_READ0(long, "munlockall");
3409 // This has different signatures for different platforms.
3411 // x86: int sys_pipe(unsigned long __user *fildes);
3412 // AMD64: long sys_pipe(int *fildes);
3413 // ppc32: int sys_pipe(int __user *fildes);
3414 // ppc64: int sys_pipe(int __user *fildes);
3416 // The type of the argument is most important, and it is an array of 32 bit
3417 // values in all cases. (The return type differs across platforms, but it
3418 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3419 // was caused by using an array of 'unsigned long's, which didn't work on
3420 // AMD64.
3421 PRE(sys_pipe)
3423 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3424 PRE_REG_READ1(int, "pipe", int *, filedes);
3425 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3427 POST(sys_pipe)
3429 Int *p = (Int *)(Addr)ARG1;
3430 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3431 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3432 VG_(close)(p[0]);
3433 VG_(close)(p[1]);
3434 SET_STATUS_Failure( VKI_EMFILE );
3435 } else {
3436 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3437 if (VG_(clo_track_fds)) {
3438 ML_(record_fd_open_nameless)(tid, p[0]);
3439 ML_(record_fd_open_nameless)(tid, p[1]);
3444 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3445 there's a second arg containing flags to be applied to the new file
3446 descriptors. It hardly seems worth the effort to factor out the
3447 duplicated code, hence: */
3448 PRE(sys_pipe2)
3450 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3451 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3452 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3454 POST(sys_pipe2)
3456 Int *p = (Int *)(Addr)ARG1;
3457 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3458 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3459 VG_(close)(p[0]);
3460 VG_(close)(p[1]);
3461 SET_STATUS_Failure( VKI_EMFILE );
3462 } else {
3463 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3464 if (VG_(clo_track_fds)) {
3465 ML_(record_fd_open_nameless)(tid, p[0]);
3466 ML_(record_fd_open_nameless)(tid, p[1]);
3471 PRE(sys_dup3)
3473 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3474 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3475 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3476 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3477 SET_STATUS_Failure( VKI_EBADF );
3480 POST(sys_dup3)
3482 vg_assert(SUCCESS);
3483 if (VG_(clo_track_fds))
3484 ML_(record_fd_open_named)(tid, RES);
3487 PRE(sys_quotactl)
3489 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3490 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3491 PRE_REG_READ4(long, "quotactl",
3492 unsigned int, cmd, const char *, special, vki_qid_t, id,
3493 void *, addr);
3494 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3497 PRE(sys_waitid)
3499 *flags |= SfMayBlock;
3500 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3501 SARG1, SARG2, ARG3, SARG4, ARG5);
3502 PRE_REG_READ5(int32_t, "sys_waitid",
3503 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3504 int, options, struct vki_rusage *, ru);
3505 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3506 if (ARG5 != 0)
3507 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3509 POST(sys_waitid)
3511 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3512 if (ARG5 != 0)
3513 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3516 PRE(sys_sync_file_range)
3518 *flags |= SfMayBlock;
3519 #if VG_WORDSIZE == 4
3520 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3521 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3522 PRE_REG_READ6(long, "sync_file_range",
3523 int, fd,
3524 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3525 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3526 unsigned int, flags);
3527 #elif VG_WORDSIZE == 8
3528 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3529 SARG1, SARG2, SARG3, ARG4);
3530 PRE_REG_READ4(long, "sync_file_range",
3531 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3532 unsigned int, flags);
3533 #else
3534 # error Unexpected word size
3535 #endif
3536 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3537 SET_STATUS_Failure( VKI_EBADF );
3540 PRE(sys_sync_file_range2)
3542 *flags |= SfMayBlock;
3543 #if VG_WORDSIZE == 4
3544 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3545 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3546 PRE_REG_READ6(long, "sync_file_range2",
3547 int, fd, unsigned int, flags,
3548 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3549 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3550 #elif VG_WORDSIZE == 8
3551 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3552 SARG1, ARG2, SARG3, SARG4);
3553 PRE_REG_READ4(long, "sync_file_range2",
3554 int, fd, unsigned int, flags,
3555 vki_loff_t, offset, vki_loff_t, nbytes);
3556 #else
3557 # error Unexpected word size
3558 #endif
3559 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
3560 SET_STATUS_Failure( VKI_EBADF );
3563 PRE(sys_stime)
3565 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
3566 PRE_REG_READ1(int, "stime", vki_time_t*, t);
3567 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
3570 PRE(sys_perf_event_open)
3572 struct vki_perf_event_attr *attr;
3573 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
3574 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
3575 PRE_REG_READ5(long, "perf_event_open",
3576 struct vki_perf_event_attr *, attr,
3577 vki_pid_t, pid, int, cpu, int, group_fd,
3578 unsigned long, flags);
3579 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
3580 PRE_MEM_READ( "perf_event_open(attr->size)",
3581 (Addr)&attr->size, sizeof(attr->size) );
3582 PRE_MEM_READ( "perf_event_open(attr)",
3583 (Addr)attr, attr->size );
3586 POST(sys_perf_event_open)
3588 vg_assert(SUCCESS);
3589 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
3590 VG_(close)(RES);
3591 SET_STATUS_Failure( VKI_EMFILE );
3592 } else {
3593 if (VG_(clo_track_fds))
3594 ML_(record_fd_open_nameless)(tid, RES);
3598 PRE(sys_getcpu)
3600 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3601 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
3602 PRE_REG_READ3(int, "getcpu",
3603 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
3604 if (ARG1 != 0)
3605 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
3606 if (ARG2 != 0)
3607 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
3608 if (ARG3 != 0)
3609 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
3612 POST(sys_getcpu)
3614 if (ARG1 != 0)
3615 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
3616 if (ARG2 != 0)
3617 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
3618 if (ARG3 != 0)
3619 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
3622 PRE(sys_move_pages)
3624 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
3625 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3626 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3627 PRE_REG_READ6(int, "move_pages",
3628 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
3629 const int *, nodes, int *, status, int, flags);
3630 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
3631 if (ARG4)
3632 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
3633 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
3636 POST(sys_move_pages)
3638 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
3641 PRE(sys_getrandom)
3643 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3644 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
3645 PRE_REG_READ3(int, "getrandom",
3646 char *, buf, vki_size_t, count, unsigned int, flags);
3647 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
3650 POST(sys_getrandom)
3652 POST_MEM_WRITE( ARG1, ARG2 );
3655 PRE(sys_memfd_create)
3657 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
3658 ARG1, ARG2);
3659 PRE_REG_READ2(int, "memfd_create",
3660 char *, uname, unsigned int, flags);
3661 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
3664 POST(sys_memfd_create)
3666 vg_assert(SUCCESS);
3667 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
3668 VG_(close)(RES);
3669 SET_STATUS_Failure( VKI_EMFILE );
3670 } else {
3671 if (VG_(clo_track_fds))
3672 ML_(record_fd_open_nameless)(tid, RES);
3676 PRE(sys_membarrier)
3678 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
3679 PRE_REG_READ1(int, "membarrier", int, flags);
3682 PRE(sys_syncfs)
3684 *flags |= SfMayBlock;
3685 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
3686 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
3689 PRE(sys_statx)
3691 FUSE_COMPATIBLE_MAY_BLOCK();
3692 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
3693 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
3694 PRE_REG_READ5(long, "statx",
3695 int, dirfd, char *, filename, int, flags,
3696 unsigned int, mask, struct statx *, buf);
3697 // Work around Rust's dubious use of statx, as described here:
3698 // https://github.com/rust-lang/rust/blob/
3699 // ccd238309f9dce92a05a23c2959e2819668c69a4/
3700 // src/libstd/sys/unix/fs.rs#L128-L142
3701 // in which it passes NULL for both filename and buf, and then looks at the
3702 // return value, so as to determine whether or not this syscall is supported.
3703 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
3704 if (!both_filename_and_buf_are_null) {
3705 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
3706 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
3709 POST(sys_statx)
3711 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
3714 /* ---------------------------------------------------------------------
3715 utime wrapper
3716 ------------------------------------------------------------------ */
3718 PRE(sys_utime)
3720 *flags |= SfMayBlock;
3721 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
3722 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
3723 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
3724 if (ARG2 != 0)
3725 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3728 /* ---------------------------------------------------------------------
3729 lseek wrapper
3730 ------------------------------------------------------------------ */
3732 PRE(sys_lseek)
3734 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
3735 ARG1, SARG2, ARG3);
3736 PRE_REG_READ3(vki_off_t, "lseek",
3737 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3740 /* ---------------------------------------------------------------------
3741 readahead wrapper
3742 ------------------------------------------------------------------ */
3744 PRE(sys_readahead)
3746 *flags |= SfMayBlock;
3747 #if VG_WORDSIZE == 4
3748 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
3749 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
3750 PRE_REG_READ4(vki_off_t, "readahead",
3751 int, fd, unsigned, MERGE64_FIRST(offset),
3752 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3753 #elif VG_WORDSIZE == 8
3754 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
3755 PRE_REG_READ3(vki_off_t, "readahead",
3756 int, fd, vki_loff_t, offset, vki_size_t, count);
3757 #else
3758 # error Unexpected word size
3759 #endif
3760 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3761 SET_STATUS_Failure( VKI_EBADF );
3764 /* ---------------------------------------------------------------------
3765 sig* wrappers
3766 ------------------------------------------------------------------ */
3768 PRE(sys_sigpending)
3770 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
3771 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3772 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3774 POST(sys_sigpending)
3776 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3779 // This syscall is not used on amd64/Linux -- it only provides
3780 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3781 // This wrapper is only suitable for 32-bit architectures.
3782 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3783 // conditional compilation like this?)
3784 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3785 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
3786 || defined(VGP_nanomips_linux)
3787 PRE(sys_sigprocmask)
3789 vki_old_sigset_t* set;
3790 vki_old_sigset_t* oldset;
3791 vki_sigset_t bigger_set;
3792 vki_sigset_t bigger_oldset;
3794 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3795 PRE_REG_READ3(long, "sigprocmask",
3796 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3797 if (ARG2 != 0)
3798 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3799 if (ARG3 != 0)
3800 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3802 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3803 // vki_sigset_t params.
3804 set = (vki_old_sigset_t*)(Addr)ARG2;
3805 oldset = (vki_old_sigset_t*)(Addr)ARG3;
3807 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
3808 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3809 if (set)
3810 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3812 SET_STATUS_from_SysRes(
3813 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3814 set ? &bigger_set : NULL,
3815 oldset ? &bigger_oldset : NULL)
3818 if (oldset)
3819 *oldset = bigger_oldset.sig[0];
3821 if (SUCCESS)
3822 *flags |= SfPollAfter;
3824 POST(sys_sigprocmask)
3826 vg_assert(SUCCESS);
3827 if (RES == 0 && ARG3 != 0)
3828 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3831 /* Convert from non-RT to RT sigset_t's */
3832 static
3833 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3835 VG_(sigemptyset)(set);
3836 set->sig[0] = *oldset;
3838 PRE(sys_sigaction)
3840 vki_sigaction_toK_t new, *newp;
3841 vki_sigaction_fromK_t old, *oldp;
3843 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
3844 PRE_REG_READ3(int, "sigaction",
3845 int, signum, const struct old_sigaction *, act,
3846 struct old_sigaction *, oldact);
3848 newp = oldp = NULL;
3850 if (ARG2 != 0) {
3851 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
3852 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3853 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3854 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3855 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
3856 && (sa->sa_flags & VKI_SA_RESTORER))
3857 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3860 if (ARG3 != 0) {
3861 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3862 oldp = &old;
3865 /* If the new or old sigaction is not NULL, but the structs
3866 aren't accessible then sigaction returns EFAULT and we cannot
3867 use either struct for our own bookkeeping. Just fail early. */
3868 if (ARG2 != 0
3869 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3870 sizeof(struct vki_old_sigaction))) {
3871 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
3872 (void *)(Addr)ARG2);
3873 SET_STATUS_Failure ( VKI_EFAULT );
3874 } else if ((ARG3 != 0
3875 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3876 sizeof(struct vki_old_sigaction)))) {
3877 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
3878 (void *)(Addr)ARG3);
3879 SET_STATUS_Failure ( VKI_EFAULT );
3880 } else {
3881 if (ARG2 != 0) {
3882 struct vki_old_sigaction *oldnew =
3883 (struct vki_old_sigaction *)(Addr)ARG2;
3885 new.ksa_handler = oldnew->ksa_handler;
3886 new.sa_flags = oldnew->sa_flags;
3887 new.sa_restorer = oldnew->sa_restorer;
3888 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3889 newp = &new;
3892 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3894 if (ARG3 != 0 && SUCCESS && RES == 0) {
3895 struct vki_old_sigaction *oldold =
3896 (struct vki_old_sigaction *)(Addr)ARG3;
3898 oldold->ksa_handler = oldp->ksa_handler;
3899 oldold->sa_flags = oldp->sa_flags;
3900 oldold->sa_restorer = oldp->sa_restorer;
3901 oldold->sa_mask = oldp->sa_mask.sig[0];
3905 POST(sys_sigaction)
3907 vg_assert(SUCCESS);
3908 if (RES == 0 && ARG3 != 0)
3909 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3911 #endif
3913 PRE(sys_signalfd)
3915 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
3916 (ULong)ARG3);
3917 PRE_REG_READ3(long, "sys_signalfd",
3918 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3919 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3920 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3921 SET_STATUS_Failure( VKI_EBADF );
3923 POST(sys_signalfd)
3925 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3926 VG_(close)(RES);
3927 SET_STATUS_Failure( VKI_EMFILE );
3928 } else {
3929 if (VG_(clo_track_fds))
3930 ML_(record_fd_open_nameless) (tid, RES);
3934 PRE(sys_signalfd4)
3936 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3937 SARG1, ARG2, ARG3, SARG4);
3938 PRE_REG_READ4(long, "sys_signalfd4",
3939 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3940 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3941 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3942 SET_STATUS_Failure( VKI_EBADF );
3944 POST(sys_signalfd4)
3946 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3947 VG_(close)(RES);
3948 SET_STATUS_Failure( VKI_EMFILE );
3949 } else {
3950 if (VG_(clo_track_fds))
3951 ML_(record_fd_open_nameless) (tid, RES);
3956 /* ---------------------------------------------------------------------
3957 rt_sig* wrappers
3958 ------------------------------------------------------------------ */
3960 PRE(sys_rt_sigaction)
3962 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3963 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3964 PRE_REG_READ4(long, "rt_sigaction",
3965 int, signum, const struct sigaction *, act,
3966 struct sigaction *, oldact, vki_size_t, sigsetsize);
3968 if (ARG2 != 0) {
3969 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
3970 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3971 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3972 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3973 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
3974 && (sa->sa_flags & VKI_SA_RESTORER))
3975 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3977 if (ARG3 != 0)
3978 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
3980 /* If the new or old sigaction is not NULL, but the structs
3981 aren't accessible then sigaction returns EFAULT and we cannot
3982 use either struct for our own bookkeeping. Just fail early. */
3983 if (ARG2 != 0
3984 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
3985 sizeof(vki_sigaction_toK_t))) {
3986 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
3987 (void *)(Addr)ARG2);
3988 SET_STATUS_Failure ( VKI_EFAULT );
3989 } else if ((ARG3 != 0
3990 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
3991 sizeof(vki_sigaction_fromK_t)))) {
3992 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
3993 (void *)(Addr)ARG3);
3994 SET_STATUS_Failure ( VKI_EFAULT );
3995 } else {
3997 // XXX: doesn't seem right to be calling do_sys_sigaction for
3998 // sys_rt_sigaction... perhaps this function should be renamed
3999 // VG_(do_sys_rt_sigaction)() --njn
4001 SET_STATUS_from_SysRes(
4002 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4003 (vki_sigaction_fromK_t *)(Addr)ARG3)
4007 POST(sys_rt_sigaction)
4009 vg_assert(SUCCESS);
4010 if (RES == 0 && ARG3 != 0)
4011 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4014 PRE(sys_rt_sigprocmask)
4016 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4017 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4018 PRE_REG_READ4(long, "rt_sigprocmask",
4019 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4020 vki_size_t, sigsetsize);
4021 if (ARG2 != 0)
4022 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4023 if (ARG3 != 0)
4024 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4026 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4027 // Since we want to use the set and oldset for bookkeeping we also want
4028 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4029 if (sizeof(vki_sigset_t) != ARG4)
4030 SET_STATUS_Failure( VKI_EINVAL );
4031 else if (ARG2 != 0
4032 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4033 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4034 (void *)(Addr)ARG2);
4035 SET_STATUS_Failure ( VKI_EFAULT );
4037 else if (ARG3 != 0
4038 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4039 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4040 (void *)(Addr)ARG3);
4041 SET_STATUS_Failure ( VKI_EFAULT );
4044 else {
4045 SET_STATUS_from_SysRes(
4046 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4047 (vki_sigset_t*) (Addr)ARG2,
4048 (vki_sigset_t*) (Addr)ARG3 )
4052 if (SUCCESS)
4053 *flags |= SfPollAfter;
4055 POST(sys_rt_sigprocmask)
4057 vg_assert(SUCCESS);
4058 if (RES == 0 && ARG3 != 0)
4059 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4062 PRE(sys_rt_sigpending)
4064 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4065 PRE_REG_READ2(long, "rt_sigpending",
4066 vki_sigset_t *, set, vki_size_t, sigsetsize);
4067 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4069 POST(sys_rt_sigpending)
4071 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4074 PRE(sys_rt_sigtimedwait)
4076 *flags |= SfMayBlock;
4077 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4078 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4079 ARG1, ARG2, ARG3, ARG4);
4080 PRE_REG_READ4(long, "rt_sigtimedwait",
4081 const vki_sigset_t *, set, vki_siginfo_t *, info,
4082 const struct timespec *, timeout, vki_size_t, sigsetsize);
4083 if (ARG1 != 0)
4084 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4085 if (ARG2 != 0)
4086 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4087 if (ARG3 != 0)
4088 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4089 ARG3, sizeof(struct vki_timespec) );
4091 POST(sys_rt_sigtimedwait)
4093 if (ARG2 != 0)
4094 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4097 PRE(sys_rt_sigqueueinfo)
4099 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4100 SARG1, SARG2, ARG3);
4101 PRE_REG_READ3(long, "rt_sigqueueinfo",
4102 int, pid, int, sig, vki_siginfo_t *, uinfo);
4103 if (ARG2 != 0)
4104 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4106 POST(sys_rt_sigqueueinfo)
4108 if (!ML_(client_signal_OK)(ARG2))
4109 SET_STATUS_Failure( VKI_EINVAL );
4112 PRE(sys_rt_tgsigqueueinfo)
4114 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4115 SARG1, SARG2, SARG3, ARG4);
4116 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4117 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4118 if (ARG3 != 0)
4119 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4122 POST(sys_rt_tgsigqueueinfo)
4124 if (!ML_(client_signal_OK)(ARG3))
4125 SET_STATUS_Failure( VKI_EINVAL );
4128 // XXX: x86-specific? The kernel prototypes for the different archs are
4129 // hard to decipher.
4130 PRE(sys_rt_sigsuspend)
4132 /* The C library interface to sigsuspend just takes a pointer to
4133 a signal mask but this system call has two arguments - a pointer
4134 to the mask and the number of bytes used by it. The kernel insists
4135 on the size being equal to sizeof(sigset_t) however and will just
4136 return EINVAL if it isn't.
4138 *flags |= SfMayBlock;
4139 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4140 ARG1, ARG2 );
4141 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4142 if (ARG1 != (Addr)NULL) {
4143 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4144 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4145 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4146 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4147 be killable by VG_(nuke_all_threads_except).
4148 We thus silently ignore the user request to mask this signal.
4149 Note that this is similar to what is done for e.g.
4150 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4151 } else {
4152 SET_STATUS_Failure(VKI_EFAULT);
4157 /* ---------------------------------------------------------------------
4158 linux msg* wrapper helpers
4159 ------------------------------------------------------------------ */
4161 void
4162 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4163 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4165 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4166 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4167 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4168 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4171 void
4172 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4173 UWord arg0, UWord arg1, UWord arg2,
4174 UWord arg3, UWord arg4 )
4176 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4177 long msgtyp, int msgflg); */
4178 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4179 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4180 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4182 void
4183 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4184 UWord res,
4185 UWord arg0, UWord arg1, UWord arg2,
4186 UWord arg3, UWord arg4 )
4188 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4189 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4190 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4193 void
4194 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4195 UWord arg0, UWord arg1, UWord arg2 )
4197 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4198 switch (arg1 /* cmd */) {
4199 case VKI_IPC_INFO:
4200 case VKI_MSG_INFO:
4201 case VKI_IPC_INFO|VKI_IPC_64:
4202 case VKI_MSG_INFO|VKI_IPC_64:
4203 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4204 arg2, sizeof(struct vki_msginfo) );
4205 break;
4206 case VKI_IPC_STAT:
4207 case VKI_MSG_STAT:
4208 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4209 arg2, sizeof(struct vki_msqid_ds) );
4210 break;
4211 case VKI_IPC_STAT|VKI_IPC_64:
4212 case VKI_MSG_STAT|VKI_IPC_64:
4213 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4214 arg2, sizeof(struct vki_msqid64_ds) );
4215 break;
4216 case VKI_IPC_SET:
4217 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4218 arg2, sizeof(struct vki_msqid_ds) );
4219 break;
4220 case VKI_IPC_SET|VKI_IPC_64:
4221 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4222 arg2, sizeof(struct vki_msqid64_ds) );
4223 break;
4226 void
4227 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4228 UWord res,
4229 UWord arg0, UWord arg1, UWord arg2 )
4231 switch (arg1 /* cmd */) {
4232 case VKI_IPC_INFO:
4233 case VKI_MSG_INFO:
4234 case VKI_IPC_INFO|VKI_IPC_64:
4235 case VKI_MSG_INFO|VKI_IPC_64:
4236 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4237 break;
4238 case VKI_IPC_STAT:
4239 case VKI_MSG_STAT:
4240 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4241 break;
4242 case VKI_IPC_STAT|VKI_IPC_64:
4243 case VKI_MSG_STAT|VKI_IPC_64:
4244 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4245 break;
4249 /* ---------------------------------------------------------------------
4250 Generic handler for sys_ipc
4251 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4252 are either direct system calls, or are all implemented via sys_ipc.
4253 ------------------------------------------------------------------ */
4254 #ifdef __NR_ipc
4255 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4257 Addr* a_p = (Addr*)a;
4258 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4259 return *a_p;
4262 static Bool semctl_cmd_has_4args (UWord cmd)
4264 switch (cmd & ~VKI_IPC_64)
4266 case VKI_IPC_INFO:
4267 case VKI_SEM_INFO:
4268 case VKI_IPC_STAT:
4269 case VKI_SEM_STAT:
4270 case VKI_IPC_SET:
4271 case VKI_GETALL:
4272 case VKI_SETALL:
4273 return True;
4274 default:
4275 return False;
4279 PRE(sys_ipc)
4281 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4282 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4284 switch (ARG1 /* call */) {
4285 case VKI_SEMOP:
4286 PRE_REG_READ5(int, "ipc",
4287 vki_uint, call, int, first, int, second, int, third,
4288 void *, ptr);
4289 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4290 *flags |= SfMayBlock;
4291 break;
4292 case VKI_SEMGET:
4293 PRE_REG_READ4(int, "ipc",
4294 vki_uint, call, int, first, int, second, int, third);
4295 break;
4296 case VKI_SEMCTL:
4298 PRE_REG_READ5(int, "ipc",
4299 vki_uint, call, int, first, int, second, int, third,
4300 void *, ptr);
4301 UWord arg;
4302 if (semctl_cmd_has_4args(ARG4))
4303 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4304 else
4305 arg = 0;
4306 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4307 break;
4309 case VKI_SEMTIMEDOP:
4310 PRE_REG_READ6(int, "ipc",
4311 vki_uint, call, int, first, int, second, int, third,
4312 void *, ptr, long, fifth);
4313 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4314 *flags |= SfMayBlock;
4315 break;
4316 case VKI_MSGSND:
4317 PRE_REG_READ5(int, "ipc",
4318 vki_uint, call, int, first, int, second, int, third,
4319 void *, ptr);
4320 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4321 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4322 *flags |= SfMayBlock;
4323 break;
4324 case VKI_MSGRCV:
4326 PRE_REG_READ5(int, "ipc",
4327 vki_uint, call, int, first, int, second, int, third,
4328 void *, ptr);
4329 Addr msgp;
4330 Word msgtyp;
4332 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4333 "msgrcv(msgp)" );
4334 msgtyp = deref_Addr( tid,
4335 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4336 "msgrcv(msgp)" );
4338 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4340 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4341 *flags |= SfMayBlock;
4342 break;
4344 case VKI_MSGGET:
4345 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4346 break;
4347 case VKI_MSGCTL:
4348 PRE_REG_READ5(int, "ipc",
4349 vki_uint, call, int, first, int, second, int, third,
4350 void *, ptr);
4351 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4352 break;
4353 case VKI_SHMAT:
4355 PRE_REG_READ5(int, "ipc",
4356 vki_uint, call, int, first, int, second, int, third,
4357 void *, ptr);
4358 UWord w;
4359 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4360 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4361 if (w == 0)
4362 SET_STATUS_Failure( VKI_EINVAL );
4363 else
4364 ARG5 = w;
4365 break;
4367 case VKI_SHMDT:
4368 PRE_REG_READ5(int, "ipc",
4369 vki_uint, call, int, first, int, second, int, third,
4370 void *, ptr);
4371 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4372 SET_STATUS_Failure( VKI_EINVAL );
4373 break;
4374 case VKI_SHMGET:
4375 PRE_REG_READ4(int, "ipc",
4376 vki_uint, call, int, first, int, second, int, third);
4377 if (ARG4 & VKI_SHM_HUGETLB) {
4378 static Bool warning_given = False;
4379 ARG4 &= ~VKI_SHM_HUGETLB;
4380 if (!warning_given) {
4381 warning_given = True;
4382 VG_(umsg)(
4383 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4386 break;
4387 case VKI_SHMCTL: /* IPCOP_shmctl */
4388 PRE_REG_READ5(int, "ipc",
4389 vki_uint, call, int, first, int, second, int, third,
4390 void *, ptr);
4391 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4392 break;
4393 default:
4394 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4395 VG_(core_panic)("... bye!\n");
4396 break; /*NOTREACHED*/
4400 POST(sys_ipc)
4402 vg_assert(SUCCESS);
4403 switch (ARG1 /* call */) {
4404 case VKI_SEMOP:
4405 case VKI_SEMGET:
4406 break;
4407 case VKI_SEMCTL:
4409 UWord arg;
4410 if (semctl_cmd_has_4args(ARG4))
4411 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4412 else
4413 arg = 0;
4414 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4415 break;
4417 case VKI_SEMTIMEDOP:
4418 case VKI_MSGSND:
4419 break;
4420 case VKI_MSGRCV:
4422 Addr msgp;
4423 Word msgtyp;
4425 msgp = deref_Addr( tid,
4426 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4427 "msgrcv(msgp)" );
4428 msgtyp = deref_Addr( tid,
4429 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4430 "msgrcv(msgp)" );
4432 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4433 break;
4435 case VKI_MSGGET:
4436 break;
4437 case VKI_MSGCTL:
4438 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4439 break;
4440 case VKI_SHMAT:
4442 Addr addr;
4444 /* force readability. before the syscall it is
4445 * indeed uninitialized, as can be seen in
4446 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4447 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4449 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4450 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4451 break;
4453 case VKI_SHMDT:
4454 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4455 break;
4456 case VKI_SHMGET:
4457 break;
4458 case VKI_SHMCTL:
4459 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4460 break;
4461 default:
4462 VG_(message)(Vg_DebugMsg,
4463 "FATAL: unhandled syscall(ipc) %lu\n",
4464 ARG1 );
4465 VG_(core_panic)("... bye!\n");
4466 break; /*NOTREACHED*/
4469 #endif
4471 PRE(sys_semget)
4473 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4474 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4477 PRE(sys_semop)
4479 *flags |= SfMayBlock;
4480 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4481 SARG1, ARG2, ARG3);
4482 PRE_REG_READ3(long, "semop",
4483 int, semid, struct sembuf *, sops, unsigned, nsoops);
4484 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4487 PRE(sys_semctl)
4489 switch (ARG3 & ~VKI_IPC_64) {
4490 case VKI_IPC_INFO:
4491 case VKI_SEM_INFO:
4492 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4493 SARG3, ARG4);
4494 PRE_REG_READ4(long, "semctl",
4495 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4496 break;
4497 case VKI_IPC_STAT:
4498 case VKI_SEM_STAT:
4499 case VKI_IPC_SET:
4500 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4501 SARG3, ARG4);
4502 PRE_REG_READ4(long, "semctl",
4503 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4504 break;
4505 case VKI_GETALL:
4506 case VKI_SETALL:
4507 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4508 SARG3, ARG4);
4509 PRE_REG_READ4(long, "semctl",
4510 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4511 break;
4512 default:
4513 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4514 PRE_REG_READ3(long, "semctl",
4515 int, semid, int, semnum, int, cmd);
4516 break;
4518 #ifdef VGP_amd64_linux
4519 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4520 #else
4521 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4522 #endif
4525 POST(sys_semctl)
4527 #ifdef VGP_amd64_linux
4528 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4529 #else
4530 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4531 #endif
4534 PRE(sys_semtimedop)
4536 *flags |= SfMayBlock;
4537 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
4538 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
4539 PRE_REG_READ4(long, "semtimedop",
4540 int, semid, struct sembuf *, sops, unsigned, nsoops,
4541 struct timespec *, timeout);
4542 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
4545 PRE(sys_msgget)
4547 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
4548 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
4551 PRE(sys_msgsnd)
4553 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4554 SARG1, ARG2, ARG3, SARG4);
4555 PRE_REG_READ4(long, "msgsnd",
4556 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
4557 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
4558 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4559 *flags |= SfMayBlock;
4562 PRE(sys_msgrcv)
4564 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
4565 SARG1, ARG2, ARG3, SARG4, SARG5);
4566 PRE_REG_READ5(long, "msgrcv",
4567 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
4568 long, msgytp, int, msgflg);
4569 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4570 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
4571 *flags |= SfMayBlock;
4573 POST(sys_msgrcv)
4575 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
4578 PRE(sys_msgctl)
4580 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4581 PRE_REG_READ3(long, "msgctl",
4582 int, msqid, int, cmd, struct msqid_ds *, buf);
4583 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
4586 POST(sys_msgctl)
4588 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
4591 PRE(sys_shmget)
4593 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
4594 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
4595 if (ARG3 & VKI_SHM_HUGETLB) {
4596 static Bool warning_given = False;
4597 ARG3 &= ~VKI_SHM_HUGETLB;
4598 if (!warning_given) {
4599 warning_given = True;
4600 VG_(umsg)(
4601 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4606 PRE(sys_shmat)
4608 UWord arg2tmp;
4609 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4610 PRE_REG_READ3(long, "shmat",
4611 int, shmid, const void *, shmaddr, int, shmflg);
4612 #if defined(VGP_arm_linux)
4613 /* Round the attach address down to an VKI_SHMLBA boundary if the
4614 client requested rounding. See #222545. This is necessary only
4615 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
4616 other linux targets it is the same as the page size. */
4617 if (ARG3 & VKI_SHM_RND)
4618 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
4619 #endif
4620 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
4621 if (arg2tmp == 0)
4622 SET_STATUS_Failure( VKI_EINVAL );
4623 else
4624 ARG2 = arg2tmp; // used in POST
4627 POST(sys_shmat)
4629 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
4632 PRE(sys_shmdt)
4634 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
4635 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
4636 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
4637 SET_STATUS_Failure( VKI_EINVAL );
4640 POST(sys_shmdt)
4642 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
4645 PRE(sys_shmctl)
4647 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
4648 PRE_REG_READ3(long, "shmctl",
4649 int, shmid, int, cmd, struct shmid_ds *, buf);
4650 #ifdef VGP_amd64_linux
4651 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
4652 #else
4653 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
4654 #endif
4657 POST(sys_shmctl)
4659 #ifdef VGP_amd64_linux
4660 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
4661 #else
4662 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
4663 #endif
4667 /* ---------------------------------------------------------------------
4668 Generic handler for sys_socketcall
4669 Depending on the platform, some socket related syscalls (e.g. socketpair,
4670 socket, bind, ...)
4671 are either direct system calls, or are all implemented via sys_socketcall.
4672 ------------------------------------------------------------------ */
4673 #ifdef __NR_socketcall
4674 PRE(sys_socketcall)
4676 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4677 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4678 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4679 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4680 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4681 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4683 // call PRE_MEM_READ and check for EFAULT result.
4684 #define PRE_MEM_READ_ef(msg, arg, size) \
4686 PRE_MEM_READ( msg, arg, size); \
4687 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
4688 SET_STATUS_Failure( VKI_EFAULT ); \
4689 break; \
4693 *flags |= SfMayBlock;
4694 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
4695 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4697 switch (ARG1 /* request */) {
4699 case VKI_SYS_SOCKETPAIR:
4700 /* int socketpair(int d, int type, int protocol, int sv[2]); */
4701 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
4702 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4703 break;
4705 case VKI_SYS_SOCKET:
4706 /* int socket(int domain, int type, int protocol); */
4707 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
4708 break;
4710 case VKI_SYS_BIND:
4711 /* int bind(int sockfd, struct sockaddr *my_addr,
4712 int addrlen); */
4713 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
4714 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
4715 break;
4717 case VKI_SYS_LISTEN:
4718 /* int listen(int s, int backlog); */
4719 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
4720 break;
4722 case VKI_SYS_ACCEPT:
4723 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4724 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
4725 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4726 break;
4728 case VKI_SYS_ACCEPT4:
4729 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4730 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
4731 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
4732 break;
4734 case VKI_SYS_SENDTO:
4735 /* int sendto(int s, const void *msg, int len,
4736 unsigned int flags,
4737 const struct sockaddr *to, int tolen); */
4738 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
4739 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
4740 ARG2_3, ARG2_4, ARG2_5 );
4741 break;
4743 case VKI_SYS_SEND:
4744 /* int send(int s, const void *msg, size_t len, int flags); */
4745 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
4746 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
4747 break;
4749 case VKI_SYS_RECVFROM:
4750 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4751 struct sockaddr *from, int *fromlen); */
4752 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
4753 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
4754 ARG2_3, ARG2_4, ARG2_5 );
4755 break;
4757 case VKI_SYS_RECV:
4758 /* int recv(int s, void *buf, int len, unsigned int flags); */
4759 /* man 2 recv says:
4760 The recv call is normally used only on a connected socket
4761 (see connect(2)) and is identical to recvfrom with a NULL
4762 from parameter.
4764 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
4765 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
4766 break;
4768 case VKI_SYS_CONNECT:
4769 /* int connect(int sockfd,
4770 struct sockaddr *serv_addr, int addrlen ); */
4771 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
4772 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
4773 break;
4775 case VKI_SYS_SETSOCKOPT:
4776 /* int setsockopt(int s, int level, int optname,
4777 const void *optval, int optlen); */
4778 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
4779 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4780 ARG2_3, ARG2_4 );
4781 break;
4783 case VKI_SYS_GETSOCKOPT:
4784 /* int getsockopt(int s, int level, int optname,
4785 void *optval, socklen_t *optlen); */
4786 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
4787 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
4788 ARG2_3, ARG2_4 );
4789 break;
4791 case VKI_SYS_GETSOCKNAME:
4792 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
4793 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
4794 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
4795 break;
4797 case VKI_SYS_GETPEERNAME:
4798 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
4799 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
4800 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
4801 break;
4803 case VKI_SYS_SHUTDOWN:
4804 /* int shutdown(int s, int how); */
4805 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
4806 break;
4808 case VKI_SYS_SENDMSG:
4809 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4810 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
4811 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
4812 (struct vki_msghdr *)(Addr)ARG2_1 );
4813 break;
4815 case VKI_SYS_RECVMSG:
4816 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4817 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
4818 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
4819 (struct vki_msghdr *)(Addr)ARG2_1 );
4820 break;
4822 case VKI_SYS_RECVMMSG:
4823 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
4824 struct timespec *timeout); */
4825 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
4826 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
4827 ARG2_4 );
4828 break;
4830 case VKI_SYS_SENDMMSG:
4831 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
4832 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
4833 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4834 break;
4836 default:
4837 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
4838 SET_STATUS_Failure( VKI_EINVAL );
4839 break;
4841 # undef ARG2_0
4842 # undef ARG2_1
4843 # undef ARG2_2
4844 # undef ARG2_3
4845 # undef ARG2_4
4846 # undef ARG2_5
4849 POST(sys_socketcall)
4851 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
4852 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
4853 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
4854 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
4855 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
4856 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
4858 SysRes r;
4859 vg_assert(SUCCESS);
4860 switch (ARG1 /* request */) {
4862 case VKI_SYS_SOCKETPAIR:
4863 r = ML_(generic_POST_sys_socketpair)(
4864 tid, VG_(mk_SysRes_Success)(RES),
4865 ARG2_0, ARG2_1, ARG2_2, ARG2_3
4867 SET_STATUS_from_SysRes(r);
4868 break;
4870 case VKI_SYS_SOCKET:
4871 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4872 SET_STATUS_from_SysRes(r);
4873 break;
4875 case VKI_SYS_BIND:
4876 /* int bind(int sockfd, struct sockaddr *my_addr,
4877 int addrlen); */
4878 break;
4880 case VKI_SYS_LISTEN:
4881 /* int listen(int s, int backlog); */
4882 break;
4884 case VKI_SYS_ACCEPT:
4885 case VKI_SYS_ACCEPT4:
4886 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4887 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4888 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4889 ARG2_0, ARG2_1, ARG2_2 );
4890 SET_STATUS_from_SysRes(r);
4891 break;
4893 case VKI_SYS_SENDTO:
4894 break;
4896 case VKI_SYS_SEND:
4897 break;
4899 case VKI_SYS_RECVFROM:
4900 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4901 ARG2_0, ARG2_1, ARG2_2,
4902 ARG2_3, ARG2_4, ARG2_5 );
4903 break;
4905 case VKI_SYS_RECV:
4906 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4907 break;
4909 case VKI_SYS_CONNECT:
4910 break;
4912 case VKI_SYS_SETSOCKOPT:
4913 break;
4915 case VKI_SYS_GETSOCKOPT:
4916 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4917 ARG2_0, ARG2_1,
4918 ARG2_2, ARG2_3, ARG2_4 );
4919 break;
4921 case VKI_SYS_GETSOCKNAME:
4922 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4923 ARG2_0, ARG2_1, ARG2_2 );
4924 break;
4926 case VKI_SYS_GETPEERNAME:
4927 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4928 ARG2_0, ARG2_1, ARG2_2 );
4929 break;
4931 case VKI_SYS_SHUTDOWN:
4932 break;
4934 case VKI_SYS_SENDMSG:
4935 break;
4937 case VKI_SYS_RECVMSG:
4938 ML_(generic_POST_sys_recvmsg)( tid, "msg",
4939 (struct vki_msghdr *)(Addr)ARG2_1, RES );
4940 break;
4942 case VKI_SYS_RECVMMSG:
4943 ML_(linux_POST_sys_recvmmsg)( tid, RES,
4944 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
4945 break;
4947 case VKI_SYS_SENDMMSG:
4948 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
4949 break;
4951 default:
4952 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4953 VG_(core_panic)("... bye!\n");
4954 break; /*NOTREACHED*/
4956 # undef ARG2_0
4957 # undef ARG2_1
4958 # undef ARG2_2
4959 # undef ARG2_3
4960 # undef ARG2_4
4961 # undef ARG2_5
4963 #endif
4965 PRE(sys_socket)
4967 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4968 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4970 POST(sys_socket)
4972 SysRes r;
4973 vg_assert(SUCCESS);
4974 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4975 SET_STATUS_from_SysRes(r);
4978 PRE(sys_setsockopt)
4980 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
4981 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
4982 PRE_REG_READ5(long, "setsockopt",
4983 int, s, int, level, int, optname,
4984 const void *, optval, unsigned, optlen); // socklen_t
4985 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4988 PRE(sys_getsockopt)
4990 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
4991 SARG1, SARG2, SARG3, ARG4, SARG5);
4992 PRE_REG_READ5(long, "getsockopt",
4993 int, s, int, level, int, optname,
4994 void *, optval, int, *optlen);
4995 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4997 POST(sys_getsockopt)
4999 vg_assert(SUCCESS);
5000 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5001 ARG1,ARG2,ARG3,ARG4,ARG5);
5004 PRE(sys_connect)
5006 *flags |= SfMayBlock;
5007 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5008 PRE_REG_READ3(long, "connect",
5009 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5010 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5013 PRE(sys_accept)
5015 *flags |= SfMayBlock;
5016 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5017 SARG1, ARG2, ARG3);
5018 PRE_REG_READ3(long, "accept",
5019 int, s, struct sockaddr *, addr, int *, addrlen);
5020 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5022 POST(sys_accept)
5024 SysRes r;
5025 vg_assert(SUCCESS);
5026 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5027 ARG1,ARG2,ARG3);
5028 SET_STATUS_from_SysRes(r);
5031 PRE(sys_accept4)
5033 *flags |= SfMayBlock;
5034 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5035 SARG1, ARG2, ARG3, SARG4);
5036 PRE_REG_READ4(long, "accept4",
5037 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5038 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5040 POST(sys_accept4)
5042 SysRes r;
5043 vg_assert(SUCCESS);
5044 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5045 ARG1,ARG2,ARG3);
5046 SET_STATUS_from_SysRes(r);
5049 PRE(sys_send)
5051 *flags |= SfMayBlock;
5052 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5053 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5054 PRE_REG_READ4(long, "send",
5055 int, s, const void *, msg, vki_size_t, len,
5056 int, flags);
5058 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5061 PRE(sys_sendto)
5063 *flags |= SfMayBlock;
5064 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5065 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5066 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5067 PRE_REG_READ6(long, "sendto",
5068 int, s, const void *, msg, vki_size_t, len,
5069 unsigned int, flags,
5070 const struct sockaddr *, to, int, tolen);
5071 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5074 PRE (sys_recv)
5076 *flags |= SfMayBlock;
5077 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5078 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5079 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5080 unsigned int, flags);
5081 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5084 POST (sys_recv)
5086 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5089 PRE(sys_recvfrom)
5091 *flags |= SfMayBlock;
5092 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5093 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5094 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5095 PRE_REG_READ6(long, "recvfrom",
5096 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5097 struct sockaddr *, from, int *, fromlen);
5098 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5100 POST(sys_recvfrom)
5102 vg_assert(SUCCESS);
5103 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5104 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5107 PRE(sys_sendmsg)
5109 *flags |= SfMayBlock;
5110 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5111 SARG1, ARG2, ARG3);
5112 PRE_REG_READ3(long, "sendmsg",
5113 int, s, const struct msghdr *, msg, unsigned int, flags);
5114 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5117 PRE(sys_recvmsg)
5119 *flags |= SfMayBlock;
5120 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5121 SARG1, ARG2, ARG3);
5122 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5123 unsigned int, flags);
5124 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5126 POST(sys_recvmsg)
5128 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5129 RES);
5132 PRE(sys_shutdown)
5134 *flags |= SfMayBlock;
5135 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5136 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5139 PRE(sys_bind)
5141 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5142 PRE_REG_READ3(long, "bind",
5143 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5144 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5147 PRE(sys_listen)
5149 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5150 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5153 PRE(sys_getsockname)
5155 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5156 SARG1, ARG2, ARG3);
5157 PRE_REG_READ3(long, "getsockname",
5158 int, s, struct sockaddr *, name, int *, namelen);
5159 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5161 POST(sys_getsockname)
5163 vg_assert(SUCCESS);
5164 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5165 ARG1,ARG2,ARG3);
5168 PRE(sys_getpeername)
5170 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5171 SARG1, ARG2, ARG3);
5172 PRE_REG_READ3(long, "getpeername",
5173 int, s, struct sockaddr *, name, int *, namelen);
5174 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5176 POST(sys_getpeername)
5178 vg_assert(SUCCESS);
5179 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5180 ARG1,ARG2,ARG3);
5183 PRE(sys_socketpair)
5185 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5186 SARG3, ARG4);
5187 PRE_REG_READ4(long, "socketpair",
5188 int, d, int, type, int, protocol, int*, sv);
5189 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5191 POST(sys_socketpair)
5193 vg_assert(SUCCESS);
5194 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5195 ARG1,ARG2,ARG3,ARG4);
5199 /* ---------------------------------------------------------------------
5200 *at wrappers
5201 ------------------------------------------------------------------ */
5203 PRE(sys_openat)
5205 HChar name[30]; // large enough
5206 SysRes sres;
5208 if (ARG3 & VKI_O_CREAT) {
5209 // 4-arg version
5210 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5211 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5212 PRE_REG_READ4(long, "openat",
5213 int, dfd, const char *, filename, int, flags, int, mode);
5214 } else {
5215 // 3-arg version
5216 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5217 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5218 PRE_REG_READ3(long, "openat",
5219 int, dfd, const char *, filename, int, flags);
5222 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5224 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5225 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5226 be sure only to compare the bottom 32 bits. */
5227 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5228 && *(Char *)(Addr)ARG2 != '/'
5229 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5230 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5231 SET_STATUS_Failure( VKI_EBADF );
5233 /* Handle the case where the open is of /proc/self/cmdline or
5234 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5235 fake file we cooked up at startup (in m_main). Also, seek the
5236 cloned fd back to the start. */
5238 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5239 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5240 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5241 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5242 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5243 SET_STATUS_from_SysRes( sres );
5244 if (!sr_isError(sres)) {
5245 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5246 if (off < 0)
5247 SET_STATUS_Failure( VKI_EMFILE );
5249 return;
5252 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5254 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5255 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5256 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5257 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5258 sres = VG_(dup)( VG_(cl_auxv_fd) );
5259 SET_STATUS_from_SysRes( sres );
5260 if (!sr_isError(sres)) {
5261 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5262 if (off < 0)
5263 SET_STATUS_Failure( VKI_EMFILE );
5265 return;
5268 /* Otherwise handle normally */
5269 *flags |= SfMayBlock;
5272 POST(sys_openat)
5274 vg_assert(SUCCESS);
5275 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5276 VG_(close)(RES);
5277 SET_STATUS_Failure( VKI_EMFILE );
5278 } else {
5279 if (VG_(clo_track_fds))
5280 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5284 PRE(sys_mkdirat)
5286 *flags |= SfMayBlock;
5287 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5288 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5289 PRE_REG_READ3(long, "mkdirat",
5290 int, dfd, const char *, pathname, int, mode);
5291 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5294 PRE(sys_mknodat)
5296 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5297 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5298 PRE_REG_READ4(long, "mknodat",
5299 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5300 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5303 PRE(sys_fchownat)
5305 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5306 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5307 PRE_REG_READ4(long, "fchownat",
5308 int, dfd, const char *, path,
5309 vki_uid_t, owner, vki_gid_t, group);
5310 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5313 PRE(sys_futimesat)
5315 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5316 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5317 PRE_REG_READ3(long, "futimesat",
5318 int, dfd, char *, filename, struct timeval *, tvp);
5319 if (ARG2 != 0)
5320 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5321 if (ARG3 != 0)
5322 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5325 PRE(sys_utimensat)
5327 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5328 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5329 PRE_REG_READ4(long, "utimensat",
5330 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5331 if (ARG2 != 0)
5332 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5333 if (ARG3 != 0) {
5334 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5335 then the tv_sec field is ignored. */
5336 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5337 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5338 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5339 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5340 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5341 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5342 if (times[0].tv_nsec != VKI_UTIME_NOW
5343 && times[0].tv_nsec != VKI_UTIME_OMIT)
5344 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5345 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5346 if (times[1].tv_nsec != VKI_UTIME_NOW
5347 && times[1].tv_nsec != VKI_UTIME_OMIT)
5348 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5349 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5354 #if !defined(VGP_nanomips_linux)
5355 PRE(sys_newfstatat)
5357 FUSE_COMPATIBLE_MAY_BLOCK();
5358 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5359 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5360 PRE_REG_READ3(long, "fstatat",
5361 int, dfd, char *, file_name, struct stat *, buf);
5362 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5363 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5366 POST(sys_newfstatat)
5368 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5370 #endif
5372 PRE(sys_unlinkat)
5374 *flags |= SfMayBlock;
5375 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5376 (HChar*)(Addr)ARG2);
5377 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5378 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5381 PRE(sys_renameat)
5383 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5384 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5385 ARG4, (HChar*)(Addr)ARG4);
5386 PRE_REG_READ4(long, "renameat",
5387 int, olddfd, const char *, oldpath,
5388 int, newdfd, const char *, newpath);
5389 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5390 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5393 PRE(sys_renameat2)
5395 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5396 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5397 ARG4, (HChar*)(Addr)ARG4, ARG5);
5398 PRE_REG_READ5(long, "renameat2",
5399 int, olddfd, const char *, oldpath,
5400 int, newdfd, const char *, newpath,
5401 unsigned int, flags);
5402 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5403 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5406 PRE(sys_linkat)
5408 *flags |= SfMayBlock;
5409 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5410 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5411 (HChar*)(Addr)ARG4, SARG5);
5412 PRE_REG_READ5(long, "linkat",
5413 int, olddfd, const char *, oldpath,
5414 int, newdfd, const char *, newpath,
5415 int, flags);
5416 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5417 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5420 PRE(sys_symlinkat)
5422 *flags |= SfMayBlock;
5423 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5424 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5425 PRE_REG_READ3(long, "symlinkat",
5426 const char *, oldpath, int, newdfd, const char *, newpath);
5427 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5428 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5431 PRE(sys_readlinkat)
5433 HChar name[30]; // large enough
5434 Word saved = SYSNO;
5436 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5437 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5438 PRE_REG_READ4(long, "readlinkat",
5439 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5440 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5441 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5444 * Handle the case where readlinkat is looking at /proc/self/exe or
5445 * /proc/<pid>/exe.
5447 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5448 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5449 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5450 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5451 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5452 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5453 ARG3, ARG4));
5454 } else {
5455 /* Normal case */
5456 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5459 if (SUCCESS && RES > 0)
5460 POST_MEM_WRITE( ARG3, RES );
5463 PRE(sys_fchmodat)
5465 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5466 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5467 PRE_REG_READ3(long, "fchmodat",
5468 int, dfd, const char *, path, vki_mode_t, mode);
5469 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
5472 PRE(sys_faccessat)
5474 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5475 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5476 PRE_REG_READ3(long, "faccessat",
5477 int, dfd, const char *, pathname, int, mode);
5478 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
5481 PRE(sys_name_to_handle_at)
5483 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
5484 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
5485 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5486 PRE_REG_READ5(int, "name_to_handle_at",
5487 int, dfd, const char *, name,
5488 struct vki_file_handle *, handle,
5489 int *, mnt_id, int, flag);
5490 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
5491 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
5492 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5493 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
5494 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
5496 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
5499 POST(sys_name_to_handle_at)
5501 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
5502 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
5503 POST_MEM_WRITE( ARG4, sizeof(int) );
5506 PRE(sys_open_by_handle_at)
5508 *flags |= SfMayBlock;
5509 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
5510 ARG2, SARG3);
5511 PRE_REG_READ3(int, "open_by_handle_at",
5512 int, mountdirfd,
5513 struct vki_file_handle *, handle,
5514 int, flags);
5515 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
5516 sizeof(struct vki_file_handle) +
5517 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
5520 POST(sys_open_by_handle_at)
5522 vg_assert(SUCCESS);
5523 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
5524 VG_(close)(RES);
5525 SET_STATUS_Failure( VKI_EMFILE );
5526 } else {
5527 if (VG_(clo_track_fds))
5528 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5532 /* ---------------------------------------------------------------------
5533 p{read,write}v wrappers
5534 ------------------------------------------------------------------ */
5535 /* This handles the common part of the PRE macro for preadv and preadv2. */
5536 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
5537 Int fd, Addr vector, Int count, const char *str)
5539 struct vki_iovec * vec;
5540 Int i;
5541 /* safe size for the "preadv/preadv2(vector[i])" string */
5542 char tmp[30];
5544 if (!ML_(fd_allowed)(fd, str, tid, False)) {
5545 SET_STATUS_Failure( VKI_EBADF );
5546 } else if (count > 0) {
5547 VG_(strcpy) (tmp, str);
5548 VG_(strcat) (tmp, "(vector)");
5549 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
5551 if (ML_(safe_to_deref) ((void *)(Addr)vector,
5552 count * sizeof(struct vki_iovec))) {
5553 vec = (struct vki_iovec *)(Addr)vector;
5554 for (i = 0; i < count; i++) {
5555 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
5556 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
5562 /* This handles the common part of the POST macro for preadv and preadv2. */
5563 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
5565 vg_assert(SUCCESS);
5566 if (RES > 0) {
5567 Int i;
5568 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
5569 Int remains = RES;
5571 /* RES holds the number of bytes read. */
5572 for (i = 0; i < count; i++) {
5573 Int nReadThisBuf = vec[i].iov_len;
5574 if (nReadThisBuf > remains) nReadThisBuf = remains;
5575 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5576 remains -= nReadThisBuf;
5577 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
5582 PRE(sys_preadv)
5584 *flags |= SfMayBlock;
5585 const char *str = "preadv";
5586 #if VG_WORDSIZE == 4
5587 /* Note that the offset argument here is in lo+hi order on both
5588 big and little endian platforms... */
5589 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5590 "u, %lld )",
5591 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5592 PRE_REG_READ5(ssize_t, "preadv",
5593 unsigned long, fd, const struct iovec *, vector,
5594 unsigned long, count, vki_u32, offset_low,
5595 vki_u32, offset_high);
5596 #elif VG_WORDSIZE == 8
5597 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5598 PRE_REG_READ4(ssize_t, "preadv",
5599 unsigned long, fd, const struct iovec *, vector,
5600 unsigned long, count, Word, offset);
5601 #else
5602 # error Unexpected word size
5603 #endif
5604 Int fd = ARG1;
5605 Addr vector = ARG2;
5606 Int count = ARG3;
5608 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
5612 POST(sys_preadv)
5614 Addr vector = ARG2;
5615 Int count = ARG3;
5617 handle_post_sys_preadv(tid, status, vector, count);
5620 PRE(sys_preadv2)
5622 *flags |= SfMayBlock;
5623 const char *str = "preadv2";
5624 #if VG_WORDSIZE == 4
5625 /* Note that the offset argument here is in lo+hi order on both
5626 big and little endian platforms... */
5627 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5628 "u, %lld, %" FMT_REGWORD "u )",
5629 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
5630 PRE_REG_READ6(ssize_t, "preadv2",
5631 unsigned long, fd, const struct iovec *, vector,
5632 unsigned long, count, vki_u32, offset_low,
5633 vki_u32, offset_high, unsigned long, flags);
5634 #elif VG_WORDSIZE == 8
5635 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
5636 PRE_REG_READ5(ssize_t, "preadv2",
5637 unsigned long, fd, const struct iovec *, vector,
5638 unsigned long, count, Word, offset, unsigned long, flags);
5639 #else
5640 # error Unexpected word size
5641 #endif
5642 Int fd = ARG1;
5643 Addr vector = ARG2;
5644 Int count = ARG3;
5646 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
5649 POST(sys_preadv2)
5651 Addr vector = ARG2;
5652 Int count = ARG3;
5654 handle_post_sys_preadv(tid, status, vector, count);
5657 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
5658 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
5659 Int fd, Addr vector, Int count, const char *str)
5661 Int i;
5662 struct vki_iovec * vec;
5663 /* safe size for the "preadv/preadv2(vector[i])" string */
5664 char tmp[30];
5666 if (!ML_(fd_allowed)(fd, str, tid, False)) {
5667 SET_STATUS_Failure( VKI_EBADF );
5668 } else if (count > 0) {
5669 VG_(strcpy) (tmp, str);
5670 VG_(strcat) (tmp, "(vector)");
5671 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
5672 if (ML_(safe_to_deref) ((void *)(Addr)vector,
5673 count * sizeof(struct vki_iovec))) {
5674 vec = (struct vki_iovec *)(Addr)vector;
5675 for (i = 0; i < count; i++) {
5676 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
5677 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
5683 PRE(sys_pwritev)
5685 *flags |= SfMayBlock;
5686 const char *str = "pwritev";
5687 #if VG_WORDSIZE == 4
5688 /* Note that the offset argument here is in lo+hi order on both
5689 big and little endian platforms... */
5690 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5691 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
5692 PRE_REG_READ5(ssize_t, "pwritev",
5693 unsigned long, fd, const struct iovec *, vector,
5694 unsigned long, count, vki_u32, offset_low,
5695 vki_u32, offset_high);
5696 #elif VG_WORDSIZE == 8
5697 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
5698 PRE_REG_READ4(ssize_t, "pwritev",
5699 unsigned long, fd, const struct iovec *, vector,
5700 unsigned long, count, Word, offset);
5701 #else
5702 # error Unexpected word size
5703 #endif
5704 Int fd = ARG1;
5705 Addr vector = ARG2;
5706 Int count = ARG3;
5708 handle_sys_pwritev(tid, status, fd, vector, count, str);
5711 PRE(sys_pwritev2)
5713 *flags |= SfMayBlock;
5714 const char *str = "pwritev2";
5715 #if VG_WORDSIZE == 4
5716 /* Note that the offset argument here is in lo+hi order on both
5717 big and little endian platforms... */
5718 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
5719 "u, %lld, %" FMT_REGWORD "u )",
5720 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
5721 PRE_REG_READ6(ssize_t, "pwritev2",
5722 unsigned long, fd, const struct iovec *, vector,
5723 unsigned long, count, vki_u32, offset_low,
5724 vki_u32, offset_high, unsigned long, flags);
5725 #elif VG_WORDSIZE == 8
5726 /* Note offset_high isn't actually used? */
5727 PRE_REG_READ6(ssize_t, "pwritev2",
5728 unsigned long, fd, const struct iovec *, vector,
5729 unsigned long, count, Word, offset,
5730 Word, offset_high, unsigned long, flags);
5731 #else
5732 # error Unexpected word size
5733 #endif
5734 Int fd = ARG1;
5735 Addr vector = ARG2;
5736 Int count = ARG3;
5738 handle_sys_pwritev(tid, status, fd, vector, count, str);
5741 /* ---------------------------------------------------------------------
5742 process_vm_{read,write}v wrappers
5743 ------------------------------------------------------------------ */
5745 PRE(sys_process_vm_readv)
5747 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5748 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5749 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5750 PRE_REG_READ6(ssize_t, "process_vm_readv",
5751 vki_pid_t, pid,
5752 const struct iovec *, lvec,
5753 unsigned long, liovcnt,
5754 const struct iovec *, rvec,
5755 unsigned long, riovcnt,
5756 unsigned long, flags);
5757 PRE_MEM_READ( "process_vm_readv(lvec)",
5758 ARG2, ARG3 * sizeof(struct vki_iovec) );
5759 PRE_MEM_READ( "process_vm_readv(rvec)",
5760 ARG4, ARG5 * sizeof(struct vki_iovec) );
5761 if (ARG2 != 0
5762 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5763 sizeof(struct vki_iovec) * ARG3)) {
5764 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5765 UInt i;
5766 for (i = 0; i < ARG3; i++)
5767 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
5768 (Addr)vec[i].iov_base, vec[i].iov_len );
5772 POST(sys_process_vm_readv)
5774 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5775 UInt remains = RES;
5776 UInt i;
5777 for (i = 0; i < ARG3; i++) {
5778 UInt nReadThisBuf = vec[i].iov_len <= remains ?
5779 vec[i].iov_len : remains;
5780 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
5781 remains -= nReadThisBuf;
5785 PRE(sys_process_vm_writev)
5787 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5788 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
5789 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5790 PRE_REG_READ6(ssize_t, "process_vm_writev",
5791 vki_pid_t, pid,
5792 const struct iovec *, lvec,
5793 unsigned long, liovcnt,
5794 const struct iovec *, rvec,
5795 unsigned long, riovcnt,
5796 unsigned long, flags);
5797 PRE_MEM_READ( "process_vm_writev(lvec)",
5798 ARG2, ARG3 * sizeof(struct vki_iovec) );
5799 PRE_MEM_READ( "process_vm_writev(rvec)",
5800 ARG4, ARG5 * sizeof(struct vki_iovec) );
5801 if (ARG2 != 0
5802 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
5803 sizeof(struct vki_iovec) * ARG3)) {
5804 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
5805 UInt i;
5806 for (i = 0; i < ARG3; i++)
5807 PRE_MEM_READ( "process_vm_writev(lvec[...])",
5808 (Addr)vec[i].iov_base, vec[i].iov_len );
5812 /* ---------------------------------------------------------------------
5813 {send,recv}mmsg wrappers
5814 ------------------------------------------------------------------ */
5816 PRE(sys_sendmmsg)
5818 *flags |= SfMayBlock;
5819 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
5820 SARG3, SARG4);
5821 PRE_REG_READ4(long, "sendmmsg",
5822 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
5823 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
5826 POST(sys_sendmmsg)
5828 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
5831 PRE(sys_recvmmsg)
5833 *flags |= SfMayBlock;
5834 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
5835 FMT_REGWORD "x )",
5836 SARG1, ARG2, SARG3, SARG4, ARG5);
5837 PRE_REG_READ5(long, "recvmmsg",
5838 int, s, struct mmsghdr *, mmsg, int, vlen,
5839 int, flags, struct timespec *, timeout);
5840 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5843 POST(sys_recvmmsg)
5845 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
5848 /* ---------------------------------------------------------------------
5849 key retention service wrappers
5850 ------------------------------------------------------------------ */
5852 PRE(sys_request_key)
5854 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5855 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
5856 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
5857 PRE_REG_READ4(long, "request_key",
5858 const char *, type, const char *, description,
5859 const char *, callout_info, vki_key_serial_t, keyring);
5860 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
5861 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
5862 if (ARG3 != (UWord)NULL)
5863 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
5866 PRE(sys_add_key)
5868 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
5869 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
5870 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
5871 PRE_REG_READ5(long, "add_key",
5872 const char *, type, const char *, description,
5873 const void *, payload, vki_size_t, plen,
5874 vki_key_serial_t, keyring);
5875 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
5876 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
5877 if (ARG3 != (UWord)NULL)
5878 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
5881 PRE(sys_keyctl)
5883 switch (ARG1 /* option */) {
5884 case VKI_KEYCTL_GET_KEYRING_ID:
5885 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
5886 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
5887 int, option, vki_key_serial_t, id, int, create);
5888 break;
5889 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
5890 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
5891 "x(%s) )", ARG2,(char*)(Addr)ARG2);
5892 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
5893 int, option, const char *, name);
5894 if (ARG2 != (UWord)NULL)
5895 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
5896 break;
5897 case VKI_KEYCTL_UPDATE:
5898 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
5899 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5900 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
5901 int, option, vki_key_serial_t, key,
5902 const void *, payload, vki_size_t, plen);
5903 if (ARG3 != (UWord)NULL)
5904 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
5905 break;
5906 case VKI_KEYCTL_REVOKE:
5907 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
5908 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
5909 int, option, vki_key_serial_t, id);
5910 break;
5911 case VKI_KEYCTL_CHOWN:
5912 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
5913 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5914 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
5915 int, option, vki_key_serial_t, id,
5916 vki_uid_t, uid, vki_gid_t, gid);
5917 break;
5918 case VKI_KEYCTL_SETPERM:
5919 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
5920 SARG2, ARG3);
5921 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
5922 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
5923 break;
5924 case VKI_KEYCTL_DESCRIBE:
5925 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
5926 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
5927 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
5928 int, option, vki_key_serial_t, id,
5929 char *, buffer, vki_size_t, buflen);
5930 if (ARG3 != (UWord)NULL)
5931 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
5932 break;
5933 case VKI_KEYCTL_CLEAR:
5934 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
5935 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
5936 int, option, vki_key_serial_t, keyring);
5937 break;
5938 case VKI_KEYCTL_LINK:
5939 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
5940 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
5941 vki_key_serial_t, keyring, vki_key_serial_t, key);
5942 break;
5943 case VKI_KEYCTL_UNLINK:
5944 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
5945 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
5946 vki_key_serial_t, keyring, vki_key_serial_t, key);
5947 break;
5948 case VKI_KEYCTL_SEARCH:
5949 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
5950 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
5951 ARG4, (HChar*)(Addr)ARG4, SARG5);
5952 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
5953 int, option, vki_key_serial_t, keyring,
5954 const char *, type, const char *, description,
5955 vki_key_serial_t, destring);
5956 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
5957 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
5958 break;
5959 case VKI_KEYCTL_READ:
5960 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5961 "u )", SARG2, ARG3, ARG4);
5962 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
5963 int, option, vki_key_serial_t, keyring,
5964 char *, buffer, vki_size_t, buflen);
5965 if (ARG3 != (UWord)NULL)
5966 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
5967 break;
5968 case VKI_KEYCTL_INSTANTIATE:
5969 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
5970 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
5971 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
5972 int, option, vki_key_serial_t, key,
5973 char *, payload, vki_size_t, plen,
5974 vki_key_serial_t, keyring);
5975 if (ARG3 != (UWord)NULL)
5976 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
5977 break;
5978 case VKI_KEYCTL_NEGATE:
5979 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
5980 SARG2, ARG3, SARG4);
5981 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
5982 int, option, vki_key_serial_t, key,
5983 unsigned, timeout, vki_key_serial_t, keyring);
5984 break;
5985 case VKI_KEYCTL_SET_REQKEY_KEYRING:
5986 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
5987 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
5988 int, option, int, reqkey_defl);
5989 break;
5990 case VKI_KEYCTL_SET_TIMEOUT:
5991 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
5992 SARG2, ARG3);
5993 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
5994 int, option, vki_key_serial_t, key, unsigned, timeout);
5995 break;
5996 case VKI_KEYCTL_ASSUME_AUTHORITY:
5997 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
5998 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
5999 int, option, vki_key_serial_t, key);
6000 break;
6001 default:
6002 PRINT("sys_keyctl ( %ld ) ", SARG1);
6003 PRE_REG_READ1(long, "keyctl", int, option);
6004 break;
6008 POST(sys_keyctl)
6010 vg_assert(SUCCESS);
6011 switch (ARG1 /* option */) {
6012 case VKI_KEYCTL_DESCRIBE:
6013 case VKI_KEYCTL_READ:
6014 if (RES > ARG4)
6015 POST_MEM_WRITE(ARG3, ARG4);
6016 else
6017 POST_MEM_WRITE(ARG3, RES);
6018 break;
6019 default:
6020 break;
6024 /* ---------------------------------------------------------------------
6025 ioprio_ wrappers
6026 ------------------------------------------------------------------ */
6028 PRE(sys_ioprio_set)
6030 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6031 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6034 PRE(sys_ioprio_get)
6036 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6037 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6040 /* ---------------------------------------------------------------------
6041 _module wrappers
6042 ------------------------------------------------------------------ */
6044 PRE(sys_init_module)
6046 *flags |= SfMayBlock;
6047 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6048 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6049 PRE_REG_READ3(long, "init_module",
6050 void *, umod, unsigned long, len, const char *, uargs);
6051 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6052 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6055 PRE(sys_finit_module)
6057 *flags |= SfMayBlock;
6059 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6060 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6061 PRE_REG_READ3(long, "finit_module",
6062 int, fd, const char *, params, int, flags);
6063 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6066 PRE(sys_delete_module)
6068 *flags |= SfMayBlock;
6069 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6070 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6071 PRE_REG_READ2(long, "delete_module",
6072 const char *, name_user, unsigned int, flags);
6073 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6076 /* ---------------------------------------------------------------------
6077 splice wrappers
6078 ------------------------------------------------------------------ */
6080 PRE(sys_splice)
6082 *flags |= SfMayBlock;
6083 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6084 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6085 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6086 PRE_REG_READ6(vki_ssize_t, "splice",
6087 int, fd_in, vki_loff_t *, off_in,
6088 int, fd_out, vki_loff_t *, off_out,
6089 vki_size_t, len, unsigned int, flags);
6090 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6091 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6092 SET_STATUS_Failure( VKI_EBADF );
6093 } else {
6094 if (ARG2 != 0)
6095 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6096 if (ARG4 != 0)
6097 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6101 PRE(sys_tee)
6103 *flags |= SfMayBlock;
6104 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6105 SARG1, SARG2, ARG3, ARG4);
6106 PRE_REG_READ4(vki_ssize_t, "tee",
6107 int, fd_in, int, fd_out,
6108 vki_size_t, len, unsigned int, flags);
6109 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6110 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6111 SET_STATUS_Failure( VKI_EBADF );
6115 PRE(sys_vmsplice)
6117 Int fdfl;
6118 *flags |= SfMayBlock;
6119 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6120 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6121 PRE_REG_READ4(vki_ssize_t, "splice",
6122 int, fd, struct vki_iovec *, iov,
6123 unsigned long, nr_segs, unsigned int, flags);
6124 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6125 SET_STATUS_Failure( VKI_EBADF );
6126 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6127 SET_STATUS_Failure( VKI_EBADF );
6128 } else {
6129 const struct vki_iovec *iov;
6130 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6131 for (iov = (struct vki_iovec *)(Addr)ARG2;
6132 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6134 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6135 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6136 PRE_MEM_WRITE( "vmsplice(iov[...])",
6137 (Addr)iov->iov_base, iov->iov_len );
6138 else
6139 PRE_MEM_READ( "vmsplice(iov[...])",
6140 (Addr)iov->iov_base, iov->iov_len );
6146 POST(sys_vmsplice)
6148 vg_assert(SUCCESS);
6149 if (RES > 0) {
6150 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6151 vg_assert(fdfl >= 0);
6152 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6154 const struct vki_iovec *iov;
6155 for (iov = (struct vki_iovec *)(Addr)ARG2;
6156 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6158 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6164 /* ---------------------------------------------------------------------
6165 oprofile-related wrappers
6166 ------------------------------------------------------------------ */
6168 #if defined(VGP_x86_linux)
6169 PRE(sys_lookup_dcookie)
6171 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6172 MERGE64(ARG1,ARG2), ARG3, ARG4);
6173 PRE_REG_READ4(long, "lookup_dcookie",
6174 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6175 char *, buf, vki_size_t, len);
6176 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6178 POST(sys_lookup_dcookie)
6180 vg_assert(SUCCESS);
6181 if (ARG3 != (Addr)NULL)
6182 POST_MEM_WRITE( ARG3, RES);
6184 #endif
6186 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6187 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6188 PRE(sys_lookup_dcookie)
6190 *flags |= SfMayBlock;
6191 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6192 PRE_REG_READ3(int, "lookup_dcookie",
6193 unsigned long long, cookie, char *, buf, vki_size_t, len);
6195 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6198 POST(sys_lookup_dcookie)
6200 vg_assert(SUCCESS);
6201 if (ARG2 != (Addr)NULL)
6202 POST_MEM_WRITE( ARG2, RES );
6204 #endif
6206 /* ---------------------------------------------------------------------
6207 fcntl wrappers
6208 ------------------------------------------------------------------ */
6210 PRE(sys_fcntl)
6212 switch (ARG2) {
6213 // These ones ignore ARG3.
6214 case VKI_F_GETFD:
6215 case VKI_F_GETFL:
6216 case VKI_F_GETOWN:
6217 case VKI_F_GETSIG:
6218 case VKI_F_GETLEASE:
6219 case VKI_F_GETPIPE_SZ:
6220 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6221 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6222 break;
6224 // These ones use ARG3 as "arg".
6225 case VKI_F_DUPFD:
6226 case VKI_F_DUPFD_CLOEXEC:
6227 case VKI_F_SETFD:
6228 case VKI_F_SETFL:
6229 case VKI_F_SETLEASE:
6230 case VKI_F_NOTIFY:
6231 case VKI_F_SETOWN:
6232 case VKI_F_SETSIG:
6233 case VKI_F_SETPIPE_SZ:
6234 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6235 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6236 PRE_REG_READ3(long, "fcntl",
6237 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6238 break;
6240 // These ones use ARG3 as "lock".
6241 case VKI_F_GETLK:
6242 case VKI_F_SETLK:
6243 case VKI_F_SETLKW:
6244 case VKI_F_OFD_GETLK:
6245 case VKI_F_OFD_SETLK:
6246 case VKI_F_OFD_SETLKW:
6247 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6248 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6249 PRE_REG_READ3(long, "fcntl",
6250 unsigned int, fd, unsigned int, cmd,
6251 struct vki_flock *, lock);
6253 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6254 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6255 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6256 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6257 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6258 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6259 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6262 break;
6264 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6265 case VKI_F_GETLK64:
6266 case VKI_F_SETLK64:
6267 case VKI_F_SETLKW64:
6268 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6269 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6270 PRE_REG_READ3(long, "fcntl",
6271 unsigned int, fd, unsigned int, cmd,
6272 struct flock64 *, lock);
6274 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6275 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6276 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6277 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6278 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6279 if (ARG2 == VKI_F_GETLK64) {
6280 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6283 break;
6284 # endif
6286 case VKI_F_SETOWN_EX:
6287 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6288 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6289 PRE_REG_READ3(long, "fcntl",
6290 unsigned int, fd, unsigned int, cmd,
6291 struct vki_f_owner_ex *, arg);
6292 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6293 break;
6295 case VKI_F_GETOWN_EX:
6296 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6297 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6298 PRE_REG_READ3(long, "fcntl",
6299 unsigned int, fd, unsigned int, cmd,
6300 struct vki_f_owner_ex *, arg);
6301 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6302 break;
6304 default:
6305 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6306 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6307 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6308 ARG2);
6309 SET_STATUS_Failure( VKI_EINVAL );
6310 break;
6313 # if defined(VGP_x86_linux)
6314 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6315 # else
6316 if (ARG2 == VKI_F_SETLKW)
6317 # endif
6318 *flags |= SfMayBlock;
6321 POST(sys_fcntl)
6323 vg_assert(SUCCESS);
6324 if (ARG2 == VKI_F_DUPFD) {
6325 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6326 VG_(close)(RES);
6327 SET_STATUS_Failure( VKI_EMFILE );
6328 } else {
6329 if (VG_(clo_track_fds))
6330 ML_(record_fd_open_named)(tid, RES);
6333 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6334 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6335 VG_(close)(RES);
6336 SET_STATUS_Failure( VKI_EMFILE );
6337 } else {
6338 if (VG_(clo_track_fds))
6339 ML_(record_fd_open_named)(tid, RES);
6341 } else if (ARG2 == VKI_F_GETOWN_EX) {
6342 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6343 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6344 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6345 POST_FIELD_WRITE(lock->l_pid);
6346 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6347 } else if (ARG2 == VKI_F_GETLK64) {
6348 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6349 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6350 # endif
6354 // XXX: wrapper only suitable for 32-bit systems
6355 PRE(sys_fcntl64)
6357 switch (ARG2) {
6358 // These ones ignore ARG3.
6359 case VKI_F_GETFD:
6360 case VKI_F_GETFL:
6361 case VKI_F_GETOWN:
6362 case VKI_F_SETOWN:
6363 case VKI_F_GETSIG:
6364 case VKI_F_SETSIG:
6365 case VKI_F_GETLEASE:
6366 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6367 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6368 break;
6370 // These ones use ARG3 as "arg".
6371 case VKI_F_DUPFD:
6372 case VKI_F_DUPFD_CLOEXEC:
6373 case VKI_F_SETFD:
6374 case VKI_F_SETFL:
6375 case VKI_F_SETLEASE:
6376 case VKI_F_NOTIFY:
6377 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6378 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6379 PRE_REG_READ3(long, "fcntl64",
6380 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6381 break;
6383 // These ones use ARG3 as "lock".
6384 case VKI_F_GETLK:
6385 case VKI_F_SETLK:
6386 case VKI_F_SETLKW:
6387 # if defined(VGP_x86_linux)
6388 case VKI_F_GETLK64:
6389 case VKI_F_SETLK64:
6390 case VKI_F_SETLKW64:
6391 # endif
6392 case VKI_F_OFD_GETLK:
6393 case VKI_F_OFD_SETLK:
6394 case VKI_F_OFD_SETLKW:
6395 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6396 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6397 PRE_REG_READ3(long, "fcntl64",
6398 unsigned int, fd, unsigned int, cmd,
6399 struct flock64 *, lock);
6400 break;
6402 case VKI_F_SETOWN_EX:
6403 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6404 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6405 PRE_REG_READ3(long, "fcntl",
6406 unsigned int, fd, unsigned int, cmd,
6407 struct vki_f_owner_ex *, arg);
6408 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6409 break;
6411 case VKI_F_GETOWN_EX:
6412 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6413 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6414 PRE_REG_READ3(long, "fcntl",
6415 unsigned int, fd, unsigned int, cmd,
6416 struct vki_f_owner_ex *, arg);
6417 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6418 break;
6421 # if defined(VGP_x86_linux)
6422 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6423 # else
6424 if (ARG2 == VKI_F_SETLKW)
6425 # endif
6426 *flags |= SfMayBlock;
6429 POST(sys_fcntl64)
6431 vg_assert(SUCCESS);
6432 if (ARG2 == VKI_F_DUPFD) {
6433 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
6434 VG_(close)(RES);
6435 SET_STATUS_Failure( VKI_EMFILE );
6436 } else {
6437 if (VG_(clo_track_fds))
6438 ML_(record_fd_open_named)(tid, RES);
6441 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6442 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
6443 VG_(close)(RES);
6444 SET_STATUS_Failure( VKI_EMFILE );
6445 } else {
6446 if (VG_(clo_track_fds))
6447 ML_(record_fd_open_named)(tid, RES);
6449 } else if (ARG2 == VKI_F_GETOWN_EX) {
6450 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6454 /* ---------------------------------------------------------------------
6455 ioctl wrappers
6456 ------------------------------------------------------------------ */
6458 struct vg_drm_version_info {
6459 struct vki_drm_version data;
6460 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
6463 PRE(sys_ioctl)
6465 *flags |= SfMayBlock;
6467 ARG2 = (UInt)ARG2;
6469 // We first handle the ones that don't use ARG3 (even as a
6470 // scalar/non-pointer argument).
6471 switch (ARG2 /* request */) {
6473 /* asm-generic/ioctls.h */
6474 case VKI_FIOCLEX:
6475 case VKI_FIONCLEX:
6476 case VKI_TIOCNOTTY:
6478 /* linux perf_event ioctls */
6479 case VKI_PERF_EVENT_IOC_ENABLE:
6480 case VKI_PERF_EVENT_IOC_DISABLE:
6482 /* linux/soundcard interface (ALSA) */
6483 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
6484 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
6485 case VKI_SNDRV_PCM_IOCTL_PREPARE:
6486 case VKI_SNDRV_PCM_IOCTL_RESET:
6487 case VKI_SNDRV_PCM_IOCTL_START:
6488 case VKI_SNDRV_PCM_IOCTL_DROP:
6489 case VKI_SNDRV_PCM_IOCTL_DRAIN:
6490 case VKI_SNDRV_PCM_IOCTL_RESUME:
6491 case VKI_SNDRV_PCM_IOCTL_XRUN:
6492 case VKI_SNDRV_PCM_IOCTL_UNLINK:
6493 case VKI_SNDRV_TIMER_IOCTL_START:
6494 case VKI_SNDRV_TIMER_IOCTL_STOP:
6495 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
6496 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
6498 /* SCSI no operand */
6499 case VKI_SCSI_IOCTL_DOORLOCK:
6500 case VKI_SCSI_IOCTL_DOORUNLOCK:
6502 /* CDROM stuff. */
6503 case VKI_CDROM_DISC_STATUS:
6504 case VKI_CDROMSTOP:
6506 /* DVD stuff */
6507 case VKI_DVD_READ_STRUCT:
6509 /* KVM ioctls that don't check for a numeric value as parameter */
6510 case VKI_KVM_S390_ENABLE_SIE:
6511 case VKI_KVM_CREATE_IRQCHIP:
6512 case VKI_KVM_S390_INITIAL_RESET:
6513 case VKI_KVM_KVMCLOCK_CTRL:
6515 /* vhost without parameter */
6516 case VKI_VHOST_SET_OWNER:
6517 case VKI_VHOST_RESET_OWNER:
6519 /* User input device creation */
6520 case VKI_UI_DEV_CREATE:
6521 case VKI_UI_DEV_DESTROY:
6523 /* InfiniBand */
6524 case VKI_IB_USER_MAD_ENABLE_PKEY:
6526 /* Lustre */
6527 case VKI_LL_IOC_GROUP_LOCK:
6528 case VKI_LL_IOC_GROUP_UNLOCK:
6530 /* V4L2 */
6531 case VKI_V4L2_LOG_STATUS:
6533 /* Mesa */
6534 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
6536 /* DVB */
6537 case VKI_DMX_STOP:
6538 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
6539 PRE_REG_READ2(long, "ioctl",
6540 unsigned int, fd, unsigned int, request);
6541 return;
6543 default:
6544 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
6545 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6546 PRE_REG_READ3(long, "ioctl",
6547 unsigned int, fd, unsigned int, request, unsigned long, arg);
6548 break;
6551 // We now handle those that do look at ARG3 (and unknown ones fall into
6552 // this category). Nb: some of these may well belong in the
6553 // doesn't-use-ARG3 switch above.
6554 switch (ARG2 /* request */) {
6556 case VKI_ION_IOC_ALLOC: {
6557 struct vki_ion_allocation_data* data
6558 = (struct vki_ion_allocation_data*)(Addr)ARG3;
6559 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
6560 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
6561 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
6562 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
6563 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
6564 break;
6566 case VKI_ION_IOC_MAP: {
6567 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6568 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
6569 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
6570 break;
6572 case VKI_ION_IOC_IMPORT: {
6573 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
6574 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
6575 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
6576 break;
6579 case VKI_SYNC_IOC_MERGE: {
6580 struct vki_sync_merge_data* data =
6581 (struct vki_sync_merge_data*)(Addr)ARG3;
6582 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
6583 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
6584 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
6585 break;
6588 case VKI_TCSETS:
6589 case VKI_TCSETSW:
6590 case VKI_TCSETSF:
6591 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
6592 break;
6593 case VKI_TCGETS:
6594 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
6595 break;
6596 case VKI_TCSETA:
6597 case VKI_TCSETAW:
6598 case VKI_TCSETAF:
6599 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
6600 break;
6601 case VKI_TCGETA:
6602 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
6603 break;
6604 case VKI_TCSBRK:
6605 case VKI_TCXONC:
6606 case VKI_TCSBRKP:
6607 case VKI_TCFLSH:
6608 case VKI_TIOCSIG:
6609 /* These just take an int by value */
6610 break;
6611 case VKI_TIOCGWINSZ:
6612 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
6613 break;
6614 case VKI_TIOCSWINSZ:
6615 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
6616 break;
6617 case VKI_TIOCMBIS:
6618 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
6619 break;
6620 case VKI_TIOCMBIC:
6621 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
6622 break;
6623 case VKI_TIOCMSET:
6624 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
6625 break;
6626 case VKI_TIOCMGET:
6627 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
6628 break;
6629 case VKI_TIOCLINUX:
6630 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
6631 if (*(char *)(Addr)ARG3 == 11) {
6632 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
6634 break;
6635 case VKI_TIOCGPGRP:
6636 /* Get process group ID for foreground processing group. */
6637 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6638 break;
6639 case VKI_TIOCSPGRP:
6640 /* Set a process group ID? */
6641 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
6642 break;
6643 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
6644 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
6645 break;
6646 case VKI_TIOCSCTTY:
6647 /* Just takes an int value. */
6648 break;
6649 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
6650 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
6651 break;
6652 case VKI_FIONBIO:
6653 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
6654 break;
6655 case VKI_FIOASYNC:
6656 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
6657 break;
6658 case VKI_FIONREAD: /* identical to SIOCINQ */
6659 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
6660 break;
6661 case VKI_FIOQSIZE:
6662 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
6663 break;
6665 case VKI_TIOCSERGETLSR:
6666 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
6667 break;
6668 case VKI_TIOCGICOUNT:
6669 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
6670 sizeof(struct vki_serial_icounter_struct) );
6671 break;
6673 case VKI_SG_SET_COMMAND_Q:
6674 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
6675 break;
6676 case VKI_SG_IO:
6677 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
6679 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
6680 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
6681 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
6682 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
6683 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
6686 break;
6687 case VKI_SG_GET_SCSI_ID:
6688 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
6689 break;
6690 case VKI_SG_SET_RESERVED_SIZE:
6691 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
6692 break;
6693 case VKI_SG_SET_TIMEOUT:
6694 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
6695 break;
6696 case VKI_SG_GET_RESERVED_SIZE:
6697 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
6698 break;
6699 case VKI_SG_GET_TIMEOUT:
6700 break;
6701 case VKI_SG_GET_VERSION_NUM:
6702 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
6703 break;
6704 case VKI_SG_EMULATED_HOST: /* 0x2203 */
6705 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
6706 break;
6707 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
6708 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
6709 break;
6711 case VKI_IIOCGETCPS:
6712 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
6713 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
6714 break;
6715 case VKI_IIOCNETGPN:
6716 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
6717 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
6718 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
6719 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
6720 sizeof(vki_isdn_net_ioctl_phone) );
6721 break;
6723 /* These all use struct ifreq AFAIK */
6724 case VKI_SIOCGIFINDEX: /* get iface index */
6725 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
6726 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6727 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
6728 break;
6729 case VKI_SIOCGIFFLAGS: /* get flags */
6730 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
6731 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6732 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6733 break;
6734 case VKI_SIOCGIFHWADDR: /* Get hardware address */
6735 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
6736 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6737 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
6738 break;
6739 case VKI_SIOCGIFMTU: /* get MTU size */
6740 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
6741 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6742 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
6743 break;
6744 case VKI_SIOCGIFADDR: /* get PA address */
6745 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
6746 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6747 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
6748 break;
6749 case VKI_SIOCGIFNETMASK: /* get network PA mask */
6750 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
6751 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6752 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
6753 break;
6754 case VKI_SIOCGIFMETRIC: /* get metric */
6755 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
6756 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6757 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
6758 break;
6759 case VKI_SIOCGIFMAP: /* Get device parameters */
6760 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
6761 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6762 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
6763 break;
6764 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
6765 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
6766 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6767 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
6768 break;
6769 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
6770 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
6771 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6772 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
6773 break;
6774 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
6775 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
6776 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6777 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
6778 break;
6779 case VKI_SIOCGIFNAME: /* get iface name */
6780 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
6781 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
6782 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
6783 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
6784 break;
6786 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
6787 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
6788 // The kernel will have to look at ifr_data to determine which operation
6789 // to perform.
6790 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
6791 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
6793 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
6795 // Is this correct? Is ifr_name *always* looked at?
6796 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
6797 (Addr)ir->vki_ifr_name );
6799 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
6800 // the whole structure is defined. So in this case, just check it's
6801 // accessible.
6802 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6803 case VKI_ETHTOOL_GSET:
6804 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
6805 (Addr)ir, sizeof(struct vki_ifreq) );
6806 break;
6807 default:
6808 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
6809 (Addr)ir, sizeof(struct vki_ifreq) );
6810 break;
6813 // Now perform the relevant pre-action for the operation.
6814 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
6815 case VKI_ETHTOOL_GSET:
6816 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
6817 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6818 break;
6819 case VKI_ETHTOOL_SSET:
6820 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
6821 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
6822 break;
6823 case VKI_ETHTOOL_GDRVINFO:
6824 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
6825 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
6826 break;
6827 case VKI_ETHTOOL_GREGS:
6828 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
6829 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
6830 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
6831 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
6832 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
6833 break;
6834 case VKI_ETHTOOL_GWOL:
6835 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
6836 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6837 break;
6838 case VKI_ETHTOOL_SWOL:
6839 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
6840 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
6841 break;
6842 case VKI_ETHTOOL_GMSGLVL:
6843 case VKI_ETHTOOL_GLINK:
6844 case VKI_ETHTOOL_GRXCSUM:
6845 case VKI_ETHTOOL_GSG:
6846 case VKI_ETHTOOL_GTSO:
6847 case VKI_ETHTOOL_GUFO:
6848 case VKI_ETHTOOL_GGSO:
6849 case VKI_ETHTOOL_GFLAGS:
6850 case VKI_ETHTOOL_GGRO:
6851 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
6852 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6853 break;
6854 case VKI_ETHTOOL_SMSGLVL:
6855 case VKI_ETHTOOL_SRXCSUM:
6856 case VKI_ETHTOOL_SSG:
6857 case VKI_ETHTOOL_STSO:
6858 case VKI_ETHTOOL_SUFO:
6859 case VKI_ETHTOOL_SGSO:
6860 case VKI_ETHTOOL_SFLAGS:
6861 case VKI_ETHTOOL_SGRO:
6862 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
6863 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
6864 break;
6865 case VKI_ETHTOOL_NWAY_RST:
6866 break;
6867 case VKI_ETHTOOL_GRINGPARAM:
6868 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
6869 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6870 break;
6871 case VKI_ETHTOOL_SRINGPARAM:
6872 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
6873 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
6874 break;
6875 case VKI_ETHTOOL_TEST:
6876 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
6877 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
6878 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
6879 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
6880 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
6881 break;
6882 case VKI_ETHTOOL_PHYS_ID:
6883 break;
6884 case VKI_ETHTOOL_GPERMADDR:
6885 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
6886 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
6887 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
6888 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
6889 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
6890 break;
6891 case VKI_ETHTOOL_RESET:
6892 break;
6893 case VKI_ETHTOOL_GSSET_INFO:
6894 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6895 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
6896 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
6897 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
6898 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
6899 break;
6900 case VKI_ETHTOOL_GFEATURES:
6901 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
6902 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
6903 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
6904 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
6905 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
6906 break;
6907 case VKI_ETHTOOL_SFEATURES:
6908 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6909 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
6910 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
6911 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
6912 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
6913 break;
6914 case VKI_ETHTOOL_GCHANNELS:
6915 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
6916 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6917 break;
6918 case VKI_ETHTOOL_SCHANNELS:
6919 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
6920 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
6921 break;
6922 case VKI_ETHTOOL_GET_TS_INFO:
6923 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
6924 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
6925 break;
6927 break;
6928 } /* case VKI_SIOCETHTOOL */
6930 case VKI_SIOCGMIIPHY: /* get hardware entry */
6931 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
6932 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6933 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
6934 break;
6935 case VKI_SIOCGMIIREG: /* get hardware entry registers */
6936 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
6937 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6938 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6939 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
6940 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
6941 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
6942 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
6943 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
6944 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
6945 sizeof(struct vki_ifreq));
6946 break;
6947 case VKI_SIOCGIFCONF: /* get iface list */
6948 /* WAS:
6949 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
6950 KERNEL_DO_SYSCALL(tid,RES);
6951 if (!VG_(is_kerror)(RES) && RES == 0)
6952 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
6954 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6955 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
6956 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
6957 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
6958 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
6959 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
6960 if ( ARG3 ) {
6961 // TODO len must be readable and writable
6962 // buf pointer only needs to be readable
6963 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
6964 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
6965 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
6967 break;
6968 case VKI_SIOCGSTAMP:
6969 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
6970 break;
6971 case VKI_SIOCGSTAMPNS:
6972 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
6973 break;
6974 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
6975 the number of bytes currently in that socket's send buffer.
6976 It writes this value as an int to the memory location
6977 indicated by the third argument of ioctl(2). */
6978 case VKI_SIOCOUTQ:
6979 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
6980 break;
6981 case VKI_SIOCGRARP: /* get RARP table entry */
6982 case VKI_SIOCGARP: /* get ARP table entry */
6983 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
6984 break;
6986 case VKI_SIOCSIFFLAGS: /* set flags */
6987 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
6988 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6989 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
6990 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
6991 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
6992 break;
6993 case VKI_SIOCSIFMAP: /* Set device parameters */
6994 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
6995 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
6996 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
6997 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
6998 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
6999 break;
7000 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7001 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7002 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7003 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7004 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7005 sizeof(struct vki_hwtstamp_config) );
7006 break;
7007 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7008 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7009 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7010 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7011 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7012 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7013 break;
7014 case VKI_SIOCSIFADDR: /* set PA address */
7015 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7016 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7017 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7018 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7019 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7020 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7021 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7022 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7023 break;
7024 case VKI_SIOCSIFMETRIC: /* set metric */
7025 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7026 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7027 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7028 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7029 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7030 break;
7031 case VKI_SIOCSIFMTU: /* set MTU size */
7032 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7033 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7034 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7035 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7036 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7037 break;
7038 case VKI_SIOCSIFHWADDR: /* set hardware address */
7039 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7040 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7041 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7042 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7043 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7044 break;
7045 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7046 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7047 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7048 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7049 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7050 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7051 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7052 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7053 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7054 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7055 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7056 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7057 break;
7058 /* Routing table calls. */
7059 case VKI_SIOCADDRT: /* add routing table entry */
7060 case VKI_SIOCDELRT: /* delete routing table entry */
7061 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7062 sizeof(struct vki_rtentry));
7063 break;
7065 /* tun/tap related ioctls */
7066 case VKI_TUNSETNOCSUM:
7067 case VKI_TUNSETDEBUG:
7068 break;
7069 case VKI_TUNSETIFF:
7070 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7071 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7072 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7073 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7074 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7075 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7076 break;
7077 case VKI_TUNSETPERSIST:
7078 case VKI_TUNSETOWNER:
7079 case VKI_TUNSETLINK:
7080 case VKI_TUNSETGROUP:
7081 break;
7082 case VKI_TUNGETFEATURES:
7083 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7084 break;
7085 case VKI_TUNSETOFFLOAD:
7086 break;
7087 case VKI_TUNGETIFF:
7088 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7089 break;
7090 case VKI_TUNGETSNDBUF:
7091 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7092 break;
7093 case VKI_TUNSETSNDBUF:
7094 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7095 break;
7096 case VKI_TUNGETVNETHDRSZ:
7097 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7098 break;
7099 case VKI_TUNSETVNETHDRSZ:
7100 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7101 break;
7102 case VKI_TUNSETQUEUE:
7103 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7104 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7105 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7106 break;
7107 case VKI_TUNSETIFINDEX:
7108 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7109 break;
7111 /* RARP cache control calls. */
7112 case VKI_SIOCDRARP: /* delete RARP table entry */
7113 case VKI_SIOCSRARP: /* set RARP table entry */
7114 /* ARP cache control calls. */
7115 case VKI_SIOCSARP: /* set ARP table entry */
7116 case VKI_SIOCDARP: /* delete ARP table entry */
7117 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7118 break;
7120 case VKI_SIOCGPGRP:
7121 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7122 break;
7123 case VKI_SIOCSPGRP:
7124 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7125 //tst->sys_flags &= ~SfMayBlock;
7126 break;
7128 case VKI_SIOCATMARK:
7129 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7130 break;
7132 /* linux/soundcard interface (OSS) */
7133 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7134 case VKI_SNDCTL_SEQ_GETINCOUNT:
7135 case VKI_SNDCTL_SEQ_PERCMODE:
7136 case VKI_SNDCTL_SEQ_TESTMIDI:
7137 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7138 case VKI_SNDCTL_SEQ_NRSYNTHS:
7139 case VKI_SNDCTL_SEQ_NRMIDIS:
7140 case VKI_SNDCTL_SEQ_GETTIME:
7141 case VKI_SNDCTL_DSP_GETBLKSIZE:
7142 case VKI_SNDCTL_DSP_GETFMTS:
7143 case VKI_SNDCTL_DSP_GETTRIGGER:
7144 case VKI_SNDCTL_DSP_GETODELAY:
7145 case VKI_SNDCTL_DSP_GETSPDIF:
7146 case VKI_SNDCTL_DSP_GETCAPS:
7147 case VKI_SOUND_PCM_READ_RATE:
7148 case VKI_SOUND_PCM_READ_CHANNELS:
7149 case VKI_SOUND_PCM_READ_BITS:
7150 case VKI_SOUND_PCM_READ_FILTER:
7151 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7152 ARG3, sizeof(int));
7153 break;
7154 case VKI_SNDCTL_SEQ_CTRLRATE:
7155 case VKI_SNDCTL_DSP_SPEED:
7156 case VKI_SNDCTL_DSP_STEREO:
7157 case VKI_SNDCTL_DSP_CHANNELS:
7158 case VKI_SOUND_PCM_WRITE_FILTER:
7159 case VKI_SNDCTL_DSP_SUBDIVIDE:
7160 case VKI_SNDCTL_DSP_SETFRAGMENT:
7161 case VKI_SNDCTL_DSP_SETFMT:
7162 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7163 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7164 case VKI_SNDCTL_TMR_TIMEBASE:
7165 case VKI_SNDCTL_TMR_TEMPO:
7166 case VKI_SNDCTL_TMR_SOURCE:
7167 case VKI_SNDCTL_MIDI_PRETIME:
7168 case VKI_SNDCTL_MIDI_MPUMODE:
7169 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7170 ARG3, sizeof(int));
7171 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7172 ARG3, sizeof(int));
7173 break;
7174 case VKI_SNDCTL_DSP_GETOSPACE:
7175 case VKI_SNDCTL_DSP_GETISPACE:
7176 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7177 ARG3, sizeof(vki_audio_buf_info));
7178 break;
7179 case VKI_SNDCTL_DSP_NONBLOCK:
7180 break;
7181 case VKI_SNDCTL_DSP_SETTRIGGER:
7182 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7183 ARG3, sizeof(int));
7184 break;
7186 case VKI_SNDCTL_DSP_POST:
7187 case VKI_SNDCTL_DSP_RESET:
7188 case VKI_SNDCTL_DSP_SYNC:
7189 case VKI_SNDCTL_DSP_SETSYNCRO:
7190 case VKI_SNDCTL_DSP_SETDUPLEX:
7191 break;
7193 /* linux/soundcard interface (ALSA) */
7194 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7195 case VKI_SNDRV_PCM_IOCTL_LINK:
7196 /* these just take an int by value */
7197 break;
7198 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7199 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7200 break;
7201 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7202 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7203 break;
7204 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7205 struct vki_snd_ctl_elem_list *data =
7206 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7207 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7208 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7209 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7210 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7211 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7212 if (data->pids) {
7213 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7215 break;
7217 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7218 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7219 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7220 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7221 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7222 break;
7224 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7225 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7226 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7227 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7228 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7229 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7230 break;
7233 /* Real Time Clock (/dev/rtc) ioctls */
7234 case VKI_RTC_UIE_ON:
7235 case VKI_RTC_UIE_OFF:
7236 case VKI_RTC_AIE_ON:
7237 case VKI_RTC_AIE_OFF:
7238 case VKI_RTC_PIE_ON:
7239 case VKI_RTC_PIE_OFF:
7240 case VKI_RTC_IRQP_SET:
7241 break;
7242 case VKI_RTC_RD_TIME:
7243 case VKI_RTC_ALM_READ:
7244 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7245 ARG3, sizeof(struct vki_rtc_time));
7246 break;
7247 case VKI_RTC_ALM_SET:
7248 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7249 break;
7250 case VKI_RTC_IRQP_READ:
7251 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7252 break;
7254 /* Block devices */
7255 case VKI_BLKROSET:
7256 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7257 break;
7258 case VKI_BLKROGET:
7259 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7260 break;
7261 case VKI_BLKGETSIZE:
7262 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7263 break;
7264 case VKI_BLKFLSBUF:
7265 break;
7266 case VKI_BLKRASET:
7267 break;
7268 case VKI_BLKRAGET:
7269 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7270 break;
7271 case VKI_BLKFRASET:
7272 break;
7273 case VKI_BLKFRAGET:
7274 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7275 break;
7276 case VKI_BLKSECTGET:
7277 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7278 break;
7279 case VKI_BLKSSZGET:
7280 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7281 break;
7282 case VKI_BLKBSZGET:
7283 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7284 break;
7285 case VKI_BLKBSZSET:
7286 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7287 break;
7288 case VKI_BLKGETSIZE64:
7289 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7290 break;
7291 case VKI_BLKPBSZGET:
7292 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7293 break;
7294 case VKI_BLKIOMIN:
7295 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7296 break;
7297 case VKI_BLKIOOPT:
7298 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7299 break;
7300 case VKI_BLKALIGNOFF:
7301 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7302 break;
7303 case VKI_BLKDISCARDZEROES:
7304 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7305 break;
7306 case VKI_BLKREPORTZONE:
7307 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7308 sizeof(struct vki_blk_zone_report));
7309 break;
7310 case VKI_BLKRESETZONE:
7311 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7312 sizeof(struct vki_blk_zone_range));
7313 break;
7315 /* Hard disks */
7316 case VKI_HDIO_GETGEO: /* 0x0301 */
7317 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7318 break;
7319 case VKI_HDIO_GET_DMA: /* 0x030b */
7320 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7321 break;
7322 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7323 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7324 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7325 break;
7327 /* SCSI */
7328 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7329 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7330 break;
7331 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7332 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7333 break;
7335 /* CD ROM stuff (??) */
7336 case VKI_CDROM_GET_MCN:
7337 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7338 sizeof(struct vki_cdrom_mcn) );
7339 break;
7340 case VKI_CDROM_SEND_PACKET:
7341 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7342 sizeof(struct vki_cdrom_generic_command));
7343 break;
7344 case VKI_CDROMSUBCHNL:
7345 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7346 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7347 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7348 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7349 sizeof(struct vki_cdrom_subchnl));
7350 break;
7351 case VKI_CDROMREADMODE1: /*0x530d*/
7352 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7353 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7354 break;
7355 case VKI_CDROMREADMODE2: /*0x530c*/
7356 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7357 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7358 break;
7359 case VKI_CDROMREADTOCHDR:
7360 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7361 sizeof(struct vki_cdrom_tochdr));
7362 break;
7363 case VKI_CDROMREADTOCENTRY:
7364 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7365 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7366 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7367 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7368 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7369 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7370 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7371 sizeof(struct vki_cdrom_tocentry));
7372 break;
7373 case VKI_CDROMMULTISESSION: /* 0x5310 */
7374 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7375 sizeof(struct vki_cdrom_multisession));
7376 break;
7377 case VKI_CDROMVOLREAD: /* 0x5313 */
7378 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7379 sizeof(struct vki_cdrom_volctrl));
7380 break;
7381 case VKI_CDROMREADRAW: /* 0x5314 */
7382 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7383 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7384 break;
7385 case VKI_CDROMREADAUDIO: /* 0x530e */
7386 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7387 sizeof (struct vki_cdrom_read_audio));
7388 if ( ARG3 ) {
7389 /* ToDo: don't do any of the following if the structure is invalid */
7390 struct vki_cdrom_read_audio *cra =
7391 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7392 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7393 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7395 break;
7396 case VKI_CDROMPLAYMSF:
7397 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7398 break;
7399 /* The following two are probably bogus (should check args
7400 for readability). JRS 20021117 */
7401 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7402 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7403 break;
7404 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7405 break;
7407 case VKI_FIGETBSZ:
7408 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7409 break;
7410 case VKI_FIBMAP:
7411 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7412 break;
7414 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7415 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7416 sizeof(struct vki_fb_var_screeninfo));
7417 break;
7418 case VKI_FBIOPUT_VSCREENINFO:
7419 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
7420 sizeof(struct vki_fb_var_screeninfo));
7421 break;
7422 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
7423 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
7424 sizeof(struct vki_fb_fix_screeninfo));
7425 break;
7426 case VKI_FBIOPAN_DISPLAY:
7427 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
7428 sizeof(struct vki_fb_var_screeninfo));
7430 break;
7431 case VKI_PPCLAIM:
7432 case VKI_PPEXCL:
7433 case VKI_PPYIELD:
7434 case VKI_PPRELEASE:
7435 break;
7436 case VKI_PPSETMODE:
7437 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
7438 break;
7439 case VKI_PPGETMODE:
7440 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
7441 break;
7442 case VKI_PPSETPHASE:
7443 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
7444 break;
7445 case VKI_PPGETPHASE:
7446 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
7447 break;
7448 case VKI_PPGETMODES:
7449 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
7450 break;
7451 case VKI_PPSETFLAGS:
7452 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
7453 break;
7454 case VKI_PPGETFLAGS:
7455 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
7456 break;
7457 case VKI_PPRSTATUS:
7458 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
7459 break;
7460 case VKI_PPRDATA:
7461 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
7462 break;
7463 case VKI_PPRCONTROL:
7464 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
7465 break;
7466 case VKI_PPWDATA:
7467 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
7468 break;
7469 case VKI_PPWCONTROL:
7470 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
7471 break;
7472 case VKI_PPFCONTROL:
7473 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
7474 break;
7475 case VKI_PPDATADIR:
7476 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
7477 break;
7478 case VKI_PPNEGOT:
7479 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
7480 break;
7481 case VKI_PPWCTLONIRQ:
7482 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
7483 break;
7484 case VKI_PPCLRIRQ:
7485 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
7486 break;
7487 case VKI_PPSETTIME:
7488 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
7489 break;
7490 case VKI_PPGETTIME:
7491 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
7492 break;
7494 case VKI_GIO_FONT:
7495 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
7496 break;
7497 case VKI_PIO_FONT:
7498 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
7499 break;
7501 case VKI_GIO_FONTX:
7502 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7503 if ( ARG3 ) {
7504 /* ToDo: don't do any of the following if the structure is invalid */
7505 struct vki_consolefontdesc *cfd =
7506 (struct vki_consolefontdesc *)(Addr)ARG3;
7507 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
7508 32 * cfd->charcount );
7510 break;
7511 case VKI_PIO_FONTX:
7512 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
7513 if ( ARG3 ) {
7514 /* ToDo: don't do any of the following if the structure is invalid */
7515 struct vki_consolefontdesc *cfd =
7516 (struct vki_consolefontdesc *)(Addr)ARG3;
7517 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
7518 32 * cfd->charcount );
7520 break;
7522 case VKI_PIO_FONTRESET:
7523 break;
7525 case VKI_GIO_CMAP:
7526 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
7527 break;
7528 case VKI_PIO_CMAP:
7529 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
7530 break;
7532 case VKI_KIOCSOUND:
7533 case VKI_KDMKTONE:
7534 break;
7536 case VKI_KDGETLED:
7537 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
7538 break;
7539 case VKI_KDSETLED:
7540 break;
7542 case VKI_KDGKBTYPE:
7543 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
7544 break;
7546 case VKI_KDADDIO:
7547 case VKI_KDDELIO:
7548 case VKI_KDENABIO:
7549 case VKI_KDDISABIO:
7550 break;
7552 case VKI_KDSETMODE:
7553 break;
7554 case VKI_KDGETMODE:
7555 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
7556 break;
7558 case VKI_KDMAPDISP:
7559 case VKI_KDUNMAPDISP:
7560 break;
7562 case VKI_GIO_SCRNMAP:
7563 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7564 break;
7565 case VKI_PIO_SCRNMAP:
7566 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
7567 break;
7568 case VKI_GIO_UNISCRNMAP:
7569 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
7570 VKI_E_TABSZ * sizeof(unsigned short) );
7571 break;
7572 case VKI_PIO_UNISCRNMAP:
7573 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
7574 VKI_E_TABSZ * sizeof(unsigned short) );
7575 break;
7577 case VKI_GIO_UNIMAP:
7578 if ( ARG3 ) {
7579 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7580 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7581 sizeof(unsigned short));
7582 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7583 sizeof(struct vki_unipair *));
7584 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
7585 desc->entry_ct * sizeof(struct vki_unipair));
7587 break;
7588 case VKI_PIO_UNIMAP:
7589 if ( ARG3 ) {
7590 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
7591 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
7592 sizeof(unsigned short) );
7593 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
7594 sizeof(struct vki_unipair *) );
7595 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
7596 desc->entry_ct * sizeof(struct vki_unipair) );
7598 break;
7599 case VKI_PIO_UNIMAPCLR:
7600 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
7601 break;
7603 case VKI_KDGKBMODE:
7604 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
7605 break;
7606 case VKI_KDSKBMODE:
7607 break;
7609 case VKI_KDGKBMETA:
7610 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
7611 break;
7612 case VKI_KDSKBMETA:
7613 break;
7615 case VKI_KDGKBLED:
7616 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
7617 break;
7618 case VKI_KDSKBLED:
7619 break;
7621 case VKI_KDGKBENT:
7622 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
7623 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7624 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7625 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
7626 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7627 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7628 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
7629 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7630 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7631 break;
7632 case VKI_KDSKBENT:
7633 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
7634 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
7635 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
7636 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
7637 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
7638 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
7639 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
7640 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
7641 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
7642 break;
7644 case VKI_KDGKBSENT:
7645 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
7646 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7647 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7648 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
7649 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
7650 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
7651 break;
7652 case VKI_KDSKBSENT:
7653 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
7654 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
7655 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
7656 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
7657 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
7658 break;
7660 case VKI_KDGKBDIACR:
7661 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7662 break;
7663 case VKI_KDSKBDIACR:
7664 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
7665 break;
7667 case VKI_KDGETKEYCODE:
7668 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
7669 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7670 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7671 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
7672 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7673 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7674 break;
7675 case VKI_KDSETKEYCODE:
7676 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
7677 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
7678 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
7679 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
7680 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
7681 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
7682 break;
7684 case VKI_KDSIGACCEPT:
7685 break;
7687 case VKI_KDKBDREP:
7688 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
7689 break;
7691 case VKI_KDFONTOP:
7692 if ( ARG3 ) {
7693 struct vki_console_font_op *op =
7694 (struct vki_console_font_op *) (Addr)ARG3;
7695 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
7696 sizeof(struct vki_console_font_op) );
7697 switch ( op->op ) {
7698 case VKI_KD_FONT_OP_SET:
7699 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
7700 (Addr)op->data,
7701 (op->width + 7) / 8 * 32 * op->charcount );
7702 break;
7703 case VKI_KD_FONT_OP_GET:
7704 if ( op->data )
7705 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
7706 (Addr)op->data,
7707 (op->width + 7) / 8 * 32 * op->charcount );
7708 break;
7709 case VKI_KD_FONT_OP_SET_DEFAULT:
7710 if ( op->data )
7711 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
7712 (Addr)op->data );
7713 break;
7714 case VKI_KD_FONT_OP_COPY:
7715 break;
7718 break;
7720 case VKI_VT_OPENQRY:
7721 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
7722 break;
7723 case VKI_VT_GETMODE:
7724 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7725 break;
7726 case VKI_VT_SETMODE:
7727 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
7728 break;
7729 case VKI_VT_GETSTATE:
7730 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
7731 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
7732 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
7733 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
7734 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
7735 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
7736 break;
7737 case VKI_VT_RELDISP:
7738 case VKI_VT_ACTIVATE:
7739 case VKI_VT_WAITACTIVE:
7740 case VKI_VT_DISALLOCATE:
7741 break;
7742 case VKI_VT_RESIZE:
7743 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
7744 break;
7745 case VKI_VT_RESIZEX:
7746 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
7747 break;
7748 case VKI_VT_LOCKSWITCH:
7749 case VKI_VT_UNLOCKSWITCH:
7750 break;
7752 case VKI_USBDEVFS_CONTROL:
7753 if ( ARG3 ) {
7754 struct vki_usbdevfs_ctrltransfer *vkuc =
7755 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
7756 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
7757 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
7758 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
7759 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
7760 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
7761 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
7762 if (vkuc->bRequestType & 0x80)
7763 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7764 else
7765 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
7767 break;
7768 case VKI_USBDEVFS_BULK:
7769 if ( ARG3 ) {
7770 struct vki_usbdevfs_bulktransfer *vkub =
7771 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
7772 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
7773 if (vkub->ep & 0x80)
7774 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7775 else
7776 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
7778 break;
7779 case VKI_USBDEVFS_GETDRIVER:
7780 if ( ARG3 ) {
7781 struct vki_usbdevfs_getdriver *vkugd =
7782 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
7783 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
7785 break;
7786 case VKI_USBDEVFS_SUBMITURB:
7787 if ( ARG3 ) {
7788 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
7790 /* Not the whole struct needs to be initialized */
7791 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
7792 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
7793 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
7794 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
7795 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
7796 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
7797 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7798 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
7799 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7800 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
7801 if (vkusp->bRequestType & 0x80)
7802 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7803 else
7804 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
7805 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7806 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7807 int total_length = 0;
7808 int i;
7809 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
7810 for(i=0; i<vkuu->number_of_packets; i++) {
7811 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
7812 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));
7813 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
7814 total_length += vkuu->iso_frame_desc[i].length;
7816 if (vkuu->endpoint & 0x80)
7817 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7818 else
7819 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
7820 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
7821 } else {
7822 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
7823 if (vkuu->endpoint & 0x80)
7824 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7825 else
7826 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
7827 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
7830 break;
7831 case VKI_USBDEVFS_DISCARDURB:
7832 break;
7833 case VKI_USBDEVFS_REAPURB:
7834 if ( ARG3 ) {
7835 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7837 break;
7838 case VKI_USBDEVFS_REAPURBNDELAY:
7839 if ( ARG3 ) {
7840 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
7842 break;
7843 case VKI_USBDEVFS_CONNECTINFO:
7844 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7845 break;
7846 case VKI_USBDEVFS_IOCTL:
7847 if ( ARG3 ) {
7848 struct vki_usbdevfs_ioctl *vkui =
7849 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
7850 UInt dir2, size2;
7851 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
7852 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
7853 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7854 if (size2 > 0) {
7855 if (dir2 & _VKI_IOC_WRITE)
7856 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
7857 else if (dir2 & _VKI_IOC_READ)
7858 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
7861 break;
7862 case VKI_USBDEVFS_RESET:
7863 break;
7865 /* I2C (/dev/i2c-*) ioctls */
7866 case VKI_I2C_SLAVE:
7867 case VKI_I2C_SLAVE_FORCE:
7868 case VKI_I2C_TENBIT:
7869 case VKI_I2C_PEC:
7870 break;
7871 case VKI_I2C_FUNCS:
7872 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
7873 break;
7874 case VKI_I2C_RDWR:
7875 if ( ARG3 ) {
7876 struct vki_i2c_rdwr_ioctl_data *vkui =
7877 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
7878 UInt i;
7879 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
7880 for (i=0; i < vkui->nmsgs; i++) {
7881 struct vki_i2c_msg *msg = vkui->msgs + i;
7882 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
7883 if (msg->flags & VKI_I2C_M_RD)
7884 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7885 else
7886 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
7889 break;
7890 case VKI_I2C_SMBUS:
7891 if ( ARG3 ) {
7892 struct vki_i2c_smbus_ioctl_data *vkis
7893 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
7894 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
7895 (Addr)&vkis->read_write, sizeof(vkis->read_write));
7896 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
7897 (Addr)&vkis->size, sizeof(vkis->size));
7898 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
7899 (Addr)&vkis->command, sizeof(vkis->command));
7900 /* i2c_smbus_write_quick hides its value in read_write, so
7901 this variable can have a different meaning */
7902 /* to make matters worse i2c_smbus_write_byte stores its
7903 value in command */
7904 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
7905 ((vkis->size == VKI_I2C_SMBUS_BYTE)
7906 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
7907 /* the rest uses the byte array to store the data,
7908 some the first byte for size */
7909 UInt size;
7910 switch(vkis->size) {
7911 case VKI_I2C_SMBUS_BYTE_DATA:
7912 size = 1;
7913 break;
7914 case VKI_I2C_SMBUS_WORD_DATA:
7915 case VKI_I2C_SMBUS_PROC_CALL:
7916 size = 2;
7917 break;
7918 case VKI_I2C_SMBUS_BLOCK_DATA:
7919 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
7920 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
7921 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
7922 size = 1 + vkis->data->block[0];
7923 break;
7924 default:
7925 size = 0;
7928 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
7929 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
7930 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
7931 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
7932 ".i2c_smbus_ioctl_data.data",
7933 (Addr)&vkis->data->block[0], size);
7934 else
7935 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
7936 "i2c_smbus_ioctl_data.data",
7937 (Addr)&vkis->data->block[0], size);
7940 break;
7942 /* Wireless extensions ioctls */
7943 case VKI_SIOCSIWCOMMIT:
7944 case VKI_SIOCSIWNWID:
7945 case VKI_SIOCSIWFREQ:
7946 case VKI_SIOCSIWMODE:
7947 case VKI_SIOCSIWSENS:
7948 case VKI_SIOCSIWRANGE:
7949 case VKI_SIOCSIWPRIV:
7950 case VKI_SIOCSIWSTATS:
7951 case VKI_SIOCSIWSPY:
7952 case VKI_SIOCSIWTHRSPY:
7953 case VKI_SIOCSIWAP:
7954 case VKI_SIOCSIWSCAN:
7955 case VKI_SIOCSIWESSID:
7956 case VKI_SIOCSIWRATE:
7957 case VKI_SIOCSIWNICKN:
7958 case VKI_SIOCSIWRTS:
7959 case VKI_SIOCSIWFRAG:
7960 case VKI_SIOCSIWTXPOW:
7961 case VKI_SIOCSIWRETRY:
7962 case VKI_SIOCSIWENCODE:
7963 case VKI_SIOCSIWPOWER:
7964 case VKI_SIOCSIWGENIE:
7965 case VKI_SIOCSIWMLME:
7966 case VKI_SIOCSIWAUTH:
7967 case VKI_SIOCSIWENCODEEXT:
7968 case VKI_SIOCSIWPMKSA:
7969 break;
7970 case VKI_SIOCGIWNAME:
7971 if (ARG3) {
7972 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
7973 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
7974 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
7976 break;
7977 case VKI_SIOCGIWNWID:
7978 case VKI_SIOCGIWSENS:
7979 case VKI_SIOCGIWRATE:
7980 case VKI_SIOCGIWRTS:
7981 case VKI_SIOCGIWFRAG:
7982 case VKI_SIOCGIWTXPOW:
7983 case VKI_SIOCGIWRETRY:
7984 case VKI_SIOCGIWPOWER:
7985 case VKI_SIOCGIWAUTH:
7986 if (ARG3) {
7987 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
7988 "RETRY|PARAM|AUTH])",
7989 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
7990 sizeof(struct vki_iw_param));
7992 break;
7993 case VKI_SIOCGIWFREQ:
7994 if (ARG3) {
7995 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
7996 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
7997 sizeof(struct vki_iw_freq));
7999 break;
8000 case VKI_SIOCGIWMODE:
8001 if (ARG3) {
8002 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8003 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8004 sizeof(__vki_u32));
8006 break;
8007 case VKI_SIOCGIWRANGE:
8008 case VKI_SIOCGIWPRIV:
8009 case VKI_SIOCGIWSTATS:
8010 case VKI_SIOCGIWSPY:
8011 case VKI_SIOCGIWTHRSPY:
8012 case VKI_SIOCGIWAPLIST:
8013 case VKI_SIOCGIWSCAN:
8014 case VKI_SIOCGIWESSID:
8015 case VKI_SIOCGIWNICKN:
8016 case VKI_SIOCGIWENCODE:
8017 case VKI_SIOCGIWGENIE:
8018 case VKI_SIOCGIWENCODEEXT:
8019 if (ARG3) {
8020 struct vki_iw_point* point;
8021 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8022 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8023 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8024 (Addr)point->pointer, point->length);
8026 break;
8027 case VKI_SIOCGIWAP:
8028 if (ARG3) {
8029 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8030 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8031 sizeof(struct vki_sockaddr));
8033 break;
8035 /* User input device creation */
8036 case VKI_UI_SET_EVBIT:
8037 case VKI_UI_SET_KEYBIT:
8038 case VKI_UI_SET_RELBIT:
8039 case VKI_UI_SET_ABSBIT:
8040 case VKI_UI_SET_MSCBIT:
8041 case VKI_UI_SET_LEDBIT:
8042 case VKI_UI_SET_SNDBIT:
8043 case VKI_UI_SET_FFBIT:
8044 case VKI_UI_SET_SWBIT:
8045 case VKI_UI_SET_PROPBIT:
8046 /* These just take an int by value */
8047 break;
8049 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8050 || defined(VGPV_mips32_linux_android) \
8051 || defined(VGPV_arm64_linux_android)
8052 /* ashmem */
8053 case VKI_ASHMEM_GET_SIZE:
8054 case VKI_ASHMEM_SET_SIZE:
8055 case VKI_ASHMEM_GET_PROT_MASK:
8056 case VKI_ASHMEM_SET_PROT_MASK:
8057 case VKI_ASHMEM_GET_PIN_STATUS:
8058 case VKI_ASHMEM_PURGE_ALL_CACHES:
8059 break;
8060 case VKI_ASHMEM_GET_NAME:
8061 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8062 break;
8063 case VKI_ASHMEM_SET_NAME:
8064 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8065 break;
8066 case VKI_ASHMEM_PIN:
8067 case VKI_ASHMEM_UNPIN:
8068 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8069 ARG3, sizeof(struct vki_ashmem_pin) );
8070 break;
8072 /* binder */
8073 case VKI_BINDER_WRITE_READ:
8074 if (ARG3) {
8075 struct vki_binder_write_read* bwr
8076 = (struct vki_binder_write_read*)(Addr)ARG3;
8078 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8079 bwr->write_buffer);
8080 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8081 bwr->write_size);
8082 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8083 bwr->write_consumed);
8084 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8085 bwr->read_buffer);
8086 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8087 bwr->read_size);
8088 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8089 bwr->read_consumed);
8091 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8092 bwr->write_consumed);
8093 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8094 bwr->read_consumed);
8096 if (bwr->read_size)
8097 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8098 (Addr)bwr->read_buffer, bwr->read_size);
8099 if (bwr->write_size)
8100 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8101 (Addr)bwr->write_buffer, bwr->write_size);
8103 break;
8105 case VKI_BINDER_SET_IDLE_TIMEOUT:
8106 case VKI_BINDER_SET_MAX_THREADS:
8107 case VKI_BINDER_SET_IDLE_PRIORITY:
8108 case VKI_BINDER_SET_CONTEXT_MGR:
8109 case VKI_BINDER_THREAD_EXIT:
8110 break;
8111 case VKI_BINDER_VERSION:
8112 if (ARG3) {
8113 struct vki_binder_version* bv =
8114 (struct vki_binder_version*)(Addr)ARG3;
8115 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8117 break;
8118 # endif /* defined(VGPV_*_linux_android) */
8120 case VKI_HCIGETDEVLIST:
8121 if (ARG3) {
8122 struct vki_hci_dev_list_req* dlr =
8123 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8124 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8125 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8126 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8127 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8128 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8130 break;
8132 case VKI_HCIINQUIRY:
8133 if (ARG3) {
8134 struct vki_hci_inquiry_req* ir =
8135 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8136 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8137 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8138 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8139 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8140 ir->num_rsp * sizeof(struct vki_inquiry_info));
8142 break;
8144 case VKI_DRM_IOCTL_VERSION:
8145 if (ARG3) {
8146 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8147 struct vg_drm_version_info* info;
8148 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8149 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8150 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8151 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8152 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8153 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8154 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8155 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8156 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8157 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8158 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8159 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8160 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8161 // To ensure we VG_(free) info even when syscall fails:
8162 *flags |= SfPostOnFail;
8163 info->data = *data;
8164 info->orig = data;
8165 ARG3 = (Addr)&info->data;
8167 break;
8168 case VKI_DRM_IOCTL_GET_UNIQUE:
8169 if (ARG3) {
8170 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8171 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8172 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8173 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8175 break;
8176 case VKI_DRM_IOCTL_GET_MAGIC:
8177 if (ARG3) {
8178 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8179 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8181 break;
8182 case VKI_DRM_IOCTL_WAIT_VBLANK:
8183 if (ARG3) {
8184 union vki_drm_wait_vblank *data =
8185 (union vki_drm_wait_vblank *)(Addr)ARG3;
8186 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8187 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8188 /* XXX: It seems request.signal isn't used */
8189 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8191 break;
8192 case VKI_DRM_IOCTL_GEM_CLOSE:
8193 if (ARG3) {
8194 struct vki_drm_gem_close *data =
8195 (struct vki_drm_gem_close *)(Addr)ARG3;
8196 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8198 break;
8199 case VKI_DRM_IOCTL_GEM_FLINK:
8200 if (ARG3) {
8201 struct vki_drm_gem_flink *data =
8202 (struct vki_drm_gem_flink *)(Addr)ARG3;
8203 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8204 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8206 break;
8207 case VKI_DRM_IOCTL_GEM_OPEN:
8208 if (ARG3) {
8209 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8210 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8211 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8212 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8214 break;
8215 case VKI_DRM_IOCTL_I915_GETPARAM:
8216 if (ARG3) {
8217 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8218 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8219 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8221 break;
8222 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8223 if (ARG3) {
8224 struct vki_drm_i915_gem_busy *data =
8225 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8226 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8227 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8229 break;
8230 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8231 if (ARG3) {
8232 struct vki_drm_i915_gem_create *data =
8233 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8234 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8235 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8237 break;
8238 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8239 if (ARG3) {
8240 struct vki_drm_i915_gem_pread *data =
8241 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8242 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8243 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8244 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8245 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8246 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8248 break;
8249 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8250 if (ARG3) {
8251 struct vki_drm_i915_gem_pwrite *data =
8252 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8253 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8254 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8255 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8256 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8257 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8258 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8259 * interleaved vertex attributes may have a wide stride with uninitialized data between
8260 * consecutive vertices) */
8262 break;
8263 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8264 if (ARG3) {
8265 struct vki_drm_i915_gem_mmap_v1 *data =
8266 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8267 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8268 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8269 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8270 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8272 break;
8273 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8274 if (ARG3) {
8275 struct vki_drm_i915_gem_mmap *data =
8276 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8277 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8278 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8279 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8280 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8281 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8283 break;
8284 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8285 if (ARG3) {
8286 struct vki_drm_i915_gem_mmap_gtt *data =
8287 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8288 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8289 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8291 break;
8292 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8293 if (ARG3) {
8294 struct vki_drm_i915_gem_set_domain *data =
8295 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8296 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8297 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8298 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8300 break;
8301 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8302 if (ARG3) {
8303 struct vki_drm_i915_gem_set_tiling *data =
8304 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8305 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8306 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8307 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8308 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8310 break;
8311 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8312 if (ARG3) {
8313 struct vki_drm_i915_gem_get_tiling *data =
8314 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8315 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8316 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8317 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8319 break;
8320 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8321 if (ARG3) {
8322 struct vki_drm_i915_gem_get_aperture *data =
8323 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8324 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8325 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8327 break;
8329 /* KVM ioctls that check for a numeric value as parameter */
8330 case VKI_KVM_GET_API_VERSION:
8331 case VKI_KVM_CREATE_VM:
8332 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8333 case VKI_KVM_CHECK_EXTENSION:
8334 case VKI_KVM_SET_TSS_ADDR:
8335 case VKI_KVM_CREATE_VCPU:
8336 case VKI_KVM_RUN:
8337 break;
8339 case VKI_KVM_S390_MEM_OP: {
8340 struct vki_kvm_s390_mem_op *args =
8341 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8342 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8343 sizeof(struct vki_kvm_s390_mem_op));
8344 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8345 break;
8346 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8347 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8348 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8349 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8351 break;
8354 #ifdef ENABLE_XEN
8355 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8356 SyscallArgs harrghs;
8357 struct vki_xen_privcmd_hypercall *args =
8358 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8360 if (!args)
8361 break;
8363 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8364 harrghs.sysno = args->op;
8365 harrghs.arg1 = args->arg[0];
8366 harrghs.arg2 = args->arg[1];
8367 harrghs.arg3 = args->arg[2];
8368 harrghs.arg4 = args->arg[3];
8369 harrghs.arg5 = args->arg[4];
8370 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8372 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8374 /* HACK. arg8 is used to return the number of hypercall
8375 * arguments actually consumed! */
8376 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8377 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8379 break;
8382 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8383 struct vki_xen_privcmd_mmap *args =
8384 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8385 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8386 (Addr)&args->num, sizeof(args->num));
8387 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8388 (Addr)&args->dom, sizeof(args->dom));
8389 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8390 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8391 break;
8393 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8394 struct vki_xen_privcmd_mmapbatch *args =
8395 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8396 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8397 (Addr)&args->num, sizeof(args->num));
8398 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8399 (Addr)&args->dom, sizeof(args->dom));
8400 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8401 (Addr)&args->addr, sizeof(args->addr));
8402 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8403 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8404 break;
8406 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8407 struct vki_xen_privcmd_mmapbatch_v2 *args =
8408 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8409 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8410 (Addr)&args->num, sizeof(args->num));
8411 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8412 (Addr)&args->dom, sizeof(args->dom));
8413 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8414 (Addr)&args->addr, sizeof(args->addr));
8415 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8416 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8417 break;
8420 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
8421 struct vki_xen_ioctl_evtchn_bind_virq *args =
8422 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
8423 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
8424 (Addr)&args->virq, sizeof(args->virq));
8426 break;
8427 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
8428 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
8429 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
8430 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
8431 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8432 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
8433 (Addr)&args->remote_port, sizeof(args->remote_port));
8435 break;
8436 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
8437 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
8438 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
8439 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
8440 (Addr)&args->remote_domain, sizeof(args->remote_domain));
8442 break;
8443 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
8444 struct vki_xen_ioctl_evtchn_unbind *args =
8445 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
8446 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
8447 (Addr)&args->port, sizeof(args->port));
8449 break;
8450 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
8451 struct vki_xen_ioctl_evtchn_notify *args =
8452 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
8453 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
8454 (Addr)&args->port, sizeof(args->port));
8456 break;
8457 case VKI_XEN_IOCTL_EVTCHN_RESET:
8458 /* No input*/
8459 break;
8460 #endif
8462 /* Lustre */
8463 case VKI_OBD_IOC_FID2PATH: {
8464 struct vki_getinfo_fid2path *gf =
8465 (struct vki_getinfo_fid2path *)(Addr)ARG3;
8466 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
8467 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
8468 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
8469 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
8470 break;
8473 case VKI_LL_IOC_PATH2FID:
8474 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
8475 break;
8477 case VKI_LL_IOC_GETPARENT: {
8478 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
8479 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
8480 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
8481 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
8482 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
8483 break;
8486 /* V4L2 */
8487 case VKI_V4L2_QUERYCAP: {
8488 struct vki_v4l2_capability *data =
8489 (struct vki_v4l2_capability *)(Addr)ARG3;
8490 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
8491 break;
8493 case VKI_V4L2_ENUM_FMT: {
8494 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
8495 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
8496 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
8497 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
8498 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
8499 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
8500 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
8501 break;
8503 case VKI_V4L2_G_FMT: {
8504 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8505 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
8506 switch (data->type) {
8507 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8508 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8509 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
8510 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
8511 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
8512 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
8513 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
8514 break;
8515 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8516 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8517 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
8518 break;
8519 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8520 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8521 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
8522 break;
8523 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8524 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8525 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
8526 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
8527 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8528 if (data->fmt.win.clipcount && data->fmt.win.clips)
8529 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
8530 (Addr)data->fmt.win.clips,
8531 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8532 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
8533 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
8534 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
8535 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
8536 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
8537 break;
8538 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8539 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8540 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
8541 break;
8542 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8543 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
8544 break;
8546 break;
8548 case VKI_V4L2_S_FMT: {
8549 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8550 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
8551 switch (data->type) {
8552 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8553 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8554 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
8555 (Addr)&data->type + sizeof(data->type),
8556 sizeof(*data) - sizeof(data->type));
8557 break;
8558 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8559 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8560 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
8561 break;
8562 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8563 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8564 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
8565 break;
8566 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8567 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8568 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
8569 if (data->fmt.win.clipcount && data->fmt.win.clips)
8570 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
8571 (Addr)data->fmt.win.clips,
8572 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8573 if (data->fmt.win.bitmap)
8574 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
8575 (Addr)data->fmt.win.bitmap,
8576 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8577 break;
8578 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8579 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8580 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
8581 break;
8582 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8583 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
8584 break;
8586 break;
8588 case VKI_V4L2_TRY_FMT: {
8589 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
8590 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
8591 switch (data->type) {
8592 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
8593 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
8594 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
8595 (Addr)&data->type + sizeof(data->type),
8596 sizeof(*data) - sizeof(data->type));
8597 break;
8598 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
8599 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
8600 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
8601 break;
8602 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
8603 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
8604 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
8605 break;
8606 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
8607 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
8608 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
8609 if (data->fmt.win.clipcount && data->fmt.win.clips)
8610 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
8611 (Addr)data->fmt.win.clips,
8612 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
8613 if (data->fmt.win.bitmap)
8614 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
8615 (Addr)data->fmt.win.bitmap,
8616 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
8617 break;
8618 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
8619 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
8620 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
8621 break;
8622 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
8623 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
8624 break;
8626 break;
8628 case VKI_V4L2_REQBUFS: {
8629 struct vki_v4l2_requestbuffers *data =
8630 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
8631 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
8632 break;
8634 case VKI_V4L2_QUERYBUF: {
8635 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8636 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
8637 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
8638 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
8639 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
8640 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8641 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8642 unsigned i;
8644 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8645 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
8646 for (i = 0; i < data->length; i++) {
8647 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8648 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
8649 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
8650 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8651 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
8653 } else {
8654 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
8655 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
8657 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
8658 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
8659 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
8660 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
8661 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
8662 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8663 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
8664 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
8665 break;
8667 case VKI_V4L2_G_FBUF: {
8668 struct vki_v4l2_framebuffer *data =
8669 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8670 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
8671 break;
8673 case VKI_V4L2_S_FBUF: {
8674 struct vki_v4l2_framebuffer *data =
8675 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
8676 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
8677 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
8678 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
8679 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
8680 break;
8682 case VKI_V4L2_OVERLAY: {
8683 int *data = (int *)(Addr)ARG3;
8684 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
8685 break;
8687 case VKI_V4L2_QBUF: {
8688 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8689 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8690 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8691 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8692 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8694 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
8695 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
8696 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
8697 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
8698 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
8699 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
8700 if (is_output) {
8701 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8702 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8704 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8705 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8706 unsigned i;
8708 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
8709 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
8710 for (i = 0; i < data->length; i++) {
8711 if (is_output) {
8712 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8713 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8715 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8716 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8717 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8718 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
8719 else
8720 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
8721 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
8723 } else {
8724 if (data->memory == VKI_V4L2_MEMORY_MMAP)
8725 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
8726 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
8727 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
8728 else
8729 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
8730 if (is_output) {
8731 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
8732 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
8735 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
8736 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
8737 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
8739 break;
8741 case VKI_V4L2_EXPBUF: {
8742 struct vki_v4l2_exportbuffer *data =
8743 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
8744 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
8745 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
8746 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
8747 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
8748 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
8749 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
8750 break;
8752 case VKI_V4L2_DQBUF: {
8753 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
8754 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
8755 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
8756 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
8757 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
8758 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
8759 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8760 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8761 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
8762 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
8763 unsigned i;
8765 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
8766 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
8767 for (i = 0; i < data->length; i++) {
8768 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
8769 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
8770 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
8771 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
8772 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
8774 } else {
8775 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
8776 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
8777 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
8778 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
8780 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
8781 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
8782 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
8783 break;
8785 case VKI_V4L2_STREAMON: {
8786 int *data = (int *)(Addr)ARG3;
8787 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
8788 break;
8790 case VKI_V4L2_STREAMOFF: {
8791 int *data = (int *)(Addr)ARG3;
8792 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
8793 break;
8795 case VKI_V4L2_G_PARM: {
8796 struct vki_v4l2_streamparm *data =
8797 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8798 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8799 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8800 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8801 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8803 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
8804 if (is_output) {
8805 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
8806 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
8807 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
8808 } else {
8809 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
8810 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
8811 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
8813 break;
8815 case VKI_V4L2_S_PARM: {
8816 struct vki_v4l2_streamparm *data =
8817 (struct vki_v4l2_streamparm *)(Addr)ARG3;
8818 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
8819 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
8820 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
8821 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
8823 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
8824 if (is_output)
8825 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
8826 else
8827 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
8828 break;
8830 case VKI_V4L2_G_STD: {
8831 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8832 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
8833 break;
8835 case VKI_V4L2_S_STD: {
8836 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
8837 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
8838 break;
8840 case VKI_V4L2_ENUMSTD: {
8841 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
8842 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
8843 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
8844 break;
8846 case VKI_V4L2_ENUMINPUT: {
8847 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
8848 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
8849 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8850 break;
8852 case VKI_V4L2_G_CTRL: {
8853 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8854 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
8855 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
8856 break;
8858 case VKI_V4L2_S_CTRL: {
8859 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
8860 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
8861 break;
8863 case VKI_V4L2_G_TUNER: {
8864 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8865 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
8866 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
8867 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
8868 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8869 break;
8871 case VKI_V4L2_S_TUNER: {
8872 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
8873 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
8874 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
8875 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
8876 break;
8878 case VKI_V4L2_G_AUDIO: {
8879 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8880 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
8881 sizeof(*data) - sizeof(data->reserved));
8882 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
8883 break;
8885 case VKI_V4L2_S_AUDIO: {
8886 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
8887 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
8888 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
8889 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
8890 break;
8892 case VKI_V4L2_QUERYCTRL: {
8893 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
8894 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
8895 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
8896 sizeof(*data) - sizeof(data->id));
8897 break;
8899 case VKI_V4L2_QUERYMENU: {
8900 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
8901 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
8902 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
8903 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
8904 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
8905 break;
8907 case VKI_V4L2_G_INPUT: {
8908 int *data = (int *)(Addr)ARG3;
8909 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
8910 break;
8912 case VKI_V4L2_S_INPUT: {
8913 int *data = (int *)(Addr)ARG3;
8914 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
8915 break;
8917 case VKI_V4L2_G_EDID: {
8918 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8919 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
8920 if (data->blocks && data->edid)
8921 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
8922 break;
8924 case VKI_V4L2_S_EDID: {
8925 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
8926 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
8927 if (data->blocks && data->edid)
8928 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
8929 break;
8931 case VKI_V4L2_G_OUTPUT: {
8932 int *data = (int *)(Addr)ARG3;
8933 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
8934 break;
8936 case VKI_V4L2_S_OUTPUT: {
8937 int *data = (int *)(Addr)ARG3;
8938 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
8939 break;
8941 case VKI_V4L2_ENUMOUTPUT: {
8942 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
8943 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
8944 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
8945 break;
8947 case VKI_V4L2_G_AUDOUT: {
8948 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8949 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
8950 sizeof(*data) - sizeof(data->reserved));
8951 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
8952 break;
8954 case VKI_V4L2_S_AUDOUT: {
8955 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
8956 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
8957 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
8958 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
8959 break;
8961 case VKI_V4L2_G_MODULATOR: {
8962 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8963 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
8964 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
8965 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
8966 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
8967 break;
8969 case VKI_V4L2_S_MODULATOR: {
8970 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
8971 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
8972 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
8973 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
8974 break;
8976 case VKI_V4L2_G_FREQUENCY: {
8977 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8978 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
8979 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
8980 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
8981 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
8982 break;
8984 case VKI_V4L2_S_FREQUENCY: {
8985 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
8986 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
8987 break;
8989 case VKI_V4L2_CROPCAP: {
8990 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
8991 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
8992 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
8993 break;
8995 case VKI_V4L2_G_CROP: {
8996 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
8997 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
8998 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
8999 break;
9001 case VKI_V4L2_S_CROP: {
9002 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9003 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9004 break;
9006 case VKI_V4L2_G_JPEGCOMP: {
9007 struct vki_v4l2_jpegcompression *data =
9008 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9009 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9010 break;
9012 case VKI_V4L2_S_JPEGCOMP: {
9013 struct vki_v4l2_jpegcompression *data =
9014 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9015 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9016 break;
9018 case VKI_V4L2_QUERYSTD: {
9019 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9020 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9021 break;
9023 case VKI_V4L2_ENUMAUDIO: {
9024 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9025 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9026 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9027 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9028 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9029 break;
9031 case VKI_V4L2_ENUMAUDOUT: {
9032 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9033 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9034 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9035 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9036 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9037 break;
9039 case VKI_V4L2_G_PRIORITY: {
9040 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9041 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9042 break;
9044 case VKI_V4L2_S_PRIORITY: {
9045 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9046 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9047 break;
9049 case VKI_V4L2_G_SLICED_VBI_CAP: {
9050 struct vki_v4l2_sliced_vbi_cap *data =
9051 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9052 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9053 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9054 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9055 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9056 break;
9058 case VKI_V4L2_G_EXT_CTRLS: {
9059 struct vki_v4l2_ext_controls *data =
9060 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9061 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9062 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9063 if (data->count) {
9064 unsigned i;
9066 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9067 for (i = 0; i < data->count; i++) {
9068 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9069 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9070 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9071 if (data->controls[i].size) {
9072 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9073 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9074 (Addr)data->controls[i].ptr, data->controls[i].size);
9075 } else {
9076 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9077 data->controls[i].value64);
9081 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9082 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9083 break;
9085 case VKI_V4L2_S_EXT_CTRLS: {
9086 struct vki_v4l2_ext_controls *data =
9087 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9088 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9089 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9090 if (data->count) {
9091 unsigned i;
9093 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9094 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9095 data->count * sizeof(data->controls[0]));
9096 for (i = 0; i < data->count; i++) {
9097 if (data->controls[i].size) {
9098 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9099 (Addr)data->controls[i].ptr, data->controls[i].size);
9103 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9104 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9105 break;
9107 case VKI_V4L2_TRY_EXT_CTRLS: {
9108 struct vki_v4l2_ext_controls *data =
9109 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9110 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9111 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9112 if (data->count) {
9113 unsigned i;
9115 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9116 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9117 data->count * sizeof(data->controls[0]));
9118 for (i = 0; i < data->count; i++) {
9119 if (data->controls[i].size) {
9120 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9121 (Addr)data->controls[i].ptr, data->controls[i].size);
9125 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9126 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9127 break;
9129 case VKI_V4L2_ENUM_FRAMESIZES: {
9130 struct vki_v4l2_frmsizeenum *data =
9131 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9132 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9133 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9134 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9135 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9136 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9137 break;
9139 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9140 struct vki_v4l2_frmivalenum *data =
9141 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9142 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9143 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9144 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9145 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9146 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9147 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9148 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9149 break;
9151 case VKI_V4L2_G_ENC_INDEX: {
9152 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9153 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9154 break;
9156 case VKI_V4L2_ENCODER_CMD: {
9157 struct vki_v4l2_encoder_cmd *data =
9158 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9159 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9160 break;
9162 case VKI_V4L2_TRY_ENCODER_CMD: {
9163 struct vki_v4l2_encoder_cmd *data =
9164 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9165 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9166 break;
9168 case VKI_V4L2_DBG_S_REGISTER: {
9169 struct vki_v4l2_dbg_register *data =
9170 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9171 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9172 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9173 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9174 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9175 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9176 break;
9178 case VKI_V4L2_DBG_G_REGISTER: {
9179 struct vki_v4l2_dbg_register *data =
9180 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9181 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9182 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9183 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9184 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9185 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9186 break;
9188 case VKI_V4L2_S_HW_FREQ_SEEK: {
9189 struct vki_v4l2_hw_freq_seek *data =
9190 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9191 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9192 break;
9194 case VKI_V4L2_S_DV_TIMINGS: {
9195 struct vki_v4l2_dv_timings *data =
9196 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9197 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9198 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9199 break;
9201 case VKI_V4L2_G_DV_TIMINGS: {
9202 struct vki_v4l2_dv_timings *data =
9203 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9204 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9205 break;
9207 case VKI_V4L2_DQEVENT: {
9208 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9209 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9210 break;
9212 case VKI_V4L2_SUBSCRIBE_EVENT: {
9213 struct vki_v4l2_event_subscription *data =
9214 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9215 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9216 break;
9218 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9219 struct vki_v4l2_event_subscription *data =
9220 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9221 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9222 break;
9224 case VKI_V4L2_CREATE_BUFS: {
9225 struct vki_v4l2_create_buffers *data =
9226 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9227 struct vki_v4l2_format *fmt = &data->format;
9228 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9229 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9231 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9232 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9233 switch (fmt->type) {
9234 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9235 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9236 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9237 break;
9238 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9239 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9240 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9241 break;
9242 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9243 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9244 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9245 break;
9246 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9247 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9248 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9249 break;
9250 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9251 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9252 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9253 break;
9254 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9255 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9256 break;
9258 break;
9260 case VKI_V4L2_PREPARE_BUF: {
9261 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9262 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9263 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9264 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9265 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9266 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9267 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9268 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9269 unsigned i;
9271 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9272 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9273 for (i = 0; i < data->length; i++) {
9274 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9277 break;
9279 case VKI_V4L2_G_SELECTION: {
9280 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9281 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9282 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9283 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9284 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9285 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9286 break;
9288 case VKI_V4L2_S_SELECTION: {
9289 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9290 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9291 break;
9293 case VKI_V4L2_DECODER_CMD: {
9294 struct vki_v4l2_decoder_cmd *data =
9295 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9296 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9297 break;
9299 case VKI_V4L2_TRY_DECODER_CMD: {
9300 struct vki_v4l2_decoder_cmd *data =
9301 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9302 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9303 break;
9305 case VKI_V4L2_ENUM_DV_TIMINGS: {
9306 struct vki_v4l2_enum_dv_timings *data =
9307 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9308 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9309 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9310 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9311 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9312 break;
9314 case VKI_V4L2_QUERY_DV_TIMINGS: {
9315 struct vki_v4l2_dv_timings *data =
9316 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9317 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9318 break;
9320 case VKI_V4L2_DV_TIMINGS_CAP: {
9321 struct vki_v4l2_dv_timings_cap *data =
9322 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9323 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9324 break;
9326 case VKI_V4L2_ENUM_FREQ_BANDS: {
9327 struct vki_v4l2_frequency_band *data =
9328 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9329 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9330 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9331 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9332 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9333 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9334 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9335 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9336 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9337 break;
9339 case VKI_V4L2_DBG_G_CHIP_INFO: {
9340 struct vki_v4l2_dbg_chip_info *data =
9341 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9342 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9343 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9344 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9345 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9346 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9347 break;
9349 case VKI_V4L2_QUERY_EXT_CTRL: {
9350 struct vki_v4l2_query_ext_ctrl *data =
9351 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9352 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9353 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9354 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9355 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9356 break;
9358 case VKI_V4L2_SUBDEV_G_FMT: {
9359 struct vki_v4l2_subdev_format *data =
9360 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9361 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9362 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9363 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9364 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9365 break;
9367 case VKI_V4L2_SUBDEV_S_FMT: {
9368 struct vki_v4l2_subdev_format *data =
9369 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9370 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9371 break;
9373 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9374 struct vki_v4l2_subdev_frame_interval *data =
9375 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9376 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9377 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9378 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9379 break;
9381 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9382 struct vki_v4l2_subdev_frame_interval *data =
9383 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9384 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9385 break;
9387 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9388 struct vki_v4l2_subdev_mbus_code_enum *data =
9389 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9390 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9391 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9392 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9393 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9394 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9395 break;
9397 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9398 struct vki_v4l2_subdev_frame_size_enum *data =
9399 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9400 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9401 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9402 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9403 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9404 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9405 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9406 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9407 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9408 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9409 break;
9411 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9412 struct vki_v4l2_subdev_frame_interval_enum *data =
9413 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9414 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9415 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9416 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9417 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
9418 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
9419 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
9420 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
9421 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
9422 break;
9424 case VKI_V4L2_SUBDEV_G_CROP: {
9425 struct vki_v4l2_subdev_crop *data =
9426 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9427 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
9428 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
9429 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
9430 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
9431 break;
9433 case VKI_V4L2_SUBDEV_S_CROP: {
9434 struct vki_v4l2_subdev_crop *data =
9435 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
9436 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
9437 break;
9439 case VKI_V4L2_SUBDEV_G_SELECTION: {
9440 struct vki_v4l2_subdev_selection *data =
9441 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9442 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
9443 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
9444 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
9445 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
9446 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
9447 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
9448 break;
9450 case VKI_V4L2_SUBDEV_S_SELECTION: {
9451 struct vki_v4l2_subdev_selection *data =
9452 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
9453 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
9454 break;
9456 case VKI_MEDIA_IOC_DEVICE_INFO: {
9457 struct vki_media_device_info *data =
9458 (struct vki_media_device_info *)(Addr)ARG3;
9459 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
9460 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
9461 (Addr)data, sizeof(*data) - sizeof(data->reserved));
9462 break;
9464 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
9465 struct vki_media_entity_desc *data =
9466 (struct vki_media_entity_desc *)(Addr)ARG3;
9467 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
9468 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
9469 (Addr)data->name, sizeof(*data) - sizeof(data->id));
9470 break;
9472 case VKI_MEDIA_IOC_ENUM_LINKS: {
9473 struct vki_media_links_enum *data =
9474 (struct vki_media_links_enum *)(Addr)ARG3;
9475 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
9476 break;
9478 case VKI_MEDIA_IOC_SETUP_LINK: {
9479 struct vki_media_link_desc *data =
9480 (struct vki_media_link_desc *)(Addr)ARG3;
9481 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
9482 break;
9485 /* Serial */
9486 case VKI_TIOCGSERIAL: {
9487 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9488 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
9489 break;
9491 case VKI_TIOCSSERIAL: {
9492 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
9493 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
9494 break;
9497 case VKI_PERF_EVENT_IOC_RESET:
9498 case VKI_PERF_EVENT_IOC_REFRESH:
9499 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
9500 case VKI_PERF_EVENT_IOC_SET_BPF:
9501 /* These take scalar arguments, so already handled above */
9502 break;
9504 case VKI_PERF_EVENT_IOC_PERIOD:
9505 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
9506 break;
9508 case VKI_PERF_EVENT_IOC_SET_FILTER:
9509 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
9510 break;
9512 case VKI_PERF_EVENT_IOC_ID:
9513 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
9514 break;
9516 /* Pulse Per Second (PPS) */
9517 case VKI_PPS_GETPARAMS: {
9518 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
9519 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
9520 break;
9522 case VKI_PPS_SETPARAMS: {
9523 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
9524 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
9525 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
9526 data->assert_off_tu.sec);
9527 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
9528 data->assert_off_tu.nsec);
9529 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
9530 data->clear_off_tu.sec);
9531 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
9532 data->clear_off_tu.nsec);
9533 break;
9535 case VKI_PPS_GETCAP:
9536 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
9537 break;
9538 case VKI_PPS_FETCH: {
9539 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
9540 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
9541 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
9542 break;
9544 case VKI_PPS_KC_BIND: {
9545 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
9546 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
9547 break;
9550 /* PTP Hardware Clock */
9551 case VKI_PTP_CLOCK_GETCAPS: {
9552 struct vki_ptp_clock_caps *data =
9553 (struct vki_ptp_clock_caps *)(Addr)ARG3;
9554 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
9555 break;
9557 case VKI_PTP_EXTTS_REQUEST: {
9558 struct vki_ptp_extts_request *data =
9559 (struct vki_ptp_extts_request *)(Addr)ARG3;
9560 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
9561 break;
9563 case VKI_PTP_PEROUT_REQUEST: {
9564 struct vki_ptp_perout_request *data =
9565 (struct vki_ptp_perout_request *)(Addr)ARG3;
9566 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
9567 break;
9569 case VKI_PTP_ENABLE_PPS:
9570 break;
9571 case VKI_PTP_SYS_OFFSET: {
9572 struct vki_ptp_sys_offset *data =
9573 (struct vki_ptp_sys_offset *)(Addr)ARG3;
9574 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
9575 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
9576 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
9577 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
9578 break;
9580 case VKI_PTP_PIN_GETFUNC: {
9581 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
9582 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
9583 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
9584 break;
9586 case VKI_PTP_PIN_SETFUNC: {
9587 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
9588 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
9589 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
9590 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
9591 break;
9593 case VKI_PTP_SYS_OFFSET_PRECISE: {
9594 struct vki_ptp_sys_offset_precise *data =
9595 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
9596 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
9597 break;
9599 case VKI_PTP_SYS_OFFSET_EXTENDED: {
9600 struct vki_ptp_sys_offset_extended *data =
9601 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
9602 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
9603 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
9604 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
9605 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
9606 3 * data->n_samples * sizeof(data->ts[0][0]));
9607 break;
9610 default:
9611 /* EVIOC* are variable length and return size written on success */
9612 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
9613 case VKI_EVIOCGNAME(0):
9614 case VKI_EVIOCGPHYS(0):
9615 case VKI_EVIOCGUNIQ(0):
9616 case VKI_EVIOCGKEY(0):
9617 case VKI_EVIOCGLED(0):
9618 case VKI_EVIOCGSND(0):
9619 case VKI_EVIOCGSW(0):
9620 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
9621 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
9622 case VKI_EVIOCGBIT(VKI_EV_REL,0):
9623 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
9624 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
9625 case VKI_EVIOCGBIT(VKI_EV_SW,0):
9626 case VKI_EVIOCGBIT(VKI_EV_LED,0):
9627 case VKI_EVIOCGBIT(VKI_EV_SND,0):
9628 case VKI_EVIOCGBIT(VKI_EV_REP,0):
9629 case VKI_EVIOCGBIT(VKI_EV_FF,0):
9630 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
9631 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
9632 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
9633 break;
9634 default:
9635 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
9636 break;
9638 break;
9642 POST(sys_ioctl)
9644 ARG2 = (UInt)ARG2;
9646 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
9648 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
9650 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9651 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
9652 VG_(clo_kernel_variant))) {
9654 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
9655 /* What's going on here: there appear to be a bunch of ioctls
9656 of the form 0xC01C67xx which are undocumented, and if
9657 unhandled give rise to a vast number of false positives in
9658 Memcheck.
9660 The "normal" interpretation of an ioctl of this form would
9661 be that the 3rd arg is a pointer to an area of size 0x1C
9662 (28 bytes) which is filled in by the kernel. Hence you
9663 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
9664 But it doesn't.
9666 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
9667 One interpretation of this is that ARG3 really does point
9668 to a 28 byte struct, but inside that are pointers to other
9669 areas also filled in by the kernel. If these happen to be
9670 allocated just back up the stack then the 256 byte paint
9671 might cover them too, somewhat indiscriminately.
9673 By printing out ARG3 and also the 28 bytes that it points
9674 at, it's possible to guess that the 7 word structure has
9675 this form
9677 0 1 2 3 4 5 6
9678 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
9680 Unfortunately that doesn't seem to work for some reason,
9681 so stay with the blunt-instrument approach for the time
9682 being.
9684 if (1) {
9685 /* blunt-instrument approach */
9686 POST_MEM_WRITE(ARG3, 256);
9687 } else {
9688 /* be a bit more sophisticated */
9689 POST_MEM_WRITE(ARG3, 28);
9690 UInt* word = (UInt*)(Addr)ARG3;
9691 if (word && word[2] && word[3] < 0x200/*stay sane*/)
9692 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
9693 if (word && word[4] && word[5] < 0x200/*stay sane*/)
9694 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
9696 goto post_sys_ioctl__out;
9699 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
9701 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
9702 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
9703 VG_(clo_kernel_variant))) {
9704 if (ARG2 == 0xC00C0902) {
9705 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
9706 goto post_sys_ioctl__out;
9709 /* END undocumented ioctls for Qualcomm Adreno 3xx */
9711 /* --- END special IOCTL handlers for specific Android hardware --- */
9713 /* --- normal handling --- */
9714 switch (ARG2 /* request */) {
9716 /* The Linux kernel "ion" memory allocator, used on Android. Note:
9717 this is pretty poor given that there's no pre-handling to check
9718 that writable areas are addressable. */
9719 case VKI_ION_IOC_ALLOC: {
9720 struct vki_ion_allocation_data* data
9721 = (struct vki_ion_allocation_data*)(Addr)ARG3;
9722 POST_FIELD_WRITE(data->handle);
9723 break;
9725 case VKI_ION_IOC_MAP: {
9726 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9727 POST_FIELD_WRITE(data->fd);
9728 break;
9730 case VKI_ION_IOC_FREE: // is this necessary?
9731 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
9732 break;
9733 case VKI_ION_IOC_SHARE:
9734 break;
9735 case VKI_ION_IOC_IMPORT: {
9736 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
9737 POST_FIELD_WRITE(data->handle);
9738 break;
9740 case VKI_ION_IOC_SYNC:
9741 break;
9742 case VKI_ION_IOC_CUSTOM: // is this necessary?
9743 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
9744 break;
9746 case VKI_SYNC_IOC_MERGE: {
9747 struct vki_sync_merge_data* data =
9748 (struct vki_sync_merge_data*)(Addr)ARG3;
9749 POST_FIELD_WRITE(data->fence);
9750 break;
9753 case VKI_TCSETS:
9754 case VKI_TCSETSW:
9755 case VKI_TCSETSF:
9756 case VKI_IB_USER_MAD_ENABLE_PKEY:
9757 break;
9758 case VKI_TCGETS:
9759 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
9760 break;
9761 case VKI_TCSETA:
9762 case VKI_TCSETAW:
9763 case VKI_TCSETAF:
9764 break;
9765 case VKI_TCGETA:
9766 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
9767 break;
9768 case VKI_TCSBRK:
9769 case VKI_TCXONC:
9770 case VKI_TCSBRKP:
9771 case VKI_TCFLSH:
9772 case VKI_TIOCSIG:
9773 break;
9774 case VKI_TIOCGWINSZ:
9775 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
9776 break;
9777 case VKI_TIOCSWINSZ:
9778 case VKI_TIOCMBIS:
9779 case VKI_TIOCMBIC:
9780 case VKI_TIOCMSET:
9781 break;
9782 case VKI_TIOCMGET:
9783 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
9784 break;
9785 case VKI_TIOCLINUX:
9786 POST_MEM_WRITE( ARG3, sizeof(char *) );
9787 break;
9788 case VKI_TIOCGPGRP:
9789 /* Get process group ID for foreground processing group. */
9790 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9791 break;
9792 case VKI_TIOCSPGRP:
9793 /* Set a process group ID? */
9794 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
9795 break;
9796 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
9797 POST_MEM_WRITE( ARG3, sizeof(int));
9798 break;
9799 case VKI_TIOCSCTTY:
9800 break;
9801 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
9802 break;
9803 case VKI_FIONBIO:
9804 break;
9805 case VKI_FIONCLEX:
9806 break;
9807 case VKI_FIOCLEX:
9808 break;
9809 case VKI_TIOCNOTTY:
9810 break;
9811 case VKI_FIOASYNC:
9812 break;
9813 case VKI_FIONREAD: /* identical to SIOCINQ */
9814 POST_MEM_WRITE( ARG3, sizeof(int) );
9815 break;
9816 case VKI_FIOQSIZE:
9817 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
9818 break;
9820 case VKI_TIOCSERGETLSR:
9821 POST_MEM_WRITE( ARG3, sizeof(int) );
9822 break;
9823 case VKI_TIOCGICOUNT:
9824 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
9825 break;
9827 case VKI_SG_SET_COMMAND_Q:
9828 break;
9829 case VKI_SG_IO:
9831 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
9832 if ( sgio->sbp ) {
9833 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
9835 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
9836 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
9837 int transferred = sgio->dxfer_len - sgio->resid;
9838 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
9841 break;
9842 case VKI_SG_GET_SCSI_ID:
9843 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
9844 break;
9845 case VKI_SG_SET_RESERVED_SIZE:
9846 break;
9847 case VKI_SG_SET_TIMEOUT:
9848 break;
9849 case VKI_SG_GET_RESERVED_SIZE:
9850 POST_MEM_WRITE(ARG3, sizeof(int));
9851 break;
9852 case VKI_SG_GET_TIMEOUT:
9853 break;
9854 case VKI_SG_GET_VERSION_NUM:
9855 POST_MEM_WRITE(ARG3, sizeof(int));
9856 break;
9857 case VKI_SG_EMULATED_HOST:
9858 POST_MEM_WRITE(ARG3, sizeof(int));
9859 break;
9860 case VKI_SG_GET_SG_TABLESIZE:
9861 POST_MEM_WRITE(ARG3, sizeof(int));
9862 break;
9864 case VKI_IIOCGETCPS:
9865 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
9866 break;
9867 case VKI_IIOCNETGPN:
9868 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
9869 break;
9871 /* These all use struct ifreq AFAIK */
9872 case VKI_SIOCGIFINDEX: /* get iface index */
9873 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
9874 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
9875 break;
9876 case VKI_SIOCGIFFLAGS: /* get flags */
9877 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
9878 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
9879 break;
9880 case VKI_SIOCGIFHWADDR: /* Get hardware address */
9881 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
9882 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
9883 break;
9884 case VKI_SIOCGIFMTU: /* get MTU size */
9885 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
9886 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
9887 break;
9888 case VKI_SIOCGIFADDR: /* get PA address */
9889 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
9890 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
9891 case VKI_SIOCGIFNETMASK: /* get network PA mask */
9892 POST_MEM_WRITE(
9893 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
9894 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
9895 break;
9896 case VKI_SIOCGIFMETRIC: /* get metric */
9897 POST_MEM_WRITE(
9898 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
9899 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
9900 break;
9901 case VKI_SIOCGIFMAP: /* Get device parameters */
9902 POST_MEM_WRITE(
9903 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
9904 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
9905 break;
9906 break;
9907 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
9908 POST_MEM_WRITE(
9909 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
9910 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
9911 break;
9912 case VKI_SIOCGIFNAME: /* get iface name */
9913 POST_MEM_WRITE(
9914 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
9915 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
9916 break;
9917 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
9918 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
9919 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
9920 case VKI_ETHTOOL_GSET:
9921 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
9922 break;
9923 case VKI_ETHTOOL_SSET:
9924 break;
9925 case VKI_ETHTOOL_GDRVINFO:
9926 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
9927 break;
9928 case VKI_ETHTOOL_GREGS:
9929 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
9930 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
9931 break;
9932 case VKI_ETHTOOL_GWOL:
9933 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
9934 break;
9935 case VKI_ETHTOOL_SWOL:
9936 break;
9937 case VKI_ETHTOOL_GMSGLVL:
9938 case VKI_ETHTOOL_GLINK:
9939 case VKI_ETHTOOL_GRXCSUM:
9940 case VKI_ETHTOOL_GSG:
9941 case VKI_ETHTOOL_GTSO:
9942 case VKI_ETHTOOL_GUFO:
9943 case VKI_ETHTOOL_GGSO:
9944 case VKI_ETHTOOL_GFLAGS:
9945 case VKI_ETHTOOL_GGRO:
9946 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
9947 break;
9948 case VKI_ETHTOOL_SMSGLVL:
9949 case VKI_ETHTOOL_SRXCSUM:
9950 case VKI_ETHTOOL_SSG:
9951 case VKI_ETHTOOL_STSO:
9952 case VKI_ETHTOOL_SUFO:
9953 case VKI_ETHTOOL_SGSO:
9954 case VKI_ETHTOOL_SFLAGS:
9955 case VKI_ETHTOOL_SGRO:
9956 break;
9957 case VKI_ETHTOOL_NWAY_RST:
9958 break;
9959 case VKI_ETHTOOL_GRINGPARAM:
9960 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
9961 break;
9962 case VKI_ETHTOOL_SRINGPARAM:
9963 break;
9964 case VKI_ETHTOOL_TEST:
9965 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
9966 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
9967 break;
9968 case VKI_ETHTOOL_PHYS_ID:
9969 break;
9970 case VKI_ETHTOOL_GPERMADDR:
9971 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
9972 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
9973 break;
9974 case VKI_ETHTOOL_RESET:
9975 break;
9976 case VKI_ETHTOOL_GSSET_INFO:
9977 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
9978 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
9979 break;
9980 case VKI_ETHTOOL_GFEATURES:
9981 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
9982 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
9983 break;
9984 case VKI_ETHTOOL_SFEATURES:
9985 break;
9986 case VKI_ETHTOOL_GCHANNELS:
9987 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
9988 break;
9989 case VKI_ETHTOOL_SCHANNELS:
9990 break;
9991 case VKI_ETHTOOL_GET_TS_INFO:
9992 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
9993 break;
9995 break;
9997 case VKI_SIOCGMIIPHY: /* get hardware entry */
9998 POST_MEM_WRITE(
9999 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10000 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10001 break;
10002 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10003 POST_MEM_WRITE(
10004 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10005 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10006 break;
10008 /* tun/tap related ioctls */
10009 case VKI_TUNSETIFF:
10010 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10011 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10012 break;
10013 case VKI_TUNGETFEATURES:
10014 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10015 break;
10016 case VKI_TUNGETIFF:
10017 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10018 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10019 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10020 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10021 break;
10022 case VKI_TUNGETSNDBUF:
10023 POST_MEM_WRITE( ARG3, sizeof(int) );
10024 break;
10025 case VKI_TUNGETVNETHDRSZ:
10026 POST_MEM_WRITE( ARG3, sizeof(int) );
10027 break;
10029 case VKI_SIOCGIFCONF: /* get iface list */
10030 /* WAS:
10031 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10032 KERNEL_DO_SYSCALL(tid,RES);
10033 if (!VG_(is_kerror)(RES) && RES == 0)
10034 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10036 if (RES == 0 && ARG3 ) {
10037 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10038 if (ifc->vki_ifc_buf != NULL)
10039 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10041 break;
10042 case VKI_SIOCGSTAMP:
10043 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10044 break;
10045 case VKI_SIOCGSTAMPNS:
10046 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10047 break;
10048 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10049 the number of bytes currently in that socket's send buffer.
10050 It writes this value as an int to the memory location
10051 indicated by the third argument of ioctl(2). */
10052 case VKI_SIOCOUTQ:
10053 POST_MEM_WRITE(ARG3, sizeof(int));
10054 break;
10055 case VKI_SIOCGRARP: /* get RARP table entry */
10056 case VKI_SIOCGARP: /* get ARP table entry */
10057 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10058 break;
10060 case VKI_SIOCSIFFLAGS: /* set flags */
10061 case VKI_SIOCSIFMAP: /* Set device parameters */
10062 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10063 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10064 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10065 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10066 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10067 case VKI_SIOCSIFMETRIC: /* set metric */
10068 case VKI_SIOCSIFADDR: /* set PA address */
10069 case VKI_SIOCSIFMTU: /* set MTU size */
10070 case VKI_SIOCSIFHWADDR: /* set hardware address */
10071 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10072 break;
10073 /* Routing table calls. */
10074 case VKI_SIOCADDRT: /* add routing table entry */
10075 case VKI_SIOCDELRT: /* delete routing table entry */
10076 break;
10078 /* RARP cache control calls. */
10079 case VKI_SIOCDRARP: /* delete RARP table entry */
10080 case VKI_SIOCSRARP: /* set RARP table entry */
10081 /* ARP cache control calls. */
10082 case VKI_SIOCSARP: /* set ARP table entry */
10083 case VKI_SIOCDARP: /* delete ARP table entry */
10084 break;
10086 case VKI_SIOCGPGRP:
10087 POST_MEM_WRITE(ARG3, sizeof(int));
10088 break;
10089 case VKI_SIOCSPGRP:
10090 break;
10092 case VKI_SIOCATMARK:
10093 POST_MEM_WRITE(ARG3, sizeof(int));
10094 break;
10096 /* linux/soundcard interface (OSS) */
10097 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10098 case VKI_SNDCTL_SEQ_GETINCOUNT:
10099 case VKI_SNDCTL_SEQ_PERCMODE:
10100 case VKI_SNDCTL_SEQ_TESTMIDI:
10101 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10102 case VKI_SNDCTL_SEQ_NRSYNTHS:
10103 case VKI_SNDCTL_SEQ_NRMIDIS:
10104 case VKI_SNDCTL_SEQ_GETTIME:
10105 case VKI_SNDCTL_DSP_GETBLKSIZE:
10106 case VKI_SNDCTL_DSP_GETFMTS:
10107 case VKI_SNDCTL_DSP_SETFMT:
10108 case VKI_SNDCTL_DSP_GETTRIGGER:
10109 case VKI_SNDCTL_DSP_GETODELAY:
10110 case VKI_SNDCTL_DSP_GETSPDIF:
10111 case VKI_SNDCTL_DSP_GETCAPS:
10112 case VKI_SOUND_PCM_READ_RATE:
10113 case VKI_SOUND_PCM_READ_CHANNELS:
10114 case VKI_SOUND_PCM_READ_BITS:
10115 case VKI_SOUND_PCM_READ_FILTER:
10116 POST_MEM_WRITE(ARG3, sizeof(int));
10117 break;
10118 case VKI_SNDCTL_SEQ_CTRLRATE:
10119 case VKI_SNDCTL_DSP_SPEED:
10120 case VKI_SNDCTL_DSP_STEREO:
10121 case VKI_SNDCTL_DSP_CHANNELS:
10122 case VKI_SOUND_PCM_WRITE_FILTER:
10123 case VKI_SNDCTL_DSP_SUBDIVIDE:
10124 case VKI_SNDCTL_DSP_SETFRAGMENT:
10125 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10126 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10127 case VKI_SNDCTL_TMR_TIMEBASE:
10128 case VKI_SNDCTL_TMR_TEMPO:
10129 case VKI_SNDCTL_TMR_SOURCE:
10130 case VKI_SNDCTL_MIDI_PRETIME:
10131 case VKI_SNDCTL_MIDI_MPUMODE:
10132 break;
10133 case VKI_SNDCTL_DSP_GETOSPACE:
10134 case VKI_SNDCTL_DSP_GETISPACE:
10135 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10136 break;
10137 case VKI_SNDCTL_DSP_NONBLOCK:
10138 break;
10139 case VKI_SNDCTL_DSP_SETTRIGGER:
10140 break;
10142 case VKI_SNDCTL_DSP_POST:
10143 case VKI_SNDCTL_DSP_RESET:
10144 case VKI_SNDCTL_DSP_SYNC:
10145 case VKI_SNDCTL_DSP_SETSYNCRO:
10146 case VKI_SNDCTL_DSP_SETDUPLEX:
10147 break;
10149 /* linux/soundcard interface (ALSA) */
10150 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10151 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10152 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10153 case VKI_SNDRV_PCM_IOCTL_RESET:
10154 case VKI_SNDRV_PCM_IOCTL_START:
10155 case VKI_SNDRV_PCM_IOCTL_DROP:
10156 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10157 case VKI_SNDRV_PCM_IOCTL_RESUME:
10158 case VKI_SNDRV_PCM_IOCTL_XRUN:
10159 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10160 case VKI_SNDRV_TIMER_IOCTL_START:
10161 case VKI_SNDRV_TIMER_IOCTL_STOP:
10162 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10163 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10164 break;
10166 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10167 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10168 break;
10170 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10171 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10172 break;
10173 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10174 struct vki_snd_ctl_elem_list *data =
10175 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10176 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10177 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10178 if (data->pids) {
10179 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10181 break;
10183 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10184 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10185 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10186 break;
10188 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10189 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10190 break;
10192 /* SCSI no operand */
10193 case VKI_SCSI_IOCTL_DOORLOCK:
10194 case VKI_SCSI_IOCTL_DOORUNLOCK:
10195 break;
10197 /* Real Time Clock (/dev/rtc) ioctls */
10198 case VKI_RTC_UIE_ON:
10199 case VKI_RTC_UIE_OFF:
10200 case VKI_RTC_AIE_ON:
10201 case VKI_RTC_AIE_OFF:
10202 case VKI_RTC_PIE_ON:
10203 case VKI_RTC_PIE_OFF:
10204 case VKI_RTC_IRQP_SET:
10205 break;
10206 case VKI_RTC_RD_TIME:
10207 case VKI_RTC_ALM_READ:
10208 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10209 break;
10210 case VKI_RTC_ALM_SET:
10211 break;
10212 case VKI_RTC_IRQP_READ:
10213 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10214 break;
10216 /* Block devices */
10217 case VKI_BLKROSET:
10218 break;
10219 case VKI_BLKROGET:
10220 POST_MEM_WRITE(ARG3, sizeof(int));
10221 break;
10222 case VKI_BLKGETSIZE:
10223 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10224 break;
10225 case VKI_BLKFLSBUF:
10226 break;
10227 case VKI_BLKRASET:
10228 break;
10229 case VKI_BLKRAGET:
10230 POST_MEM_WRITE(ARG3, sizeof(long));
10231 break;
10232 case VKI_BLKFRASET:
10233 break;
10234 case VKI_BLKFRAGET:
10235 POST_MEM_WRITE(ARG3, sizeof(long));
10236 break;
10237 case VKI_BLKSECTGET:
10238 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10239 break;
10240 case VKI_BLKSSZGET:
10241 POST_MEM_WRITE(ARG3, sizeof(int));
10242 break;
10243 case VKI_BLKBSZGET:
10244 POST_MEM_WRITE(ARG3, sizeof(int));
10245 break;
10246 case VKI_BLKBSZSET:
10247 break;
10248 case VKI_BLKGETSIZE64:
10249 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10250 break;
10251 case VKI_BLKPBSZGET:
10252 POST_MEM_WRITE(ARG3, sizeof(int));
10253 break;
10254 case VKI_BLKIOMIN:
10255 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10256 break;
10257 case VKI_BLKIOOPT:
10258 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10259 break;
10260 case VKI_BLKALIGNOFF:
10261 POST_MEM_WRITE(ARG3, sizeof(int));
10262 break;
10263 case VKI_BLKDISCARDZEROES:
10264 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10265 break;
10266 case VKI_BLKREPORTZONE: {
10267 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10269 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10270 break;
10272 case VKI_BLKRESETZONE:
10273 break;
10275 /* Hard disks */
10276 case VKI_HDIO_GETGEO: /* 0x0301 */
10277 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10278 break;
10279 case VKI_HDIO_GET_DMA: /* 0x030b */
10280 POST_MEM_WRITE(ARG3, sizeof(long));
10281 break;
10282 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10283 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10284 break;
10286 /* SCSI */
10287 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10288 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10289 break;
10290 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10291 POST_MEM_WRITE(ARG3, sizeof(int));
10292 break;
10294 /* CD ROM stuff (??) */
10295 case VKI_CDROM_DISC_STATUS:
10296 case VKI_CDROMSTOP:
10297 break;
10298 case VKI_CDROMSUBCHNL:
10299 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10300 break;
10301 case VKI_CDROMREADTOCHDR:
10302 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10303 break;
10304 case VKI_CDROMREADTOCENTRY:
10305 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10306 break;
10307 case VKI_CDROMMULTISESSION:
10308 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10309 break;
10310 case VKI_CDROMVOLREAD:
10311 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10312 break;
10313 case VKI_CDROMREADMODE1:
10314 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10315 break;
10316 case VKI_CDROMREADMODE2:
10317 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10318 break;
10319 case VKI_CDROMREADRAW:
10320 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10321 break;
10322 case VKI_CDROMREADAUDIO:
10324 struct vki_cdrom_read_audio *cra =
10325 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10326 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10327 break;
10330 case VKI_CDROMPLAYMSF:
10331 break;
10332 /* The following two are probably bogus (should check args
10333 for readability). JRS 20021117 */
10334 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10335 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10336 break;
10337 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10338 break;
10340 /* DVD stuff */
10341 case VKI_DVD_READ_STRUCT:
10342 break;
10344 case VKI_FIGETBSZ:
10345 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10346 break;
10347 case VKI_FIBMAP:
10348 POST_MEM_WRITE(ARG3, sizeof(int));
10349 break;
10351 case VKI_FBIOGET_VSCREENINFO: //0x4600
10352 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10353 break;
10354 case VKI_FBIOGET_FSCREENINFO: //0x4602
10355 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10356 break;
10358 case VKI_PPCLAIM:
10359 case VKI_PPEXCL:
10360 case VKI_PPYIELD:
10361 case VKI_PPRELEASE:
10362 case VKI_PPSETMODE:
10363 case VKI_PPSETPHASE:
10364 case VKI_PPSETFLAGS:
10365 case VKI_PPWDATA:
10366 case VKI_PPWCONTROL:
10367 case VKI_PPFCONTROL:
10368 case VKI_PPDATADIR:
10369 case VKI_PPNEGOT:
10370 case VKI_PPWCTLONIRQ:
10371 case VKI_PPSETTIME:
10372 break;
10373 case VKI_PPGETMODE:
10374 POST_MEM_WRITE( ARG3, sizeof(int) );
10375 break;
10376 case VKI_PPGETPHASE:
10377 POST_MEM_WRITE( ARG3, sizeof(int) );
10378 break;
10379 case VKI_PPGETMODES:
10380 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10381 break;
10382 case VKI_PPGETFLAGS:
10383 POST_MEM_WRITE( ARG3, sizeof(int) );
10384 break;
10385 case VKI_PPRSTATUS:
10386 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10387 break;
10388 case VKI_PPRDATA:
10389 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10390 break;
10391 case VKI_PPRCONTROL:
10392 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10393 break;
10394 case VKI_PPCLRIRQ:
10395 POST_MEM_WRITE( ARG3, sizeof(int) );
10396 break;
10397 case VKI_PPGETTIME:
10398 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10399 break;
10401 case VKI_GIO_FONT:
10402 POST_MEM_WRITE( ARG3, 32 * 256 );
10403 break;
10404 case VKI_PIO_FONT:
10405 break;
10407 case VKI_GIO_FONTX:
10408 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10409 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10410 break;
10411 case VKI_PIO_FONTX:
10412 break;
10414 case VKI_PIO_FONTRESET:
10415 break;
10417 case VKI_GIO_CMAP:
10418 POST_MEM_WRITE( ARG3, 16 * 3 );
10419 break;
10420 case VKI_PIO_CMAP:
10421 break;
10423 case VKI_KIOCSOUND:
10424 case VKI_KDMKTONE:
10425 break;
10427 case VKI_KDGETLED:
10428 POST_MEM_WRITE( ARG3, sizeof(char) );
10429 break;
10430 case VKI_KDSETLED:
10431 break;
10433 case VKI_KDGKBTYPE:
10434 POST_MEM_WRITE( ARG3, sizeof(char) );
10435 break;
10437 case VKI_KDADDIO:
10438 case VKI_KDDELIO:
10439 case VKI_KDENABIO:
10440 case VKI_KDDISABIO:
10441 break;
10443 case VKI_KDSETMODE:
10444 break;
10445 case VKI_KDGETMODE:
10446 POST_MEM_WRITE( ARG3, sizeof(int) );
10447 break;
10449 case VKI_KDMAPDISP:
10450 case VKI_KDUNMAPDISP:
10451 break;
10453 case VKI_GIO_SCRNMAP:
10454 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
10455 break;
10456 case VKI_PIO_SCRNMAP:
10457 break;
10458 case VKI_GIO_UNISCRNMAP:
10459 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
10460 break;
10461 case VKI_PIO_UNISCRNMAP:
10462 break;
10464 case VKI_GIO_UNIMAP:
10465 if ( ARG3 ) {
10466 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
10467 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
10468 POST_MEM_WRITE( (Addr)desc->entries,
10469 desc->entry_ct * sizeof(struct vki_unipair) );
10471 break;
10472 case VKI_PIO_UNIMAP:
10473 break;
10474 case VKI_PIO_UNIMAPCLR:
10475 break;
10477 case VKI_KDGKBMODE:
10478 POST_MEM_WRITE( ARG3, sizeof(int) );
10479 break;
10480 case VKI_KDSKBMODE:
10481 break;
10483 case VKI_KDGKBMETA:
10484 POST_MEM_WRITE( ARG3, sizeof(int) );
10485 break;
10486 case VKI_KDSKBMETA:
10487 break;
10489 case VKI_KDGKBLED:
10490 POST_MEM_WRITE( ARG3, sizeof(char) );
10491 break;
10492 case VKI_KDSKBLED:
10493 break;
10495 case VKI_KDGKBENT:
10496 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
10497 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
10498 break;
10499 case VKI_KDSKBENT:
10500 break;
10502 case VKI_KDGKBSENT:
10503 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
10504 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
10505 break;
10506 case VKI_KDSKBSENT:
10507 break;
10509 case VKI_KDGKBDIACR:
10510 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
10511 break;
10512 case VKI_KDSKBDIACR:
10513 break;
10515 case VKI_KDGETKEYCODE:
10516 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
10517 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
10518 break;
10519 case VKI_KDSETKEYCODE:
10520 break;
10522 case VKI_KDSIGACCEPT:
10523 break;
10525 case VKI_KDKBDREP:
10526 break;
10528 case VKI_KDFONTOP:
10529 if ( ARG3 ) {
10530 struct vki_console_font_op *op =
10531 (struct vki_console_font_op *) (Addr)ARG3;
10532 switch ( op->op ) {
10533 case VKI_KD_FONT_OP_SET:
10534 break;
10535 case VKI_KD_FONT_OP_GET:
10536 if ( op->data )
10537 POST_MEM_WRITE( (Addr) op->data,
10538 (op->width + 7) / 8 * 32 * op->charcount );
10539 break;
10540 case VKI_KD_FONT_OP_SET_DEFAULT:
10541 break;
10542 case VKI_KD_FONT_OP_COPY:
10543 break;
10545 POST_MEM_WRITE( (Addr) op, sizeof(*op));
10547 break;
10549 case VKI_VT_OPENQRY:
10550 POST_MEM_WRITE( ARG3, sizeof(int) );
10551 break;
10552 case VKI_VT_GETMODE:
10553 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
10554 break;
10555 case VKI_VT_SETMODE:
10556 break;
10557 case VKI_VT_GETSTATE:
10558 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
10559 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
10560 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
10561 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
10562 break;
10563 case VKI_VT_RELDISP:
10564 case VKI_VT_ACTIVATE:
10565 case VKI_VT_WAITACTIVE:
10566 case VKI_VT_DISALLOCATE:
10567 break;
10568 case VKI_VT_RESIZE:
10569 break;
10570 case VKI_VT_RESIZEX:
10571 break;
10572 case VKI_VT_LOCKSWITCH:
10573 case VKI_VT_UNLOCKSWITCH:
10574 break;
10576 case VKI_USBDEVFS_CONTROL:
10577 if ( ARG3 ) {
10578 struct vki_usbdevfs_ctrltransfer *vkuc =
10579 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
10580 if (vkuc->bRequestType & 0x80)
10581 POST_MEM_WRITE((Addr)vkuc->data, RES);
10583 break;
10584 case VKI_USBDEVFS_BULK:
10585 if ( ARG3 ) {
10586 struct vki_usbdevfs_bulktransfer *vkub =
10587 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
10588 if (vkub->ep & 0x80)
10589 POST_MEM_WRITE((Addr)vkub->data, RES);
10591 break;
10592 case VKI_USBDEVFS_GETDRIVER:
10593 if ( ARG3 ) {
10594 struct vki_usbdevfs_getdriver *vkugd =
10595 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
10596 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
10598 break;
10599 case VKI_USBDEVFS_REAPURB:
10600 case VKI_USBDEVFS_REAPURBNDELAY:
10601 if ( ARG3 ) {
10602 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
10603 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
10604 if (!*vkuu)
10605 break;
10606 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
10607 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
10608 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
10609 if (vkusp->bRequestType & 0x80)
10610 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
10611 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10612 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
10613 char *bp = (*vkuu)->buffer;
10614 int i;
10615 for(i=0; i<(*vkuu)->number_of_packets; i++) {
10616 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
10617 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
10618 if ((*vkuu)->endpoint & 0x80)
10619 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
10620 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
10622 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
10623 } else {
10624 if ((*vkuu)->endpoint & 0x80)
10625 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
10626 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
10629 break;
10630 case VKI_USBDEVFS_CONNECTINFO:
10631 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
10632 break;
10633 case VKI_USBDEVFS_IOCTL:
10634 if ( ARG3 ) {
10635 struct vki_usbdevfs_ioctl *vkui =
10636 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
10637 UInt dir2, size2;
10638 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
10639 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
10640 if (size2 > 0) {
10641 if (dir2 & _VKI_IOC_READ)
10642 POST_MEM_WRITE((Addr)vkui->data, size2);
10645 break;
10647 /* I2C (/dev/i2c-*) ioctls */
10648 case VKI_I2C_SLAVE:
10649 case VKI_I2C_SLAVE_FORCE:
10650 case VKI_I2C_TENBIT:
10651 case VKI_I2C_PEC:
10652 break;
10653 case VKI_I2C_FUNCS:
10654 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
10655 break;
10656 case VKI_I2C_RDWR:
10657 if ( ARG3 ) {
10658 struct vki_i2c_rdwr_ioctl_data *vkui =
10659 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
10660 UInt i;
10661 for (i=0; i < vkui->nmsgs; i++) {
10662 struct vki_i2c_msg *msg = vkui->msgs + i;
10663 if (msg->flags & VKI_I2C_M_RD)
10664 POST_MEM_WRITE((Addr)msg->buf, msg->len);
10667 break;
10668 case VKI_I2C_SMBUS:
10669 if ( ARG3 ) {
10670 struct vki_i2c_smbus_ioctl_data *vkis
10671 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
10672 /* i2c_smbus_write_quick hides its value in read_write, so
10673 this variable can have a different meaning */
10674 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
10675 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
10676 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
10677 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
10678 UInt size;
10679 switch(vkis->size) {
10680 case VKI_I2C_SMBUS_BYTE:
10681 case VKI_I2C_SMBUS_BYTE_DATA:
10682 size = 1;
10683 break;
10684 case VKI_I2C_SMBUS_WORD_DATA:
10685 case VKI_I2C_SMBUS_PROC_CALL:
10686 size = 2;
10687 break;
10688 case VKI_I2C_SMBUS_BLOCK_DATA:
10689 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
10690 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
10691 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
10692 size = 1 + vkis->data->block[0];
10693 break;
10694 default:
10695 size = 0;
10697 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
10701 break;
10703 /* Wireless extensions ioctls */
10704 case VKI_SIOCSIWCOMMIT:
10705 case VKI_SIOCSIWNWID:
10706 case VKI_SIOCSIWFREQ:
10707 case VKI_SIOCSIWMODE:
10708 case VKI_SIOCSIWSENS:
10709 case VKI_SIOCSIWRANGE:
10710 case VKI_SIOCSIWPRIV:
10711 case VKI_SIOCSIWSTATS:
10712 case VKI_SIOCSIWSPY:
10713 case VKI_SIOCSIWTHRSPY:
10714 case VKI_SIOCSIWAP:
10715 case VKI_SIOCSIWSCAN:
10716 case VKI_SIOCSIWESSID:
10717 case VKI_SIOCSIWRATE:
10718 case VKI_SIOCSIWNICKN:
10719 case VKI_SIOCSIWRTS:
10720 case VKI_SIOCSIWFRAG:
10721 case VKI_SIOCSIWTXPOW:
10722 case VKI_SIOCSIWRETRY:
10723 case VKI_SIOCSIWENCODE:
10724 case VKI_SIOCSIWPOWER:
10725 case VKI_SIOCSIWGENIE:
10726 case VKI_SIOCSIWMLME:
10727 case VKI_SIOCSIWAUTH:
10728 case VKI_SIOCSIWENCODEEXT:
10729 case VKI_SIOCSIWPMKSA:
10730 break;
10731 case VKI_SIOCGIWNAME:
10732 if (ARG3) {
10733 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
10734 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
10736 break;
10737 case VKI_SIOCGIWNWID:
10738 case VKI_SIOCGIWSENS:
10739 case VKI_SIOCGIWRATE:
10740 case VKI_SIOCGIWRTS:
10741 case VKI_SIOCGIWFRAG:
10742 case VKI_SIOCGIWTXPOW:
10743 case VKI_SIOCGIWRETRY:
10744 case VKI_SIOCGIWPOWER:
10745 case VKI_SIOCGIWAUTH:
10746 if (ARG3) {
10747 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
10748 sizeof(struct vki_iw_param));
10750 break;
10751 case VKI_SIOCGIWFREQ:
10752 if (ARG3) {
10753 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
10754 sizeof(struct vki_iw_freq));
10756 break;
10757 case VKI_SIOCGIWMODE:
10758 if (ARG3) {
10759 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
10760 sizeof(__vki_u32));
10762 break;
10763 case VKI_SIOCGIWRANGE:
10764 case VKI_SIOCGIWPRIV:
10765 case VKI_SIOCGIWSTATS:
10766 case VKI_SIOCGIWSPY:
10767 case VKI_SIOCGIWTHRSPY:
10768 case VKI_SIOCGIWAPLIST:
10769 case VKI_SIOCGIWSCAN:
10770 case VKI_SIOCGIWESSID:
10771 case VKI_SIOCGIWNICKN:
10772 case VKI_SIOCGIWENCODE:
10773 case VKI_SIOCGIWGENIE:
10774 case VKI_SIOCGIWENCODEEXT:
10775 if (ARG3) {
10776 struct vki_iw_point* point;
10777 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
10778 POST_MEM_WRITE((Addr)point->pointer, point->length);
10780 break;
10781 case VKI_SIOCGIWAP:
10782 if (ARG3) {
10783 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
10784 sizeof(struct vki_sockaddr));
10786 break;
10788 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
10789 || defined(VGPV_mips32_linux_android) \
10790 || defined(VGPV_arm64_linux_android)
10791 /* ashmem */
10792 case VKI_ASHMEM_GET_SIZE:
10793 case VKI_ASHMEM_SET_SIZE:
10794 case VKI_ASHMEM_GET_PROT_MASK:
10795 case VKI_ASHMEM_SET_PROT_MASK:
10796 case VKI_ASHMEM_GET_PIN_STATUS:
10797 case VKI_ASHMEM_PURGE_ALL_CACHES:
10798 case VKI_ASHMEM_SET_NAME:
10799 case VKI_ASHMEM_PIN:
10800 case VKI_ASHMEM_UNPIN:
10801 break;
10802 case VKI_ASHMEM_GET_NAME:
10803 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
10804 break;
10806 /* binder */
10807 case VKI_BINDER_WRITE_READ:
10808 if (ARG3) {
10809 struct vki_binder_write_read* bwr
10810 = (struct vki_binder_write_read*)(Addr)ARG3;
10811 POST_FIELD_WRITE(bwr->write_consumed);
10812 POST_FIELD_WRITE(bwr->read_consumed);
10814 if (bwr->read_size)
10815 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
10817 break;
10819 case VKI_BINDER_SET_IDLE_TIMEOUT:
10820 case VKI_BINDER_SET_MAX_THREADS:
10821 case VKI_BINDER_SET_IDLE_PRIORITY:
10822 case VKI_BINDER_SET_CONTEXT_MGR:
10823 case VKI_BINDER_THREAD_EXIT:
10824 break;
10825 case VKI_BINDER_VERSION:
10826 if (ARG3) {
10827 struct vki_binder_version* bv =
10828 (struct vki_binder_version*)(Addr)ARG3;
10829 POST_FIELD_WRITE(bv->protocol_version);
10831 break;
10832 # endif /* defined(VGPV_*_linux_android) */
10834 case VKI_HCIGETDEVLIST:
10835 if (ARG3) {
10836 struct vki_hci_dev_list_req* dlr =
10837 (struct vki_hci_dev_list_req*)(Addr)ARG3;
10838 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
10839 dlr->dev_num * sizeof(struct vki_hci_dev_req));
10841 break;
10843 case VKI_HCIINQUIRY:
10844 if (ARG3) {
10845 struct vki_hci_inquiry_req* ir =
10846 (struct vki_hci_inquiry_req*)(Addr)ARG3;
10847 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
10848 ir->num_rsp * sizeof(struct vki_inquiry_info));
10850 break;
10852 case VKI_DRM_IOCTL_VERSION:
10853 if (ARG3) {
10854 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
10855 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
10856 const vki_size_t orig_name_len = info->orig->name_len;
10857 const vki_size_t orig_date_len = info->orig->date_len;
10858 const vki_size_t orig_desc_len = info->orig->desc_len;
10859 *info->orig = info->data;
10860 ARG3 = (Addr)info->orig;
10861 data = info->orig;
10862 VG_(free)(info);
10863 if (SUCCESS) {
10864 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
10865 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
10866 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
10867 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
10868 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
10869 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
10870 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
10871 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
10872 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
10875 break;
10876 case VKI_DRM_IOCTL_GET_UNIQUE:
10877 if (ARG3) {
10878 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
10879 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
10881 break;
10882 case VKI_DRM_IOCTL_GET_MAGIC:
10883 if (ARG3) {
10884 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
10885 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
10887 break;
10888 case VKI_DRM_IOCTL_WAIT_VBLANK:
10889 if (ARG3) {
10890 union vki_drm_wait_vblank *data =
10891 (union vki_drm_wait_vblank *)(Addr)ARG3;
10892 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
10894 break;
10895 case VKI_DRM_IOCTL_GEM_FLINK:
10896 if (ARG3) {
10897 struct vki_drm_gem_flink *data =
10898 (struct vki_drm_gem_flink *)(Addr)ARG3;
10899 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
10901 break;
10902 case VKI_DRM_IOCTL_GEM_OPEN:
10903 if (ARG3) {
10904 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
10905 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10906 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
10908 break;
10909 case VKI_DRM_IOCTL_I915_GETPARAM:
10910 if (ARG3) {
10911 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
10912 POST_MEM_WRITE((Addr)data->value, sizeof(int));
10914 break;
10915 case VKI_DRM_IOCTL_I915_GEM_BUSY:
10916 if (ARG3) {
10917 struct vki_drm_i915_gem_busy *data =
10918 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
10919 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
10921 break;
10922 case VKI_DRM_IOCTL_I915_GEM_CREATE:
10923 if (ARG3) {
10924 struct vki_drm_i915_gem_create *data =
10925 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
10926 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
10928 break;
10929 case VKI_DRM_IOCTL_I915_GEM_PREAD:
10930 if (ARG3) {
10931 struct vki_drm_i915_gem_pread *data =
10932 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
10933 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
10935 break;
10936 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
10937 if (ARG3) {
10938 struct vki_drm_i915_gem_mmap_v1 *data =
10939 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
10940 Addr addr = data->addr_ptr;
10941 SizeT size = data->size;
10942 vg_assert(ML_(valid_client_addr)(addr, size, tid,
10943 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
10944 ML_(notify_core_and_tool_of_mmap)(addr, size,
10945 VKI_PROT_READ | VKI_PROT_WRITE,
10946 VKI_MAP_ANONYMOUS, -1, 0 );
10947 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
10949 break;
10950 case VKI_DRM_IOCTL_I915_GEM_MMAP:
10951 if (ARG3) {
10952 struct vki_drm_i915_gem_mmap *data =
10953 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
10954 Addr addr = data->addr_ptr;
10955 SizeT size = data->size;
10956 vg_assert(ML_(valid_client_addr)(addr, size, tid,
10957 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
10958 ML_(notify_core_and_tool_of_mmap)(addr, size,
10959 VKI_PROT_READ | VKI_PROT_WRITE,
10960 VKI_MAP_ANONYMOUS, -1, 0 );
10961 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
10963 break;
10964 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
10965 if (ARG3) {
10966 struct vki_drm_i915_gem_mmap_gtt *data =
10967 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
10968 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
10970 break;
10971 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
10972 if (ARG3) {
10973 struct vki_drm_i915_gem_set_tiling *data =
10974 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
10975 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10976 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
10977 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10979 break;
10980 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
10981 if (ARG3) {
10982 struct vki_drm_i915_gem_get_tiling *data =
10983 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
10984 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
10985 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
10987 break;
10988 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
10989 if (ARG3) {
10990 struct vki_drm_i915_gem_get_aperture *data =
10991 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
10992 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
10993 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
10995 break;
10997 /* KVM ioctls that only write the system call return value */
10998 case VKI_KVM_GET_API_VERSION:
10999 case VKI_KVM_CREATE_VM:
11000 case VKI_KVM_CHECK_EXTENSION:
11001 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11002 case VKI_KVM_S390_ENABLE_SIE:
11003 case VKI_KVM_CREATE_VCPU:
11004 case VKI_KVM_SET_TSS_ADDR:
11005 case VKI_KVM_CREATE_IRQCHIP:
11006 case VKI_KVM_RUN:
11007 case VKI_KVM_S390_INITIAL_RESET:
11008 case VKI_KVM_KVMCLOCK_CTRL:
11009 break;
11011 case VKI_KVM_S390_MEM_OP: {
11012 struct vki_kvm_s390_mem_op *args =
11013 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11014 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11015 break;
11016 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11017 POST_MEM_WRITE((Addr)args->buf, args->size);
11019 break;
11021 #ifdef ENABLE_XEN
11022 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11023 SyscallArgs harrghs;
11024 struct vki_xen_privcmd_hypercall *args =
11025 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11027 if (!args)
11028 break;
11030 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11031 harrghs.sysno = args->op;
11032 harrghs.arg1 = args->arg[0];
11033 harrghs.arg2 = args->arg[1];
11034 harrghs.arg3 = args->arg[2];
11035 harrghs.arg4 = args->arg[3];
11036 harrghs.arg5 = args->arg[4];
11037 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11039 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11041 break;
11043 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11044 break;
11045 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11046 struct vki_xen_privcmd_mmapbatch *args =
11047 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11048 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11050 break;
11051 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11052 struct vki_xen_privcmd_mmapbatch_v2 *args =
11053 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11054 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11056 break;
11058 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11059 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11060 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11061 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11062 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11063 case VKI_XEN_IOCTL_EVTCHN_RESET:
11064 /* No output */
11065 break;
11066 #endif
11068 /* Lustre */
11069 case VKI_OBD_IOC_FID2PATH: {
11070 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11071 POST_FIELD_WRITE(args->gf_recno);
11072 POST_FIELD_WRITE(args->gf_linkno);
11073 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11074 break;
11077 case VKI_LL_IOC_PATH2FID:
11078 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11079 break;
11081 case VKI_LL_IOC_GETPARENT: {
11082 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11083 POST_FIELD_WRITE(gp->gp_fid);
11084 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11085 break;
11088 /* V4L2 */
11089 case VKI_V4L2_S_FMT:
11090 case VKI_V4L2_TRY_FMT:
11091 case VKI_V4L2_REQBUFS:
11092 case VKI_V4L2_OVERLAY:
11093 case VKI_V4L2_STREAMON:
11094 case VKI_V4L2_STREAMOFF:
11095 case VKI_V4L2_S_PARM:
11096 case VKI_V4L2_S_STD:
11097 case VKI_V4L2_S_FREQUENCY:
11098 case VKI_V4L2_S_CTRL:
11099 case VKI_V4L2_S_TUNER:
11100 case VKI_V4L2_S_AUDIO:
11101 case VKI_V4L2_S_INPUT:
11102 case VKI_V4L2_S_EDID:
11103 case VKI_V4L2_S_OUTPUT:
11104 case VKI_V4L2_S_AUDOUT:
11105 case VKI_V4L2_S_MODULATOR:
11106 case VKI_V4L2_S_JPEGCOMP:
11107 case VKI_V4L2_S_CROP:
11108 case VKI_V4L2_S_PRIORITY:
11109 case VKI_V4L2_S_HW_FREQ_SEEK:
11110 case VKI_V4L2_S_DV_TIMINGS:
11111 case VKI_V4L2_SUBSCRIBE_EVENT:
11112 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11113 case VKI_V4L2_PREPARE_BUF:
11114 break;
11115 case VKI_V4L2_QUERYCAP: {
11116 struct vki_v4l2_capability *data =
11117 (struct vki_v4l2_capability *)(Addr)ARG3;
11118 POST_MEM_WRITE((Addr)data, sizeof(*data));
11119 break;
11121 case VKI_V4L2_ENUM_FMT: {
11122 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11123 POST_FIELD_WRITE(data->flags);
11124 POST_FIELD_WRITE(data->description);
11125 POST_FIELD_WRITE(data->pixelformat);
11126 POST_FIELD_WRITE(data->reserved);
11127 break;
11129 case VKI_V4L2_G_FMT: {
11130 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11131 switch (data->type) {
11132 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11133 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11134 POST_FIELD_WRITE(data->fmt.pix);
11135 break;
11136 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11137 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11138 POST_FIELD_WRITE(data->fmt.vbi);
11139 break;
11140 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11141 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11142 POST_FIELD_WRITE(data->fmt.sliced);
11143 break;
11144 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11145 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11146 POST_FIELD_WRITE(data->fmt.win);
11147 break;
11148 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11149 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11150 POST_FIELD_WRITE(data->fmt.pix_mp);
11151 break;
11152 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11153 POST_FIELD_WRITE(data->fmt.sdr);
11154 break;
11156 break;
11158 case VKI_V4L2_QUERYBUF: {
11159 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11160 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11161 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11162 unsigned i;
11164 for (i = 0; i < data->length; i++) {
11165 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11166 POST_FIELD_WRITE(data->m.planes[i].length);
11167 POST_FIELD_WRITE(data->m.planes[i].m);
11168 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11169 POST_FIELD_WRITE(data->m.planes[i].reserved);
11171 } else {
11172 POST_FIELD_WRITE(data->m);
11173 POST_FIELD_WRITE(data->length);
11175 POST_FIELD_WRITE(data->bytesused);
11176 POST_FIELD_WRITE(data->flags);
11177 POST_FIELD_WRITE(data->field);
11178 POST_FIELD_WRITE(data->timestamp);
11179 POST_FIELD_WRITE(data->timecode);
11180 POST_FIELD_WRITE(data->sequence);
11181 POST_FIELD_WRITE(data->memory);
11182 POST_FIELD_WRITE(data->sequence);
11183 break;
11185 case VKI_V4L2_G_FBUF: {
11186 struct vki_v4l2_framebuffer *data =
11187 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11188 POST_MEM_WRITE((Addr)data, sizeof(*data));
11189 break;
11191 case VKI_V4L2_S_FBUF: {
11192 struct vki_v4l2_framebuffer *data =
11193 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11194 POST_FIELD_WRITE(data->capability);
11195 POST_FIELD_WRITE(data->flags);
11196 POST_FIELD_WRITE(data->fmt);
11197 break;
11199 case VKI_V4L2_QBUF: {
11200 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11202 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11203 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11204 unsigned i;
11206 for (i = 0; i < data->length; i++) {
11207 POST_FIELD_WRITE(data->m.planes[i].length);
11208 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11209 POST_FIELD_WRITE(data->m.planes[i].m);
11211 } else {
11212 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11213 POST_FIELD_WRITE(data->m);
11214 POST_FIELD_WRITE(data->length);
11216 break;
11218 case VKI_V4L2_EXPBUF: {
11219 struct vki_v4l2_exportbuffer *data =
11220 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11221 POST_FIELD_WRITE(data->fd);
11222 break;
11224 case VKI_V4L2_DQBUF: {
11225 struct vki_v4l2_buffer *data =
11226 (struct vki_v4l2_buffer *)(Addr)ARG3;
11227 POST_FIELD_WRITE(data->index);
11228 POST_FIELD_WRITE(data->bytesused);
11229 POST_FIELD_WRITE(data->field);
11230 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11231 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11232 unsigned i;
11234 for (i = 0; i < data->length; i++) {
11235 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11236 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11237 POST_FIELD_WRITE(data->m.planes[i].length);
11238 POST_FIELD_WRITE(data->m.planes[i].m);
11240 } else {
11241 POST_FIELD_WRITE(data->m);
11242 POST_FIELD_WRITE(data->length);
11243 POST_FIELD_WRITE(data->bytesused);
11244 POST_FIELD_WRITE(data->field);
11246 POST_FIELD_WRITE(data->timestamp);
11247 POST_FIELD_WRITE(data->timecode);
11248 POST_FIELD_WRITE(data->sequence);
11249 break;
11251 case VKI_V4L2_G_PARM: {
11252 struct vki_v4l2_streamparm *data =
11253 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11254 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11255 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11256 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11257 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11259 if (is_output)
11260 POST_MEM_WRITE((Addr)&data->parm.output,
11261 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11262 else
11263 POST_MEM_WRITE((Addr)&data->parm.capture,
11264 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11265 break;
11267 case VKI_V4L2_G_STD: {
11268 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11269 POST_MEM_WRITE((Addr)data, sizeof(*data));
11270 break;
11272 case VKI_V4L2_ENUMSTD: {
11273 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11274 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11275 break;
11277 case VKI_V4L2_ENUMINPUT: {
11278 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11279 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11280 break;
11282 case VKI_V4L2_G_CTRL: {
11283 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11284 POST_FIELD_WRITE(data->value);
11285 break;
11287 case VKI_V4L2_G_TUNER: {
11288 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11289 POST_MEM_WRITE((Addr)data->name,
11290 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11291 break;
11293 case VKI_V4L2_G_AUDIO: {
11294 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11295 POST_MEM_WRITE((Addr)data,
11296 sizeof(*data) - sizeof(data->reserved));
11297 break;
11299 case VKI_V4L2_QUERYCTRL: {
11300 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11301 POST_MEM_WRITE((Addr)&data->type,
11302 sizeof(*data) - sizeof(data->id));
11303 break;
11305 case VKI_V4L2_QUERYMENU: {
11306 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11307 POST_MEM_WRITE((Addr)data->name,
11308 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11309 break;
11311 case VKI_V4L2_G_INPUT: {
11312 int *data = (int *)(Addr)ARG3;
11313 POST_MEM_WRITE((Addr)data, sizeof(*data));
11314 break;
11316 case VKI_V4L2_G_EDID: {
11317 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11318 if (data->blocks && data->edid)
11319 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11320 break;
11322 case VKI_V4L2_G_OUTPUT: {
11323 int *data = (int *)(Addr)ARG3;
11324 POST_MEM_WRITE((Addr)data, sizeof(*data));
11325 break;
11327 case VKI_V4L2_ENUMOUTPUT: {
11328 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11329 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11330 break;
11332 case VKI_V4L2_G_AUDOUT: {
11333 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11334 POST_MEM_WRITE((Addr)data,
11335 sizeof(*data) - sizeof(data->reserved));
11336 break;
11338 case VKI_V4L2_G_MODULATOR: {
11339 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11340 POST_MEM_WRITE((Addr)data->name,
11341 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11342 break;
11344 case VKI_V4L2_G_FREQUENCY: {
11345 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11346 POST_FIELD_WRITE(data->type);
11347 POST_FIELD_WRITE(data->frequency);
11348 break;
11350 case VKI_V4L2_CROPCAP: {
11351 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11352 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11353 break;
11355 case VKI_V4L2_G_CROP: {
11356 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11357 POST_FIELD_WRITE(data->c);
11358 break;
11360 case VKI_V4L2_G_JPEGCOMP: {
11361 struct vki_v4l2_jpegcompression *data =
11362 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11363 POST_MEM_WRITE((Addr)data, sizeof(*data));
11364 break;
11366 case VKI_V4L2_QUERYSTD: {
11367 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11368 POST_MEM_WRITE((Addr)data, sizeof(*data));
11369 break;
11371 case VKI_V4L2_ENUMAUDIO: {
11372 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11373 POST_MEM_WRITE((Addr)data->name,
11374 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11375 break;
11377 case VKI_V4L2_ENUMAUDOUT: {
11378 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11379 POST_MEM_WRITE((Addr)data->name,
11380 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11381 break;
11383 case VKI_V4L2_G_PRIORITY: {
11384 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11385 POST_MEM_WRITE((Addr)data, sizeof(*data));
11386 break;
11388 case VKI_V4L2_G_SLICED_VBI_CAP: {
11389 struct vki_v4l2_sliced_vbi_cap *data =
11390 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11391 POST_MEM_WRITE((Addr)data,
11392 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11393 break;
11395 case VKI_V4L2_G_EXT_CTRLS: {
11396 struct vki_v4l2_ext_controls *data =
11397 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11398 if (data->count) {
11399 unsigned i;
11401 for (i = 0; i < data->count; i++) {
11402 if (data->controls[i].size)
11403 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11404 else
11405 POST_FIELD_WRITE(data->controls[i].value64);
11408 POST_FIELD_WRITE(data->error_idx);
11409 break;
11411 case VKI_V4L2_S_EXT_CTRLS: {
11412 struct vki_v4l2_ext_controls *data =
11413 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11414 POST_FIELD_WRITE(data->error_idx);
11415 break;
11417 case VKI_V4L2_TRY_EXT_CTRLS: {
11418 struct vki_v4l2_ext_controls *data =
11419 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11420 POST_FIELD_WRITE(data->error_idx);
11421 break;
11423 case VKI_V4L2_ENUM_FRAMESIZES: {
11424 struct vki_v4l2_frmsizeenum *data =
11425 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
11426 POST_FIELD_WRITE(data->type);
11427 POST_FIELD_WRITE(data->stepwise);
11428 break;
11430 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
11431 struct vki_v4l2_frmivalenum *data =
11432 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
11433 POST_FIELD_WRITE(data->type);
11434 POST_FIELD_WRITE(data->stepwise);
11435 break;
11437 case VKI_V4L2_G_ENC_INDEX: {
11438 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
11439 POST_MEM_WRITE((Addr)data, sizeof(*data));
11440 break;
11442 case VKI_V4L2_ENCODER_CMD: {
11443 struct vki_v4l2_encoder_cmd *data =
11444 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11445 POST_FIELD_WRITE(data->flags);
11446 break;
11448 case VKI_V4L2_TRY_ENCODER_CMD: {
11449 struct vki_v4l2_encoder_cmd *data =
11450 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
11451 POST_FIELD_WRITE(data->flags);
11452 break;
11454 case VKI_V4L2_DBG_S_REGISTER: {
11455 struct vki_v4l2_dbg_register *data =
11456 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11457 POST_FIELD_WRITE(data->size);
11458 break;
11460 case VKI_V4L2_DBG_G_REGISTER: {
11461 struct vki_v4l2_dbg_register *data =
11462 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
11463 POST_FIELD_WRITE(data->val);
11464 POST_FIELD_WRITE(data->size);
11465 break;
11467 case VKI_V4L2_G_DV_TIMINGS: {
11468 struct vki_v4l2_dv_timings *data =
11469 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11470 POST_MEM_WRITE((Addr)data, sizeof(*data));
11471 break;
11473 case VKI_V4L2_DQEVENT: {
11474 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
11475 POST_MEM_WRITE((Addr)data, sizeof(*data));
11476 break;
11478 case VKI_V4L2_CREATE_BUFS: {
11479 struct vki_v4l2_create_buffers *data =
11480 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
11481 POST_FIELD_WRITE(data->index);
11482 break;
11484 case VKI_V4L2_G_SELECTION: {
11485 struct vki_v4l2_selection *data =
11486 (struct vki_v4l2_selection *)(Addr)ARG3;
11487 POST_FIELD_WRITE(data->r);
11488 break;
11490 case VKI_V4L2_S_SELECTION: {
11491 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
11492 POST_FIELD_WRITE(data->r);
11493 break;
11495 case VKI_V4L2_DECODER_CMD: {
11496 struct vki_v4l2_decoder_cmd *data =
11497 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11498 POST_FIELD_WRITE(data->flags);
11499 break;
11501 case VKI_V4L2_TRY_DECODER_CMD: {
11502 struct vki_v4l2_decoder_cmd *data =
11503 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
11504 POST_FIELD_WRITE(data->flags);
11505 break;
11507 case VKI_V4L2_ENUM_DV_TIMINGS: {
11508 struct vki_v4l2_enum_dv_timings *data =
11509 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
11510 POST_FIELD_WRITE(data->timings);
11511 break;
11513 case VKI_V4L2_QUERY_DV_TIMINGS: {
11514 struct vki_v4l2_dv_timings *data =
11515 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
11516 POST_MEM_WRITE((Addr)data, sizeof(*data));
11517 break;
11519 case VKI_V4L2_DV_TIMINGS_CAP: {
11520 struct vki_v4l2_dv_timings_cap *data =
11521 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
11522 POST_MEM_WRITE((Addr)data, sizeof(*data));
11523 break;
11525 case VKI_V4L2_ENUM_FREQ_BANDS: {
11526 struct vki_v4l2_frequency_band *data =
11527 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
11528 POST_FIELD_WRITE(data->capability);
11529 POST_FIELD_WRITE(data->rangelow);
11530 POST_FIELD_WRITE(data->rangehigh);
11531 POST_FIELD_WRITE(data->modulation);
11532 break;
11534 case VKI_V4L2_DBG_G_CHIP_INFO: {
11535 struct vki_v4l2_dbg_chip_info *data =
11536 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
11537 POST_FIELD_WRITE(data->name);
11538 POST_FIELD_WRITE(data->flags);
11539 break;
11541 case VKI_V4L2_QUERY_EXT_CTRL: {
11542 struct vki_v4l2_query_ext_ctrl *data =
11543 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
11544 POST_MEM_WRITE((Addr)&data->type,
11545 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
11546 break;
11549 case VKI_V4L2_SUBDEV_S_FMT:
11550 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
11551 case VKI_V4L2_SUBDEV_S_CROP:
11552 case VKI_V4L2_SUBDEV_S_SELECTION:
11553 break;
11555 case VKI_V4L2_SUBDEV_G_FMT: {
11556 struct vki_v4l2_subdev_format *data =
11557 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
11558 POST_FIELD_WRITE(data->format);
11559 break;
11561 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
11562 struct vki_v4l2_subdev_frame_interval *data =
11563 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
11564 POST_FIELD_WRITE(data->interval);
11565 break;
11567 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
11568 struct vki_v4l2_subdev_mbus_code_enum *data =
11569 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
11570 POST_FIELD_WRITE(data->code);
11571 break;
11573 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
11574 struct vki_v4l2_subdev_frame_size_enum *data =
11575 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
11576 POST_FIELD_WRITE(data->min_width);
11577 POST_FIELD_WRITE(data->min_height);
11578 POST_FIELD_WRITE(data->max_width);
11579 POST_FIELD_WRITE(data->max_height);
11580 break;
11582 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
11583 struct vki_v4l2_subdev_frame_interval_enum *data =
11584 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
11585 POST_FIELD_WRITE(data->interval);
11586 break;
11588 case VKI_V4L2_SUBDEV_G_CROP: {
11589 struct vki_v4l2_subdev_crop *data =
11590 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
11591 POST_FIELD_WRITE(data->rect);
11592 break;
11594 case VKI_V4L2_SUBDEV_G_SELECTION: {
11595 struct vki_v4l2_subdev_selection *data =
11596 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
11597 POST_FIELD_WRITE(data->r);
11598 break;
11600 case VKI_MEDIA_IOC_DEVICE_INFO: {
11601 struct vki_media_device_info *data =
11602 (struct vki_media_device_info *)(Addr)ARG3;
11603 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
11604 break;
11606 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
11607 struct vki_media_entity_desc *data =
11608 (struct vki_media_entity_desc *)(Addr)ARG3;
11609 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
11610 break;
11612 case VKI_MEDIA_IOC_ENUM_LINKS:
11614 * This ioctl does write to the provided pointers, but it's not
11615 * possible to deduce the size of the array those pointers point to.
11617 break;
11618 case VKI_MEDIA_IOC_SETUP_LINK:
11619 break;
11621 /* Serial */
11622 case VKI_TIOCGSERIAL: {
11623 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
11624 POST_MEM_WRITE((Addr)data, sizeof(*data));
11625 break;
11627 case VKI_TIOCSSERIAL:
11628 break;
11630 case VKI_PERF_EVENT_IOC_ENABLE:
11631 case VKI_PERF_EVENT_IOC_DISABLE:
11632 case VKI_PERF_EVENT_IOC_REFRESH:
11633 case VKI_PERF_EVENT_IOC_RESET:
11634 case VKI_PERF_EVENT_IOC_PERIOD:
11635 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
11636 case VKI_PERF_EVENT_IOC_SET_FILTER:
11637 case VKI_PERF_EVENT_IOC_SET_BPF:
11638 break;
11640 case VKI_PERF_EVENT_IOC_ID:
11641 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
11642 break;
11644 /* Pulse Per Second (PPS) */
11645 case VKI_PPS_GETPARAMS: {
11646 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
11647 POST_MEM_WRITE((Addr)data, sizeof(*data));
11648 break;
11650 case VKI_PPS_GETCAP:
11651 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
11652 break;
11653 case VKI_PPS_FETCH: {
11654 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
11655 POST_FIELD_WRITE(data->info);
11656 break;
11658 case VKI_PPS_SETPARAMS:
11659 case VKI_PPS_KC_BIND:
11660 break;
11662 /* PTP Hardware Clock */
11663 case VKI_PTP_CLOCK_GETCAPS: {
11664 struct vki_ptp_clock_caps *data =
11665 (struct vki_ptp_clock_caps *)(Addr)ARG3;
11666 POST_MEM_WRITE((Addr)data, sizeof(*data));
11667 break;
11669 case VKI_PTP_SYS_OFFSET: {
11670 struct vki_ptp_sys_offset *data =
11671 (struct vki_ptp_sys_offset *)(Addr)ARG3;
11672 POST_MEM_WRITE((Addr)data->ts,
11673 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
11674 break;
11676 case VKI_PTP_PIN_GETFUNC: {
11677 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
11678 POST_MEM_WRITE((Addr)data, sizeof(*data));
11679 break;
11681 case VKI_PTP_SYS_OFFSET_PRECISE: {
11682 struct vki_ptp_sys_offset_precise *data =
11683 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
11684 POST_MEM_WRITE((Addr)data, sizeof(*data));
11685 break;
11687 case VKI_PTP_SYS_OFFSET_EXTENDED: {
11688 struct vki_ptp_sys_offset_extended *data =
11689 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
11690 POST_MEM_WRITE((Addr)data->ts,
11691 3 * data->n_samples * sizeof(data->ts[0][0]));
11692 break;
11694 case VKI_PTP_EXTTS_REQUEST:
11695 case VKI_PTP_PEROUT_REQUEST:
11696 case VKI_PTP_ENABLE_PPS:
11697 case VKI_PTP_PIN_SETFUNC:
11698 break;
11700 default:
11701 /* EVIOC* are variable length and return size written on success */
11702 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
11703 case VKI_EVIOCGNAME(0):
11704 case VKI_EVIOCGPHYS(0):
11705 case VKI_EVIOCGUNIQ(0):
11706 case VKI_EVIOCGKEY(0):
11707 case VKI_EVIOCGLED(0):
11708 case VKI_EVIOCGSND(0):
11709 case VKI_EVIOCGSW(0):
11710 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
11711 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
11712 case VKI_EVIOCGBIT(VKI_EV_REL,0):
11713 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
11714 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
11715 case VKI_EVIOCGBIT(VKI_EV_SW,0):
11716 case VKI_EVIOCGBIT(VKI_EV_LED,0):
11717 case VKI_EVIOCGBIT(VKI_EV_SND,0):
11718 case VKI_EVIOCGBIT(VKI_EV_REP,0):
11719 case VKI_EVIOCGBIT(VKI_EV_FF,0):
11720 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
11721 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
11722 if (RES > 0)
11723 POST_MEM_WRITE(ARG3, RES);
11724 break;
11725 default:
11726 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
11727 break;
11729 break;
11732 post_sys_ioctl__out:
11733 {} /* keep C compilers happy */
11736 /* ---------------------------------------------------------------------
11737 socketcall wrapper helpers
11738 ------------------------------------------------------------------ */
11740 void
11741 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
11742 UWord arg0, UWord arg1, UWord arg2,
11743 UWord arg3, UWord arg4 )
11745 /* int getsockopt(int s, int level, int optname,
11746 void *optval, socklen_t *optlen); */
11747 Addr optval_p = arg3;
11748 Addr optlen_p = arg4;
11749 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
11750 if (optval_p != (Addr)NULL) {
11751 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
11752 "socketcall.getsockopt(optval)",
11753 "socketcall.getsockopt(optlen)" );
11754 if (arg1 == VKI_SOL_SCTP &&
11755 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11756 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11758 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11759 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
11760 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
11761 (Addr)ga->addrs, address_bytes );
11766 void
11767 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
11768 SysRes res,
11769 UWord arg0, UWord arg1, UWord arg2,
11770 UWord arg3, UWord arg4 )
11772 Addr optval_p = arg3;
11773 Addr optlen_p = arg4;
11774 vg_assert(!sr_isError(res)); /* guaranteed by caller */
11775 if (optval_p != (Addr)NULL) {
11776 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
11777 "socketcall.getsockopt(optlen_out)" );
11778 if (arg1 == VKI_SOL_SCTP &&
11779 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
11780 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
11782 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
11783 struct vki_sockaddr *a = ga->addrs;
11784 int i;
11785 for (i = 0; i < ga->addr_num; i++) {
11786 int sl = 0;
11787 if (a->sa_family == VKI_AF_INET)
11788 sl = sizeof(struct vki_sockaddr_in);
11789 else if (a->sa_family == VKI_AF_INET6)
11790 sl = sizeof(struct vki_sockaddr_in6);
11791 else {
11792 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
11793 "address type %d\n", a->sa_family);
11795 a = (struct vki_sockaddr*)((char*)a + sl);
11797 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
11802 void
11803 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
11804 UWord arg0, UWord arg1, UWord arg2,
11805 UWord arg3, UWord arg4 )
11807 /* int setsockopt(int s, int level, int optname,
11808 const void *optval, socklen_t optlen); */
11809 Addr optval_p = arg3;
11810 if (optval_p != (Addr)NULL) {
11812 * OK, let's handle at least some setsockopt levels and options
11813 * ourselves, so we don't get false claims of references to
11814 * uninitialized memory (such as padding in structures) and *do*
11815 * check what pointers in the argument point to.
11817 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
11819 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
11822 * struct sock_fprog has a 16-bit count of instructions,
11823 * followed by a pointer to an array of those instructions.
11824 * There's padding between those two elements.
11826 * So that we don't bogusly complain about the padding bytes,
11827 * we just report that we read len and and filter.
11829 * We then make sure that what filter points to is valid.
11831 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
11832 (Addr)&fp->len, sizeof(fp->len) );
11833 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
11834 (Addr)&fp->filter, sizeof(fp->filter) );
11836 /* len * sizeof (*filter) */
11837 if (fp->filter != NULL)
11839 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
11840 (Addr)(fp->filter),
11841 fp->len * sizeof(*fp->filter) );
11844 else
11846 PRE_MEM_READ( "socketcall.setsockopt(optval)",
11847 arg3, /* optval */
11848 arg4 /* optlen */ );
11853 void
11854 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
11855 UWord arg1, UWord arg2, UWord arg3,
11856 UWord arg4, UWord arg5 )
11858 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11859 HChar name[40]; // large enough
11860 UInt i;
11861 for (i = 0; i < arg3; i++) {
11862 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11863 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
11864 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
11865 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11867 if (arg5)
11868 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
11871 void
11872 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
11873 UWord arg1, UWord arg2, UWord arg3,
11874 UWord arg4, UWord arg5 )
11876 if (res > 0) {
11877 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11878 HChar name[32]; // large enough
11879 UInt i;
11880 for (i = 0; i < res; i++) {
11881 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11882 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
11883 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11888 void
11889 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
11890 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11892 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11893 HChar name[40]; // large enough
11894 UInt i;
11895 for (i = 0; i < arg3; i++) {
11896 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
11897 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
11898 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
11899 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11903 void
11904 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
11905 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
11907 if (res > 0) {
11908 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
11909 UInt i;
11910 for (i = 0; i < res; i++) {
11911 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
11916 /* ---------------------------------------------------------------------
11917 ptrace wrapper helpers
11918 ------------------------------------------------------------------ */
11920 void
11921 ML_(linux_POST_traceme) ( ThreadId tid )
11923 ThreadState *tst = VG_(get_ThreadState)(tid);
11924 tst->ptrace = VKI_PT_PTRACED;
11927 void
11928 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
11930 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11932 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
11933 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
11934 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11935 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
11936 (Addr) iov->iov_base, iov->iov_len);
11940 void
11941 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
11943 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11945 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
11946 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
11947 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
11948 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
11949 (Addr) iov->iov_base, iov->iov_len);
11953 void
11954 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
11956 struct vki_iovec *iov = (struct vki_iovec *) arg4;
11958 /* XXX: The actual amount of data written by the kernel might be
11959 less than iov_len, depending on the regset (arg3). */
11960 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
11963 PRE(sys_kcmp)
11965 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
11966 SARG1, SARG2, SARG3, ARG4, ARG5);
11967 switch (ARG3) {
11968 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
11969 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
11970 /* Most of the comparison types don't look at |idx1| or
11971 |idx2|. */
11972 PRE_REG_READ3(long, "kcmp",
11973 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
11974 break;
11975 case VKI_KCMP_FILE:
11976 default:
11977 PRE_REG_READ5(long, "kcmp",
11978 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
11979 unsigned long, idx1, unsigned long, idx2);
11980 break;
11984 /* ---------------------------------------------------------------------
11985 bpf wrappers
11986 ------------------------------------------------------------------ */
11988 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
11990 HChar path[32], buf[1024]; /* large enough */
11991 SysRes sres;
11992 HChar *comp;
11993 Int proc_fd;
11995 *key_size = 0;
11996 *value_size = 0;
11998 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
11999 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12000 if (sr_isError(sres))
12001 return False;
12002 proc_fd = sr_Res(sres);
12004 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12005 return False;
12006 VG_(close)(proc_fd);
12008 comp = VG_(strstr)(buf, "key_size:");
12009 if (comp)
12010 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12012 comp = VG_(strstr)(buf, "value_size:");
12013 if (comp)
12014 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12016 return (*key_size && *value_size);
12020 * From a file descriptor for an eBPF object, try to determine the size of the
12021 * struct that will be written, i.e. determine if object is a map or a program.
12022 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12023 * search for strings "prog_type" or "map_type".
12025 static UInt bpf_obj_get_info_size(Int fd)
12027 HChar path[32], buf[1024]; /* large enough */
12028 SysRes sres;
12029 Int proc_fd;
12031 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12032 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12033 if (sr_isError(sres))
12034 return 0;
12035 proc_fd = sr_Res(sres);
12037 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12038 return 0;
12039 VG_(close)(proc_fd);
12041 if (VG_(strstr)(buf, "prog_type:"))
12042 return sizeof(struct vki_bpf_prog_info);
12044 if (VG_(strstr)(buf, "map_type:"))
12045 return sizeof(struct vki_bpf_map_info);
12047 return 0;
12050 PRE(sys_bpf)
12052 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12053 UInt res, key_size, value_size;
12055 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12056 (Word)ARG1, ARG2, ARG3);
12057 PRE_REG_READ3(long, "bpf",
12058 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12059 switch (ARG1) {
12060 case VKI_BPF_PROG_GET_NEXT_ID:
12061 case VKI_BPF_MAP_GET_NEXT_ID:
12062 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12063 break;
12064 case VKI_BPF_PROG_GET_FD_BY_ID:
12065 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12066 break;
12067 case VKI_BPF_MAP_GET_FD_BY_ID:
12068 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12069 break;
12070 case VKI_BPF_BTF_GET_FD_BY_ID:
12071 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12072 break;
12073 case VKI_BPF_MAP_CREATE:
12074 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12075 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12076 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12077 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12078 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12079 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12080 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12081 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12082 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12083 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12084 switch (attr->map_type) {
12085 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12086 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12087 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12088 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12089 SET_STATUS_Failure(VKI_EBADF);
12090 break;
12091 case VKI_BPF_MAP_TYPE_ARRAY:
12092 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12093 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12094 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12095 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12096 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12097 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12098 SET_STATUS_Failure(VKI_EBADF);
12099 break;
12103 break;
12104 case VKI_BPF_MAP_TYPE_UNSPEC:
12105 case VKI_BPF_MAP_TYPE_HASH:
12106 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12107 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12108 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12109 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12110 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12111 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12112 case VKI_BPF_MAP_TYPE_LRU_HASH:
12113 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12114 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12115 case VKI_BPF_MAP_TYPE_DEVMAP:
12116 case VKI_BPF_MAP_TYPE_SOCKMAP:
12117 case VKI_BPF_MAP_TYPE_CPUMAP:
12118 case VKI_BPF_MAP_TYPE_XSKMAP:
12119 case VKI_BPF_MAP_TYPE_SOCKHASH:
12120 default:
12121 break;
12123 break;
12124 case VKI_BPF_MAP_LOOKUP_ELEM:
12125 /* Perform a lookup on an eBPF map. Read key, write value. */
12126 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12127 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12128 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12129 if (ML_(safe_to_deref)(attr, ARG3)) {
12130 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12131 SET_STATUS_Failure(VKI_EBADF);
12132 break;
12134 /* Get size of key and value for this map. */
12135 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12136 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12137 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12140 break;
12141 case VKI_BPF_MAP_UPDATE_ELEM:
12142 /* Add or update a map element in kernel. Read key, read value. */
12143 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12144 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12145 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12146 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12147 if (ML_(safe_to_deref)(attr, ARG3)) {
12148 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12149 SET_STATUS_Failure(VKI_EBADF);
12150 break;
12152 /* Get size of key and value for this map. */
12153 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12154 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12155 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12158 break;
12159 case VKI_BPF_MAP_DELETE_ELEM:
12160 /* Delete a map element in kernel. Read key from user space. */
12161 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12162 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12163 if (ML_(safe_to_deref)(attr, ARG3)) {
12164 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12165 SET_STATUS_Failure(VKI_EBADF);
12166 break;
12168 /* Get size of key for this map. */
12169 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12170 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12172 break;
12173 case VKI_BPF_MAP_GET_NEXT_KEY:
12174 /* From a key, get next key for the map. Read key, write next key. */
12175 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12176 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12177 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12178 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12179 if (ML_(safe_to_deref)(attr, ARG3)) {
12180 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12181 SET_STATUS_Failure(VKI_EBADF);
12182 break;
12184 /* Get size of key for this map. */
12185 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12186 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12187 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12190 break;
12191 case VKI_BPF_PROG_LOAD:
12192 /* Load a program into the kernel from an array of instructions. */
12193 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12194 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12195 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12196 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12197 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12198 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12199 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12200 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12201 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12202 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12203 if (ML_(safe_to_deref)(attr, ARG3)) {
12204 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12205 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12206 /* Read instructions, license, program name. */
12207 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12208 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12209 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12210 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12211 /* Possibly write up to log_len into user space log buffer. */
12212 if (attr->log_level || attr->log_size || attr->log_buf)
12213 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12215 break;
12216 case VKI_BPF_OBJ_PIN:
12217 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12218 /* fall through */
12219 case VKI_BPF_OBJ_GET:
12220 /* Get pinned eBPF program or map. Read path name. */
12221 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12222 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12223 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12224 if (ML_(safe_to_deref)(attr, ARG3)) {
12225 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12226 SET_STATUS_Failure(VKI_EBADF);
12227 break;
12229 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12231 break;
12232 case VKI_BPF_PROG_ATTACH:
12233 case VKI_BPF_PROG_DETACH:
12234 /* Detach eBPF program from kernel attach point. */
12235 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12236 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12237 if (ML_(safe_to_deref)(attr, ARG3)) {
12238 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12239 SET_STATUS_Failure(VKI_EBADF);
12240 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12241 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12242 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12243 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12244 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12245 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12246 SET_STATUS_Failure(VKI_EBADF);
12249 break;
12250 case VKI_BPF_PROG_TEST_RUN:
12251 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12252 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12253 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12254 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12255 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12256 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12257 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12258 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12259 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12260 if (ML_(safe_to_deref)(attr, ARG3)) {
12261 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12262 SET_STATUS_Failure(VKI_EBADF);
12263 break;
12265 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12266 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12267 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12269 break;
12270 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12271 /* Get info for eBPF map or program. Write info. */
12272 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12273 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12274 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12275 if (ML_(safe_to_deref)(attr, ARG3)) {
12276 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12277 SET_STATUS_Failure(VKI_EBADF);
12278 break;
12280 /* Get size of struct to write: is object a program or a map? */
12281 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12282 if (res)
12283 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12284 VG_MIN(attr->info.info_len, res));
12285 else
12286 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12287 VG_MIN(attr->info.info_len,
12288 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12289 sizeof(struct vki_bpf_map_info)),
12290 sizeof(struct vki_bpf_btf_info))));
12292 break;
12293 case VKI_BPF_PROG_QUERY:
12295 * Query list of eBPF program attached to cgroup.
12296 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12298 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12299 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12300 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12301 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12302 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12303 if (ML_(safe_to_deref)(attr, ARG3)) {
12304 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12305 SET_STATUS_Failure(VKI_EBADF);
12306 break;
12308 if (attr->query.prog_cnt > 0) {
12309 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12310 if (attr->query.prog_ids) {
12311 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12312 attr->query.prog_cnt * sizeof(__vki_u32));
12316 break;
12317 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12318 /* Open raw tracepoint. Read tracepoint name. */
12319 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12320 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12321 if (ML_(safe_to_deref)(attr, ARG3)) {
12322 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12323 "bpf", tid, False)) {
12324 SET_STATUS_Failure(VKI_EBADF);
12325 break;
12327 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12328 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
12329 "bpf(attr->raw_tracepoint.name)");
12331 break;
12332 case VKI_BPF_BTF_LOAD:
12333 /* Load BTF information about a program into the kernel. */
12334 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
12335 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
12336 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
12337 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
12338 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
12339 if (ML_(safe_to_deref)(attr, ARG3)) {
12340 /* Read BTF data. */
12341 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
12342 /* Possibly write up to btf_log_len into user space log buffer. */
12343 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
12344 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
12345 attr->btf_log_buf, attr->btf_log_size);
12347 break;
12348 case VKI_BPF_TASK_FD_QUERY:
12349 /* Get info about the task. Write collected info. */
12350 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
12351 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
12352 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
12353 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
12354 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
12355 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12356 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12357 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12358 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12359 if (ML_(safe_to_deref)(attr, ARG3)) {
12360 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
12361 SET_STATUS_Failure(VKI_EBADF);
12362 break;
12364 if (attr->task_fd_query.buf_len > 0) {
12365 /* Write task or perf event name. */
12366 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
12367 attr->task_fd_query.buf,
12368 attr->task_fd_query.buf_len);
12371 break;
12372 default:
12373 VG_(message)(Vg_DebugMsg,
12374 "FATAL: unhandled eBPF command %lu\n", ARG1);
12375 VG_(core_panic)("... bye!\n");
12376 break;
12380 POST(sys_bpf)
12382 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12383 UInt key_size, value_size;
12385 vg_assert(SUCCESS);
12387 switch (ARG1) {
12388 case VKI_BPF_PROG_GET_NEXT_ID:
12389 case VKI_BPF_MAP_GET_NEXT_ID:
12390 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12391 break;
12392 case VKI_BPF_MAP_UPDATE_ELEM:
12393 case VKI_BPF_MAP_DELETE_ELEM:
12394 case VKI_BPF_OBJ_PIN:
12395 case VKI_BPF_PROG_ATTACH:
12396 case VKI_BPF_PROG_DETACH:
12397 break;
12398 /* Following commands have bpf() return a file descriptor. */
12399 case VKI_BPF_MAP_CREATE:
12400 case VKI_BPF_OBJ_GET:
12401 case VKI_BPF_PROG_GET_FD_BY_ID:
12402 case VKI_BPF_MAP_GET_FD_BY_ID:
12403 case VKI_BPF_BTF_GET_FD_BY_ID:
12404 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12405 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12406 VG_(close)(RES);
12407 SET_STATUS_Failure(VKI_EMFILE);
12408 } else {
12409 if (VG_(clo_track_fds))
12410 ML_(record_fd_open_nameless)(tid, RES);
12412 break;
12414 * TODO: Is there a way to pass information between PRE and POST hooks?
12415 * To avoid querying again for the size of keys and values.
12417 case VKI_BPF_MAP_LOOKUP_ELEM:
12418 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12419 POST_MEM_WRITE(attr->value, value_size);
12420 break;
12421 case VKI_BPF_MAP_GET_NEXT_KEY:
12422 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12423 POST_MEM_WRITE(attr->next_key, key_size);
12424 break;
12425 case VKI_BPF_PROG_LOAD:
12426 /* Return a file descriptor for loaded program, write into log_buf. */
12427 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12428 VG_(close)(RES);
12429 SET_STATUS_Failure(VKI_EMFILE);
12430 } else {
12431 if (VG_(clo_track_fds))
12432 ML_(record_fd_open_nameless)(tid, RES);
12434 if (attr->log_level || attr->log_size || attr->log_buf)
12435 POST_MEM_WRITE(attr->log_buf, attr->log_size);
12436 break;
12437 case VKI_BPF_PROG_TEST_RUN:
12438 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
12439 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12440 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
12441 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
12442 break;
12443 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12444 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
12445 break;
12446 case VKI_BPF_PROG_QUERY:
12447 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12448 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12449 if (attr->query.prog_ids)
12450 POST_MEM_WRITE(attr->query.prog_ids,
12451 attr->query.prog_cnt * sizeof(__vki_u32));
12452 break;
12453 case VKI_BPF_BTF_LOAD:
12454 /* Return a file descriptor for BTF data, write into btf_log_buf. */
12455 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12456 VG_(close)(RES);
12457 SET_STATUS_Failure(VKI_EMFILE);
12458 } else {
12459 if (VG_(clo_track_fds))
12460 ML_(record_fd_open_nameless)(tid, RES);
12462 if (attr->btf_log_level)
12463 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
12464 break;
12465 case VKI_BPF_TASK_FD_QUERY:
12466 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
12467 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12468 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12469 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12470 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12471 break;
12472 default:
12473 VG_(message)(Vg_DebugMsg,
12474 "FATAL: unhandled eBPF command %lu\n", ARG1);
12475 VG_(core_panic)("... bye!\n");
12476 break;
12480 PRE(sys_copy_file_range)
12482 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
12483 ARG4, ARG5, ARG6);
12485 PRE_REG_READ6(vki_size_t, "copy_file_range",
12486 int, "fd_in",
12487 vki_loff_t *, "off_in",
12488 int, "fd_out",
12489 vki_loff_t *, "off_out",
12490 vki_size_t, "len",
12491 unsigned int, "flags");
12493 /* File descriptors are "specially" tracked by valgrind.
12494 valgrind itself uses some, so make sure someone didn't
12495 put in one of our own... */
12496 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
12497 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
12498 SET_STATUS_Failure( VKI_EBADF );
12499 } else {
12500 /* Now see if the offsets are defined. PRE_MEM_READ will
12501 double check it can dereference them. */
12502 if (ARG2 != 0)
12503 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
12504 if (ARG4 != 0)
12505 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
12509 PRE(sys_pkey_alloc)
12511 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
12513 PRE_REG_READ2(long, "pkey_alloc",
12514 unsigned long, "flags",
12515 unsigned long, "access_rights");
12517 /* The kernel says: pkey_alloc() is always safe to call regardless of
12518 whether or not the operating system supports protection keys. It can be
12519 used in lieu of any other mechanism for detecting pkey support and will
12520 simply fail with the error ENOSPC if the operating system has no pkey
12521 support.
12523 So we simply always return ENOSPC to signal memory protection keys are
12524 not supported under valgrind, unless there are unknown flags, then we
12525 return EINVAL. */
12526 unsigned long pkey_flags = ARG1;
12527 if (pkey_flags != 0)
12528 SET_STATUS_Failure( VKI_EINVAL );
12529 else
12530 SET_STATUS_Failure( VKI_ENOSPC );
12533 PRE(sys_pkey_free)
12535 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
12537 PRE_REG_READ1(long, "pkey_free",
12538 unsigned long, "pkey");
12540 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
12541 always an error. */
12542 SET_STATUS_Failure( VKI_EINVAL );
12545 PRE(sys_pkey_mprotect)
12547 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12548 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
12549 PRE_REG_READ4(long, "pkey_mprotect",
12550 unsigned long, addr, vki_size_t, len, unsigned long, prot,
12551 unsigned long, pkey);
12553 Addr addr = ARG1;
12554 SizeT len = ARG2;
12555 Int prot = ARG3;
12556 Int pkey = ARG4;
12558 /* Since pkey_alloc () can never succeed, see above, any pkey is
12559 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
12560 if (pkey != -1)
12561 SET_STATUS_Failure( VKI_EINVAL );
12562 else
12563 handle_sys_mprotect (tid, status, &addr, &len, &prot);
12565 ARG1 = addr;
12566 ARG2 = len;
12567 ARG3 = prot;
12570 POST(sys_pkey_mprotect)
12572 Addr addr = ARG1;
12573 SizeT len = ARG2;
12574 Int prot = ARG3;
12576 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
12579 PRE(sys_io_uring_setup)
12581 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12582 ARG1, ARG2);
12583 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
12584 struct vki_io_uring_params *, p);
12585 if (ARG2)
12586 PRE_MEM_READ("io_uring_setup(p)", ARG2,
12587 offsetof(struct vki_io_uring_params, sq_off));
12590 POST(sys_io_uring_setup)
12592 vg_assert(SUCCESS);
12593 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
12594 VG_(close)(RES);
12595 SET_STATUS_Failure( VKI_EMFILE );
12596 } else {
12597 if (VG_(clo_track_fds))
12598 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
12599 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
12600 sizeof(struct vki_io_sqring_offsets) +
12601 sizeof(struct vki_io_cqring_offsets));
12605 PRE(sys_io_uring_enter)
12607 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12608 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
12609 FMT_REGWORD "u )",
12610 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
12611 PRE_REG_READ6(long, "io_uring_enter",
12612 unsigned int, fd, unsigned int, to_submit,
12613 unsigned int, min_complete, unsigned int, flags,
12614 const void *, sig, unsigned long, sigsz);
12615 if (ARG5)
12616 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
12619 POST(sys_io_uring_enter)
12623 PRE(sys_io_uring_register)
12625 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
12626 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
12627 PRE_REG_READ4(long, "io_uring_register",
12628 unsigned int, fd, unsigned int, opcode,
12629 void *, arg, unsigned int, nr_args);
12630 switch (ARG2) {
12631 case VKI_IORING_REGISTER_BUFFERS:
12632 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
12633 break;
12634 case VKI_IORING_UNREGISTER_BUFFERS:
12635 break;
12636 case VKI_IORING_REGISTER_FILES:
12637 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
12638 break;
12639 case VKI_IORING_UNREGISTER_FILES:
12640 break;
12641 case VKI_IORING_REGISTER_EVENTFD:
12642 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
12643 break;
12644 case VKI_IORING_UNREGISTER_EVENTFD:
12645 break;
12649 POST(sys_io_uring_register)
12653 #undef PRE
12654 #undef POST
12656 #endif // defined(VGO_linux)
12658 /*--------------------------------------------------------------------*/
12659 /*--- end ---*/
12660 /*--------------------------------------------------------------------*/