vgdb: Handle EAGAIN in read_buf
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob26f1fbee3cce4bb16ccbe87209858e0ed896b5b2
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 Int lwpid = VG_(gettid)();
74 ThreadState* tst = VG_(get_ThreadState)(tid);
76 VG_(debugLog)(1, "syswrap-linux",
77 "thread_wrapper(tid=%u,lwpid=%d): entry\n",
78 tid, lwpid);
80 vg_assert(tst->status == VgTs_Init);
82 /* make sure we get the CPU lock before doing anything significant */
83 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
85 if (0)
86 VG_(printf)("thread tid %u started: stack = %p\n",
87 tid, (void *)&tid);
89 /* Make sure error reporting is enabled in the new thread. */
90 tst->err_disablement_level = 0;
92 VG_TRACK(pre_thread_first_insn, tid);
94 tst->os_state.lwpid = lwpid;
95 /* Set the threadgroup for real. This overwrites the provisional value set
96 in do_clone(). See comments in do_clone for background, also #226116. */
97 tst->os_state.threadgroup = VG_(getpid)();
99 /* Thread created with all signals blocked; scheduler will set the
100 appropriate mask */
102 ret = VG_(scheduler)(tid);
104 vg_assert(VG_(is_exiting)(tid));
106 vg_assert(tst->status == VgTs_Runnable);
107 vg_assert(VG_(is_running_thread)(tid));
109 VG_(debugLog)(1, "syswrap-linux",
110 "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n",
111 tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret));
113 /* Return to caller, still holding the lock. */
114 return ret;
118 /* ---------------------------------------------------------------------
119 clone-related stuff
120 ------------------------------------------------------------------ */
122 /* Run a thread all the way to the end, then do appropriate exit actions
123 (this is the last-one-out-turn-off-the-lights bit). */
124 static void run_a_thread_NORETURN ( Word tidW )
126 ThreadId tid = (ThreadId)tidW;
127 VgSchedReturnCode src;
128 Int c;
129 ThreadState* tst;
130 #ifdef ENABLE_INNER_CLIENT_REQUEST
131 Int registered_vgstack_id;
132 #endif
134 VG_(debugLog)(1, "syswrap-linux",
135 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
136 tid);
138 tst = VG_(get_ThreadState)(tid);
139 vg_assert(tst);
141 /* An thread has two stacks:
142 * the simulated stack (used by the synthetic cpu. Guest process
143 is using this stack).
144 * the valgrind stack (used by the real cpu. Valgrind code is running
145 on this stack).
146 When Valgrind runs as an inner, it must signals that its (real) stack
147 is the stack to use by the outer to e.g. do stacktraces.
149 INNER_REQUEST
150 (registered_vgstack_id
151 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
152 tst->os_state.valgrind_stack_init_SP));
154 /* Run the thread all the way through. */
155 src = thread_wrapper(tid);
157 VG_(debugLog)(1, "syswrap-linux",
158 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
159 tid);
161 c = VG_(count_living_threads)();
162 vg_assert(c >= 1); /* stay sane */
164 /* Deregister thread's stack. */
165 if (tst->os_state.stk_id != NULL_STK_ID)
166 VG_(deregister_stack)(tst->os_state.stk_id);
168 // Tell the tool this thread is exiting
169 VG_TRACK( pre_thread_ll_exit, tid );
171 /* If the thread is exiting with errors disabled, complain loudly;
172 doing so is bad (does the user know this has happened?) Also,
173 in all cases, be paranoid and clear the flag anyway so that the
174 thread slot is safe in this respect if later reallocated. This
175 should be unnecessary since the flag should be cleared when the
176 slot is reallocated, in thread_wrapper(). */
177 if (tst->err_disablement_level > 0) {
178 VG_(umsg)(
179 "WARNING: exiting thread has error reporting disabled.\n"
180 "WARNING: possibly as a result of some mistake in the use\n"
181 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
183 VG_(debugLog)(
184 1, "syswrap-linux",
185 "run_a_thread_NORETURN(tid=%u): "
186 "WARNING: exiting thread has err_disablement_level = %u\n",
187 tid, tst->err_disablement_level
190 tst->err_disablement_level = 0;
192 if (c == 1) {
194 VG_(debugLog)(1, "syswrap-linux",
195 "run_a_thread_NORETURN(tid=%u): "
196 "last one standing\n",
197 tid);
199 /* We are the last one standing. Keep hold of the lock and
200 carry on to show final tool results, then exit the entire system.
201 Use the continuation pointer set at startup in m_main. */
202 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
203 } else {
205 VG_(debugLog)(1, "syswrap-linux",
206 "run_a_thread_NORETURN(tid=%u): "
207 "not last one standing\n",
208 tid);
210 /* OK, thread is dead, but others still exist. Just exit. */
212 /* This releases the run lock */
213 VG_(exit_thread)(tid);
214 vg_assert(tst->status == VgTs_Zombie);
215 vg_assert(sizeof(tst->status) == 4);
216 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
218 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
220 /* We have to use this sequence to terminate the thread to
221 prevent a subtle race. If VG_(exit_thread)() had left the
222 ThreadState as Empty, then it could have been reallocated,
223 reusing the stack while we're doing these last cleanups.
224 Instead, VG_(exit_thread) leaves it as Zombie to prevent
225 reallocation. We need to make sure we don't touch the stack
226 between marking it Empty and exiting. Hence the
227 assembler. */
228 #if defined(VGP_x86_linux)
229 asm volatile (
230 "pushl %%ebx\n"
231 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
232 "movl %2, %%eax\n" /* set %eax = __NR_exit */
233 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
234 "int $0x80\n" /* exit(tst->os_state.exitcode) */
235 "popl %%ebx\n"
236 : "=m" (tst->status)
237 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
238 : "eax"
240 #elif defined(VGP_amd64_linux)
241 asm volatile (
242 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
243 "movq %2, %%rax\n" /* set %rax = __NR_exit */
244 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
245 "syscall\n" /* exit(tst->os_state.exitcode) */
246 : "=m" (tst->status)
247 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
248 : "rax", "rdi"
250 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
251 || defined(VGP_ppc64le_linux)
252 { UInt vgts_empty = (UInt)VgTs_Empty;
253 asm volatile (
254 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
255 "li 0,%2\n\t" /* set r0 = __NR_exit */
256 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
257 "sc\n\t" /* exit(tst->os_state.exitcode) */
258 : "=m" (tst->status)
259 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
260 : "r0", "r3"
263 #elif defined(VGP_arm_linux)
264 asm volatile (
265 "str %1, %0\n" /* set tst->status = VgTs_Empty */
266 "mov r7, %2\n" /* set %r7 = __NR_exit */
267 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
268 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
269 : "=m" (tst->status)
270 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
271 : "r0", "r7"
273 #elif defined(VGP_arm64_linux)
274 asm volatile (
275 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
276 "mov x8, %2\n" /* set %x8 = __NR_exit */
277 "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */
278 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
279 : "=m" (tst->status)
280 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
281 : "x0", "x8"
283 #elif defined(VGP_s390x_linux)
284 asm volatile (
285 "st %1, %0\n" /* set tst->status = VgTs_Empty */
286 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
287 "svc %2\n" /* exit(tst->os_state.exitcode) */
288 : "=m" (tst->status)
289 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
290 : "2"
292 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
293 asm volatile (
294 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
295 "li $2, %2\n\t" /* set v0 = __NR_exit */
296 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
297 "syscall\n\t" /* exit(tst->os_state.exitcode) */
298 "nop"
299 : "=m" (tst->status)
300 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
301 : "cc", "memory" , "v0", "a0"
303 #elif defined(VGP_nanomips_linux)
304 asm volatile (
305 "sw %1, %0 \n\t" /* set tst->status = VgTs_Empty */
306 "li $t4, %2 \n\t" /* set t4 = __NR_exit */
307 "lw $a0, %3 \n\t" /* set a0 = tst->os_state.exitcode */
308 "syscall[32] \n\t" /* exit(tst->os_state.exitcode) */
309 : "=m" (tst->status)
310 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
311 : "memory" , "$t4", "$a0"
313 #else
314 # error Unknown platform
315 #endif
317 VG_(core_panic)("Thread exit failed?\n");
320 /*NOTREACHED*/
321 vg_assert(0);
324 Word ML_(start_thread_NORETURN) ( void* arg )
326 ThreadState* tst = (ThreadState*)arg;
327 ThreadId tid = tst->tid;
329 run_a_thread_NORETURN ( (Word)tid );
330 /*NOTREACHED*/
331 vg_assert(0);
334 /* Allocate a stack for this thread, if it doesn't already have one.
335 They're allocated lazily, and never freed. Returns the initial stack
336 pointer value to use, or 0 if allocation failed. */
337 Addr ML_(allocstack)(ThreadId tid)
339 ThreadState* tst = VG_(get_ThreadState)(tid);
340 VgStack* stack;
341 Addr initial_SP;
343 /* Either the stack_base and stack_init_SP are both zero (in which
344 case a stack hasn't been allocated) or they are both non-zero,
345 in which case it has. */
347 if (tst->os_state.valgrind_stack_base == 0)
348 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
350 if (tst->os_state.valgrind_stack_base != 0)
351 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
353 /* If no stack is present, allocate one. */
355 if (tst->os_state.valgrind_stack_base == 0) {
356 stack = VG_(am_alloc_VgStack)( &initial_SP );
357 if (stack) {
358 tst->os_state.valgrind_stack_base = (Addr)stack;
359 tst->os_state.valgrind_stack_init_SP = initial_SP;
363 if (0)
364 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
365 tid,
366 (void*)tst->os_state.valgrind_stack_base,
367 (void*)tst->os_state.valgrind_stack_init_SP );
369 return tst->os_state.valgrind_stack_init_SP;
372 /* Allocate a stack for the main thread, and run it all the way to the
373 end. Although we already have a working VgStack
374 (VG_(interim_stack)) it's better to allocate a new one, so that
375 overflow detection works uniformly for all threads.
377 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
379 Addr sp;
380 VG_(debugLog)(1, "syswrap-linux",
381 "entering VG_(main_thread_wrapper_NORETURN)\n");
383 sp = ML_(allocstack)(tid);
384 #if defined(ENABLE_INNER_CLIENT_REQUEST)
386 // we must register the main thread stack before the call
387 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
388 // reports 'write error' on the non registered stack.
389 ThreadState* tst = VG_(get_ThreadState)(tid);
390 INNER_REQUEST
391 ((void)
392 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
393 tst->os_state.valgrind_stack_init_SP));
395 #endif
397 #if defined(VGP_ppc32_linux)
398 /* make a stack frame */
399 sp -= 16;
400 sp &= ~0xF;
401 *(UWord *)sp = 0;
402 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
403 /* make a stack frame */
404 sp -= 112;
405 sp &= ~((Addr)0xF);
406 *(UWord *)sp = 0;
407 #elif defined(VGP_s390x_linux)
408 /* make a stack frame */
409 sp -= 160;
410 sp &= ~((Addr)0xF);
411 *(UWord *)sp = 0;
412 #endif
414 /* If we can't even allocate the first thread's stack, we're hosed.
415 Give up. */
416 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
418 /* shouldn't be any other threads around yet */
419 vg_assert( VG_(count_living_threads)() == 1 );
421 ML_(call_on_new_stack_0_1)(
422 (Addr)sp, /* stack */
423 0, /* bogus return address */
424 run_a_thread_NORETURN, /* fn to call */
425 (Word)tid /* arg to give it */
428 /*NOTREACHED*/
429 vg_assert(0);
432 /* Clone a new thread. Note that in the clone syscalls, we hard-code
433 tlsaddr argument as NULL : the guest TLS is emulated via guest
434 registers, and Valgrind itself has no thread local storage. */
435 static SysRes clone_new_thread ( Word (*fn)(void *),
436 void* stack,
437 Word flags,
438 ThreadState* ctst,
439 Int* child_tidptr,
440 Int* parent_tidptr)
442 SysRes res;
443 /* Note that in all the below, we make sys_clone appear to have returned
444 Success(0) in the child, by assigning the relevant child guest
445 register(s) just before the clone syscall. */
446 #if defined(VGP_x86_linux)
447 Int eax;
448 ctst->arch.vex.guest_EAX = 0;
449 eax = do_syscall_clone_x86_linux
450 (ML_(start_thread_NORETURN), stack, flags, ctst,
451 child_tidptr, parent_tidptr, NULL);
452 res = VG_(mk_SysRes_x86_linux)( eax );
453 #elif defined(VGP_amd64_linux)
454 Long rax;
455 ctst->arch.vex.guest_RAX = 0;
456 rax = do_syscall_clone_amd64_linux
457 (ML_(start_thread_NORETURN), stack, flags, ctst,
458 child_tidptr, parent_tidptr, NULL);
459 res = VG_(mk_SysRes_amd64_linux)( rax );
460 #elif defined(VGP_ppc32_linux)
461 ULong word64;
462 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
463 /* %r3 = 0 */
464 ctst->arch.vex.guest_GPR3 = 0;
465 /* %cr0.so = 0 */
466 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
467 word64 = do_syscall_clone_ppc32_linux
468 (ML_(start_thread_NORETURN), stack, flags, ctst,
469 child_tidptr, parent_tidptr, NULL);
470 /* High half word64 is syscall return value. Low half is
471 the entire CR, from which we need to extract CR0.SO. */
472 /* VG_(printf)("word64 = 0x%llx\n", word64); */
473 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
474 /*errflag*/ (((UInt)word64) >> 28) & 1);
475 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
476 ULong word64;
477 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
478 UInt flag = ctst->arch.vex.guest_syscall_flag;
479 /* %r3 = 0 */
480 ctst->arch.vex.guest_GPR3 = 0;
481 /* %cr0.so = 0 */
482 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
483 word64 = do_syscall_clone_ppc64_linux
484 (ML_(start_thread_NORETURN), stack, flags, ctst,
485 child_tidptr, parent_tidptr, NULL);
486 /* Low half word64 is syscall return value. Hi half is
487 the entire CR, from which we need to extract CR0.SO. */
488 /* VG_(printf)("word64 = 0x%llx\n", word64); */
489 res = VG_(mk_SysRes_ppc64_linux)
490 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
491 /*errflag*/ (UInt)((word64 >> (32+28)) & 1), flag);
492 #elif defined(VGP_s390x_linux)
493 ULong r2;
494 ctst->arch.vex.guest_r2 = 0;
495 r2 = do_syscall_clone_s390x_linux
496 (stack, flags, parent_tidptr, child_tidptr, NULL,
497 ML_(start_thread_NORETURN), ctst);
498 res = VG_(mk_SysRes_s390x_linux)( r2 );
499 #elif defined(VGP_arm64_linux)
500 ULong x0;
501 ctst->arch.vex.guest_X0 = 0;
502 x0 = do_syscall_clone_arm64_linux
503 (ML_(start_thread_NORETURN), stack, flags, ctst,
504 child_tidptr, parent_tidptr, NULL);
505 res = VG_(mk_SysRes_arm64_linux)( x0 );
506 #elif defined(VGP_arm_linux)
507 UInt r0;
508 ctst->arch.vex.guest_R0 = 0;
509 r0 = do_syscall_clone_arm_linux
510 (ML_(start_thread_NORETURN), stack, flags, ctst,
511 child_tidptr, parent_tidptr, NULL);
512 res = VG_(mk_SysRes_arm_linux)( r0 );
513 #elif defined(VGP_mips64_linux)
514 UInt ret = 0;
515 ctst->arch.vex.guest_r2 = 0;
516 ctst->arch.vex.guest_r7 = 0;
517 ret = do_syscall_clone_mips64_linux
518 (ML_(start_thread_NORETURN), stack, flags, ctst,
519 parent_tidptr, NULL, child_tidptr);
520 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
521 #elif defined(VGP_mips32_linux)
522 UInt ret = 0;
523 ctst->arch.vex.guest_r2 = 0;
524 ctst->arch.vex.guest_r7 = 0;
525 ret = do_syscall_clone_mips_linux
526 (ML_(start_thread_NORETURN), stack, flags, ctst,
527 child_tidptr, parent_tidptr, NULL);
528 /* High half word64 is syscall return value. Low half is
529 the entire CR, from which we need to extract CR0.SO. */
530 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
531 #elif defined(VGP_nanomips_linux)
532 UInt ret = 0;
533 ctst->arch.vex.guest_r4 = 0;
534 ret = do_syscall_clone_nanomips_linux
535 (ML_(start_thread_NORETURN), stack, flags, ctst,
536 child_tidptr, parent_tidptr, NULL);
537 res = VG_ (mk_SysRes_nanomips_linux) (ret);
538 #else
539 # error Unknown platform
540 #endif
541 return res;
544 static void setup_child ( /*OUT*/ ThreadArchState *child,
545 /*IN*/ ThreadArchState *parent )
547 /* We inherit our parent's guest state. */
548 child->vex = parent->vex;
549 child->vex_shadow1 = parent->vex_shadow1;
550 child->vex_shadow2 = parent->vex_shadow2;
552 #if defined(VGP_x86_linux)
553 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
554 /*IN*/ ThreadArchState *parent );
555 ML_(x86_setup_LDT_GDT)(child, parent);
556 #endif
559 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
561 static const Bool debug = False;
562 ThreadState* ctst = VG_(get_ThreadState)(ctid);
563 // res is succesful by default, overriden if a real syscall is needed/done.
564 SysRes res = VG_(mk_SysRes_Success)(0);
566 if (debug)
567 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
569 #if defined(VGP_x86_linux)
570 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
571 if (debug)
572 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
573 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
574 tlsinfo, tlsinfo->entry_number,
575 tlsinfo->base_addr, tlsinfo->limit,
576 ctst->arch.vex.guest_ESP,
577 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
578 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
579 #elif defined(VGP_amd64_linux)
580 ctst->arch.vex.guest_FS_CONST = tlsaddr;
581 #elif defined(VGP_ppc32_linux)
582 ctst->arch.vex.guest_GPR2 = tlsaddr;
583 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
584 ctst->arch.vex.guest_GPR13 = tlsaddr;
585 #elif defined(VGP_s390x_linux)
586 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
587 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
588 #elif defined(VGP_arm64_linux)
589 /* Just assign the tls pointer in the guest TPIDR_EL0. */
590 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
591 #elif defined(VGP_arm_linux)
592 /* Just assign the tls pointer in the guest TPIDRURO. */
593 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
594 #elif defined(VGP_mips64_linux)
595 ctst->arch.vex.guest_ULR = tlsaddr;
596 ctst->arch.vex.guest_r27 = tlsaddr;
597 #elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
598 ctst->arch.vex.guest_ULR = tlsaddr;
599 ctst->arch.vex.guest_r27 = tlsaddr;
600 #else
601 # error Unknown platform
602 #endif
603 return res;
607 When a client clones, we need to keep track of the new thread. This means:
608 1. allocate a ThreadId+ThreadState+stack for the thread
610 2. initialize the thread's new VCPU state
612 3. create the thread using the same args as the client requested,
613 but using the scheduler entrypoint for EIP, and a separate stack
614 for ESP.
616 static SysRes do_clone ( ThreadId ptid,
617 UWord flags, Addr sp,
618 Int* parent_tidptr,
619 Int* child_tidptr,
620 Addr tlsaddr)
622 ThreadId ctid = VG_(alloc_ThreadState)();
623 ThreadState* ptst = VG_(get_ThreadState)(ptid);
624 ThreadState* ctst = VG_(get_ThreadState)(ctid);
625 UWord* stack;
626 SysRes res;
627 vki_sigset_t blockall, savedmask;
629 VG_(sigfillset)(&blockall);
631 vg_assert(VG_(is_running_thread)(ptid));
632 vg_assert(VG_(is_valid_tid)(ctid));
634 stack = (UWord*)ML_(allocstack)(ctid);
635 if (stack == NULL) {
636 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
637 goto out;
640 /* Copy register state
642 Both parent and child return to the same place, and the code
643 following the clone syscall works out which is which, so we
644 don't need to worry about it.
646 The parent gets the child's new tid returned from clone, but the
647 child gets 0.
649 If the clone call specifies a NULL sp for the new thread, then
650 it actually gets a copy of the parent's sp.
652 setup_child( &ctst->arch, &ptst->arch );
654 if (sp != 0)
655 VG_(set_SP)(ctid, sp);
657 ctst->os_state.parent = ptid;
659 /* inherit signal mask */
660 ctst->sig_mask = ptst->sig_mask;
661 ctst->tmp_sig_mask = ptst->sig_mask;
663 /* Start the child with its threadgroup being the same as the
664 parent's. This is so that any exit_group calls that happen
665 after the child is created but before it sets its
666 os_state.threadgroup field for real (in thread_wrapper in
667 syswrap-linux.c), really kill the new thread. a.k.a this avoids
668 a race condition in which the thread is unkillable (via
669 exit_group) because its threadgroup is not set. The race window
670 is probably only a few hundred or a few thousand cycles long.
671 See #226116. */
672 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
674 ML_(guess_and_register_stack) (sp, ctst);
676 /* Assume the clone will succeed, and tell any tool that wants to
677 know that this thread has come into existence. We cannot defer
678 it beyond this point because setup_tls, just below,
679 causes checks to assert by making references to the new ThreadId
680 if we don't state the new thread exists prior to that point.
681 If the clone fails, we'll send out a ll_exit notification for it
682 at the out: label below, to clean up. */
683 vg_assert(VG_(owns_BigLock_LL)(ptid));
684 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
686 if (flags & VKI_CLONE_SETTLS) {
687 res = setup_child_tls(ctid, tlsaddr);
688 if (sr_isError(res))
689 goto out;
691 flags &= ~VKI_CLONE_SETTLS;
693 /* start the thread with everything blocked */
694 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
696 /* Create the new thread */
697 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
698 child_tidptr, parent_tidptr);
700 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
702 out:
703 if (sr_isError(res)) {
704 /* clone failed */
705 VG_(cleanup_thread)(&ctst->arch);
706 ctst->status = VgTs_Empty;
707 /* oops. Better tell the tool the thread exited in a hurry :-) */
708 VG_TRACK( pre_thread_ll_exit, ctid );
711 return res;
714 /* Do a clone which is really a fork().
715 ML_(do_fork_clone) uses the clone syscall to fork a child process.
716 Note that this should not be called for a thread creation.
717 Also, some flags combinations are not supported, and such combinations
718 are handled either by masking the non supported flags or by asserting.
720 The CLONE_VFORK flag is accepted, as this just tells that the parent is
721 suspended till the child exits or calls execve. We better keep this flag,
722 just in case the guests parent/client code depends on this synchronisation.
724 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
725 instructions in the child process, that will mess up the parent host
726 memory. So, we hope for the best and assumes that the guest application does
727 not (really) depends on sharing the memory between parent and child in the
728 interval between clone and exits/execve.
730 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
731 clone syscall, before child guest instructions are executed. */
732 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
733 Int* parent_tidptr, Int* child_tidptr,
734 Addr child_sp)
736 vki_sigset_t fork_saved_mask;
737 vki_sigset_t mask;
738 SysRes res;
740 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
741 | VKI_CLONE_FILES))
742 return VG_(mk_SysRes_Error)( VKI_EINVAL );
744 /* Block all signals during fork, so that we can fix things up in
745 the child without being interrupted. */
746 VG_(sigfillset)(&mask);
747 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
749 VG_(do_atfork_pre)(tid);
751 /* Since this is the fork() form of clone, we don't need all that
752 VG_(clone) stuff */
753 #if defined(VGP_x86_linux) \
754 || defined(VGP_ppc32_linux) \
755 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
756 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
757 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
758 || defined(VGP_nanomips_linux)
759 res = VG_(do_syscall5)( __NR_clone, flags,
760 (UWord)NULL, (UWord)parent_tidptr,
761 (UWord)NULL, (UWord)child_tidptr );
762 #elif defined(VGP_amd64_linux)
763 /* note that the last two arguments are the opposite way round to x86 and
764 ppc32 as the amd64 kernel expects the arguments in a different order */
765 res = VG_(do_syscall5)( __NR_clone, flags,
766 (UWord)NULL, (UWord)parent_tidptr,
767 (UWord)child_tidptr, (UWord)NULL );
768 #elif defined(VGP_s390x_linux)
769 /* Note that s390 has the stack first and then the flags */
770 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
771 (UWord)parent_tidptr, (UWord)child_tidptr);
772 #else
773 # error Unknown platform
774 #endif
776 if (!sr_isError(res) && sr_Res(res) == 0) {
777 /* child */
778 if (child_sp != 0)
779 VG_(set_SP)(tid, child_sp);
780 VG_(do_atfork_child)(tid);
782 /* restore signal mask */
783 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
785 else
786 if (!sr_isError(res) && sr_Res(res) > 0) {
787 /* parent */
788 VG_(do_atfork_parent)(tid);
790 if (VG_(clo_trace_syscalls))
791 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
792 VG_(getpid)(), (RegWord)sr_Res(res));
794 /* restore signal mask */
795 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
798 return res;
801 /* ---------------------------------------------------------------------
802 PRE/POST wrappers for arch-generic, Linux-specific syscalls
803 ------------------------------------------------------------------ */
805 // Nb: See the comment above the generic PRE/POST wrappers in
806 // m_syswrap/syswrap-generic.c for notes about how they work.
808 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
809 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
811 PRE(sys_clone)
813 UInt cloneflags;
814 Bool badarg = False;
816 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
817 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
818 ARG4, ARG5);
820 // Order of arguments differs between platforms.
821 #if defined(VGP_x86_linux) \
822 || defined(VGP_ppc32_linux) \
823 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
824 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
825 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
826 || defined(VGP_nanomips_linux)
827 #define ARG_CHILD_TIDPTR ARG5
828 #define PRA_CHILD_TIDPTR PRA5
829 #define ARG_TLS ARG4
830 #define PRA_TLS PRA4
831 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
832 #define ARG_CHILD_TIDPTR ARG4
833 #define PRA_CHILD_TIDPTR PRA4
834 #define ARG_TLS ARG5
835 #define PRA_TLS PRA5
836 #else
837 # error Unknown platform
838 #endif
839 // And s390x is even more special, and inverts flags and child stack args
840 #if defined(VGP_s390x_linux)
841 #define ARG_FLAGS ARG2
842 #define PRA_FLAGS PRA2
843 #define ARG_CHILD_STACK ARG1
844 #define PRA_CHILD_STACK PRA1
845 #else
846 #define ARG_FLAGS ARG1
847 #define PRA_FLAGS PRA1
848 #define ARG_CHILD_STACK ARG2
849 #define PRA_CHILD_STACK PRA2
850 #endif
852 if (VG_(tdict).track_pre_reg_read) {
853 PRA_FLAGS("clone", unsigned long, flags);
854 PRA_CHILD_STACK("clone", void *, child_stack);
857 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD)) {
858 if (VG_(tdict).track_pre_reg_read) {
859 PRA3("clone", int *, parent_tidptr);
861 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
862 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
863 VKI_PROT_WRITE)) {
864 badarg = True;
867 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
868 if (VG_(tdict).track_pre_reg_read) {
869 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
871 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
872 dummy type (that we define as a char). We only dereference/check the
873 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
874 if (sizeof(vki_modify_ldt_t) > 1) {
875 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
876 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
877 VKI_PROT_READ)) {
878 badarg = True;
882 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
883 if (VG_(tdict).track_pre_reg_read) {
884 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
886 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
887 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
888 VKI_PROT_WRITE)) {
889 badarg = True;
893 if (badarg) {
894 SET_STATUS_Failure( VKI_EFAULT );
895 return;
898 cloneflags = ARG_FLAGS;
900 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
901 SET_STATUS_Failure( VKI_EINVAL );
902 return;
905 /* Only look at the flags we really care about */
906 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
907 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
908 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
909 /* thread creation */
910 SET_STATUS_from_SysRes(
911 do_clone(tid,
912 ARG_FLAGS, /* flags */
913 (Addr)ARG_CHILD_STACK, /* child ESP */
914 (Int*)(Addr)ARG3, /* parent_tidptr */
915 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
916 (Addr)ARG_TLS)); /* set_tls */
917 break;
919 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
920 case VKI_CLONE_VFORK: /* vfork without memory sharing */
921 cloneflags &= ~VKI_CLONE_VM;
922 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
924 case 0: /* plain fork */
925 SET_STATUS_from_SysRes(
926 ML_(do_fork_clone)(tid,
927 cloneflags, /* flags */
928 (Int*)(Addr)ARG3, /* parent_tidptr */
929 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
930 (Addr)ARG_CHILD_STACK));
931 break;
933 default:
934 /* should we just ENOSYS? */
935 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
936 "x\n", ARG_FLAGS);
937 VG_(message)(Vg_UserMsg, "\n");
938 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
939 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
940 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
941 VG_(unimplemented)
942 ("Valgrind does not support general clone().");
945 if (SUCCESS && RES != 0) {
946 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD))
947 POST_MEM_WRITE(ARG3, sizeof(Int));
948 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
949 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
950 if (ARG_FLAGS & VKI_CLONE_PIDFD) {
951 Int fd = *(Int*)(Addr)ARG3;
952 if (!ML_(fd_allowed)(fd, "clone", tid, True)) {
953 VG_(close)(fd);
954 SET_STATUS_Failure( VKI_EMFILE );
955 } else {
956 if (VG_(clo_track_fds))
957 ML_(record_fd_open_nameless) (tid, fd);
961 /* Thread creation was successful; let the child have the chance
962 to run */
963 *flags |= SfYieldAfter;
966 #undef ARG_CHILD_TIDPTR
967 #undef PRA_CHILD_TIDPTR
968 #undef ARG_TLS
969 #undef PRA_TLS
970 #undef ARG_FLAGS
971 #undef PRA_FLAGS
972 #undef ARG_CHILD_STACK
973 #undef PRA_CHILD_STACK
976 /* ---------------------------------------------------------------------
977 *mount wrappers
978 ------------------------------------------------------------------ */
980 PRE(sys_mount)
982 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
983 // We are conservative and check everything, except the memory pointed to
984 // by 'data'.
985 *flags |= SfMayBlock;
986 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
987 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
988 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
989 (HChar*)(Addr)ARG3, ARG4, ARG5);
990 PRE_REG_READ5(long, "mount",
991 char *, source, char *, target, char *, type,
992 unsigned long, flags, void *, data);
993 if (ARG1)
994 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
995 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
996 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
999 PRE(sys_oldumount)
1001 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
1002 PRE_REG_READ1(long, "umount", char *, path);
1003 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
1006 PRE(sys_umount)
1008 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
1009 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
1010 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1013 /* Not actually wrapped by GLibc but does things with the system
1014 * mounts so it is put here.
1016 PRE(sys_pivot_root)
1018 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1019 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1020 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1021 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1025 /* ---------------------------------------------------------------------
1026 16- and 32-bit uid/gid wrappers
1027 ------------------------------------------------------------------ */
1029 PRE(sys_setfsuid16)
1031 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1032 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1035 PRE(sys_setfsuid)
1037 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1038 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1041 PRE(sys_setfsgid16)
1043 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1044 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1047 PRE(sys_setfsgid)
1049 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1050 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1053 PRE(sys_setresuid16)
1055 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1056 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1057 PRE_REG_READ3(long, "setresuid16",
1058 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1061 PRE(sys_setresuid)
1063 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1064 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1065 PRE_REG_READ3(long, "setresuid",
1066 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1069 PRE(sys_getresuid16)
1071 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1072 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1073 PRE_REG_READ3(long, "getresuid16",
1074 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1075 vki_old_uid_t *, suid);
1076 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1077 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1078 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1080 POST(sys_getresuid16)
1082 vg_assert(SUCCESS);
1083 if (RES == 0) {
1084 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1085 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1086 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1090 PRE(sys_getresuid)
1092 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1093 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1094 PRE_REG_READ3(long, "getresuid",
1095 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1096 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1097 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1098 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1100 POST(sys_getresuid)
1102 vg_assert(SUCCESS);
1103 if (RES == 0) {
1104 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1105 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1106 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1110 PRE(sys_setresgid16)
1112 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1113 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1114 PRE_REG_READ3(long, "setresgid16",
1115 vki_old_gid_t, rgid,
1116 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1119 PRE(sys_setresgid)
1121 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1122 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1123 PRE_REG_READ3(long, "setresgid",
1124 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1127 PRE(sys_getresgid16)
1129 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1130 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1131 PRE_REG_READ3(long, "getresgid16",
1132 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1133 vki_old_gid_t *, sgid);
1134 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1135 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1136 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1138 POST(sys_getresgid16)
1140 vg_assert(SUCCESS);
1141 if (RES == 0) {
1142 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1143 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1144 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1148 PRE(sys_getresgid)
1150 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1151 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1152 PRE_REG_READ3(long, "getresgid",
1153 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1154 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1155 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1156 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1158 POST(sys_getresgid)
1160 vg_assert(SUCCESS);
1161 if (RES == 0) {
1162 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1163 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1164 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1168 /* ---------------------------------------------------------------------
1169 miscellaneous wrappers
1170 ------------------------------------------------------------------ */
1172 PRE(sys_exit_group)
1174 ThreadId t;
1175 ThreadState* tst;
1177 PRINT("exit_group( %ld )", SARG1);
1178 PRE_REG_READ1(void, "exit_group", int, status);
1180 tst = VG_(get_ThreadState)(tid);
1181 /* A little complex; find all the threads with the same threadgroup
1182 as this one (including this one), and mark them to exit */
1183 /* It is unclear how one can get a threadgroup in this process which
1184 is not the threadgroup of the calling thread:
1185 The assignments to threadgroups are:
1186 = 0; /// scheduler.c os_state_clear
1187 = getpid(); /// scheduler.c in child after fork
1188 = getpid(); /// this file, in thread_wrapper
1189 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1190 copying the thread group of the thread doing clone
1191 So, the only case where the threadgroup might be different to the getpid
1192 value is in the child, just after fork. But then the fork syscall is
1193 still going on, the forked thread has had no chance yet to make this
1194 syscall. */
1195 for (t = 1; t < VG_N_THREADS; t++) {
1196 if ( /* not alive */
1197 VG_(threads)[t].status == VgTs_Empty
1199 /* not our group */
1200 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1202 continue;
1203 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1204 the exitreason. */
1205 VG_(threads)[t].os_state.exitcode = ARG1;
1208 /* Indicate in all other threads that the process is exiting.
1209 Then wait using VG_(reap_threads) for these threads to disappear.
1211 Can this give a deadlock if another thread is calling exit in parallel
1212 and would then wait for this thread to disappear ?
1213 The answer is no:
1214 Other threads are either blocked in a syscall or have yielded the CPU.
1216 A thread that has yielded the CPU is trying to get the big lock in
1217 VG_(scheduler). This thread will get the CPU thanks to the call
1218 to VG_(reap_threads). The scheduler will then check for signals,
1219 kill the process if this is a fatal signal, and otherwise prepare
1220 the thread for handling this signal. After this preparation, if
1221 the thread status is VG_(is_exiting), the scheduler exits the thread.
1222 So, a thread that has yielded the CPU does not have a chance to
1223 call exit => no deadlock for this thread.
1225 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1226 to all threads blocked in a syscall.
1227 The syscall will be interrupted, and the control will go to the
1228 scheduler. The scheduler will then return, as the thread is in
1229 exiting state. */
1231 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1232 VG_(reap_threads)(tid);
1233 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1234 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1235 is the thread calling exit_group and so its registers must be considered
1236 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1238 /* We have to claim the syscall already succeeded. */
1239 SET_STATUS_Success(0);
1242 PRE(sys_llseek)
1244 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1245 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1246 ARG1, ARG2, ARG3, ARG4, ARG5);
1247 PRE_REG_READ5(long, "llseek",
1248 unsigned int, fd, unsigned long, offset_high,
1249 unsigned long, offset_low, vki_loff_t *, result,
1250 unsigned int, whence);
1251 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1252 SET_STATUS_Failure( VKI_EBADF );
1253 else
1254 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1256 POST(sys_llseek)
1258 vg_assert(SUCCESS);
1259 if (RES == 0)
1260 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1263 PRE(sys_adjtimex)
1265 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1266 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1267 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1269 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1270 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1272 #define ADJX(bits,field) \
1273 if (tx->modes & (bits)) \
1274 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1275 (Addr)&tx->field, sizeof(tx->field))
1277 if (tx->modes & VKI_ADJ_ADJTIME) {
1278 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1279 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1280 } else {
1281 ADJX(VKI_ADJ_OFFSET, offset);
1282 ADJX(VKI_ADJ_FREQUENCY, freq);
1283 ADJX(VKI_ADJ_MAXERROR, maxerror);
1284 ADJX(VKI_ADJ_ESTERROR, esterror);
1285 ADJX(VKI_ADJ_STATUS, status);
1286 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1287 ADJX(VKI_ADJ_TICK, tick);
1289 #undef ADJX
1292 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1295 POST(sys_adjtimex)
1297 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1300 PRE(sys_clock_adjtime)
1302 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1303 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1304 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1305 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1307 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1308 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1310 #define ADJX(bits,field) \
1311 if (tx->modes & (bits)) \
1312 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1313 (Addr)&tx->field, sizeof(tx->field))
1315 if (tx->modes & VKI_ADJ_ADJTIME) {
1316 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1317 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1318 } else {
1319 ADJX(VKI_ADJ_OFFSET, offset);
1320 ADJX(VKI_ADJ_FREQUENCY, freq);
1321 ADJX(VKI_ADJ_MAXERROR, maxerror);
1322 ADJX(VKI_ADJ_ESTERROR, esterror);
1323 ADJX(VKI_ADJ_STATUS, status);
1324 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1325 ADJX(VKI_ADJ_TICK, tick);
1327 #undef ADJX
1330 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1333 POST(sys_clock_adjtime)
1335 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1338 PRE(sys_ioperm)
1340 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1341 ARG1, ARG2, SARG3 );
1342 PRE_REG_READ3(long, "ioperm",
1343 unsigned long, from, unsigned long, num, int, turn_on);
1346 PRE(sys_syslog)
1348 *flags |= SfMayBlock;
1349 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1350 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1351 switch (ARG1) {
1352 // The kernel uses magic numbers here, rather than named constants,
1353 // therefore so do we.
1354 case 2: case 3: case 4:
1355 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1356 break;
1357 default:
1358 break;
1361 POST(sys_syslog)
1363 switch (ARG1) {
1364 case 2: case 3: case 4:
1365 POST_MEM_WRITE( ARG2, ARG3 );
1366 break;
1367 default:
1368 break;
1372 PRE(sys_vhangup)
1374 PRINT("sys_vhangup ( )");
1375 PRE_REG_READ0(long, "vhangup");
1378 PRE(sys_sysinfo)
1380 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1381 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1382 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1384 POST(sys_sysinfo)
1386 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1389 PRE(sys_personality)
1391 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1392 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1395 PRE(sys_sysctl)
1397 struct __vki_sysctl_args *args;
1398 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1399 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1400 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1401 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1402 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1403 VKI_PROT_READ)) {
1404 SET_STATUS_Failure( VKI_EFAULT );
1405 return;
1408 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1409 if (args->newval != NULL)
1410 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1411 if (args->oldlenp != NULL) {
1412 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1413 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1416 POST(sys_sysctl)
1418 struct __vki_sysctl_args *args;
1419 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1420 if (args->oldlenp != NULL) {
1421 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1422 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1426 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1427 const char *attr_name)
1429 const HChar *step_str = (const HChar *)str;
1430 SizeT len;
1431 UInt i;
1434 * The name can be up to maxlen bytes long, including the terminating null
1435 * byte. So do not check more than maxlen bytes.
1437 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1438 len = VG_(strnlen)((const HChar *)str, maxlen);
1439 if (len < maxlen)
1440 PRE_MEM_RASCIIZ(attr_name, str);
1441 else
1442 PRE_MEM_READ(attr_name, str, maxlen);
1443 } else {
1445 * Do it the slow way, one byte at a time, while checking for terminating
1446 * '\0'.
1448 for (i = 0; i < maxlen; i++) {
1449 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1450 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1451 break;
1456 PRE(sys_prctl)
1458 *flags |= SfMayBlock;
1459 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1460 switch (ARG1) {
1461 case VKI_PR_SET_PDEATHSIG:
1462 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1463 break;
1464 case VKI_PR_GET_PDEATHSIG:
1465 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1466 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1467 break;
1468 case VKI_PR_GET_DUMPABLE:
1469 PRE_REG_READ1(int, "prctl", int, option);
1470 break;
1471 case VKI_PR_SET_DUMPABLE:
1472 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1473 break;
1474 case VKI_PR_GET_UNALIGN:
1475 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1476 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1477 break;
1478 case VKI_PR_SET_UNALIGN:
1479 PRE_REG_READ2(int, "prctl", int, option, int, value);
1480 break;
1481 case VKI_PR_GET_KEEPCAPS:
1482 PRE_REG_READ1(int, "prctl", int, option);
1483 break;
1484 case VKI_PR_SET_KEEPCAPS:
1485 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1486 break;
1487 case VKI_PR_GET_FPEMU:
1488 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1489 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1490 break;
1491 case VKI_PR_SET_FPEMU:
1492 PRE_REG_READ2(int, "prctl", int, option, int, value);
1493 break;
1494 case VKI_PR_GET_FPEXC:
1495 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1496 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1497 break;
1498 case VKI_PR_SET_FPEXC:
1499 PRE_REG_READ2(int, "prctl", int, option, int, value);
1500 break;
1501 case VKI_PR_GET_TIMING:
1502 PRE_REG_READ1(int, "prctl", int, option);
1503 break;
1504 case VKI_PR_SET_TIMING:
1505 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1506 break;
1507 case VKI_PR_SET_NAME:
1508 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1509 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1510 break;
1511 case VKI_PR_GET_NAME:
1512 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1513 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1514 break;
1515 case VKI_PR_GET_ENDIAN:
1516 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1517 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1518 break;
1519 case VKI_PR_SET_ENDIAN:
1520 PRE_REG_READ2(int, "prctl", int, option, int, value);
1521 break;
1522 case VKI_PR_SET_PTRACER:
1523 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1524 break;
1525 case VKI_PR_SET_SECCOMP:
1526 /* This is a bit feeble in that it uses |option| before checking
1527 it, but at least both sides of the conditional check it. */
1528 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1529 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1530 if (ARG3) {
1531 /* Should check that ARG3 points at a valid struct sock_fprog.
1532 Sounds complex; hence be lame. */
1533 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1534 ARG3, 1 );
1536 } else {
1537 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1539 break;
1540 case VKI_PR_CAPBSET_READ:
1541 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1542 break;
1543 case VKI_PR_CAPBSET_DROP:
1544 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1545 break;
1546 default:
1547 PRE_REG_READ5(long, "prctl",
1548 int, option, unsigned long, arg2, unsigned long, arg3,
1549 unsigned long, arg4, unsigned long, arg5);
1550 break;
1553 POST(sys_prctl)
1555 switch (ARG1) {
1556 case VKI_PR_GET_PDEATHSIG:
1557 POST_MEM_WRITE(ARG2, sizeof(Int));
1558 break;
1559 case VKI_PR_GET_UNALIGN:
1560 POST_MEM_WRITE(ARG2, sizeof(Int));
1561 break;
1562 case VKI_PR_GET_FPEMU:
1563 POST_MEM_WRITE(ARG2, sizeof(Int));
1564 break;
1565 case VKI_PR_GET_FPEXC:
1566 POST_MEM_WRITE(ARG2, sizeof(Int));
1567 break;
1568 case VKI_PR_GET_NAME:
1569 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1570 break;
1571 case VKI_PR_GET_ENDIAN:
1572 POST_MEM_WRITE(ARG2, sizeof(Int));
1573 break;
1574 case VKI_PR_SET_NAME:
1576 const HChar* new_name = (const HChar*) (Addr)ARG2;
1577 if (new_name) { // Paranoia
1578 ThreadState* tst = VG_(get_ThreadState)(tid);
1579 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1581 /* Don't bother reusing the memory. This is a rare event. */
1582 tst->thread_name =
1583 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1584 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1587 break;
1591 PRE(sys_sendfile)
1593 *flags |= SfMayBlock;
1594 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1595 SARG1, SARG2, ARG3, ARG4);
1596 PRE_REG_READ4(ssize_t, "sendfile",
1597 int, out_fd, int, in_fd, vki_off_t *, offset,
1598 vki_size_t, count);
1599 if (ARG3 != 0)
1600 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1602 POST(sys_sendfile)
1604 if (ARG3 != 0 ) {
1605 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1609 PRE(sys_sendfile64)
1611 *flags |= SfMayBlock;
1612 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1613 SARG1, SARG2, ARG3, ARG4);
1614 PRE_REG_READ4(ssize_t, "sendfile64",
1615 int, out_fd, int, in_fd, vki_loff_t *, offset,
1616 vki_size_t, count);
1617 if (ARG3 != 0)
1618 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1620 POST(sys_sendfile64)
1622 if (ARG3 != 0 ) {
1623 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1627 static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
1629 struct vki_timespec64 *ts64 = (void *)(Addr)arg;
1630 PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
1631 PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
1634 static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
1636 struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
1637 pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
1638 pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
1641 static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1642 SyscallArgs* arrghs, SyscallStatus* status,
1643 UWord* flags, Bool is_time64 )
1646 arg param used by ops
1648 ARG1 - u32 *futex all
1649 ARG2 - int op
1650 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1651 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1652 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1653 ARG6 - int val3 CMP_REQUEUE
1656 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1657 case VKI_FUTEX_CMP_REQUEUE:
1658 case VKI_FUTEX_WAKE_OP:
1659 case VKI_FUTEX_CMP_REQUEUE_PI:
1660 if (is_time64) {
1661 PRE_REG_READ6(long, "futex_time64",
1662 vki_u32 *, futex, int, op, int, val,
1663 struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
1664 } else {
1665 PRE_REG_READ6(long, "futex",
1666 vki_u32 *, futex, int, op, int, val,
1667 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1669 break;
1670 case VKI_FUTEX_REQUEUE:
1671 case VKI_FUTEX_WAIT_REQUEUE_PI:
1672 if (is_time64) {
1673 PRE_REG_READ5(long, "futex_time64",
1674 vki_u32 *, futex, int, op, int, val,
1675 struct timespec64 *, utime, vki_u32 *, uaddr2);
1676 } else {
1677 PRE_REG_READ5(long, "futex",
1678 vki_u32 *, futex, int, op, int, val,
1679 struct timespec *, utime, vki_u32 *, uaddr2);
1681 break;
1682 case VKI_FUTEX_WAIT_BITSET:
1683 /* Check that the address at least begins in client-accessible area. */
1684 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1685 SET_STATUS_Failure( VKI_EFAULT );
1686 return;
1688 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1689 if (is_time64) {
1690 PRE_REG_READ4(long, "futex_time64",
1691 vki_u32 *, futex, int, op, int, val,
1692 struct timespec64 *, utime);
1693 } else {
1694 PRE_REG_READ4(long, "futex",
1695 vki_u32 *, futex, int, op, int, val,
1696 struct timespec64 *, utime);
1698 } else {
1699 /* Note argument 5 is unused, but argument 6 is used.
1700 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1701 if (is_time64) {
1702 PRE_REG_READ4(long, "futex_time64",
1703 vki_u32 *, futex, int, op, int, val,
1704 struct timespec64 *, utime);
1705 } else {
1706 PRE_REG_READ4(long, "futex",
1707 vki_u32 *, futex, int, op, int, val,
1708 struct timespec *, utime);
1710 if (VG_(tdict).track_pre_reg_read)
1711 PRA6("futex",int,val3);
1713 break;
1714 case VKI_FUTEX_WAKE_BITSET:
1715 PRE_REG_READ3(long, "futex",
1716 vki_u32 *, futex, int, op, int, val);
1717 if (VG_(tdict).track_pre_reg_read) {
1718 PRA6("futex", int, val3);
1720 break;
1721 case VKI_FUTEX_WAIT:
1722 case VKI_FUTEX_LOCK_PI:
1723 if (is_time64) {
1724 PRE_REG_READ4(long, "futex_time64",
1725 vki_u32 *, futex, int, op, int, val,
1726 struct timespec64 *, utime);
1727 } else {
1728 PRE_REG_READ4(long, "futex",
1729 vki_u32 *, futex, int, op, int, val,
1730 struct timespec *, utime);
1732 break;
1733 case VKI_FUTEX_WAKE:
1734 case VKI_FUTEX_FD:
1735 PRE_REG_READ3(long, "futex",
1736 vki_u32 *, futex, int, op, int, val);
1737 break;
1738 case VKI_FUTEX_TRYLOCK_PI:
1739 case VKI_FUTEX_UNLOCK_PI:
1740 default:
1741 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1742 break;
1745 *flags |= SfMayBlock;
1746 if ((ARG2 & (VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_LOCK_PI)) == (VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_LOCK_PI)) {
1747 *flags |= SfKernelRestart;
1750 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1751 case VKI_FUTEX_WAIT:
1752 case VKI_FUTEX_LOCK_PI:
1753 case VKI_FUTEX_WAIT_BITSET:
1754 case VKI_FUTEX_WAIT_REQUEUE_PI:
1755 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1756 if (ARG4 != 0) {
1757 if (is_time64) {
1758 pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
1759 } else {
1760 PRE_MEM_READ( "futex(timeout)", ARG4,
1761 sizeof(struct vki_timespec) );
1764 break;
1766 case VKI_FUTEX_REQUEUE:
1767 case VKI_FUTEX_CMP_REQUEUE:
1768 case VKI_FUTEX_CMP_REQUEUE_PI:
1769 case VKI_FUTEX_WAKE_OP:
1770 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1771 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1772 break;
1774 case VKI_FUTEX_FD:
1775 case VKI_FUTEX_TRYLOCK_PI:
1776 case VKI_FUTEX_UNLOCK_PI:
1777 case VKI_FUTEX_WAKE:
1778 case VKI_FUTEX_WAKE_BITSET:
1779 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1780 break;
1782 default:
1783 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1784 break;
1788 static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
1789 SyscallStatus* status )
1791 vg_assert(SUCCESS);
1792 POST_MEM_WRITE( ARG1, sizeof(int) );
1793 if (ARG2 == VKI_FUTEX_FD) {
1794 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1795 VG_(close)(RES);
1796 SET_STATUS_Failure( VKI_EMFILE );
1797 } else {
1798 if (VG_(clo_track_fds))
1799 ML_(record_fd_open_nameless)(tid, RES);
1804 PRE(sys_futex)
1806 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1807 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1808 futex_pre_helper (tid, layout, arrghs, status, flags, False);
1811 POST(sys_futex)
1813 futex_post_helper (tid, arrghs, status);
1816 PRE(sys_futex_time64)
1818 PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1819 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1820 futex_pre_helper (tid, layout, arrghs, status, flags, True);
1823 POST(sys_futex_time64)
1825 futex_post_helper (tid, arrghs, status);
1828 PRE(sys_set_robust_list)
1830 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1831 FMT_REGWORD "u )", ARG1, ARG2);
1832 PRE_REG_READ2(long, "set_robust_list",
1833 struct vki_robust_list_head *, head, vki_size_t, len);
1835 /* Just check the robust_list_head structure is readable - don't
1836 try and chase the list as the kernel will only read it when
1837 the thread exits so the current contents is irrelevant. */
1838 if (ARG1 != 0)
1839 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1842 PRE(sys_get_robust_list)
1844 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1845 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1846 PRE_REG_READ3(long, "get_robust_list",
1847 int, pid,
1848 struct vki_robust_list_head **, head_ptr,
1849 vki_size_t *, len_ptr);
1850 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1851 ARG2, sizeof(struct vki_robust_list_head *));
1852 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1853 ARG3, sizeof(struct vki_size_t *));
1855 POST(sys_get_robust_list)
1857 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1858 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1861 struct pselect_sized_sigset {
1862 const vki_sigset_t *ss;
1863 vki_size_t ss_len;
1865 struct pselect_adjusted_sigset {
1866 struct pselect_sized_sigset ss; /* The actual syscall arg */
1867 vki_sigset_t adjusted_ss;
1870 static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1871 SyscallArgs* arrghs, SyscallStatus* status,
1872 UWord* flags, Bool is_time64 )
1874 *flags |= SfMayBlock | SfPostOnFail;
1875 if (is_time64) {
1876 PRE_REG_READ6(long, "pselect6_time64",
1877 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1878 vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
1879 void *, sig);
1880 } else {
1881 PRE_REG_READ6(long, "pselect6",
1882 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1883 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
1884 void *, sig);
1886 // XXX: this possibly understates how much memory is read.
1887 if (ARG2 != 0)
1888 PRE_MEM_READ( "pselect6(readfds)",
1889 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1890 if (ARG3 != 0)
1891 PRE_MEM_READ( "pselect6(writefds)",
1892 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1893 if (ARG4 != 0)
1894 PRE_MEM_READ( "pselect6(exceptfds)",
1895 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1896 if (ARG5 != 0) {
1897 if (is_time64) {
1898 pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
1899 } else {
1900 PRE_MEM_READ( "pselect6(timeout)", ARG5,
1901 sizeof(struct vki_timespec) );
1904 if (ARG6 != 0) {
1905 const struct pselect_sized_sigset *pss =
1906 (struct pselect_sized_sigset *)(Addr)ARG6;
1907 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1908 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1909 ARG6 = 1; /* Something recognisable to POST() hook. */
1910 } else {
1911 struct pselect_adjusted_sigset *pas;
1912 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1913 ARG6 = (Addr)pas;
1914 pas->ss.ss = (void *)1;
1915 pas->ss.ss_len = pss->ss_len;
1916 if (pss->ss_len == sizeof(*pss->ss)) {
1917 if (pss->ss == NULL) {
1918 pas->ss.ss = NULL;
1919 } else {
1920 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1921 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1922 pas->adjusted_ss = *pss->ss;
1923 pas->ss.ss = &pas->adjusted_ss;
1924 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1932 PRE(sys_pselect6)
1934 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1935 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1936 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1937 pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
1940 POST(sys_pselect6)
1942 if (ARG6 != 0 && ARG6 != 1) {
1943 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1947 PRE(sys_pselect6_time64)
1949 PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1950 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1951 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1952 pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
1955 POST(sys_pselect6_time64)
1957 if (ARG6 != 0 && ARG6 != 1) {
1958 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1962 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1963 SyscallArgs* arrghs, SyscallStatus* status,
1964 UWord* flags, Bool is_time64 )
1966 UInt i;
1967 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1968 *flags |= SfMayBlock | SfPostOnFail;
1969 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1970 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1971 ARG1, ARG2, ARG3, ARG4, ARG5);
1972 if (is_time64) {
1973 PRE_REG_READ5(long, "ppoll_time64",
1974 struct vki_pollfd *, ufds, unsigned int, nfds,
1975 struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
1976 vki_size_t, sigsetsize);
1977 } else {
1978 PRE_REG_READ5(long, "ppoll",
1979 struct vki_pollfd *, ufds, unsigned int, nfds,
1980 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1981 vki_size_t, sigsetsize);
1984 for (i = 0; i < ARG2; i++) {
1985 PRE_MEM_READ( "ppoll(ufds.fd)",
1986 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1987 PRE_MEM_READ( "ppoll(ufds.events)",
1988 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1989 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1990 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1993 if (ARG3) {
1994 if (is_time64) {
1995 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
1996 } else {
1997 PRE_MEM_READ( "ppoll(tsp)", ARG3,
1998 sizeof(struct vki_timespec) );
2001 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
2002 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
2003 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
2004 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
2005 ARG4 = 1; /* Something recognisable to POST() hook. */
2006 } else {
2007 vki_sigset_t *vg_sigmask =
2008 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
2009 ARG4 = (Addr)vg_sigmask;
2010 *vg_sigmask = *guest_sigmask;
2011 VG_(sanitize_client_sigmask)(vg_sigmask);
2016 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2017 SyscallStatus* status )
2019 vg_assert(SUCCESS || FAILURE);
2020 if (SUCCESS && (RES >= 0)) {
2021 UInt i;
2022 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2023 for (i = 0; i < ARG2; i++)
2024 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2026 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
2027 VG_(free)((vki_sigset_t *) (Addr)ARG4);
2031 PRE(sys_ppoll)
2033 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2034 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2035 ARG1, ARG2, ARG3, ARG4, ARG5);
2036 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2039 POST(sys_ppoll)
2041 ppoll_post_helper (tid, arrghs, status);
2044 PRE(sys_ppoll_time64)
2046 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2047 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2048 ARG1, ARG2, ARG3, ARG4, ARG5);
2049 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2052 POST(sys_ppoll_time64)
2054 ppoll_post_helper (tid, arrghs, status);
2058 /* ---------------------------------------------------------------------
2059 epoll_* wrappers
2060 ------------------------------------------------------------------ */
2062 PRE(sys_epoll_create)
2064 PRINT("sys_epoll_create ( %ld )", SARG1);
2065 PRE_REG_READ1(long, "epoll_create", int, size);
2067 POST(sys_epoll_create)
2069 vg_assert(SUCCESS);
2070 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2071 VG_(close)(RES);
2072 SET_STATUS_Failure( VKI_EMFILE );
2073 } else {
2074 if (VG_(clo_track_fds))
2075 ML_(record_fd_open_nameless) (tid, RES);
2079 PRE(sys_epoll_create1)
2081 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2082 PRE_REG_READ1(long, "epoll_create1", int, flags);
2084 POST(sys_epoll_create1)
2086 vg_assert(SUCCESS);
2087 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2088 VG_(close)(RES);
2089 SET_STATUS_Failure( VKI_EMFILE );
2090 } else {
2091 if (VG_(clo_track_fds))
2092 ML_(record_fd_open_nameless) (tid, RES);
2096 PRE(sys_epoll_ctl)
2098 static const HChar* epoll_ctl_s[3] = {
2099 "EPOLL_CTL_ADD",
2100 "EPOLL_CTL_DEL",
2101 "EPOLL_CTL_MOD"
2103 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2104 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2105 PRE_REG_READ4(long, "epoll_ctl",
2106 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2107 if (ARG2 != VKI_EPOLL_CTL_DEL) {
2108 /* Just check the events field, the data field is for user space and
2109 unused by the kernel. */
2110 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2111 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2112 sizeof(__vki_u32) );
2116 /* RES event records have been written (exclude padding). */
2117 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2118 SyscallStatus* status )
2120 vg_assert(SUCCESS);
2121 if (RES > 0) {
2122 Int i;
2123 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2124 for (i = 0; i < RES; i++) {
2125 /* Assume both events and data are set (data is user space only). */
2126 POST_FIELD_WRITE(events[i].events);
2127 POST_FIELD_WRITE(events[i].data);
2132 PRE(sys_epoll_wait)
2134 *flags |= SfMayBlock;
2135 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2136 SARG1, ARG2, SARG3, SARG4);
2137 PRE_REG_READ4(long, "epoll_wait",
2138 int, epfd, struct vki_epoll_event *, events,
2139 int, maxevents, int, timeout);
2140 /* Assume all (maxevents) events records should be (fully) writable. */
2141 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2143 POST(sys_epoll_wait)
2145 epoll_post_helper (tid, arrghs, status);
2148 PRE(sys_epoll_pwait)
2150 *flags |= SfMayBlock;
2151 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2152 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2153 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2154 PRE_REG_READ6(long, "epoll_pwait",
2155 int, epfd, struct vki_epoll_event *, events,
2156 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2157 vki_size_t, sigsetsize);
2158 /* Assume all (maxevents) events records should be (fully) writable. */
2159 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2160 if (ARG5)
2161 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2163 POST(sys_epoll_pwait)
2165 epoll_post_helper (tid, arrghs, status);
2168 PRE(sys_eventfd)
2170 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2171 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2173 POST(sys_eventfd)
2175 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2176 VG_(close)(RES);
2177 SET_STATUS_Failure( VKI_EMFILE );
2178 } else {
2179 if (VG_(clo_track_fds))
2180 ML_(record_fd_open_nameless) (tid, RES);
2184 PRE(sys_eventfd2)
2186 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2187 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2189 POST(sys_eventfd2)
2191 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2192 VG_(close)(RES);
2193 SET_STATUS_Failure( VKI_EMFILE );
2194 } else {
2195 if (VG_(clo_track_fds))
2196 ML_(record_fd_open_nameless) (tid, RES);
2200 PRE(sys_fallocate)
2202 *flags |= SfMayBlock;
2203 #if VG_WORDSIZE == 4
2204 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2205 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2206 PRE_REG_READ6(long, "fallocate",
2207 int, fd, int, mode,
2208 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2209 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2210 #elif VG_WORDSIZE == 8
2211 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2212 SARG1, SARG2, SARG3, SARG4);
2213 PRE_REG_READ4(long, "fallocate",
2214 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2215 #else
2216 # error Unexpected word size
2217 #endif
2218 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2219 SET_STATUS_Failure( VKI_EBADF );
2222 PRE(sys_prlimit64)
2224 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2225 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2226 PRE_REG_READ4(long, "prlimit64",
2227 vki_pid_t, pid, unsigned int, resource,
2228 const struct rlimit64 *, new_rlim,
2229 struct rlimit64 *, old_rlim);
2230 if (ARG3)
2231 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2232 if (ARG4)
2233 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2235 if (ARG3 &&
2236 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2237 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2238 SET_STATUS_Failure( VKI_EINVAL );
2240 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2241 switch (ARG2) {
2242 case VKI_RLIMIT_NOFILE:
2243 SET_STATUS_Success( 0 );
2244 if (ARG4) {
2245 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2246 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2248 if (ARG3) {
2249 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2250 > VG_(fd_hard_limit) ||
2251 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2252 != VG_(fd_hard_limit)) {
2253 SET_STATUS_Failure( VKI_EPERM );
2255 else {
2256 VG_(fd_soft_limit) =
2257 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2260 break;
2262 case VKI_RLIMIT_DATA:
2263 SET_STATUS_Success( 0 );
2264 if (ARG4) {
2265 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2266 VG_(client_rlimit_data).rlim_cur;
2267 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2268 VG_(client_rlimit_data).rlim_max;
2270 if (ARG3) {
2271 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2272 > VG_(client_rlimit_data).rlim_max ||
2273 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2274 > VG_(client_rlimit_data).rlim_max) {
2275 SET_STATUS_Failure( VKI_EPERM );
2277 else {
2278 VG_(client_rlimit_data).rlim_cur =
2279 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2280 VG_(client_rlimit_data).rlim_max =
2281 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2284 break;
2286 case VKI_RLIMIT_STACK:
2287 SET_STATUS_Success( 0 );
2288 if (ARG4) {
2289 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2290 VG_(client_rlimit_stack).rlim_cur;
2291 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2292 VG_(client_rlimit_stack).rlim_max;
2294 if (ARG3) {
2295 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2296 > VG_(client_rlimit_stack).rlim_max ||
2297 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2298 > VG_(client_rlimit_stack).rlim_max) {
2299 SET_STATUS_Failure( VKI_EPERM );
2301 else {
2302 VG_(threads)[tid].client_stack_szB =
2303 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2304 VG_(client_rlimit_stack).rlim_cur =
2305 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2306 VG_(client_rlimit_stack).rlim_max =
2307 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2310 break;
2315 POST(sys_prlimit64)
2317 if (ARG4)
2318 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2321 /* ---------------------------------------------------------------------
2322 tid-related wrappers
2323 ------------------------------------------------------------------ */
2325 PRE(sys_gettid)
2327 PRINT("sys_gettid ()");
2328 PRE_REG_READ0(long, "gettid");
2331 PRE(sys_set_tid_address)
2333 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2334 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2337 PRE(sys_tkill)
2339 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2340 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2341 if (!ML_(client_signal_OK)(ARG2)) {
2342 SET_STATUS_Failure( VKI_EINVAL );
2343 return;
2346 /* Check to see if this kill gave us a pending signal */
2347 *flags |= SfPollAfter;
2349 if (VG_(clo_trace_signals))
2350 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2351 SARG2, SARG1);
2353 /* If we're sending SIGKILL, check to see if the target is one of
2354 our threads and handle it specially. */
2355 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2356 SET_STATUS_Success(0);
2357 return;
2360 /* Ask to handle this syscall via the slow route, since that's the
2361 only one that sets tst->status to VgTs_WaitSys. If the result
2362 of doing the syscall is an immediate run of
2363 async_signalhandler() in m_signals, then we need the thread to
2364 be properly tidied away. I have the impression the previous
2365 version of this wrapper worked on x86/amd64 only because the
2366 kernel did not immediately deliver the async signal to this
2367 thread (on ppc it did, which broke the assertion re tst->status
2368 at the top of async_signalhandler()). */
2369 *flags |= SfMayBlock;
2371 POST(sys_tkill)
2373 if (VG_(clo_trace_signals))
2374 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2375 SARG2, SARG1);
2378 PRE(sys_tgkill)
2380 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2381 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2382 if (!ML_(client_signal_OK)(ARG3)) {
2383 SET_STATUS_Failure( VKI_EINVAL );
2384 return;
2387 /* Check to see if this kill gave us a pending signal */
2388 *flags |= SfPollAfter;
2390 if (VG_(clo_trace_signals))
2391 VG_(message)(Vg_DebugMsg,
2392 "tgkill: sending signal %ld to pid %ld/%ld\n",
2393 SARG3, SARG1, SARG2);
2395 /* If we're sending SIGKILL, check to see if the target is one of
2396 our threads and handle it specially. */
2397 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2398 SET_STATUS_Success(0);
2399 return;
2402 /* Ask to handle this syscall via the slow route, since that's the
2403 only one that sets tst->status to VgTs_WaitSys. If the result
2404 of doing the syscall is an immediate run of
2405 async_signalhandler() in m_signals, then we need the thread to
2406 be properly tidied away. I have the impression the previous
2407 version of this wrapper worked on x86/amd64 only because the
2408 kernel did not immediately deliver the async signal to this
2409 thread (on ppc it did, which broke the assertion re tst->status
2410 at the top of async_signalhandler()). */
2411 *flags |= SfMayBlock;
2413 POST(sys_tgkill)
2415 if (VG_(clo_trace_signals))
2416 VG_(message)(Vg_DebugMsg,
2417 "tgkill: sent signal %ld to pid %ld/%ld\n",
2418 SARG3, SARG1, SARG2);
2421 /* ---------------------------------------------------------------------
2422 fadvise64* wrappers
2423 ------------------------------------------------------------------ */
2425 PRE(sys_fadvise64)
2427 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2428 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2429 PRE_REG_READ5(long, "fadvise64",
2430 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2431 vki_size_t, len, int, advice);
2434 PRE(sys_fadvise64_64)
2436 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2437 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2438 PRE_REG_READ6(long, "fadvise64_64",
2439 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2440 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2443 /* ---------------------------------------------------------------------
2444 io_* wrappers
2445 ------------------------------------------------------------------ */
2447 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2448 // and this allows us to control exactly the code that gets run while
2449 // the padding is in place.
2451 PRE(sys_io_setup)
2453 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2454 PRE_REG_READ2(long, "io_setup",
2455 unsigned, nr_events, vki_aio_context_t *, ctxp);
2456 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2459 POST(sys_io_setup)
2461 SizeT size;
2462 struct vki_aio_ring *r;
2464 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2465 ARG1*sizeof(struct vki_io_event));
2466 r = *(struct vki_aio_ring **)(Addr)ARG2;
2467 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2469 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2470 VKI_PROT_READ | VKI_PROT_WRITE,
2471 VKI_MAP_ANONYMOUS, -1, 0 );
2473 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2476 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2477 // after the syscall. We must get 'size' from the aio_ring structure,
2478 // before the syscall, while the aio_ring structure still exists. (And we
2479 // know that we must look at the aio_ring structure because Tom inspected the
2480 // kernel and glibc sources to see what they do, yuk.)
2482 // XXX This segment can be implicitly unmapped when aio
2483 // file-descriptors are closed...
2484 PRE(sys_io_destroy)
2486 SizeT size = 0;
2488 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2489 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2491 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2492 // possible...
2493 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2494 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2495 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2496 r->nr*sizeof(struct vki_io_event));
2499 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2501 if (SUCCESS && RES == 0) {
2502 Bool d = VG_(am_notify_munmap)( ARG1, size );
2503 VG_TRACK( die_mem_munmap, ARG1, size );
2504 if (d)
2505 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2506 "PRE(sys_io_destroy)" );
2510 PRE(sys_io_getevents)
2512 *flags |= SfMayBlock;
2513 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2514 FMT_REGWORD "x )",
2515 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2516 PRE_REG_READ5(long, "io_getevents",
2517 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2518 struct io_event *, events,
2519 struct timespec *, timeout);
2520 if (ARG3 > 0)
2521 PRE_MEM_WRITE( "io_getevents(events)",
2522 ARG4, sizeof(struct vki_io_event)*ARG3 );
2523 if (ARG5 != 0)
2524 PRE_MEM_READ( "io_getevents(timeout)",
2525 ARG5, sizeof(struct vki_timespec));
2527 POST(sys_io_getevents)
2529 Int i;
2530 vg_assert(SUCCESS);
2531 if (RES > 0) {
2532 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2533 for (i = 0; i < RES; i++) {
2534 const struct vki_io_event *vev =
2535 ((struct vki_io_event *)(Addr)ARG4) + i;
2536 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2538 switch (cb->aio_lio_opcode) {
2539 case VKI_IOCB_CMD_PREAD:
2540 if (vev->result > 0)
2541 POST_MEM_WRITE( cb->aio_buf, vev->result );
2542 break;
2544 case VKI_IOCB_CMD_PWRITE:
2545 break;
2547 case VKI_IOCB_CMD_FSYNC:
2548 break;
2550 case VKI_IOCB_CMD_FDSYNC:
2551 break;
2553 case VKI_IOCB_CMD_PREADV:
2554 if (vev->result > 0) {
2555 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2556 Int remains = vev->result;
2557 Int j;
2559 for (j = 0; j < cb->aio_nbytes; j++) {
2560 Int nReadThisBuf = vec[j].iov_len;
2561 if (nReadThisBuf > remains) nReadThisBuf = remains;
2562 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2563 remains -= nReadThisBuf;
2564 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2567 break;
2569 case VKI_IOCB_CMD_PWRITEV:
2570 break;
2572 default:
2573 VG_(message)(Vg_DebugMsg,
2574 "Warning: unhandled io_getevents opcode: %u\n",
2575 cb->aio_lio_opcode);
2576 break;
2582 PRE(sys_io_submit)
2584 Int i, j;
2586 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2587 ARG1, SARG2, ARG3);
2588 PRE_REG_READ3(long, "io_submit",
2589 vki_aio_context_t, ctx_id, long, nr,
2590 struct iocb **, iocbpp);
2591 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2592 if (ARG3 != 0) {
2593 for (i = 0; i < ARG2; i++) {
2594 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2595 struct vki_iovec *iov;
2597 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2598 switch (cb->aio_lio_opcode) {
2599 case VKI_IOCB_CMD_PREAD:
2600 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2601 break;
2603 case VKI_IOCB_CMD_PWRITE:
2604 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2605 break;
2607 case VKI_IOCB_CMD_FSYNC:
2608 break;
2610 case VKI_IOCB_CMD_FDSYNC:
2611 break;
2613 case VKI_IOCB_CMD_PREADV:
2614 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2615 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2616 for (j = 0; j < cb->aio_nbytes; j++)
2617 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2618 break;
2620 case VKI_IOCB_CMD_PWRITEV:
2621 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2622 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2623 for (j = 0; j < cb->aio_nbytes; j++)
2624 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2625 break;
2627 default:
2628 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2629 cb->aio_lio_opcode);
2630 break;
2636 PRE(sys_io_cancel)
2638 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2639 (ULong)ARG1, ARG2, ARG3);
2640 PRE_REG_READ3(long, "io_cancel",
2641 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2642 struct io_event *, result);
2643 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2644 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2646 POST(sys_io_cancel)
2648 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2651 /* ---------------------------------------------------------------------
2652 *_mempolicy wrappers
2653 ------------------------------------------------------------------ */
2655 PRE(sys_mbind)
2657 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2658 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2659 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2660 PRE_REG_READ6(long, "mbind",
2661 unsigned long, start, unsigned long, len,
2662 unsigned long, policy, unsigned long *, nodemask,
2663 unsigned long, maxnode, unsigned, flags);
2664 if (ARG1 != 0)
2665 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2666 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2669 PRE(sys_set_mempolicy)
2671 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2672 SARG1, ARG2, ARG3);
2673 PRE_REG_READ3(long, "set_mempolicy",
2674 int, policy, unsigned long *, nodemask,
2675 unsigned long, maxnode);
2676 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2677 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2680 PRE(sys_get_mempolicy)
2682 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2683 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2684 ARG1, ARG2, ARG3, ARG4, ARG5);
2685 PRE_REG_READ5(long, "get_mempolicy",
2686 int *, policy, unsigned long *, nodemask,
2687 unsigned long, maxnode, unsigned long, addr,
2688 unsigned long, flags);
2689 if (ARG1 != 0)
2690 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2691 if (ARG2 != 0)
2692 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2693 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2695 POST(sys_get_mempolicy)
2697 if (ARG1 != 0)
2698 POST_MEM_WRITE( ARG1, sizeof(Int) );
2699 if (ARG2 != 0)
2700 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2703 /* ---------------------------------------------------------------------
2704 fanotify_* wrappers
2705 ------------------------------------------------------------------ */
2707 PRE(sys_fanotify_init)
2709 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2710 ARG1, ARG2);
2711 PRE_REG_READ2(long, "fanotify_init",
2712 unsigned int, flags, unsigned int, event_f_flags);
2715 POST(sys_fanotify_init)
2717 vg_assert(SUCCESS);
2718 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2719 VG_(close)(RES);
2720 SET_STATUS_Failure( VKI_EMFILE );
2721 } else {
2722 if (VG_(clo_track_fds))
2723 ML_(record_fd_open_nameless) (tid, RES);
2727 PRE(sys_fanotify_mark)
2729 #if VG_WORDSIZE == 4
2730 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2731 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2732 (HChar *)(Addr)ARG6);
2733 PRE_REG_READ6(long, "sys_fanotify_mark",
2734 int, fanotify_fd, unsigned int, flags,
2735 __vki_u32, mask0, __vki_u32, mask1,
2736 int, dfd, const char *, pathname);
2737 if (ARG6)
2738 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2739 #elif VG_WORDSIZE == 8
2740 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2741 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2742 PRE_REG_READ5(long, "sys_fanotify_mark",
2743 int, fanotify_fd, unsigned int, flags,
2744 __vki_u64, mask,
2745 int, dfd, const char *, pathname);
2746 if (ARG5)
2747 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2748 #else
2749 # error Unexpected word size
2750 #endif
2753 /* ---------------------------------------------------------------------
2754 inotify_* wrappers
2755 ------------------------------------------------------------------ */
2757 PRE(sys_inotify_init)
2759 PRINT("sys_inotify_init ( )");
2760 PRE_REG_READ0(long, "inotify_init");
2762 POST(sys_inotify_init)
2764 vg_assert(SUCCESS);
2765 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2766 VG_(close)(RES);
2767 SET_STATUS_Failure( VKI_EMFILE );
2768 } else {
2769 if (VG_(clo_track_fds))
2770 ML_(record_fd_open_nameless) (tid, RES);
2774 PRE(sys_inotify_init1)
2776 PRINT("sys_inotify_init ( %ld )", SARG1);
2777 PRE_REG_READ1(long, "inotify_init", int, flag);
2780 POST(sys_inotify_init1)
2782 vg_assert(SUCCESS);
2783 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2784 VG_(close)(RES);
2785 SET_STATUS_Failure( VKI_EMFILE );
2786 } else {
2787 if (VG_(clo_track_fds))
2788 ML_(record_fd_open_nameless) (tid, RES);
2792 PRE(sys_inotify_add_watch)
2794 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2795 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2796 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2797 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2800 PRE(sys_inotify_rm_watch)
2802 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2803 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2806 /* ---------------------------------------------------------------------
2807 mq_* wrappers
2808 ------------------------------------------------------------------ */
2810 PRE(sys_mq_open)
2812 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2813 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2814 PRE_REG_READ4(long, "mq_open",
2815 const char *, name, int, oflag, vki_mode_t, mode,
2816 struct mq_attr *, attr);
2817 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2818 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2819 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2820 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2821 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2822 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2823 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2826 POST(sys_mq_open)
2828 vg_assert(SUCCESS);
2829 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2830 VG_(close)(RES);
2831 SET_STATUS_Failure( VKI_EMFILE );
2832 } else {
2833 if (VG_(clo_track_fds))
2834 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2838 PRE(sys_mq_unlink)
2840 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2841 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2842 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2845 PRE(sys_mq_timedsend)
2847 *flags |= SfMayBlock;
2848 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2849 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2850 SARG1,ARG2,ARG3,ARG4,ARG5);
2851 PRE_REG_READ5(long, "mq_timedsend",
2852 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2853 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2854 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2855 SET_STATUS_Failure( VKI_EBADF );
2856 } else {
2857 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2858 if (ARG5 != 0)
2859 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2860 sizeof(struct vki_timespec) );
2864 PRE(sys_mq_timedsend_time64)
2866 *flags |= SfMayBlock;
2867 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2868 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2869 SARG1,ARG2,ARG3,ARG4,ARG5);
2870 PRE_REG_READ5(long, "mq_timedsend_time64",
2871 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2872 unsigned int, msg_prio,
2873 const struct vki_timespec64 *, abs_timeout);
2874 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2875 SET_STATUS_Failure( VKI_EBADF );
2876 } else {
2877 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2878 if (ARG5 != 0)
2879 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2883 PRE(sys_mq_timedreceive)
2885 *flags |= SfMayBlock;
2886 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2887 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2888 SARG1,ARG2,ARG3,ARG4,ARG5);
2889 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2890 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2891 unsigned int *, msg_prio,
2892 const struct timespec *, abs_timeout);
2893 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2894 SET_STATUS_Failure( VKI_EBADF );
2895 } else {
2896 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2897 if (ARG4 != 0)
2898 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2899 ARG4, sizeof(unsigned int) );
2900 if (ARG5 != 0)
2901 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2902 ARG5, sizeof(struct vki_timespec) );
2905 POST(sys_mq_timedreceive)
2907 POST_MEM_WRITE( ARG2, RES );
2908 if (ARG4 != 0)
2909 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2912 PRE(sys_mq_timedreceive_time64)
2914 *flags |= SfMayBlock;
2915 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2916 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2917 SARG1,ARG2,ARG3,ARG4,ARG5);
2918 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2919 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2920 unsigned int *, msg_prio,
2921 const struct vki_timespec64 *, abs_timeout);
2922 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2923 SET_STATUS_Failure( VKI_EBADF );
2924 } else {
2925 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2926 if (ARG4 != 0)
2927 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2928 ARG4, sizeof(unsigned int) );
2929 if (ARG5 != 0)
2930 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2934 POST(sys_mq_timedreceive_time64)
2936 POST_MEM_WRITE( ARG2, RES );
2937 if (ARG4 != 0)
2938 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2941 PRE(sys_mq_notify)
2943 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2944 PRE_REG_READ2(long, "mq_notify",
2945 vki_mqd_t, mqdes, const struct sigevent *, notification);
2946 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2947 SET_STATUS_Failure( VKI_EBADF );
2948 else if (ARG2 != 0)
2949 PRE_MEM_READ( "mq_notify(notification)",
2950 ARG2, sizeof(struct vki_sigevent) );
2953 PRE(sys_mq_getsetattr)
2955 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2956 SARG1, ARG2, ARG3 );
2957 PRE_REG_READ3(long, "mq_getsetattr",
2958 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2959 struct mq_attr *, omqstat);
2960 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2961 SET_STATUS_Failure( VKI_EBADF );
2962 } else {
2963 if (ARG2 != 0) {
2964 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2965 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2966 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2968 if (ARG3 != 0)
2969 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2970 sizeof(struct vki_mq_attr) );
2973 POST(sys_mq_getsetattr)
2975 if (ARG3 != 0)
2976 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2979 /* ---------------------------------------------------------------------
2980 clock_* wrappers
2981 ------------------------------------------------------------------ */
2983 PRE(sys_clock_settime)
2985 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2986 PRE_REG_READ2(long, "clock_settime",
2987 vki_clockid_t, clk_id, const struct timespec *, tp);
2988 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2991 PRE(sys_clock_settime64)
2993 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2994 PRE_REG_READ2(long, "clock_settime64",
2995 vki_clockid_t, clk_id, const struct timespec64 *, tp);
2996 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
2999 PRE(sys_clock_gettime)
3001 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3002 PRE_REG_READ2(long, "clock_gettime",
3003 vki_clockid_t, clk_id, struct timespec *, tp);
3004 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3006 POST(sys_clock_gettime)
3008 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3011 PRE(sys_clock_gettime64)
3013 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3014 PRE_REG_READ2(long, "clock_gettime64",
3015 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3016 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3017 sizeof(struct vki_timespec64) );
3019 POST(sys_clock_gettime64)
3021 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3024 PRE(sys_clock_getres)
3026 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3027 // Nb: we can't use "RES" as the param name because that's a macro
3028 // defined above!
3029 PRE_REG_READ2(long, "clock_getres",
3030 vki_clockid_t, clk_id, struct timespec *, res);
3031 if (ARG2 != 0)
3032 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3034 POST(sys_clock_getres)
3036 if (ARG2 != 0)
3037 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3040 PRE(sys_clock_getres_time64)
3042 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3043 // Nb: we can't use "RES" as the param name because that's a macro
3044 // defined above!
3045 PRE_REG_READ2(long, "clock_getres_time64",
3046 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3047 if (ARG2 != 0)
3048 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3049 sizeof(struct vki_timespec64) );
3051 POST(sys_clock_getres_time64)
3053 if (ARG2 != 0)
3054 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3057 PRE(sys_clock_nanosleep)
3059 *flags |= SfMayBlock|SfPostOnFail;
3060 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3061 FMT_REGWORD "x )",
3062 SARG1, SARG2, ARG3, ARG4);
3063 PRE_REG_READ4(int32_t, "clock_nanosleep",
3064 vki_clockid_t, clkid, int, flags,
3065 const struct timespec *, rqtp, struct timespec *, rmtp);
3066 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3067 if (ARG4 != 0)
3068 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3070 POST(sys_clock_nanosleep)
3072 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3073 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3076 PRE(sys_clock_nanosleep_time64)
3078 *flags |= SfMayBlock|SfPostOnFail;
3079 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3080 FMT_REGWORD "x )",
3081 SARG1, SARG2, ARG3, ARG4);
3082 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3083 vki_clockid_t, clkid, int, flags,
3084 const struct vki_timespec64 *, rqtp,
3085 struct vki_timespec64 *, rmtp);
3086 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3087 if (ARG4 != 0)
3088 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3089 sizeof(struct vki_timespec64) );
3091 POST(sys_clock_nanosleep_time64)
3093 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3094 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3097 /* ---------------------------------------------------------------------
3098 timer_* wrappers
3099 ------------------------------------------------------------------ */
3101 PRE(sys_timer_create)
3103 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3104 SARG1, ARG2, ARG3);
3105 PRE_REG_READ3(long, "timer_create",
3106 vki_clockid_t, clockid, struct sigevent *, evp,
3107 vki_timer_t *, timerid);
3108 if (ARG2 != 0) {
3109 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3110 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3111 sizeof(vki_sigval_t) );
3112 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3113 sizeof(int) );
3114 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3115 sizeof(int) );
3116 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3117 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3118 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3119 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3121 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3123 POST(sys_timer_create)
3125 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3128 PRE(sys_timer_settime)
3130 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3131 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3132 PRE_REG_READ4(long, "timer_settime",
3133 vki_timer_t, timerid, int, flags,
3134 const struct itimerspec *, value,
3135 struct itimerspec *, ovalue);
3136 PRE_MEM_READ( "timer_settime(value)", ARG3,
3137 sizeof(struct vki_itimerspec) );
3138 if (ARG4 != 0)
3139 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3140 sizeof(struct vki_itimerspec) );
3142 POST(sys_timer_settime)
3144 if (ARG4 != 0)
3145 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3148 PRE(sys_timer_settime64)
3150 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3151 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3152 PRE_REG_READ4(long, "timer_settime64",
3153 vki_timer_t, timerid, int, flags,
3154 const struct vki_itimerspec64 *, value,
3155 struct vki_itimerspec64 *, ovalue);
3156 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3157 sizeof(struct vki_itimerspec64) );
3158 if (ARG4 != 0)
3159 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3160 sizeof(struct vki_itimerspec64) );
3162 POST(sys_timer_settime64)
3164 if (ARG4 != 0)
3165 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3168 PRE(sys_timer_gettime)
3170 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3171 PRE_REG_READ2(long, "timer_gettime",
3172 vki_timer_t, timerid, struct itimerspec *, value);
3173 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3174 sizeof(struct vki_itimerspec));
3176 POST(sys_timer_gettime)
3178 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3181 PRE(sys_timer_gettime64)
3183 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3184 PRE_REG_READ2(long, "timer_gettime64",
3185 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3186 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3187 sizeof(struct vki_itimerspec64));
3189 POST(sys_timer_gettime64)
3191 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3194 PRE(sys_timer_getoverrun)
3196 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3197 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3200 PRE(sys_timer_delete)
3202 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3203 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3206 /* ---------------------------------------------------------------------
3207 timerfd* wrappers
3208 See also http://lwn.net/Articles/260172/ for an overview.
3209 See also /usr/src/linux/fs/timerfd.c for the implementation.
3210 ------------------------------------------------------------------ */
3212 /* Returns True if running on 2.6.22, else False (or False if
3213 cannot be determined). */
3214 static Bool linux_kernel_2_6_22(void)
3216 static Int result = -1;
3217 Int fd, read;
3218 HChar release[64]; // large enough
3219 SysRes res;
3221 if (result == -1) {
3222 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3223 if (sr_isError(res))
3224 return False;
3225 fd = sr_Res(res);
3226 read = VG_(read)(fd, release, sizeof(release) - 1);
3227 if (read < 0)
3228 return False;
3229 release[read] = 0;
3230 VG_(close)(fd);
3231 //VG_(printf)("kernel release = %s\n", release);
3232 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3233 && ! VG_(isdigit)(release[6]);
3235 vg_assert(result == 0 || result == 1);
3236 return result == 1;
3239 PRE(sys_timerfd_create)
3241 if (linux_kernel_2_6_22()) {
3242 /* 2.6.22 kernel: timerfd system call. */
3243 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3244 PRE_REG_READ3(long, "sys_timerfd",
3245 int, fd, int, clockid, const struct itimerspec *, tmr);
3246 PRE_MEM_READ("timerfd(tmr)", ARG3,
3247 sizeof(struct vki_itimerspec) );
3248 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3249 SET_STATUS_Failure( VKI_EBADF );
3250 } else {
3251 /* 2.6.24 and later kernels: timerfd_create system call. */
3252 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3253 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3256 POST(sys_timerfd_create)
3258 if (linux_kernel_2_6_22())
3260 /* 2.6.22 kernel: timerfd system call. */
3261 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3262 VG_(close)(RES);
3263 SET_STATUS_Failure( VKI_EMFILE );
3264 } else {
3265 if (VG_(clo_track_fds))
3266 ML_(record_fd_open_nameless) (tid, RES);
3269 else
3271 /* 2.6.24 and later kernels: timerfd_create system call. */
3272 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3273 VG_(close)(RES);
3274 SET_STATUS_Failure( VKI_EMFILE );
3275 } else {
3276 if (VG_(clo_track_fds))
3277 ML_(record_fd_open_nameless) (tid, RES);
3282 PRE(sys_timerfd_gettime)
3284 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3285 PRE_REG_READ2(long, "timerfd_gettime",
3286 int, ufd,
3287 struct vki_itimerspec*, otmr);
3288 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3289 SET_STATUS_Failure(VKI_EBADF);
3290 else
3291 PRE_MEM_WRITE("timerfd_gettime(result)",
3292 ARG2, sizeof(struct vki_itimerspec));
3294 POST(sys_timerfd_gettime)
3296 if (RES == 0)
3297 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3300 PRE(sys_timerfd_gettime64)
3302 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3303 PRE_REG_READ2(long, "timerfd_gettime64",
3304 int, ufd,
3305 struct vki_itimerspec64*, otmr);
3306 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3307 SET_STATUS_Failure(VKI_EBADF);
3308 else
3309 PRE_MEM_WRITE("timerfd_gettime64(result)",
3310 ARG2, sizeof(struct vki_itimerspec64));
3312 POST(sys_timerfd_gettime64)
3314 if (RES == 0)
3315 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3318 PRE(sys_timerfd_settime)
3320 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3321 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3322 PRE_REG_READ4(long, "timerfd_settime",
3323 int, ufd,
3324 int, flags,
3325 const struct vki_itimerspec*, utmr,
3326 struct vki_itimerspec*, otmr);
3327 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3328 SET_STATUS_Failure(VKI_EBADF);
3329 else
3331 PRE_MEM_READ("timerfd_settime(result)",
3332 ARG3, sizeof(struct vki_itimerspec));
3333 if (ARG4)
3335 PRE_MEM_WRITE("timerfd_settime(result)",
3336 ARG4, sizeof(struct vki_itimerspec));
3340 POST(sys_timerfd_settime)
3342 if (RES == 0 && ARG4 != 0)
3343 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3346 PRE(sys_timerfd_settime64)
3348 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3349 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3350 PRE_REG_READ4(long, "timerfd_settime64",
3351 int, ufd,
3352 int, flags,
3353 const struct vki_itimerspec64*, utmr,
3354 struct vki_itimerspec64*, otmr);
3355 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3356 SET_STATUS_Failure(VKI_EBADF);
3357 else
3359 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3360 if (ARG4)
3362 PRE_MEM_WRITE("timerfd_settime64(result)",
3363 ARG4, sizeof(struct vki_itimerspec64));
3367 POST(sys_timerfd_settime64)
3369 if (RES == 0 && ARG4 != 0)
3370 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3373 /* ---------------------------------------------------------------------
3374 capabilities wrappers
3375 ------------------------------------------------------------------ */
3377 PRE(sys_capget)
3379 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3380 PRE_REG_READ2(long, "capget",
3381 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3382 PRE_MEM_READ( "capget(header)", ARG1,
3383 sizeof(struct __vki_user_cap_header_struct) );
3384 if (ARG2 != (Addr)NULL)
3385 PRE_MEM_WRITE( "capget(data)", ARG2,
3386 sizeof(struct __vki_user_cap_data_struct) );
3388 POST(sys_capget)
3390 if (ARG2 != (Addr)NULL)
3391 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3394 PRE(sys_capset)
3396 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3397 PRE_REG_READ2(long, "capset",
3398 vki_cap_user_header_t, header,
3399 const vki_cap_user_data_t, data);
3400 PRE_MEM_READ( "capset(header)",
3401 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3402 PRE_MEM_READ( "capset(data)",
3403 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3406 /* ---------------------------------------------------------------------
3407 16-bit uid/gid/groups wrappers
3408 ------------------------------------------------------------------ */
3410 PRE(sys_getuid16)
3412 PRINT("sys_getuid16 ( )");
3413 PRE_REG_READ0(long, "getuid16");
3416 PRE(sys_setuid16)
3418 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3419 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3422 PRE(sys_getgid16)
3424 PRINT("sys_getgid16 ( )");
3425 PRE_REG_READ0(long, "getgid16");
3428 PRE(sys_setgid16)
3430 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3431 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3434 PRE(sys_geteuid16)
3436 PRINT("sys_geteuid16 ( )");
3437 PRE_REG_READ0(long, "geteuid16");
3440 PRE(sys_getegid16)
3442 PRINT("sys_getegid16 ( )");
3443 PRE_REG_READ0(long, "getegid16");
3446 PRE(sys_setreuid16)
3448 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3449 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3452 PRE(sys_setregid16)
3454 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3455 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3458 PRE(sys_getgroups16)
3460 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3461 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3462 if (ARG1 > 0)
3463 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3465 POST(sys_getgroups16)
3467 vg_assert(SUCCESS);
3468 if (ARG1 > 0 && RES > 0)
3469 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3472 PRE(sys_setgroups16)
3474 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3475 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3476 if (ARG1 > 0)
3477 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3480 /* ---------------------------------------------------------------------
3481 *chown16 wrappers
3482 ------------------------------------------------------------------ */
3484 PRE(sys_chown16)
3486 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3487 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3488 PRE_REG_READ3(long, "chown16",
3489 const char *, path,
3490 vki_old_uid_t, owner, vki_old_gid_t, group);
3491 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3494 PRE(sys_fchown16)
3496 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3497 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3498 PRE_REG_READ3(long, "fchown16",
3499 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3502 /* ---------------------------------------------------------------------
3503 *xattr wrappers
3504 ------------------------------------------------------------------ */
3506 PRE(sys_setxattr)
3508 *flags |= SfMayBlock;
3509 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3510 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3511 ARG4, SARG5);
3512 PRE_REG_READ5(long, "setxattr",
3513 char *, path, char *, name,
3514 void *, value, vki_size_t, size, int, flags);
3515 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3516 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3517 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3520 PRE(sys_lsetxattr)
3522 *flags |= SfMayBlock;
3523 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3524 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3525 ARG1, ARG2, ARG3, ARG4, SARG5);
3526 PRE_REG_READ5(long, "lsetxattr",
3527 char *, path, char *, name,
3528 void *, value, vki_size_t, size, int, flags);
3529 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3530 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3531 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3534 PRE(sys_fsetxattr)
3536 *flags |= SfMayBlock;
3537 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3538 FMT_REGWORD "u, %ld )",
3539 SARG1, ARG2, ARG3, ARG4, SARG5);
3540 PRE_REG_READ5(long, "fsetxattr",
3541 int, fd, char *, name, void *, value,
3542 vki_size_t, size, int, flags);
3543 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3544 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3547 PRE(sys_getxattr)
3549 *flags |= SfMayBlock;
3550 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3551 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3552 PRE_REG_READ4(ssize_t, "getxattr",
3553 char *, path, char *, name, void *, value, vki_size_t, size);
3554 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3555 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3556 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3558 POST(sys_getxattr)
3560 vg_assert(SUCCESS);
3561 if (RES > 0 && ARG3 != (Addr)NULL) {
3562 POST_MEM_WRITE( ARG3, RES );
3566 PRE(sys_lgetxattr)
3568 *flags |= SfMayBlock;
3569 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3570 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3571 PRE_REG_READ4(ssize_t, "lgetxattr",
3572 char *, path, char *, name, void *, value, vki_size_t, size);
3573 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3574 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3575 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3577 POST(sys_lgetxattr)
3579 vg_assert(SUCCESS);
3580 if (RES > 0 && ARG3 != (Addr)NULL) {
3581 POST_MEM_WRITE( ARG3, RES );
3585 PRE(sys_fgetxattr)
3587 *flags |= SfMayBlock;
3588 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3589 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3590 PRE_REG_READ4(ssize_t, "fgetxattr",
3591 int, fd, char *, name, void *, value, vki_size_t, size);
3592 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3593 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3595 POST(sys_fgetxattr)
3597 if (RES > 0 && ARG3 != (Addr)NULL)
3598 POST_MEM_WRITE( ARG3, RES );
3601 PRE(sys_listxattr)
3603 *flags |= SfMayBlock;
3604 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3605 ARG1, ARG2, (ULong)ARG3);
3606 PRE_REG_READ3(ssize_t, "listxattr",
3607 char *, path, char *, list, vki_size_t, size);
3608 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3609 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3611 POST(sys_listxattr)
3613 if (RES > 0 && ARG2 != (Addr)NULL)
3614 POST_MEM_WRITE( ARG2, RES );
3617 PRE(sys_llistxattr)
3619 *flags |= SfMayBlock;
3620 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3621 ARG1, ARG2, (ULong)ARG3);
3622 PRE_REG_READ3(ssize_t, "llistxattr",
3623 char *, path, char *, list, vki_size_t, size);
3624 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3625 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3627 POST(sys_llistxattr)
3629 if (RES > 0 && ARG2 != (Addr)NULL)
3630 POST_MEM_WRITE( ARG2, RES );
3633 PRE(sys_flistxattr)
3635 *flags |= SfMayBlock;
3636 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3637 SARG1, ARG2, ARG3);
3638 PRE_REG_READ3(ssize_t, "flistxattr",
3639 int, fd, char *, list, vki_size_t, size);
3640 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3642 POST(sys_flistxattr)
3644 if (RES > 0 && ARG2 != (Addr)NULL)
3645 POST_MEM_WRITE( ARG2, RES );
3648 PRE(sys_removexattr)
3650 *flags |= SfMayBlock;
3651 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3652 ARG1, ARG2);
3653 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3654 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3655 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3658 PRE(sys_lremovexattr)
3660 *flags |= SfMayBlock;
3661 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3662 ARG1, ARG2);
3663 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3664 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3665 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3668 PRE(sys_fremovexattr)
3670 *flags |= SfMayBlock;
3671 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3672 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3673 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3676 /* ---------------------------------------------------------------------
3677 sched_* wrappers
3678 ------------------------------------------------------------------ */
3680 PRE(sys_sched_setparam)
3682 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3683 PRE_REG_READ2(long, "sched_setparam",
3684 vki_pid_t, pid, struct sched_param *, p);
3685 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3687 POST(sys_sched_setparam)
3689 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3692 PRE(sys_sched_getparam)
3694 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3695 PRE_REG_READ2(long, "sched_getparam",
3696 vki_pid_t, pid, struct sched_param *, p);
3697 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3699 POST(sys_sched_getparam)
3701 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3704 PRE(sys_sched_setattr)
3706 struct vki_sched_attr *attr;
3707 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3708 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3709 PRE_REG_READ3(long, "sched_setattr",
3710 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3711 /* We need to be able to read at least the size field. */
3712 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3713 attr = (struct vki_sched_attr *)(Addr)ARG2;
3714 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3715 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3718 PRE(sys_sched_getattr)
3720 struct vki_sched_attr *attr;
3721 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3722 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3723 PRE_REG_READ4(long, "sched_getattr",
3724 vki_pid_t, pid, struct sched_attr *, p,
3725 unsigned int, size, unsigned int, flags);
3726 /* We need to be able to read at least the size field. */
3727 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3728 /* And the kernel needs to be able to write to the whole struct size. */
3729 attr = (struct vki_sched_attr *)(Addr)ARG2;
3730 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3731 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3733 POST(sys_sched_getattr)
3735 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3736 POST_MEM_WRITE( (Addr)attr, attr->size );
3739 PRE(sys_sched_getscheduler)
3741 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3742 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3745 PRE(sys_sched_setscheduler)
3747 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3748 SARG1, SARG2, ARG3);
3749 PRE_REG_READ3(long, "sched_setscheduler",
3750 vki_pid_t, pid, int, policy, struct sched_param *, p);
3751 if (ARG3 != 0)
3752 PRE_MEM_READ( "sched_setscheduler(p)",
3753 ARG3, sizeof(struct vki_sched_param));
3756 PRE(sys_sched_yield)
3758 *flags |= SfMayBlock;
3759 PRINT("sched_yield()");
3760 PRE_REG_READ0(long, "sys_sched_yield");
3763 PRE(sys_sched_get_priority_max)
3765 PRINT("sched_get_priority_max ( %ld )", SARG1);
3766 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3769 PRE(sys_sched_get_priority_min)
3771 PRINT("sched_get_priority_min ( %ld )", SARG1);
3772 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3775 PRE(sys_sched_rr_get_interval)
3777 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3778 PRE_REG_READ2(int, "sched_rr_get_interval",
3779 vki_pid_t, pid,
3780 struct vki_timespec *, tp);
3781 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3782 ARG2, sizeof(struct vki_timespec));
3785 POST(sys_sched_rr_get_interval)
3787 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3790 PRE(sys_sched_rr_get_interval_time64)
3792 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3793 SARG1, ARG2);
3794 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3795 vki_pid_t, pid,
3796 struct vki_timespec *, tp);
3797 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3798 ARG2, sizeof(struct vki_timespec64));
3801 POST(sys_sched_rr_get_interval_time64)
3803 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3806 PRE(sys_sched_setaffinity)
3808 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3809 SARG1, ARG2, ARG3);
3810 PRE_REG_READ3(long, "sched_setaffinity",
3811 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3812 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3815 PRE(sys_sched_getaffinity)
3817 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3818 SARG1, ARG2, ARG3);
3819 PRE_REG_READ3(long, "sched_getaffinity",
3820 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3821 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3823 POST(sys_sched_getaffinity)
3825 POST_MEM_WRITE(ARG3, ARG2);
3828 PRE(sys_unshare)
3830 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3831 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3834 PRE(sys_setns)
3836 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3837 PRE_REG_READ2(int, "setns",
3838 int, fd,
3839 int, nstype);
3840 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3841 SET_STATUS_Failure( VKI_EBADF );
3845 /* ---------------------------------------------------------------------
3846 miscellaneous wrappers
3847 ------------------------------------------------------------------ */
3849 PRE(sys_munlockall)
3851 *flags |= SfMayBlock;
3852 PRINT("sys_munlockall ( )");
3853 PRE_REG_READ0(long, "munlockall");
3856 // This has different signatures for different platforms.
3858 // x86: int sys_pipe(unsigned long __user *fildes);
3859 // AMD64: long sys_pipe(int *fildes);
3860 // ppc32: int sys_pipe(int __user *fildes);
3861 // ppc64: int sys_pipe(int __user *fildes);
3863 // The type of the argument is most important, and it is an array of 32 bit
3864 // values in all cases. (The return type differs across platforms, but it
3865 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3866 // was caused by using an array of 'unsigned long's, which didn't work on
3867 // AMD64.
3868 PRE(sys_pipe)
3870 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3871 PRE_REG_READ1(int, "pipe", int *, filedes);
3872 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3874 POST(sys_pipe)
3876 Int *p = (Int *)(Addr)ARG1;
3877 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3878 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3879 VG_(close)(p[0]);
3880 VG_(close)(p[1]);
3881 SET_STATUS_Failure( VKI_EMFILE );
3882 } else {
3883 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3884 if (VG_(clo_track_fds)) {
3885 ML_(record_fd_open_nameless)(tid, p[0]);
3886 ML_(record_fd_open_nameless)(tid, p[1]);
3891 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3892 there's a second arg containing flags to be applied to the new file
3893 descriptors. It hardly seems worth the effort to factor out the
3894 duplicated code, hence: */
3895 PRE(sys_pipe2)
3897 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3898 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3899 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3901 POST(sys_pipe2)
3903 Int *p = (Int *)(Addr)ARG1;
3904 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3905 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3906 VG_(close)(p[0]);
3907 VG_(close)(p[1]);
3908 SET_STATUS_Failure( VKI_EMFILE );
3909 } else {
3910 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3911 if (VG_(clo_track_fds)) {
3912 ML_(record_fd_open_nameless)(tid, p[0]);
3913 ML_(record_fd_open_nameless)(tid, p[1]);
3918 PRE(sys_dup3)
3920 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3921 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3922 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3923 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3924 SET_STATUS_Failure( VKI_EBADF );
3927 POST(sys_dup3)
3929 vg_assert(SUCCESS);
3930 if (VG_(clo_track_fds))
3931 ML_(record_fd_open_named)(tid, RES);
3934 PRE(sys_quotactl)
3936 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3937 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3938 PRE_REG_READ4(long, "quotactl",
3939 unsigned int, cmd, const char *, special, vki_qid_t, id,
3940 void *, addr);
3941 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3944 PRE(sys_waitid)
3946 *flags |= SfMayBlock;
3947 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3948 SARG1, SARG2, ARG3, SARG4, ARG5);
3949 PRE_REG_READ5(int32_t, "sys_waitid",
3950 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3951 int, options, struct vki_rusage *, ru);
3952 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3953 if (ARG5 != 0)
3954 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3956 POST(sys_waitid)
3958 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3959 if (ARG5 != 0)
3960 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3963 PRE(sys_sync_file_range)
3965 *flags |= SfMayBlock;
3966 #if VG_WORDSIZE == 4
3967 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3968 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3969 PRE_REG_READ6(long, "sync_file_range",
3970 int, fd,
3971 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3972 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3973 unsigned int, flags);
3974 #elif VG_WORDSIZE == 8
3975 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3976 SARG1, SARG2, SARG3, ARG4);
3977 PRE_REG_READ4(long, "sync_file_range",
3978 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3979 unsigned int, flags);
3980 #else
3981 # error Unexpected word size
3982 #endif
3983 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3984 SET_STATUS_Failure( VKI_EBADF );
3987 PRE(sys_sync_file_range2)
3989 *flags |= SfMayBlock;
3990 #if VG_WORDSIZE == 4
3991 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3992 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3993 PRE_REG_READ6(long, "sync_file_range2",
3994 int, fd, unsigned int, flags,
3995 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3996 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3997 #elif VG_WORDSIZE == 8
3998 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3999 SARG1, ARG2, SARG3, SARG4);
4000 PRE_REG_READ4(long, "sync_file_range2",
4001 int, fd, unsigned int, flags,
4002 vki_loff_t, offset, vki_loff_t, nbytes);
4003 #else
4004 # error Unexpected word size
4005 #endif
4006 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4007 SET_STATUS_Failure( VKI_EBADF );
4010 PRE(sys_stime)
4012 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4013 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4014 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4017 PRE(sys_perf_event_open)
4019 struct vki_perf_event_attr *attr;
4020 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4021 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4022 PRE_REG_READ5(long, "perf_event_open",
4023 struct vki_perf_event_attr *, attr,
4024 vki_pid_t, pid, int, cpu, int, group_fd,
4025 unsigned long, flags);
4026 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4027 PRE_MEM_READ( "perf_event_open(attr->size)",
4028 (Addr)&attr->size, sizeof(attr->size) );
4029 PRE_MEM_READ( "perf_event_open(attr)",
4030 (Addr)attr, attr->size );
4033 POST(sys_perf_event_open)
4035 vg_assert(SUCCESS);
4036 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4037 VG_(close)(RES);
4038 SET_STATUS_Failure( VKI_EMFILE );
4039 } else {
4040 if (VG_(clo_track_fds))
4041 ML_(record_fd_open_nameless)(tid, RES);
4045 PRE(sys_getcpu)
4047 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4048 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4049 PRE_REG_READ3(int, "getcpu",
4050 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4051 if (ARG1 != 0)
4052 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4053 if (ARG2 != 0)
4054 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4055 if (ARG3 != 0)
4056 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4059 POST(sys_getcpu)
4061 if (ARG1 != 0)
4062 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4063 if (ARG2 != 0)
4064 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4065 if (ARG3 != 0)
4066 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4069 PRE(sys_move_pages)
4071 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4072 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4073 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4074 PRE_REG_READ6(int, "move_pages",
4075 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4076 const int *, nodes, int *, status, int, flags);
4077 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4078 if (ARG4)
4079 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4080 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4083 POST(sys_move_pages)
4085 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4088 PRE(sys_getrandom)
4090 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4091 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4092 PRE_REG_READ3(int, "getrandom",
4093 char *, buf, vki_size_t, count, unsigned int, flags);
4094 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4097 POST(sys_getrandom)
4099 POST_MEM_WRITE( ARG1, ARG2 );
4102 PRE(sys_memfd_create)
4104 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4105 ARG1, ARG2);
4106 PRE_REG_READ2(int, "memfd_create",
4107 char *, uname, unsigned int, flags);
4108 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4111 POST(sys_memfd_create)
4113 vg_assert(SUCCESS);
4114 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4115 VG_(close)(RES);
4116 SET_STATUS_Failure( VKI_EMFILE );
4117 } else {
4118 if (VG_(clo_track_fds))
4119 ML_(record_fd_open_nameless)(tid, RES);
4123 PRE(sys_memfd_secret)
4125 PRINT("sys_memfd_secret ( %#" FMT_REGWORD "x )", ARG1);
4126 PRE_REG_READ1(int, "memfd_secret", unsigned int, flags);
4129 POST(sys_memfd_secret)
4131 vg_assert(SUCCESS);
4132 if (!ML_(fd_allowed)(RES, "memfd_secret", tid, True)) {
4133 VG_(close)(RES);
4134 SET_STATUS_Failure( VKI_EMFILE );
4135 } else {
4136 if (VG_(clo_track_fds))
4137 ML_(record_fd_open_nameless)(tid, RES);
4141 PRE(sys_membarrier)
4143 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4144 PRE_REG_READ1(int, "membarrier", int, flags);
4147 PRE(sys_syncfs)
4149 *flags |= SfMayBlock;
4150 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4151 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4154 PRE(sys_statx)
4156 FUSE_COMPATIBLE_MAY_BLOCK();
4157 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4158 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4159 PRE_REG_READ5(long, "statx",
4160 int, dirfd, char *, filename, int, flags,
4161 unsigned int, mask, struct statx *, buf);
4162 // Work around Rust's dubious use of statx, as described here:
4163 // https://github.com/rust-lang/rust/blob/
4164 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4165 // src/libstd/sys/unix/fs.rs#L128-L142
4166 // in which it passes NULL for both filename and buf, and then looks at the
4167 // return value, so as to determine whether or not this syscall is supported.
4168 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4169 if (!both_filename_and_buf_are_null) {
4170 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4171 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4174 POST(sys_statx)
4176 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4179 /* ---------------------------------------------------------------------
4180 utime wrapper
4181 ------------------------------------------------------------------ */
4183 PRE(sys_utime)
4185 *flags |= SfMayBlock;
4186 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4187 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4188 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4189 if (ARG2 != 0)
4190 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4193 /* ---------------------------------------------------------------------
4194 lseek wrapper
4195 ------------------------------------------------------------------ */
4197 PRE(sys_lseek)
4199 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4200 ARG1, SARG2, ARG3);
4201 PRE_REG_READ3(vki_off_t, "lseek",
4202 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4205 /* ---------------------------------------------------------------------
4206 readahead wrapper
4207 ------------------------------------------------------------------ */
4209 PRE(sys_readahead)
4211 *flags |= SfMayBlock;
4212 #if VG_WORDSIZE == 4
4213 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4214 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4215 PRE_REG_READ4(vki_off_t, "readahead",
4216 int, fd, unsigned, MERGE64_FIRST(offset),
4217 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4218 #elif VG_WORDSIZE == 8
4219 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4220 PRE_REG_READ3(vki_off_t, "readahead",
4221 int, fd, vki_loff_t, offset, vki_size_t, count);
4222 #else
4223 # error Unexpected word size
4224 #endif
4225 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4226 SET_STATUS_Failure( VKI_EBADF );
4229 /* ---------------------------------------------------------------------
4230 sig* wrappers
4231 ------------------------------------------------------------------ */
4233 PRE(sys_sigpending)
4235 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4236 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4237 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4239 POST(sys_sigpending)
4241 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4244 // This syscall is not used on amd64/Linux -- it only provides
4245 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4246 // This wrapper is only suitable for 32-bit architectures.
4247 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4248 // conditional compilation like this?)
4249 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4250 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4251 || defined(VGP_nanomips_linux)
4252 PRE(sys_sigprocmask)
4254 vki_old_sigset_t* set;
4255 vki_old_sigset_t* oldset;
4256 vki_sigset_t bigger_set;
4257 vki_sigset_t bigger_oldset;
4259 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4260 PRE_REG_READ3(long, "sigprocmask",
4261 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4262 if (ARG2 != 0)
4263 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4264 if (ARG3 != 0)
4265 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4267 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4268 // vki_sigset_t params.
4269 set = (vki_old_sigset_t*)(Addr)ARG2;
4270 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4272 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4273 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4274 if (set)
4275 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4277 SET_STATUS_from_SysRes(
4278 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4279 set ? &bigger_set : NULL,
4280 oldset ? &bigger_oldset : NULL)
4283 if (oldset)
4284 *oldset = bigger_oldset.sig[0];
4286 if (SUCCESS)
4287 *flags |= SfPollAfter;
4289 POST(sys_sigprocmask)
4291 vg_assert(SUCCESS);
4292 if (RES == 0 && ARG3 != 0)
4293 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4296 /* Convert from non-RT to RT sigset_t's */
4297 static
4298 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4300 VG_(sigemptyset)(set);
4301 set->sig[0] = *oldset;
4303 PRE(sys_sigaction)
4305 vki_sigaction_toK_t new, *newp;
4306 vki_sigaction_fromK_t old, *oldp;
4308 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4309 PRE_REG_READ3(int, "sigaction",
4310 int, signum, const struct old_sigaction *, act,
4311 struct old_sigaction *, oldact);
4313 newp = oldp = NULL;
4315 if (ARG2 != 0) {
4316 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4317 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4318 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4319 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4320 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4321 && (sa->sa_flags & VKI_SA_RESTORER))
4322 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4325 if (ARG3 != 0) {
4326 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4327 oldp = &old;
4330 /* If the new or old sigaction is not NULL, but the structs
4331 aren't accessible then sigaction returns EFAULT and we cannot
4332 use either struct for our own bookkeeping. Just fail early. */
4333 if (ARG2 != 0
4334 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4335 sizeof(struct vki_old_sigaction))) {
4336 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4337 (void *)(Addr)ARG2);
4338 SET_STATUS_Failure ( VKI_EFAULT );
4339 } else if ((ARG3 != 0
4340 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4341 sizeof(struct vki_old_sigaction)))) {
4342 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4343 (void *)(Addr)ARG3);
4344 SET_STATUS_Failure ( VKI_EFAULT );
4345 } else {
4346 if (ARG2 != 0) {
4347 struct vki_old_sigaction *oldnew =
4348 (struct vki_old_sigaction *)(Addr)ARG2;
4350 new.ksa_handler = oldnew->ksa_handler;
4351 new.sa_flags = oldnew->sa_flags;
4352 new.sa_restorer = oldnew->sa_restorer;
4353 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4354 newp = &new;
4357 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4359 if (ARG3 != 0 && SUCCESS && RES == 0) {
4360 struct vki_old_sigaction *oldold =
4361 (struct vki_old_sigaction *)(Addr)ARG3;
4363 oldold->ksa_handler = oldp->ksa_handler;
4364 oldold->sa_flags = oldp->sa_flags;
4365 oldold->sa_restorer = oldp->sa_restorer;
4366 oldold->sa_mask = oldp->sa_mask.sig[0];
4370 POST(sys_sigaction)
4372 vg_assert(SUCCESS);
4373 if (RES == 0 && ARG3 != 0)
4374 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4376 #endif
4378 PRE(sys_signalfd)
4380 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4381 (ULong)ARG3);
4382 PRE_REG_READ3(long, "sys_signalfd",
4383 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4384 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4385 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4386 SET_STATUS_Failure( VKI_EBADF );
4388 POST(sys_signalfd)
4390 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4391 VG_(close)(RES);
4392 SET_STATUS_Failure( VKI_EMFILE );
4393 } else {
4394 if (VG_(clo_track_fds))
4395 ML_(record_fd_open_nameless) (tid, RES);
4399 PRE(sys_signalfd4)
4401 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4402 SARG1, ARG2, ARG3, SARG4);
4403 PRE_REG_READ4(long, "sys_signalfd4",
4404 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4405 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4406 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4407 SET_STATUS_Failure( VKI_EBADF );
4409 POST(sys_signalfd4)
4411 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4412 VG_(close)(RES);
4413 SET_STATUS_Failure( VKI_EMFILE );
4414 } else {
4415 if (VG_(clo_track_fds))
4416 ML_(record_fd_open_nameless) (tid, RES);
4421 /* ---------------------------------------------------------------------
4422 rt_sig* wrappers
4423 ------------------------------------------------------------------ */
4425 PRE(sys_rt_sigaction)
4427 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4428 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4429 PRE_REG_READ4(long, "rt_sigaction",
4430 int, signum, const struct sigaction *, act,
4431 struct sigaction *, oldact, vki_size_t, sigsetsize);
4433 if (ARG2 != 0) {
4434 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4435 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4436 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4437 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4438 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4439 && (sa->sa_flags & VKI_SA_RESTORER))
4440 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4442 if (ARG3 != 0)
4443 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4445 /* If the new or old sigaction is not NULL, but the structs
4446 aren't accessible then sigaction returns EFAULT and we cannot
4447 use either struct for our own bookkeeping. Just fail early. */
4448 if (ARG2 != 0
4449 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4450 sizeof(vki_sigaction_toK_t))) {
4451 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4452 (void *)(Addr)ARG2);
4453 SET_STATUS_Failure ( VKI_EFAULT );
4454 } else if ((ARG3 != 0
4455 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4456 sizeof(vki_sigaction_fromK_t)))) {
4457 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4458 (void *)(Addr)ARG3);
4459 SET_STATUS_Failure ( VKI_EFAULT );
4460 } else {
4462 // XXX: doesn't seem right to be calling do_sys_sigaction for
4463 // sys_rt_sigaction... perhaps this function should be renamed
4464 // VG_(do_sys_rt_sigaction)() --njn
4466 SET_STATUS_from_SysRes(
4467 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4468 (vki_sigaction_fromK_t *)(Addr)ARG3)
4472 POST(sys_rt_sigaction)
4474 vg_assert(SUCCESS);
4475 if (RES == 0 && ARG3 != 0)
4476 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4479 PRE(sys_rt_sigprocmask)
4481 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4482 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4483 PRE_REG_READ4(long, "rt_sigprocmask",
4484 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4485 vki_size_t, sigsetsize);
4486 if (ARG2 != 0)
4487 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4488 if (ARG3 != 0)
4489 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4491 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4492 // Since we want to use the set and oldset for bookkeeping we also want
4493 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4494 if (sizeof(vki_sigset_t) != ARG4)
4495 SET_STATUS_Failure( VKI_EINVAL );
4496 else if (ARG2 != 0
4497 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4498 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4499 (void *)(Addr)ARG2);
4500 SET_STATUS_Failure ( VKI_EFAULT );
4502 else if (ARG3 != 0
4503 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4504 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4505 (void *)(Addr)ARG3);
4506 SET_STATUS_Failure ( VKI_EFAULT );
4509 else {
4510 SET_STATUS_from_SysRes(
4511 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4512 (vki_sigset_t*) (Addr)ARG2,
4513 (vki_sigset_t*) (Addr)ARG3 )
4517 if (SUCCESS)
4518 *flags |= SfPollAfter;
4520 POST(sys_rt_sigprocmask)
4522 vg_assert(SUCCESS);
4523 if (RES == 0 && ARG3 != 0)
4524 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4527 PRE(sys_rt_sigpending)
4529 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4530 PRE_REG_READ2(long, "rt_sigpending",
4531 vki_sigset_t *, set, vki_size_t, sigsetsize);
4532 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4534 POST(sys_rt_sigpending)
4536 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4539 PRE(sys_rt_sigtimedwait)
4541 *flags |= SfMayBlock;
4542 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4543 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4544 ARG1, ARG2, ARG3, ARG4);
4545 PRE_REG_READ4(long, "rt_sigtimedwait",
4546 const vki_sigset_t *, set, vki_siginfo_t *, info,
4547 const struct timespec *, timeout, vki_size_t, sigsetsize);
4548 if (ARG1 != 0)
4549 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4550 if (ARG2 != 0)
4551 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4552 if (ARG3 != 0)
4553 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4554 ARG3, sizeof(struct vki_timespec) );
4556 POST(sys_rt_sigtimedwait)
4558 if (ARG2 != 0)
4559 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4562 PRE(sys_rt_sigtimedwait_time64)
4564 *flags |= SfMayBlock;
4565 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4566 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4567 ARG1, ARG2, ARG3, ARG4);
4568 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4569 const vki_sigset_t *, set, vki_siginfo_t *, info,
4570 const struct vki_timespec64 *, timeout,
4571 vki_size_t, sigsetsize);
4572 if (ARG1 != 0)
4573 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4574 if (ARG2 != 0)
4575 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4576 sizeof(vki_siginfo_t) );
4577 if (ARG3 != 0)
4578 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4580 POST(sys_rt_sigtimedwait_time64)
4582 if (ARG2 != 0)
4583 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4586 PRE(sys_rt_sigqueueinfo)
4588 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4589 SARG1, SARG2, ARG3);
4590 PRE_REG_READ3(long, "rt_sigqueueinfo",
4591 int, pid, int, sig, vki_siginfo_t *, uinfo);
4592 if (ARG2 != 0)
4593 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4595 POST(sys_rt_sigqueueinfo)
4597 if (!ML_(client_signal_OK)(ARG2))
4598 SET_STATUS_Failure( VKI_EINVAL );
4601 PRE(sys_rt_tgsigqueueinfo)
4603 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4604 SARG1, SARG2, SARG3, ARG4);
4605 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4606 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4607 if (ARG3 != 0)
4608 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4611 POST(sys_rt_tgsigqueueinfo)
4613 if (!ML_(client_signal_OK)(ARG3))
4614 SET_STATUS_Failure( VKI_EINVAL );
4617 // XXX: x86-specific? The kernel prototypes for the different archs are
4618 // hard to decipher.
4619 PRE(sys_rt_sigsuspend)
4621 /* The C library interface to sigsuspend just takes a pointer to
4622 a signal mask but this system call has two arguments - a pointer
4623 to the mask and the number of bytes used by it. The kernel insists
4624 on the size being equal to sizeof(sigset_t) however and will just
4625 return EINVAL if it isn't.
4627 *flags |= SfMayBlock;
4628 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4629 ARG1, ARG2 );
4630 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4631 if (ARG1 != (Addr)NULL) {
4632 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4633 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4634 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4635 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4636 be killable by VG_(nuke_all_threads_except).
4637 We thus silently ignore the user request to mask this signal.
4638 Note that this is similar to what is done for e.g.
4639 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4640 } else {
4641 SET_STATUS_Failure(VKI_EFAULT);
4646 /* ---------------------------------------------------------------------
4647 linux msg* wrapper helpers
4648 ------------------------------------------------------------------ */
4650 void
4651 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4652 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4654 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4655 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4656 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4657 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4660 void
4661 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4662 UWord arg0, UWord arg1, UWord arg2,
4663 UWord arg3, UWord arg4 )
4665 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4666 long msgtyp, int msgflg); */
4667 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4668 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4669 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4671 void
4672 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4673 UWord res,
4674 UWord arg0, UWord arg1, UWord arg2,
4675 UWord arg3, UWord arg4 )
4677 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4678 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4679 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4682 void
4683 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4684 UWord arg0, UWord arg1, UWord arg2 )
4686 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4687 switch (arg1 /* cmd */) {
4688 case VKI_IPC_INFO:
4689 case VKI_MSG_INFO:
4690 case VKI_IPC_INFO|VKI_IPC_64:
4691 case VKI_MSG_INFO|VKI_IPC_64:
4692 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4693 arg2, sizeof(struct vki_msginfo) );
4694 break;
4695 case VKI_IPC_STAT:
4696 case VKI_MSG_STAT:
4697 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4698 arg2, sizeof(struct vki_msqid_ds) );
4699 break;
4700 case VKI_IPC_STAT|VKI_IPC_64:
4701 case VKI_MSG_STAT|VKI_IPC_64:
4702 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4703 arg2, sizeof(struct vki_msqid64_ds) );
4704 break;
4705 case VKI_IPC_SET:
4706 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4707 arg2, sizeof(struct vki_msqid_ds) );
4708 break;
4709 case VKI_IPC_SET|VKI_IPC_64:
4710 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4711 arg2, sizeof(struct vki_msqid64_ds) );
4712 break;
4715 void
4716 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4717 UWord res,
4718 UWord arg0, UWord arg1, UWord arg2 )
4720 switch (arg1 /* cmd */) {
4721 case VKI_IPC_INFO:
4722 case VKI_MSG_INFO:
4723 case VKI_IPC_INFO|VKI_IPC_64:
4724 case VKI_MSG_INFO|VKI_IPC_64:
4725 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4726 break;
4727 case VKI_IPC_STAT:
4728 case VKI_MSG_STAT:
4729 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4730 break;
4731 case VKI_IPC_STAT|VKI_IPC_64:
4732 case VKI_MSG_STAT|VKI_IPC_64:
4733 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4734 break;
4738 /* ---------------------------------------------------------------------
4739 Generic handler for sys_ipc
4740 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4741 are either direct system calls, or are all implemented via sys_ipc.
4742 ------------------------------------------------------------------ */
4743 #ifdef __NR_ipc
4744 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4746 Addr* a_p = (Addr*)a;
4747 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4748 return *a_p;
4751 static Bool semctl_cmd_has_4args (UWord cmd)
4753 switch (cmd & ~VKI_IPC_64)
4755 case VKI_IPC_INFO:
4756 case VKI_SEM_INFO:
4757 case VKI_IPC_STAT:
4758 case VKI_SEM_STAT:
4759 case VKI_IPC_SET:
4760 case VKI_GETALL:
4761 case VKI_SETALL:
4762 return True;
4763 default:
4764 return False;
4768 PRE(sys_ipc)
4770 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4771 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4773 switch (ARG1 /* call */) {
4774 case VKI_SEMOP:
4775 PRE_REG_READ5(int, "ipc",
4776 vki_uint, call, int, first, int, second, int, third,
4777 void *, ptr);
4778 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4779 *flags |= SfMayBlock;
4780 break;
4781 case VKI_SEMGET:
4782 PRE_REG_READ4(int, "ipc",
4783 vki_uint, call, int, first, int, second, int, third);
4784 break;
4785 case VKI_SEMCTL:
4787 PRE_REG_READ5(int, "ipc",
4788 vki_uint, call, int, first, int, second, int, third,
4789 void *, ptr);
4790 UWord arg;
4791 if (semctl_cmd_has_4args(ARG4))
4792 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4793 else
4794 arg = 0;
4795 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4796 break;
4798 case VKI_SEMTIMEDOP:
4799 #ifdef VGP_s390x_linux
4800 /* On s390x Linux platforms the sys_ipc semtimedop call has four instead
4801 of five parameters, where the timeout is passed in the third instead of
4802 the fifth. */
4803 PRE_REG_READ5(int, "ipc",
4804 vki_uint, call, int, first, int, second, long, third,
4805 void *, ptr);
4806 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG4 );
4807 #else
4808 PRE_REG_READ6(int, "ipc",
4809 vki_uint, call, int, first, int, second, int, third,
4810 void *, ptr, long, fifth);
4811 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4812 #endif
4813 *flags |= SfMayBlock;
4814 break;
4815 case VKI_MSGSND:
4816 PRE_REG_READ5(int, "ipc",
4817 vki_uint, call, int, first, int, second, int, third,
4818 void *, ptr);
4819 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4820 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4821 *flags |= SfMayBlock;
4822 break;
4823 case VKI_MSGRCV:
4825 PRE_REG_READ5(int, "ipc",
4826 vki_uint, call, int, first, int, second, int, third,
4827 void *, ptr);
4828 Addr msgp;
4829 Word msgtyp;
4831 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4832 "msgrcv(msgp)" );
4833 msgtyp = deref_Addr( tid,
4834 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4835 "msgrcv(msgp)" );
4837 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4839 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4840 *flags |= SfMayBlock;
4841 break;
4843 case VKI_MSGGET:
4844 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4845 break;
4846 case VKI_MSGCTL:
4847 PRE_REG_READ5(int, "ipc",
4848 vki_uint, call, int, first, int, second, int, third,
4849 void *, ptr);
4850 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4851 break;
4852 case VKI_SHMAT:
4854 PRE_REG_READ5(int, "ipc",
4855 vki_uint, call, int, first, int, second, int, third,
4856 void *, ptr);
4857 UWord w;
4858 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4859 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4860 if (w == 0)
4861 SET_STATUS_Failure( VKI_EINVAL );
4862 else
4863 ARG5 = w;
4864 break;
4866 case VKI_SHMDT:
4867 PRE_REG_READ5(int, "ipc",
4868 vki_uint, call, int, first, int, second, int, third,
4869 void *, ptr);
4870 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4871 SET_STATUS_Failure( VKI_EINVAL );
4872 break;
4873 case VKI_SHMGET:
4874 PRE_REG_READ4(int, "ipc",
4875 vki_uint, call, int, first, int, second, int, third);
4876 if (ARG4 & VKI_SHM_HUGETLB) {
4877 static Bool warning_given = False;
4878 ARG4 &= ~VKI_SHM_HUGETLB;
4879 if (!warning_given) {
4880 warning_given = True;
4881 VG_(umsg)(
4882 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4885 break;
4886 case VKI_SHMCTL: /* IPCOP_shmctl */
4887 PRE_REG_READ5(int, "ipc",
4888 vki_uint, call, int, first, int, second, int, third,
4889 void *, ptr);
4890 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4891 break;
4892 default:
4893 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4894 VG_(core_panic)("... bye!\n");
4895 break; /*NOTREACHED*/
4899 POST(sys_ipc)
4901 vg_assert(SUCCESS);
4902 switch (ARG1 /* call */) {
4903 case VKI_SEMOP:
4904 case VKI_SEMGET:
4905 break;
4906 case VKI_SEMCTL:
4908 UWord arg;
4909 if (semctl_cmd_has_4args(ARG4))
4910 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4911 else
4912 arg = 0;
4913 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4914 break;
4916 case VKI_SEMTIMEDOP:
4917 case VKI_MSGSND:
4918 break;
4919 case VKI_MSGRCV:
4921 Addr msgp;
4922 Word msgtyp;
4924 msgp = deref_Addr( tid,
4925 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4926 "msgrcv(msgp)" );
4927 msgtyp = deref_Addr( tid,
4928 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4929 "msgrcv(msgp)" );
4931 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4932 break;
4934 case VKI_MSGGET:
4935 break;
4936 case VKI_MSGCTL:
4937 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4938 break;
4939 case VKI_SHMAT:
4941 Addr addr;
4943 /* force readability. before the syscall it is
4944 * indeed uninitialized, as can be seen in
4945 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4946 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4948 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4949 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4950 break;
4952 case VKI_SHMDT:
4953 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4954 break;
4955 case VKI_SHMGET:
4956 break;
4957 case VKI_SHMCTL:
4958 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4959 break;
4960 default:
4961 VG_(message)(Vg_DebugMsg,
4962 "FATAL: unhandled syscall(ipc) %lu\n",
4963 ARG1 );
4964 VG_(core_panic)("... bye!\n");
4965 break; /*NOTREACHED*/
4968 #endif
4970 PRE(sys_semget)
4972 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4973 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4976 PRE(sys_semop)
4978 *flags |= SfMayBlock;
4979 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4980 SARG1, ARG2, ARG3);
4981 PRE_REG_READ3(long, "semop",
4982 int, semid, struct sembuf *, sops, unsigned, nsoops);
4983 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4986 PRE(sys_semctl)
4988 switch (ARG3 & ~VKI_IPC_64) {
4989 case VKI_IPC_INFO:
4990 case VKI_SEM_INFO:
4991 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4992 SARG3, ARG4);
4993 PRE_REG_READ4(long, "semctl",
4994 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4995 break;
4996 case VKI_IPC_STAT:
4997 case VKI_SEM_STAT:
4998 case VKI_IPC_SET:
4999 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5000 SARG3, ARG4);
5001 PRE_REG_READ4(long, "semctl",
5002 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
5003 break;
5004 case VKI_GETALL:
5005 case VKI_SETALL:
5006 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5007 SARG3, ARG4);
5008 PRE_REG_READ4(long, "semctl",
5009 int, semid, int, semnum, int, cmd, unsigned short *, arg);
5010 break;
5011 default:
5012 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5013 PRE_REG_READ3(long, "semctl",
5014 int, semid, int, semnum, int, cmd);
5015 break;
5017 #ifdef VGP_amd64_linux
5018 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5019 #else
5020 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
5021 #endif
5024 POST(sys_semctl)
5026 #ifdef VGP_amd64_linux
5027 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5028 #else
5029 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
5030 #endif
5033 PRE(sys_semtimedop)
5035 *flags |= SfMayBlock;
5036 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5037 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5038 PRE_REG_READ4(long, "semtimedop",
5039 int, semid, struct sembuf *, sops, unsigned, nsoops,
5040 struct timespec *, timeout);
5041 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5044 PRE(sys_semtimedop_time64)
5046 *flags |= SfMayBlock;
5047 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5048 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5049 PRE_REG_READ4(long, "semtimedop_time64",
5050 int, semid, struct sembuf *, sops, unsigned, nsoops,
5051 struct vki_timespec64 *, timeout);
5052 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5053 ARG2 * sizeof(struct vki_sembuf) );
5054 if (ARG3 != 0)
5055 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5058 PRE(sys_msgget)
5060 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5061 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5064 PRE(sys_msgsnd)
5066 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5067 SARG1, ARG2, ARG3, SARG4);
5068 PRE_REG_READ4(long, "msgsnd",
5069 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5070 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5071 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5072 *flags |= SfMayBlock;
5075 PRE(sys_msgrcv)
5077 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5078 SARG1, ARG2, ARG3, SARG4, SARG5);
5079 PRE_REG_READ5(long, "msgrcv",
5080 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5081 long, msgytp, int, msgflg);
5082 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5083 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5084 *flags |= SfMayBlock;
5086 POST(sys_msgrcv)
5088 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5091 PRE(sys_msgctl)
5093 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5094 PRE_REG_READ3(long, "msgctl",
5095 int, msqid, int, cmd, struct msqid_ds *, buf);
5096 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5099 POST(sys_msgctl)
5101 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5104 PRE(sys_shmget)
5106 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5107 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5108 if (ARG3 & VKI_SHM_HUGETLB) {
5109 static Bool warning_given = False;
5110 ARG3 &= ~VKI_SHM_HUGETLB;
5111 if (!warning_given) {
5112 warning_given = True;
5113 VG_(umsg)(
5114 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5119 PRE(sys_shmat)
5121 UWord arg2tmp;
5122 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5123 PRE_REG_READ3(long, "shmat",
5124 int, shmid, const void *, shmaddr, int, shmflg);
5125 #if defined(VGP_arm_linux)
5126 /* Round the attach address down to an VKI_SHMLBA boundary if the
5127 client requested rounding. See #222545. This is necessary only
5128 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5129 other linux targets it is the same as the page size. */
5130 if (ARG3 & VKI_SHM_RND)
5131 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5132 #endif
5133 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5134 if (arg2tmp == 0)
5135 SET_STATUS_Failure( VKI_EINVAL );
5136 else
5137 ARG2 = arg2tmp; // used in POST
5140 POST(sys_shmat)
5142 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5145 PRE(sys_shmdt)
5147 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5148 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5149 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5150 SET_STATUS_Failure( VKI_EINVAL );
5153 POST(sys_shmdt)
5155 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5158 PRE(sys_shmctl)
5160 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5161 PRE_REG_READ3(long, "shmctl",
5162 int, shmid, int, cmd, struct shmid_ds *, buf);
5163 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5164 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5165 #else
5166 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5167 #endif
5170 POST(sys_shmctl)
5172 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5173 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5174 #else
5175 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5176 #endif
5180 /* ---------------------------------------------------------------------
5181 Generic handler for sys_socketcall
5182 Depending on the platform, some socket related syscalls (e.g. socketpair,
5183 socket, bind, ...)
5184 are either direct system calls, or are all implemented via sys_socketcall.
5185 ------------------------------------------------------------------ */
5186 #ifdef __NR_socketcall
5187 PRE(sys_socketcall)
5189 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5190 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5191 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5192 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5193 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5194 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5196 // call PRE_MEM_READ and check for EFAULT result.
5197 #define PRE_MEM_READ_ef(msg, arg, size) \
5199 PRE_MEM_READ( msg, arg, size); \
5200 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5201 SET_STATUS_Failure( VKI_EFAULT ); \
5202 break; \
5206 *flags |= SfMayBlock;
5207 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5208 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5210 switch (ARG1 /* request */) {
5212 case VKI_SYS_SOCKETPAIR:
5213 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5214 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5215 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5216 break;
5218 case VKI_SYS_SOCKET:
5219 /* int socket(int domain, int type, int protocol); */
5220 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5221 break;
5223 case VKI_SYS_BIND:
5224 /* int bind(int sockfd, struct sockaddr *my_addr,
5225 int addrlen); */
5226 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5227 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5228 break;
5230 case VKI_SYS_LISTEN:
5231 /* int listen(int s, int backlog); */
5232 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5233 break;
5235 case VKI_SYS_ACCEPT:
5236 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5237 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5238 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5239 break;
5241 case VKI_SYS_ACCEPT4:
5242 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5243 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5244 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5245 break;
5247 case VKI_SYS_SENDTO:
5248 /* int sendto(int s, const void *msg, int len,
5249 unsigned int flags,
5250 const struct sockaddr *to, int tolen); */
5251 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5252 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5253 ARG2_3, ARG2_4, ARG2_5 );
5254 break;
5256 case VKI_SYS_SEND:
5257 /* int send(int s, const void *msg, size_t len, int flags); */
5258 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5259 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5260 break;
5262 case VKI_SYS_RECVFROM:
5263 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5264 struct sockaddr *from, int *fromlen); */
5265 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5266 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5267 ARG2_3, ARG2_4, ARG2_5 );
5268 break;
5270 case VKI_SYS_RECV:
5271 /* int recv(int s, void *buf, int len, unsigned int flags); */
5272 /* man 2 recv says:
5273 The recv call is normally used only on a connected socket
5274 (see connect(2)) and is identical to recvfrom with a NULL
5275 from parameter.
5277 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5278 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5279 break;
5281 case VKI_SYS_CONNECT:
5282 /* int connect(int sockfd,
5283 struct sockaddr *serv_addr, int addrlen ); */
5284 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5285 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5286 break;
5288 case VKI_SYS_SETSOCKOPT:
5289 /* int setsockopt(int s, int level, int optname,
5290 const void *optval, int optlen); */
5291 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5292 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5293 ARG2_3, ARG2_4 );
5294 break;
5296 case VKI_SYS_GETSOCKOPT:
5297 /* int getsockopt(int s, int level, int optname,
5298 void *optval, socklen_t *optlen); */
5299 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5300 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5301 ARG2_3, ARG2_4 );
5302 break;
5304 case VKI_SYS_GETSOCKNAME:
5305 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5306 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5307 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5308 break;
5310 case VKI_SYS_GETPEERNAME:
5311 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5312 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5313 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5314 break;
5316 case VKI_SYS_SHUTDOWN:
5317 /* int shutdown(int s, int how); */
5318 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5319 break;
5321 case VKI_SYS_SENDMSG:
5322 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5323 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5324 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5325 (struct vki_msghdr *)(Addr)ARG2_1 );
5326 break;
5328 case VKI_SYS_RECVMSG:
5329 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5330 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5331 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5332 (struct vki_msghdr *)(Addr)ARG2_1 );
5333 break;
5335 case VKI_SYS_RECVMMSG:
5336 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5337 struct timespec *timeout); */
5338 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5339 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5340 ARG2_4 );
5341 break;
5343 case VKI_SYS_SENDMMSG:
5344 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5345 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5346 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5347 break;
5349 default:
5350 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5351 SET_STATUS_Failure( VKI_EINVAL );
5352 break;
5354 # undef ARG2_0
5355 # undef ARG2_1
5356 # undef ARG2_2
5357 # undef ARG2_3
5358 # undef ARG2_4
5359 # undef ARG2_5
5362 POST(sys_socketcall)
5364 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5365 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5366 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5367 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5368 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5369 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5371 SysRes r;
5372 vg_assert(SUCCESS);
5373 switch (ARG1 /* request */) {
5375 case VKI_SYS_SOCKETPAIR:
5376 r = ML_(generic_POST_sys_socketpair)(
5377 tid, VG_(mk_SysRes_Success)(RES),
5378 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5380 SET_STATUS_from_SysRes(r);
5381 break;
5383 case VKI_SYS_SOCKET:
5384 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5385 SET_STATUS_from_SysRes(r);
5386 break;
5388 case VKI_SYS_BIND:
5389 /* int bind(int sockfd, struct sockaddr *my_addr,
5390 int addrlen); */
5391 break;
5393 case VKI_SYS_LISTEN:
5394 /* int listen(int s, int backlog); */
5395 break;
5397 case VKI_SYS_ACCEPT:
5398 case VKI_SYS_ACCEPT4:
5399 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5400 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5401 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5402 ARG2_0, ARG2_1, ARG2_2 );
5403 SET_STATUS_from_SysRes(r);
5404 break;
5406 case VKI_SYS_SENDTO:
5407 break;
5409 case VKI_SYS_SEND:
5410 break;
5412 case VKI_SYS_RECVFROM:
5413 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5414 ARG2_0, ARG2_1, ARG2_2,
5415 ARG2_3, ARG2_4, ARG2_5 );
5416 break;
5418 case VKI_SYS_RECV:
5419 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5420 break;
5422 case VKI_SYS_CONNECT:
5423 break;
5425 case VKI_SYS_SETSOCKOPT:
5426 break;
5428 case VKI_SYS_GETSOCKOPT:
5429 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5430 ARG2_0, ARG2_1,
5431 ARG2_2, ARG2_3, ARG2_4 );
5432 break;
5434 case VKI_SYS_GETSOCKNAME:
5435 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5436 ARG2_0, ARG2_1, ARG2_2 );
5437 break;
5439 case VKI_SYS_GETPEERNAME:
5440 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5441 ARG2_0, ARG2_1, ARG2_2 );
5442 break;
5444 case VKI_SYS_SHUTDOWN:
5445 break;
5447 case VKI_SYS_SENDMSG:
5448 break;
5450 case VKI_SYS_RECVMSG:
5451 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5452 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5453 break;
5455 case VKI_SYS_RECVMMSG:
5456 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5457 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5458 break;
5460 case VKI_SYS_SENDMMSG:
5461 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5462 break;
5464 default:
5465 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5466 VG_(core_panic)("... bye!\n");
5467 break; /*NOTREACHED*/
5469 # undef ARG2_0
5470 # undef ARG2_1
5471 # undef ARG2_2
5472 # undef ARG2_3
5473 # undef ARG2_4
5474 # undef ARG2_5
5476 #endif
5478 PRE(sys_socket)
5480 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5481 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5483 POST(sys_socket)
5485 SysRes r;
5486 vg_assert(SUCCESS);
5487 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5488 SET_STATUS_from_SysRes(r);
5491 PRE(sys_setsockopt)
5493 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5494 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5495 PRE_REG_READ5(long, "setsockopt",
5496 int, s, int, level, int, optname,
5497 const void *, optval, unsigned, optlen); // socklen_t
5498 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5501 PRE(sys_getsockopt)
5503 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5504 SARG1, SARG2, SARG3, ARG4, SARG5);
5505 PRE_REG_READ5(long, "getsockopt",
5506 int, s, int, level, int, optname,
5507 void *, optval, int, *optlen);
5508 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5510 POST(sys_getsockopt)
5512 vg_assert(SUCCESS);
5513 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5514 ARG1,ARG2,ARG3,ARG4,ARG5);
5517 PRE(sys_connect)
5519 *flags |= SfMayBlock;
5520 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5521 PRE_REG_READ3(long, "connect",
5522 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5523 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5526 PRE(sys_accept)
5528 *flags |= SfMayBlock;
5529 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5530 SARG1, ARG2, ARG3);
5531 PRE_REG_READ3(long, "accept",
5532 int, s, struct sockaddr *, addr, int *, addrlen);
5533 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5535 POST(sys_accept)
5537 SysRes r;
5538 vg_assert(SUCCESS);
5539 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5540 ARG1,ARG2,ARG3);
5541 SET_STATUS_from_SysRes(r);
5544 PRE(sys_accept4)
5546 *flags |= SfMayBlock;
5547 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5548 SARG1, ARG2, ARG3, SARG4);
5549 PRE_REG_READ4(long, "accept4",
5550 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5551 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5553 POST(sys_accept4)
5555 SysRes r;
5556 vg_assert(SUCCESS);
5557 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5558 ARG1,ARG2,ARG3);
5559 SET_STATUS_from_SysRes(r);
5562 PRE(sys_send)
5564 *flags |= SfMayBlock;
5565 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5566 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5567 PRE_REG_READ4(long, "send",
5568 int, s, const void *, msg, vki_size_t, len,
5569 int, flags);
5571 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5574 PRE(sys_sendto)
5576 *flags |= SfMayBlock;
5577 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5578 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5579 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5580 PRE_REG_READ6(long, "sendto",
5581 int, s, const void *, msg, vki_size_t, len,
5582 unsigned int, flags,
5583 const struct sockaddr *, to, int, tolen);
5584 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5587 PRE (sys_recv)
5589 *flags |= SfMayBlock;
5590 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5591 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5592 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5593 unsigned int, flags);
5594 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5597 POST (sys_recv)
5599 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5602 PRE(sys_recvfrom)
5604 *flags |= SfMayBlock;
5605 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5606 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5607 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5608 PRE_REG_READ6(long, "recvfrom",
5609 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5610 struct sockaddr *, from, int *, fromlen);
5611 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5613 POST(sys_recvfrom)
5615 vg_assert(SUCCESS);
5616 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5617 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5620 PRE(sys_sendmsg)
5622 *flags |= SfMayBlock;
5623 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5624 SARG1, ARG2, ARG3);
5625 PRE_REG_READ3(long, "sendmsg",
5626 int, s, const struct msghdr *, msg, unsigned int, flags);
5627 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5630 PRE(sys_recvmsg)
5632 *flags |= SfMayBlock;
5633 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5634 SARG1, ARG2, ARG3);
5635 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5636 unsigned int, flags);
5637 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5639 POST(sys_recvmsg)
5641 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5642 RES);
5645 PRE(sys_shutdown)
5647 *flags |= SfMayBlock;
5648 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5649 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5652 PRE(sys_bind)
5654 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5655 PRE_REG_READ3(long, "bind",
5656 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5657 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5660 PRE(sys_listen)
5662 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5663 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5666 PRE(sys_getsockname)
5668 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5669 SARG1, ARG2, ARG3);
5670 PRE_REG_READ3(long, "getsockname",
5671 int, s, struct sockaddr *, name, int *, namelen);
5672 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5674 POST(sys_getsockname)
5676 vg_assert(SUCCESS);
5677 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5678 ARG1,ARG2,ARG3);
5681 PRE(sys_getpeername)
5683 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5684 SARG1, ARG2, ARG3);
5685 PRE_REG_READ3(long, "getpeername",
5686 int, s, struct sockaddr *, name, int *, namelen);
5687 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5689 POST(sys_getpeername)
5691 vg_assert(SUCCESS);
5692 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5693 ARG1,ARG2,ARG3);
5696 PRE(sys_socketpair)
5698 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5699 SARG3, ARG4);
5700 PRE_REG_READ4(long, "socketpair",
5701 int, d, int, type, int, protocol, int*, sv);
5702 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5704 POST(sys_socketpair)
5706 vg_assert(SUCCESS);
5707 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5708 ARG1,ARG2,ARG3,ARG4);
5712 /* ---------------------------------------------------------------------
5713 *at wrappers
5714 ------------------------------------------------------------------ */
5716 PRE(sys_openat)
5718 HChar name[30]; // large enough
5719 SysRes sres;
5721 if (ARG3 & VKI_O_CREAT) {
5722 // 4-arg version
5723 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5724 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5725 PRE_REG_READ4(long, "openat",
5726 int, dfd, const char *, filename, int, flags, int, mode);
5727 } else {
5728 // 3-arg version
5729 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5730 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5731 PRE_REG_READ3(long, "openat",
5732 int, dfd, const char *, filename, int, flags);
5735 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5737 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5738 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5739 be sure only to compare the bottom 32 bits. */
5740 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5741 && *(Char *)(Addr)ARG2 != '/'
5742 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5743 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5744 SET_STATUS_Failure( VKI_EBADF );
5746 /* Handle the case where the open is of /proc/self/cmdline or
5747 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5748 fake file we cooked up at startup (in m_main). Also, seek the
5749 cloned fd back to the start. */
5751 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5752 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5753 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5754 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5755 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5756 SET_STATUS_from_SysRes( sres );
5757 if (!sr_isError(sres)) {
5758 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5759 if (off < 0)
5760 SET_STATUS_Failure( VKI_EMFILE );
5762 return;
5765 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5767 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5768 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5769 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5770 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5771 sres = VG_(dup)( VG_(cl_auxv_fd) );
5772 SET_STATUS_from_SysRes( sres );
5773 if (!sr_isError(sres)) {
5774 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5775 if (off < 0)
5776 SET_STATUS_Failure( VKI_EMFILE );
5778 return;
5781 /* And for /proc/self/exe or /proc/<pid>/exe case. */
5783 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5784 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5785 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5786 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5787 sres = VG_(dup)( VG_(cl_exec_fd) );
5788 SET_STATUS_from_SysRes( sres );
5789 if (!sr_isError(sres)) {
5790 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5791 if (off < 0)
5792 SET_STATUS_Failure( VKI_EMFILE );
5794 return;
5797 /* Otherwise handle normally */
5798 *flags |= SfMayBlock;
5801 POST(sys_openat)
5803 vg_assert(SUCCESS);
5804 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5805 VG_(close)(RES);
5806 SET_STATUS_Failure( VKI_EMFILE );
5807 } else {
5808 if (VG_(clo_track_fds))
5809 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5813 PRE(sys_mkdirat)
5815 *flags |= SfMayBlock;
5816 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5817 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5818 PRE_REG_READ3(long, "mkdirat",
5819 int, dfd, const char *, pathname, int, mode);
5820 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5823 PRE(sys_mknodat)
5825 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5826 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5827 PRE_REG_READ4(long, "mknodat",
5828 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5829 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5832 PRE(sys_fchownat)
5834 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5835 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5836 PRE_REG_READ4(long, "fchownat",
5837 int, dfd, const char *, path,
5838 vki_uid_t, owner, vki_gid_t, group);
5839 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5842 PRE(sys_futimesat)
5844 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5845 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5846 PRE_REG_READ3(long, "futimesat",
5847 int, dfd, char *, filename, struct timeval *, tvp);
5848 if (ARG2 != 0)
5849 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5850 if (ARG3 != 0)
5851 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5854 PRE(sys_utimensat)
5856 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5857 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5858 PRE_REG_READ4(long, "utimensat",
5859 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5860 if (ARG2 != 0)
5861 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5862 if (ARG3 != 0) {
5863 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5864 then the tv_sec field is ignored. */
5865 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5866 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5867 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5868 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5869 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5870 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5871 if (times[0].tv_nsec != VKI_UTIME_NOW
5872 && times[0].tv_nsec != VKI_UTIME_OMIT)
5873 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5874 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5875 if (times[1].tv_nsec != VKI_UTIME_NOW
5876 && times[1].tv_nsec != VKI_UTIME_OMIT)
5877 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5878 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5883 PRE(sys_utimensat_time64)
5885 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5886 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5887 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5888 PRE_REG_READ4(long, "utimensat_time64",
5889 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5890 if (ARG2 != 0)
5891 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5892 if (ARG3 != 0) {
5893 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5894 then the tv_sec field is ignored. */
5895 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5896 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5897 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5898 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5899 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5900 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5901 if (times[0].tv_nsec != VKI_UTIME_NOW
5902 && times[0].tv_nsec != VKI_UTIME_OMIT)
5903 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5904 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5905 if (times[1].tv_nsec != VKI_UTIME_NOW
5906 && times[1].tv_nsec != VKI_UTIME_OMIT)
5907 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5908 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5913 #if !defined(VGP_nanomips_linux)
5914 PRE(sys_newfstatat)
5916 FUSE_COMPATIBLE_MAY_BLOCK();
5917 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5918 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5919 PRE_REG_READ3(long, "fstatat",
5920 int, dfd, char *, file_name, struct stat *, buf);
5921 // See the comment about Rust in PRE(sys_statx). When glibc does support
5922 // statx rust uses that instead of the system call, but glibc's statx is
5923 // implemented in terms of fstatat, so the filename being NULL is
5924 // transferred here.
5925 if (ARG2 != 0) {
5926 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5927 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5931 POST(sys_newfstatat)
5933 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5935 #endif
5937 PRE(sys_unlinkat)
5939 *flags |= SfMayBlock;
5940 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5941 (HChar*)(Addr)ARG2);
5942 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5943 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5946 PRE(sys_renameat)
5948 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5949 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5950 ARG4, (HChar*)(Addr)ARG4);
5951 PRE_REG_READ4(long, "renameat",
5952 int, olddfd, const char *, oldpath,
5953 int, newdfd, const char *, newpath);
5954 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5955 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5958 PRE(sys_renameat2)
5960 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5961 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5962 ARG4, (HChar*)(Addr)ARG4, ARG5);
5963 PRE_REG_READ5(long, "renameat2",
5964 int, olddfd, const char *, oldpath,
5965 int, newdfd, const char *, newpath,
5966 unsigned int, flags);
5967 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5968 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5971 PRE(sys_linkat)
5973 *flags |= SfMayBlock;
5974 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5975 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5976 (HChar*)(Addr)ARG4, SARG5);
5977 PRE_REG_READ5(long, "linkat",
5978 int, olddfd, const char *, oldpath,
5979 int, newdfd, const char *, newpath,
5980 int, flags);
5981 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5982 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5985 PRE(sys_symlinkat)
5987 *flags |= SfMayBlock;
5988 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5989 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5990 PRE_REG_READ3(long, "symlinkat",
5991 const char *, oldpath, int, newdfd, const char *, newpath);
5992 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5993 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5996 PRE(sys_readlinkat)
5998 HChar name[30]; // large enough
5999 Word saved = SYSNO;
6001 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
6002 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
6003 PRE_REG_READ4(long, "readlinkat",
6004 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
6005 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
6006 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
6009 * Handle the case where readlinkat is looking at /proc/self/exe or
6010 * /proc/<pid>/exe.
6012 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
6013 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
6014 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
6015 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
6016 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
6017 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
6018 ARG3, ARG4));
6019 } else {
6020 /* Normal case */
6021 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
6024 if (SUCCESS && RES > 0)
6025 POST_MEM_WRITE( ARG3, RES );
6028 PRE(sys_fchmodat)
6030 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
6031 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6032 PRE_REG_READ3(long, "fchmodat",
6033 int, dfd, const char *, path, vki_mode_t, mode);
6034 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
6037 PRE(sys_faccessat)
6039 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
6040 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
6041 PRE_REG_READ3(long, "faccessat",
6042 int, dfd, const char *, pathname, int, mode);
6043 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
6046 PRE(sys_faccessat2)
6048 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
6049 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
6050 PRE_REG_READ4(long, "faccessat2",
6051 int, dfd, const char *, pathname, int, mode, int, flags);
6052 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6055 PRE(sys_name_to_handle_at)
6057 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6058 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6059 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6060 PRE_REG_READ5(int, "name_to_handle_at",
6061 int, dfd, const char *, name,
6062 struct vki_file_handle *, handle,
6063 int *, mnt_id, int, flag);
6064 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6065 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6066 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6067 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6068 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6070 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6073 POST(sys_name_to_handle_at)
6075 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6076 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6077 POST_MEM_WRITE( ARG4, sizeof(int) );
6080 PRE(sys_open_by_handle_at)
6082 *flags |= SfMayBlock;
6083 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6084 ARG2, SARG3);
6085 PRE_REG_READ3(int, "open_by_handle_at",
6086 int, mountdirfd,
6087 struct vki_file_handle *, handle,
6088 int, flags);
6089 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6090 sizeof(struct vki_file_handle) +
6091 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6094 POST(sys_open_by_handle_at)
6096 vg_assert(SUCCESS);
6097 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6098 VG_(close)(RES);
6099 SET_STATUS_Failure( VKI_EMFILE );
6100 } else {
6101 if (VG_(clo_track_fds))
6102 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6106 /* ---------------------------------------------------------------------
6107 p{read,write}v wrappers
6108 ------------------------------------------------------------------ */
6109 /* This handles the common part of the PRE macro for preadv and preadv2. */
6110 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6111 Int fd, Addr vector, Int count, const char *str)
6113 struct vki_iovec * vec;
6114 Int i;
6115 /* safe size for the "preadv/preadv2(vector[i])" string */
6116 char tmp[30];
6118 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6119 SET_STATUS_Failure( VKI_EBADF );
6120 } else if (count > 0) {
6121 VG_(strcpy) (tmp, str);
6122 VG_(strcat) (tmp, "(vector)");
6123 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6125 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6126 count * sizeof(struct vki_iovec))) {
6127 vec = (struct vki_iovec *)(Addr)vector;
6128 for (i = 0; i < count; i++) {
6129 /* Note: building such a dynamic error string is *not*
6130 a pattern to follow. See bug 417075. */
6131 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6132 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6138 /* This handles the common part of the POST macro for preadv and preadv2. */
6139 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6141 vg_assert(SUCCESS);
6142 if (RES > 0) {
6143 Int i;
6144 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6145 Int remains = RES;
6147 /* RES holds the number of bytes read. */
6148 for (i = 0; i < count; i++) {
6149 Int nReadThisBuf = vec[i].iov_len;
6150 if (nReadThisBuf > remains) nReadThisBuf = remains;
6151 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6152 remains -= nReadThisBuf;
6153 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6158 PRE(sys_preadv)
6160 *flags |= SfMayBlock;
6161 const char *str = "preadv";
6162 #if VG_WORDSIZE == 4
6163 /* Note that the offset argument here is in lo+hi order on both
6164 big and little endian platforms... */
6165 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6166 "u, %lld )",
6167 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6168 PRE_REG_READ5(ssize_t, "preadv",
6169 unsigned long, fd, const struct iovec *, vector,
6170 unsigned long, count, vki_u32, offset_low,
6171 vki_u32, offset_high);
6172 #elif VG_WORDSIZE == 8
6173 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6174 PRE_REG_READ4(ssize_t, "preadv",
6175 unsigned long, fd, const struct iovec *, vector,
6176 unsigned long, count, Word, offset);
6177 #else
6178 # error Unexpected word size
6179 #endif
6180 Int fd = ARG1;
6181 Addr vector = ARG2;
6182 Int count = ARG3;
6184 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6188 POST(sys_preadv)
6190 Addr vector = ARG2;
6191 Int count = ARG3;
6193 handle_post_sys_preadv(tid, status, vector, count);
6196 PRE(sys_preadv2)
6198 *flags |= SfMayBlock;
6199 const char *str = "preadv2";
6200 #if VG_WORDSIZE == 4
6201 /* Note that the offset argument here is in lo+hi order on both
6202 big and little endian platforms... */
6203 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6204 "u, %lld, %" FMT_REGWORD "u )",
6205 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6206 PRE_REG_READ6(ssize_t, "preadv2",
6207 unsigned long, fd, const struct iovec *, vector,
6208 unsigned long, count, vki_u32, offset_low,
6209 vki_u32, offset_high, unsigned long, flags);
6210 #elif VG_WORDSIZE == 8
6211 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6212 PRE_REG_READ5(ssize_t, "preadv2",
6213 unsigned long, fd, const struct iovec *, vector,
6214 unsigned long, count, Word, offset, unsigned long, flags);
6215 #else
6216 # error Unexpected word size
6217 #endif
6218 Int fd = ARG1;
6219 Addr vector = ARG2;
6220 Int count = ARG3;
6222 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6225 POST(sys_preadv2)
6227 Addr vector = ARG2;
6228 Int count = ARG3;
6230 handle_post_sys_preadv(tid, status, vector, count);
6233 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6234 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6235 Int fd, Addr vector, Int count, const char *str)
6237 Int i;
6238 struct vki_iovec * vec;
6239 /* safe size for the "preadv/preadv2(vector[i])" string */
6240 char tmp[30];
6242 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6243 SET_STATUS_Failure( VKI_EBADF );
6244 } else if (count > 0) {
6245 VG_(strcpy) (tmp, str);
6246 VG_(strcat) (tmp, "(vector)");
6247 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6248 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6249 count * sizeof(struct vki_iovec))) {
6250 vec = (struct vki_iovec *)(Addr)vector;
6251 for (i = 0; i < count; i++) {
6252 /* Note: building such a dynamic error string is *not*
6253 a pattern to follow. See bug 417075. */
6254 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6255 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6261 PRE(sys_pwritev)
6263 *flags |= SfMayBlock;
6264 const char *str = "pwritev";
6265 #if VG_WORDSIZE == 4
6266 /* Note that the offset argument here is in lo+hi order on both
6267 big and little endian platforms... */
6268 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6269 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6270 PRE_REG_READ5(ssize_t, "pwritev",
6271 unsigned long, fd, const struct iovec *, vector,
6272 unsigned long, count, vki_u32, offset_low,
6273 vki_u32, offset_high);
6274 #elif VG_WORDSIZE == 8
6275 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6276 PRE_REG_READ4(ssize_t, "pwritev",
6277 unsigned long, fd, const struct iovec *, vector,
6278 unsigned long, count, Word, offset);
6279 #else
6280 # error Unexpected word size
6281 #endif
6282 Int fd = ARG1;
6283 Addr vector = ARG2;
6284 Int count = ARG3;
6286 handle_sys_pwritev(tid, status, fd, vector, count, str);
6289 PRE(sys_pwritev2)
6291 *flags |= SfMayBlock;
6292 const char *str = "pwritev2";
6293 #if VG_WORDSIZE == 4
6294 /* Note that the offset argument here is in lo+hi order on both
6295 big and little endian platforms... */
6296 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6297 "u, %lld, %" FMT_REGWORD "u )",
6298 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6299 PRE_REG_READ6(ssize_t, "pwritev2",
6300 unsigned long, fd, const struct iovec *, vector,
6301 unsigned long, count, vki_u32, offset_low,
6302 vki_u32, offset_high, unsigned long, flags);
6303 #elif VG_WORDSIZE == 8
6304 /* Note offset_high isn't actually used? */
6305 PRE_REG_READ6(ssize_t, "pwritev2",
6306 unsigned long, fd, const struct iovec *, vector,
6307 unsigned long, count, Word, offset,
6308 Word, offset_high, unsigned long, flags);
6309 #else
6310 # error Unexpected word size
6311 #endif
6312 Int fd = ARG1;
6313 Addr vector = ARG2;
6314 Int count = ARG3;
6316 handle_sys_pwritev(tid, status, fd, vector, count, str);
6319 /* ---------------------------------------------------------------------
6320 process_vm_{read,write}v wrappers
6321 ------------------------------------------------------------------ */
6323 PRE(sys_process_vm_readv)
6325 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6326 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6327 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6328 PRE_REG_READ6(ssize_t, "process_vm_readv",
6329 vki_pid_t, pid,
6330 const struct iovec *, lvec,
6331 unsigned long, liovcnt,
6332 const struct iovec *, rvec,
6333 unsigned long, riovcnt,
6334 unsigned long, flags);
6335 PRE_MEM_READ( "process_vm_readv(lvec)",
6336 ARG2, ARG3 * sizeof(struct vki_iovec) );
6337 PRE_MEM_READ( "process_vm_readv(rvec)",
6338 ARG4, ARG5 * sizeof(struct vki_iovec) );
6339 if (ARG2 != 0
6340 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6341 sizeof(struct vki_iovec) * ARG3)) {
6342 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6343 UInt i;
6344 for (i = 0; i < ARG3; i++)
6345 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6346 (Addr)vec[i].iov_base, vec[i].iov_len );
6350 POST(sys_process_vm_readv)
6352 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6353 UInt remains = RES;
6354 UInt i;
6355 for (i = 0; i < ARG3; i++) {
6356 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6357 vec[i].iov_len : remains;
6358 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6359 remains -= nReadThisBuf;
6363 PRE(sys_process_vm_writev)
6365 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6366 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6367 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6368 PRE_REG_READ6(ssize_t, "process_vm_writev",
6369 vki_pid_t, pid,
6370 const struct iovec *, lvec,
6371 unsigned long, liovcnt,
6372 const struct iovec *, rvec,
6373 unsigned long, riovcnt,
6374 unsigned long, flags);
6375 PRE_MEM_READ( "process_vm_writev(lvec)",
6376 ARG2, ARG3 * sizeof(struct vki_iovec) );
6377 PRE_MEM_READ( "process_vm_writev(rvec)",
6378 ARG4, ARG5 * sizeof(struct vki_iovec) );
6379 if (ARG2 != 0
6380 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6381 sizeof(struct vki_iovec) * ARG3)) {
6382 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6383 UInt i;
6384 for (i = 0; i < ARG3; i++)
6385 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6386 (Addr)vec[i].iov_base, vec[i].iov_len );
6390 /* ---------------------------------------------------------------------
6391 {send,recv}mmsg wrappers
6392 ------------------------------------------------------------------ */
6394 PRE(sys_sendmmsg)
6396 *flags |= SfMayBlock;
6397 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6398 SARG3, SARG4);
6399 PRE_REG_READ4(long, "sendmmsg",
6400 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6401 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6404 POST(sys_sendmmsg)
6406 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6409 PRE(sys_recvmmsg)
6411 *flags |= SfMayBlock;
6412 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6413 FMT_REGWORD "x )",
6414 SARG1, ARG2, SARG3, SARG4, ARG5);
6415 PRE_REG_READ5(long, "recvmmsg",
6416 int, s, struct mmsghdr *, mmsg, int, vlen,
6417 int, flags, struct timespec *, timeout);
6418 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6421 POST(sys_recvmmsg)
6423 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6426 PRE(sys_recvmmsg_time64)
6428 *flags |= SfMayBlock;
6429 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6430 FMT_REGWORD "x )",
6431 SARG1, ARG2, SARG3, SARG4, ARG5);
6432 PRE_REG_READ5(long, "recvmmsg_time64",
6433 int, s, struct mmsghdr *, mmsg, int, vlen,
6434 int, flags, struct vki_timespec64 *, timeout);
6435 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6436 HChar name[40]; // large enough
6437 UInt i;
6438 for (i = 0; i < ARG3; i++) {
6439 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6440 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6441 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6442 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6444 if (ARG5)
6445 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6448 POST(sys_recvmmsg_time64)
6450 /* ARG5 isn't actually used, so just use the generic POST. */
6451 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6454 /* ---------------------------------------------------------------------
6455 key retention service wrappers
6456 ------------------------------------------------------------------ */
6458 PRE(sys_request_key)
6460 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6461 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6462 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6463 PRE_REG_READ4(long, "request_key",
6464 const char *, type, const char *, description,
6465 const char *, callout_info, vki_key_serial_t, keyring);
6466 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6467 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6468 if (ARG3 != (UWord)NULL)
6469 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6472 PRE(sys_add_key)
6474 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6475 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6476 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6477 PRE_REG_READ5(long, "add_key",
6478 const char *, type, const char *, description,
6479 const void *, payload, vki_size_t, plen,
6480 vki_key_serial_t, keyring);
6481 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6482 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6483 if (ARG3 != (UWord)NULL)
6484 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6487 PRE(sys_keyctl)
6489 switch (ARG1 /* option */) {
6490 case VKI_KEYCTL_GET_KEYRING_ID:
6491 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6492 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6493 int, option, vki_key_serial_t, id, int, create);
6494 break;
6495 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6496 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6497 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6498 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6499 int, option, const char *, name);
6500 if (ARG2 != (UWord)NULL)
6501 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6502 break;
6503 case VKI_KEYCTL_UPDATE:
6504 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6505 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6506 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6507 int, option, vki_key_serial_t, key,
6508 const void *, payload, vki_size_t, plen);
6509 if (ARG3 != (UWord)NULL)
6510 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6511 break;
6512 case VKI_KEYCTL_REVOKE:
6513 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6514 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6515 int, option, vki_key_serial_t, id);
6516 break;
6517 case VKI_KEYCTL_CHOWN:
6518 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6519 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6520 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6521 int, option, vki_key_serial_t, id,
6522 vki_uid_t, uid, vki_gid_t, gid);
6523 break;
6524 case VKI_KEYCTL_SETPERM:
6525 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6526 SARG2, ARG3);
6527 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6528 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6529 break;
6530 case VKI_KEYCTL_DESCRIBE:
6531 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6532 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6533 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6534 int, option, vki_key_serial_t, id,
6535 char *, buffer, vki_size_t, buflen);
6536 if (ARG3 != (UWord)NULL)
6537 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6538 break;
6539 case VKI_KEYCTL_CLEAR:
6540 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6541 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6542 int, option, vki_key_serial_t, keyring);
6543 break;
6544 case VKI_KEYCTL_LINK:
6545 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6546 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6547 vki_key_serial_t, keyring, vki_key_serial_t, key);
6548 break;
6549 case VKI_KEYCTL_UNLINK:
6550 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6551 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6552 vki_key_serial_t, keyring, vki_key_serial_t, key);
6553 break;
6554 case VKI_KEYCTL_SEARCH:
6555 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6556 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6557 ARG4, (HChar*)(Addr)ARG4, SARG5);
6558 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6559 int, option, vki_key_serial_t, keyring,
6560 const char *, type, const char *, description,
6561 vki_key_serial_t, destring);
6562 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6563 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6564 break;
6565 case VKI_KEYCTL_READ:
6566 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6567 "u )", SARG2, ARG3, ARG4);
6568 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6569 int, option, vki_key_serial_t, keyring,
6570 char *, buffer, vki_size_t, buflen);
6571 if (ARG3 != (UWord)NULL)
6572 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6573 break;
6574 case VKI_KEYCTL_INSTANTIATE:
6575 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6576 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6577 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6578 int, option, vki_key_serial_t, key,
6579 char *, payload, vki_size_t, plen,
6580 vki_key_serial_t, keyring);
6581 if (ARG3 != (UWord)NULL)
6582 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6583 break;
6584 case VKI_KEYCTL_NEGATE:
6585 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6586 SARG2, ARG3, SARG4);
6587 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6588 int, option, vki_key_serial_t, key,
6589 unsigned, timeout, vki_key_serial_t, keyring);
6590 break;
6591 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6592 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6593 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6594 int, option, int, reqkey_defl);
6595 break;
6596 case VKI_KEYCTL_SET_TIMEOUT:
6597 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6598 SARG2, ARG3);
6599 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6600 int, option, vki_key_serial_t, key, unsigned, timeout);
6601 break;
6602 case VKI_KEYCTL_ASSUME_AUTHORITY:
6603 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6604 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6605 int, option, vki_key_serial_t, key);
6606 break;
6607 default:
6608 PRINT("sys_keyctl ( %ld ) ", SARG1);
6609 PRE_REG_READ1(long, "keyctl", int, option);
6610 break;
6614 POST(sys_keyctl)
6616 vg_assert(SUCCESS);
6617 switch (ARG1 /* option */) {
6618 case VKI_KEYCTL_DESCRIBE:
6619 case VKI_KEYCTL_READ:
6620 if (RES > ARG4)
6621 POST_MEM_WRITE(ARG3, ARG4);
6622 else
6623 POST_MEM_WRITE(ARG3, RES);
6624 break;
6625 default:
6626 break;
6630 /* ---------------------------------------------------------------------
6631 ioprio_ wrappers
6632 ------------------------------------------------------------------ */
6634 PRE(sys_ioprio_set)
6636 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6637 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6640 PRE(sys_ioprio_get)
6642 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6643 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6646 /* ---------------------------------------------------------------------
6647 _module wrappers
6648 ------------------------------------------------------------------ */
6650 PRE(sys_init_module)
6652 *flags |= SfMayBlock;
6653 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6654 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6655 PRE_REG_READ3(long, "init_module",
6656 void *, umod, unsigned long, len, const char *, uargs);
6657 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6658 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6661 PRE(sys_finit_module)
6663 *flags |= SfMayBlock;
6665 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6666 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6667 PRE_REG_READ3(long, "finit_module",
6668 int, fd, const char *, params, int, flags);
6669 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6672 PRE(sys_delete_module)
6674 *flags |= SfMayBlock;
6675 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6676 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6677 PRE_REG_READ2(long, "delete_module",
6678 const char *, name_user, unsigned int, flags);
6679 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6682 /* ---------------------------------------------------------------------
6683 splice wrappers
6684 ------------------------------------------------------------------ */
6686 PRE(sys_splice)
6688 *flags |= SfMayBlock;
6689 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6690 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6691 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6692 PRE_REG_READ6(vki_ssize_t, "splice",
6693 int, fd_in, vki_loff_t *, off_in,
6694 int, fd_out, vki_loff_t *, off_out,
6695 vki_size_t, len, unsigned int, flags);
6696 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6697 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6698 SET_STATUS_Failure( VKI_EBADF );
6699 } else {
6700 if (ARG2 != 0)
6701 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6702 if (ARG4 != 0)
6703 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6707 PRE(sys_tee)
6709 *flags |= SfMayBlock;
6710 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6711 SARG1, SARG2, ARG3, ARG4);
6712 PRE_REG_READ4(vki_ssize_t, "tee",
6713 int, fd_in, int, fd_out,
6714 vki_size_t, len, unsigned int, flags);
6715 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6716 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6717 SET_STATUS_Failure( VKI_EBADF );
6721 PRE(sys_vmsplice)
6723 Int fdfl;
6724 *flags |= SfMayBlock;
6725 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6726 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6727 PRE_REG_READ4(vki_ssize_t, "splice",
6728 int, fd, struct vki_iovec *, iov,
6729 unsigned long, nr_segs, unsigned int, flags);
6730 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6731 SET_STATUS_Failure( VKI_EBADF );
6732 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6733 SET_STATUS_Failure( VKI_EBADF );
6734 } else {
6735 const struct vki_iovec *iov;
6736 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6737 for (iov = (struct vki_iovec *)(Addr)ARG2;
6738 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6740 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6741 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6742 PRE_MEM_WRITE( "vmsplice(iov[...])",
6743 (Addr)iov->iov_base, iov->iov_len );
6744 else
6745 PRE_MEM_READ( "vmsplice(iov[...])",
6746 (Addr)iov->iov_base, iov->iov_len );
6752 POST(sys_vmsplice)
6754 vg_assert(SUCCESS);
6755 if (RES > 0) {
6756 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6757 vg_assert(fdfl >= 0);
6758 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6760 const struct vki_iovec *iov;
6761 for (iov = (struct vki_iovec *)(Addr)ARG2;
6762 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6764 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6770 /* ---------------------------------------------------------------------
6771 oprofile-related wrappers
6772 ------------------------------------------------------------------ */
6774 #if defined(VGP_x86_linux)
6775 PRE(sys_lookup_dcookie)
6777 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6778 MERGE64(ARG1,ARG2), ARG3, ARG4);
6779 PRE_REG_READ4(long, "lookup_dcookie",
6780 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6781 char *, buf, vki_size_t, len);
6782 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6784 POST(sys_lookup_dcookie)
6786 vg_assert(SUCCESS);
6787 if (ARG3 != (Addr)NULL)
6788 POST_MEM_WRITE( ARG3, RES);
6790 #endif
6792 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6793 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6794 PRE(sys_lookup_dcookie)
6796 *flags |= SfMayBlock;
6797 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6798 PRE_REG_READ3(int, "lookup_dcookie",
6799 unsigned long long, cookie, char *, buf, vki_size_t, len);
6801 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6804 POST(sys_lookup_dcookie)
6806 vg_assert(SUCCESS);
6807 if (ARG2 != (Addr)NULL)
6808 POST_MEM_WRITE( ARG2, RES );
6810 #endif
6812 /* ---------------------------------------------------------------------
6813 fcntl wrappers
6814 ------------------------------------------------------------------ */
6816 PRE(sys_fcntl)
6818 switch (ARG2) {
6819 // These ones ignore ARG3.
6820 case VKI_F_GETFD:
6821 case VKI_F_GETFL:
6822 case VKI_F_GETOWN:
6823 case VKI_F_GETSIG:
6824 case VKI_F_GETLEASE:
6825 case VKI_F_GETPIPE_SZ:
6826 case VKI_F_GET_SEALS:
6827 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6828 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6829 break;
6831 // These ones use ARG3 as "arg".
6832 case VKI_F_DUPFD:
6833 case VKI_F_DUPFD_CLOEXEC:
6834 case VKI_F_SETFD:
6835 case VKI_F_SETFL:
6836 case VKI_F_SETLEASE:
6837 case VKI_F_NOTIFY:
6838 case VKI_F_SETOWN:
6839 case VKI_F_SETSIG:
6840 case VKI_F_SETPIPE_SZ:
6841 case VKI_F_ADD_SEALS:
6842 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6843 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6844 PRE_REG_READ3(long, "fcntl",
6845 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6846 break;
6848 // These ones use ARG3 as "lock".
6849 case VKI_F_GETLK:
6850 case VKI_F_SETLK:
6851 case VKI_F_SETLKW:
6852 case VKI_F_OFD_GETLK:
6853 case VKI_F_OFD_SETLK:
6854 case VKI_F_OFD_SETLKW:
6855 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6856 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6857 PRE_REG_READ3(long, "fcntl",
6858 unsigned int, fd, unsigned int, cmd,
6859 struct vki_flock *, lock);
6861 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6862 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6863 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6864 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6865 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6866 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6867 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6870 break;
6872 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6873 case VKI_F_GETLK64:
6874 case VKI_F_SETLK64:
6875 case VKI_F_SETLKW64:
6876 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6877 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6878 PRE_REG_READ3(long, "fcntl",
6879 unsigned int, fd, unsigned int, cmd,
6880 struct flock64 *, lock);
6882 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6883 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6884 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6885 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6886 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6887 if (ARG2 == VKI_F_GETLK64) {
6888 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6891 break;
6892 # endif
6894 case VKI_F_SETOWN_EX:
6895 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6896 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6897 PRE_REG_READ3(long, "fcntl",
6898 unsigned int, fd, unsigned int, cmd,
6899 struct vki_f_owner_ex *, arg);
6900 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6901 break;
6903 case VKI_F_GETOWN_EX:
6904 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6905 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6906 PRE_REG_READ3(long, "fcntl",
6907 unsigned int, fd, unsigned int, cmd,
6908 struct vki_f_owner_ex *, arg);
6909 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6910 break;
6912 default:
6913 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6914 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6915 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6916 ARG2);
6917 SET_STATUS_Failure( VKI_EINVAL );
6918 break;
6921 # if defined(VGP_x86_linux)
6922 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6923 # else
6924 if (ARG2 == VKI_F_SETLKW)
6925 # endif
6926 *flags |= SfMayBlock;
6929 POST(sys_fcntl)
6931 vg_assert(SUCCESS);
6932 if (ARG2 == VKI_F_DUPFD) {
6933 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6934 VG_(close)(RES);
6935 SET_STATUS_Failure( VKI_EMFILE );
6936 } else {
6937 if (VG_(clo_track_fds))
6938 ML_(record_fd_open_named)(tid, RES);
6941 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6942 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6943 VG_(close)(RES);
6944 SET_STATUS_Failure( VKI_EMFILE );
6945 } else {
6946 if (VG_(clo_track_fds))
6947 ML_(record_fd_open_named)(tid, RES);
6949 } else if (ARG2 == VKI_F_GETOWN_EX) {
6950 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6951 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6952 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6953 POST_FIELD_WRITE(lock->l_pid);
6954 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6955 } else if (ARG2 == VKI_F_GETLK64) {
6956 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6957 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6958 # endif
6962 // XXX: wrapper only suitable for 32-bit systems
6963 PRE(sys_fcntl64)
6965 switch (ARG2) {
6966 // These ones ignore ARG3.
6967 case VKI_F_GETFD:
6968 case VKI_F_GETFL:
6969 case VKI_F_GETOWN:
6970 case VKI_F_SETOWN:
6971 case VKI_F_GETSIG:
6972 case VKI_F_SETSIG:
6973 case VKI_F_GETLEASE:
6974 case VKI_F_GET_SEALS:
6975 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6976 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6977 break;
6979 // These ones use ARG3 as "arg".
6980 case VKI_F_DUPFD:
6981 case VKI_F_DUPFD_CLOEXEC:
6982 case VKI_F_SETFD:
6983 case VKI_F_SETFL:
6984 case VKI_F_SETLEASE:
6985 case VKI_F_NOTIFY:
6986 case VKI_F_ADD_SEALS:
6987 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6988 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6989 PRE_REG_READ3(long, "fcntl64",
6990 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6991 break;
6993 // These ones use ARG3 as "lock".
6994 case VKI_F_GETLK:
6995 case VKI_F_SETLK:
6996 case VKI_F_SETLKW:
6997 # if defined(VGP_x86_linux)
6998 case VKI_F_GETLK64:
6999 case VKI_F_SETLK64:
7000 case VKI_F_SETLKW64:
7001 # endif
7002 case VKI_F_OFD_GETLK:
7003 case VKI_F_OFD_SETLK:
7004 case VKI_F_OFD_SETLKW:
7005 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7006 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7007 PRE_REG_READ3(long, "fcntl64",
7008 unsigned int, fd, unsigned int, cmd,
7009 struct flock64 *, lock);
7010 break;
7012 case VKI_F_SETOWN_EX:
7013 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7014 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7015 PRE_REG_READ3(long, "fcntl",
7016 unsigned int, fd, unsigned int, cmd,
7017 struct vki_f_owner_ex *, arg);
7018 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7019 break;
7021 case VKI_F_GETOWN_EX:
7022 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7023 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7024 PRE_REG_READ3(long, "fcntl",
7025 unsigned int, fd, unsigned int, cmd,
7026 struct vki_f_owner_ex *, arg);
7027 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7028 break;
7031 # if defined(VGP_x86_linux)
7032 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7033 # else
7034 if (ARG2 == VKI_F_SETLKW)
7035 # endif
7036 *flags |= SfMayBlock;
7039 POST(sys_fcntl64)
7041 vg_assert(SUCCESS);
7042 if (ARG2 == VKI_F_DUPFD) {
7043 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
7044 VG_(close)(RES);
7045 SET_STATUS_Failure( VKI_EMFILE );
7046 } else {
7047 if (VG_(clo_track_fds))
7048 ML_(record_fd_open_named)(tid, RES);
7051 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7052 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
7053 VG_(close)(RES);
7054 SET_STATUS_Failure( VKI_EMFILE );
7055 } else {
7056 if (VG_(clo_track_fds))
7057 ML_(record_fd_open_named)(tid, RES);
7059 } else if (ARG2 == VKI_F_GETOWN_EX) {
7060 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7064 /* ---------------------------------------------------------------------
7065 ioctl wrappers
7066 ------------------------------------------------------------------ */
7068 struct vg_drm_version_info {
7069 struct vki_drm_version data;
7070 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7073 PRE(sys_ioctl)
7075 *flags |= SfMayBlock;
7077 ARG2 = (UInt)ARG2;
7079 // We first handle the ones that don't use ARG3 (even as a
7080 // scalar/non-pointer argument).
7081 switch (ARG2 /* request */) {
7083 /* asm-generic/ioctls.h */
7084 case VKI_FIOCLEX:
7085 case VKI_FIONCLEX:
7086 case VKI_TIOCNOTTY:
7088 /* linux perf_event ioctls */
7089 case VKI_PERF_EVENT_IOC_ENABLE:
7090 case VKI_PERF_EVENT_IOC_DISABLE:
7092 /* linux/soundcard interface (ALSA) */
7093 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7094 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7095 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7096 case VKI_SNDRV_PCM_IOCTL_RESET:
7097 case VKI_SNDRV_PCM_IOCTL_START:
7098 case VKI_SNDRV_PCM_IOCTL_DROP:
7099 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7100 case VKI_SNDRV_PCM_IOCTL_RESUME:
7101 case VKI_SNDRV_PCM_IOCTL_XRUN:
7102 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7103 case VKI_SNDRV_TIMER_IOCTL_START:
7104 case VKI_SNDRV_TIMER_IOCTL_STOP:
7105 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7106 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7108 /* SCSI no operand */
7109 case VKI_SCSI_IOCTL_DOORLOCK:
7110 case VKI_SCSI_IOCTL_DOORUNLOCK:
7112 /* CDROM stuff. */
7113 case VKI_CDROM_DISC_STATUS:
7114 case VKI_CDROMSTOP:
7116 /* DVD stuff */
7117 case VKI_DVD_READ_STRUCT:
7119 /* KVM ioctls that don't check for a numeric value as parameter */
7120 case VKI_KVM_S390_ENABLE_SIE:
7121 case VKI_KVM_CREATE_IRQCHIP:
7122 case VKI_KVM_S390_INITIAL_RESET:
7123 case VKI_KVM_KVMCLOCK_CTRL:
7125 /* vhost without parameter */
7126 case VKI_VHOST_SET_OWNER:
7127 case VKI_VHOST_RESET_OWNER:
7129 /* User input device creation */
7130 case VKI_UI_DEV_CREATE:
7131 case VKI_UI_DEV_DESTROY:
7133 /* InfiniBand */
7134 case VKI_IB_USER_MAD_ENABLE_PKEY:
7136 /* Lustre */
7137 case VKI_LL_IOC_GROUP_LOCK:
7138 case VKI_LL_IOC_GROUP_UNLOCK:
7140 /* V4L2 */
7141 case VKI_V4L2_LOG_STATUS:
7143 /* Mesa */
7144 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7146 /* DVB */
7147 case VKI_DMX_STOP:
7148 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7149 PRE_REG_READ2(long, "ioctl",
7150 unsigned int, fd, unsigned int, request);
7151 return;
7153 default:
7154 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7155 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7156 PRE_REG_READ3(long, "ioctl",
7157 unsigned int, fd, unsigned int, request, unsigned long, arg);
7158 break;
7161 // We now handle those that do look at ARG3 (and unknown ones fall into
7162 // this category). Nb: some of these may well belong in the
7163 // doesn't-use-ARG3 switch above.
7164 switch (ARG2 /* request */) {
7166 case VKI_ION_IOC_ALLOC: {
7167 struct vki_ion_allocation_data* data
7168 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7169 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7170 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7171 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7172 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7173 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7174 break;
7176 case VKI_ION_IOC_MAP: {
7177 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7178 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7179 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7180 break;
7182 case VKI_ION_IOC_IMPORT: {
7183 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7184 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7185 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7186 break;
7189 case VKI_SYNC_IOC_MERGE: {
7190 struct vki_sync_merge_data* data =
7191 (struct vki_sync_merge_data*)(Addr)ARG3;
7192 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7193 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7194 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7195 break;
7198 case VKI_TCSETS:
7199 case VKI_TCSETSW:
7200 case VKI_TCSETSF:
7201 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7202 break;
7203 case VKI_TCGETS:
7204 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7205 break;
7206 case VKI_TCSETA:
7207 case VKI_TCSETAW:
7208 case VKI_TCSETAF:
7209 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7210 break;
7211 case VKI_TCGETA:
7212 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7213 break;
7214 case VKI_TCSBRK:
7215 case VKI_TCXONC:
7216 case VKI_TCSBRKP:
7217 case VKI_TCFLSH:
7218 case VKI_TIOCSIG:
7219 /* These just take an int by value */
7220 break;
7221 case VKI_TIOCGWINSZ:
7222 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7223 break;
7224 case VKI_TIOCSWINSZ:
7225 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7226 break;
7227 case VKI_TIOCMBIS:
7228 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7229 break;
7230 case VKI_TIOCMBIC:
7231 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7232 break;
7233 case VKI_TIOCMSET:
7234 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7235 break;
7236 case VKI_TIOCMGET:
7237 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7238 break;
7239 case VKI_TIOCLINUX:
7240 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7241 if (*(char *)(Addr)ARG3 == 11) {
7242 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7244 break;
7245 case VKI_TIOCGPGRP:
7246 /* Get process group ID for foreground processing group. */
7247 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7248 break;
7249 case VKI_TIOCSPGRP:
7250 /* Set a process group ID? */
7251 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7252 break;
7253 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7254 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7255 break;
7256 case VKI_TIOCSCTTY:
7257 /* Just takes an int value. */
7258 break;
7259 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7260 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7261 break;
7262 case VKI_FIONBIO:
7263 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7264 break;
7265 case VKI_FIOASYNC:
7266 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7267 break;
7268 case VKI_FIONREAD: /* identical to SIOCINQ */
7269 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7270 break;
7271 case VKI_FIOQSIZE:
7272 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7273 break;
7275 case VKI_TIOCSERGETLSR:
7276 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7277 break;
7278 case VKI_TIOCGICOUNT:
7279 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7280 sizeof(struct vki_serial_icounter_struct) );
7281 break;
7283 case VKI_SG_SET_COMMAND_Q:
7284 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7285 break;
7286 case VKI_SG_IO:
7287 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7289 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7290 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7291 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7292 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7293 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7296 break;
7297 case VKI_SG_GET_SCSI_ID:
7298 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7299 break;
7300 case VKI_SG_SET_RESERVED_SIZE:
7301 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7302 break;
7303 case VKI_SG_SET_TIMEOUT:
7304 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7305 break;
7306 case VKI_SG_GET_RESERVED_SIZE:
7307 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7308 break;
7309 case VKI_SG_GET_TIMEOUT:
7310 break;
7311 case VKI_SG_GET_VERSION_NUM:
7312 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7313 break;
7314 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7315 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7316 break;
7317 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7318 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7319 break;
7321 case VKI_IIOCGETCPS:
7322 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7323 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7324 break;
7325 case VKI_IIOCNETGPN:
7326 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7327 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7328 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7329 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7330 sizeof(vki_isdn_net_ioctl_phone) );
7331 break;
7333 /* These all use struct ifreq AFAIK */
7334 case VKI_SIOCGIFINDEX: /* get iface index */
7335 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7336 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7337 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7338 break;
7339 case VKI_SIOCGIFFLAGS: /* get flags */
7340 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7341 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7342 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7343 break;
7344 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7345 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7346 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7347 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7348 break;
7349 case VKI_SIOCGIFMTU: /* get MTU size */
7350 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7351 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7352 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7353 break;
7354 case VKI_SIOCGIFADDR: /* get PA address */
7355 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7356 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7357 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7358 break;
7359 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7360 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7361 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7362 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7363 break;
7364 case VKI_SIOCGIFMETRIC: /* get metric */
7365 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7366 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7367 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7368 break;
7369 case VKI_SIOCGIFMAP: /* Get device parameters */
7370 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7371 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7372 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7373 break;
7374 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7375 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7376 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7377 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7378 break;
7379 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7380 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7381 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7382 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7383 break;
7384 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7385 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7386 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7387 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7388 break;
7389 case VKI_SIOCGIFNAME: /* get iface name */
7390 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7391 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7392 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7393 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7394 break;
7396 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7397 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7398 // The kernel will have to look at ifr_data to determine which operation
7399 // to perform.
7400 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7401 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7403 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7405 // Is this correct? Is ifr_name *always* looked at?
7406 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7407 (Addr)ir->vki_ifr_name );
7409 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7410 // the whole structure is defined. So in this case, just check it's
7411 // accessible.
7412 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7413 case VKI_ETHTOOL_GSET:
7414 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7415 (Addr)ir, sizeof(struct vki_ifreq) );
7416 break;
7417 default:
7418 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7419 (Addr)ir, sizeof(struct vki_ifreq) );
7420 break;
7423 // Now perform the relevant pre-action for the operation.
7424 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7425 case VKI_ETHTOOL_GSET:
7426 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7427 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7428 break;
7429 case VKI_ETHTOOL_SSET:
7430 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7431 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7432 break;
7433 case VKI_ETHTOOL_GDRVINFO:
7434 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7435 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7436 break;
7437 case VKI_ETHTOOL_GREGS:
7438 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7439 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7440 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7441 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7442 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7443 break;
7444 case VKI_ETHTOOL_GWOL:
7445 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7446 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7447 break;
7448 case VKI_ETHTOOL_SWOL:
7449 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7450 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7451 break;
7452 case VKI_ETHTOOL_GMSGLVL:
7453 case VKI_ETHTOOL_GLINK:
7454 case VKI_ETHTOOL_GRXCSUM:
7455 case VKI_ETHTOOL_GSG:
7456 case VKI_ETHTOOL_GTSO:
7457 case VKI_ETHTOOL_GUFO:
7458 case VKI_ETHTOOL_GGSO:
7459 case VKI_ETHTOOL_GFLAGS:
7460 case VKI_ETHTOOL_GGRO:
7461 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7462 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7463 break;
7464 case VKI_ETHTOOL_SMSGLVL:
7465 case VKI_ETHTOOL_SRXCSUM:
7466 case VKI_ETHTOOL_SSG:
7467 case VKI_ETHTOOL_STSO:
7468 case VKI_ETHTOOL_SUFO:
7469 case VKI_ETHTOOL_SGSO:
7470 case VKI_ETHTOOL_SFLAGS:
7471 case VKI_ETHTOOL_SGRO:
7472 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7473 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7474 break;
7475 case VKI_ETHTOOL_NWAY_RST:
7476 break;
7477 case VKI_ETHTOOL_GRINGPARAM:
7478 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7479 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7480 break;
7481 case VKI_ETHTOOL_SRINGPARAM:
7482 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7483 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7484 break;
7485 case VKI_ETHTOOL_TEST:
7486 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7487 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7488 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7489 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7490 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7491 break;
7492 case VKI_ETHTOOL_PHYS_ID:
7493 break;
7494 case VKI_ETHTOOL_GPERMADDR:
7495 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7496 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7497 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7498 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7499 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7500 break;
7501 case VKI_ETHTOOL_RESET:
7502 break;
7503 case VKI_ETHTOOL_GSSET_INFO:
7504 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7505 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7506 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7507 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7508 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7509 break;
7510 case VKI_ETHTOOL_GFEATURES:
7511 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7512 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7513 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7514 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7515 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7516 break;
7517 case VKI_ETHTOOL_SFEATURES:
7518 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7519 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7520 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7521 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7522 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7523 break;
7524 case VKI_ETHTOOL_GCHANNELS:
7525 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7526 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7527 break;
7528 case VKI_ETHTOOL_SCHANNELS:
7529 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7530 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7531 break;
7532 case VKI_ETHTOOL_GET_TS_INFO:
7533 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7534 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7535 break;
7537 break;
7538 } /* case VKI_SIOCETHTOOL */
7540 case VKI_SIOCGMIIPHY: /* get hardware entry */
7541 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7542 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7543 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7544 break;
7545 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7546 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7547 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7548 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7549 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7550 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7551 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7552 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7553 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7554 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7555 sizeof(struct vki_ifreq));
7556 break;
7557 case VKI_SIOCGIFCONF: /* get iface list */
7558 /* WAS:
7559 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7560 KERNEL_DO_SYSCALL(tid,RES);
7561 if (!VG_(is_kerror)(RES) && RES == 0)
7562 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7564 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7565 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7566 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7567 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7568 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7569 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7570 if ( ARG3 ) {
7571 // TODO len must be readable and writable
7572 // buf pointer only needs to be readable
7573 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7574 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7575 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7577 break;
7578 case VKI_SIOCGSTAMP:
7579 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7580 break;
7581 case VKI_SIOCGSTAMPNS:
7582 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7583 break;
7584 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7585 the number of bytes currently in that socket's send buffer.
7586 It writes this value as an int to the memory location
7587 indicated by the third argument of ioctl(2). */
7588 case VKI_SIOCOUTQ:
7589 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7590 break;
7591 case VKI_SIOCGRARP: /* get RARP table entry */
7592 case VKI_SIOCGARP: /* get ARP table entry */
7593 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7594 break;
7596 case VKI_SIOCSIFFLAGS: /* set flags */
7597 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7598 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7599 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7600 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7601 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7602 break;
7603 case VKI_SIOCSIFMAP: /* Set device parameters */
7604 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7605 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7606 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7607 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7608 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7609 break;
7610 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7611 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7612 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7613 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7614 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7615 sizeof(struct vki_hwtstamp_config) );
7616 break;
7617 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7618 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7619 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7620 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7621 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7622 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7623 break;
7624 case VKI_SIOCSIFADDR: /* set PA address */
7625 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7626 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7627 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7628 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7629 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7630 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7631 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7632 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7633 break;
7634 case VKI_SIOCSIFMETRIC: /* set metric */
7635 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7636 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7637 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7638 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7639 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7640 break;
7641 case VKI_SIOCSIFMTU: /* set MTU size */
7642 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7643 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7644 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7645 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7646 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7647 break;
7648 case VKI_SIOCSIFHWADDR: /* set hardware address */
7649 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7650 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7651 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7652 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7653 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7654 break;
7655 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7656 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7657 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7658 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7659 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7660 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7661 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7662 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7663 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7664 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7665 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7666 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7667 break;
7668 /* Routing table calls. */
7669 case VKI_SIOCADDRT: /* add routing table entry */
7670 case VKI_SIOCDELRT: /* delete routing table entry */
7671 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7672 sizeof(struct vki_rtentry));
7673 break;
7675 /* tun/tap related ioctls */
7676 case VKI_TUNSETNOCSUM:
7677 case VKI_TUNSETDEBUG:
7678 break;
7679 case VKI_TUNSETIFF:
7680 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7681 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7682 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7683 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7684 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7685 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7686 break;
7687 case VKI_TUNSETPERSIST:
7688 case VKI_TUNSETOWNER:
7689 case VKI_TUNSETLINK:
7690 case VKI_TUNSETGROUP:
7691 break;
7692 case VKI_TUNGETFEATURES:
7693 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7694 break;
7695 case VKI_TUNSETOFFLOAD:
7696 break;
7697 case VKI_TUNGETIFF:
7698 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7699 break;
7700 case VKI_TUNGETSNDBUF:
7701 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7702 break;
7703 case VKI_TUNSETSNDBUF:
7704 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7705 break;
7706 case VKI_TUNGETVNETHDRSZ:
7707 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7708 break;
7709 case VKI_TUNSETVNETHDRSZ:
7710 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7711 break;
7712 case VKI_TUNSETQUEUE:
7713 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7714 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7715 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7716 break;
7717 case VKI_TUNSETIFINDEX:
7718 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7719 break;
7721 /* RARP cache control calls. */
7722 case VKI_SIOCDRARP: /* delete RARP table entry */
7723 case VKI_SIOCSRARP: /* set RARP table entry */
7724 /* ARP cache control calls. */
7725 case VKI_SIOCSARP: /* set ARP table entry */
7726 case VKI_SIOCDARP: /* delete ARP table entry */
7727 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7728 break;
7730 case VKI_SIOCGPGRP:
7731 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7732 break;
7733 case VKI_SIOCSPGRP:
7734 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7735 //tst->sys_flags &= ~SfMayBlock;
7736 break;
7738 case VKI_SIOCATMARK:
7739 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7740 break;
7742 /* linux/soundcard interface (OSS) */
7743 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7744 case VKI_SNDCTL_SEQ_GETINCOUNT:
7745 case VKI_SNDCTL_SEQ_PERCMODE:
7746 case VKI_SNDCTL_SEQ_TESTMIDI:
7747 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7748 case VKI_SNDCTL_SEQ_NRSYNTHS:
7749 case VKI_SNDCTL_SEQ_NRMIDIS:
7750 case VKI_SNDCTL_SEQ_GETTIME:
7751 case VKI_SNDCTL_DSP_GETBLKSIZE:
7752 case VKI_SNDCTL_DSP_GETFMTS:
7753 case VKI_SNDCTL_DSP_GETTRIGGER:
7754 case VKI_SNDCTL_DSP_GETODELAY:
7755 case VKI_SNDCTL_DSP_GETSPDIF:
7756 case VKI_SNDCTL_DSP_GETCAPS:
7757 case VKI_SOUND_PCM_READ_RATE:
7758 case VKI_SOUND_PCM_READ_CHANNELS:
7759 case VKI_SOUND_PCM_READ_BITS:
7760 case VKI_SOUND_PCM_READ_FILTER:
7761 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7762 ARG3, sizeof(int));
7763 break;
7764 case VKI_SNDCTL_SEQ_CTRLRATE:
7765 case VKI_SNDCTL_DSP_SPEED:
7766 case VKI_SNDCTL_DSP_STEREO:
7767 case VKI_SNDCTL_DSP_CHANNELS:
7768 case VKI_SOUND_PCM_WRITE_FILTER:
7769 case VKI_SNDCTL_DSP_SUBDIVIDE:
7770 case VKI_SNDCTL_DSP_SETFRAGMENT:
7771 case VKI_SNDCTL_DSP_SETFMT:
7772 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7773 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7774 case VKI_SNDCTL_TMR_TIMEBASE:
7775 case VKI_SNDCTL_TMR_TEMPO:
7776 case VKI_SNDCTL_TMR_SOURCE:
7777 case VKI_SNDCTL_MIDI_PRETIME:
7778 case VKI_SNDCTL_MIDI_MPUMODE:
7779 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7780 ARG3, sizeof(int));
7781 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7782 ARG3, sizeof(int));
7783 break;
7784 case VKI_SNDCTL_DSP_GETOSPACE:
7785 case VKI_SNDCTL_DSP_GETISPACE:
7786 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7787 ARG3, sizeof(vki_audio_buf_info));
7788 break;
7789 case VKI_SNDCTL_DSP_NONBLOCK:
7790 break;
7791 case VKI_SNDCTL_DSP_SETTRIGGER:
7792 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7793 ARG3, sizeof(int));
7794 break;
7796 case VKI_SNDCTL_DSP_POST:
7797 case VKI_SNDCTL_DSP_RESET:
7798 case VKI_SNDCTL_DSP_SYNC:
7799 case VKI_SNDCTL_DSP_SETSYNCRO:
7800 case VKI_SNDCTL_DSP_SETDUPLEX:
7801 break;
7803 /* linux/soundcard interface (ALSA) */
7804 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7805 case VKI_SNDRV_PCM_IOCTL_LINK:
7806 /* these just take an int by value */
7807 break;
7808 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7809 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7810 break;
7811 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7812 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7813 break;
7814 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7815 struct vki_snd_ctl_elem_list *data =
7816 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7817 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7818 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7819 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7820 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7821 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7822 if (data->pids) {
7823 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7825 break;
7827 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7828 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7829 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7830 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7831 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7832 break;
7834 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7835 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7836 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7837 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7838 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7839 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7840 break;
7843 /* Real Time Clock (/dev/rtc) ioctls */
7844 case VKI_RTC_UIE_ON:
7845 case VKI_RTC_UIE_OFF:
7846 case VKI_RTC_AIE_ON:
7847 case VKI_RTC_AIE_OFF:
7848 case VKI_RTC_PIE_ON:
7849 case VKI_RTC_PIE_OFF:
7850 case VKI_RTC_IRQP_SET:
7851 break;
7852 case VKI_RTC_RD_TIME:
7853 case VKI_RTC_ALM_READ:
7854 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7855 ARG3, sizeof(struct vki_rtc_time));
7856 break;
7857 case VKI_RTC_ALM_SET:
7858 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7859 break;
7860 case VKI_RTC_IRQP_READ:
7861 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7862 break;
7864 /* Loopback control */
7865 case VKI_LOOP_CTL_ADD:
7866 case VKI_LOOP_CTL_REMOVE:
7867 case VKI_LOOP_CTL_GET_FREE:
7868 break;
7869 /* Loopback device */
7870 case VKI_LOOP_SET_FD:
7871 case VKI_LOOP_CLR_FD:
7872 case VKI_LOOP_CHANGE_FD:
7873 case VKI_LOOP_SET_CAPACITY:
7874 case VKI_LOOP_SET_DIRECT_IO:
7875 case VKI_LOOP_SET_BLOCK_SIZE:
7876 break;
7877 case VKI_LOOP_SET_STATUS:
7878 PRE_MEM_READ("ioctl(LOOP_SET_STATUS)", ARG3, sizeof(struct vki_loop_info));
7879 break;
7880 case VKI_LOOP_GET_STATUS:
7881 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS)", ARG3, sizeof(struct vki_loop_info));
7882 break;
7883 case VKI_LOOP_SET_STATUS64:
7884 PRE_MEM_READ("ioctl(LOOP_SET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
7885 break;
7886 case VKI_LOOP_GET_STATUS64:
7887 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
7888 break;
7890 /* Block devices */
7891 case VKI_BLKROSET:
7892 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7893 break;
7894 case VKI_BLKROGET:
7895 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7896 break;
7897 case VKI_BLKGETSIZE:
7898 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7899 break;
7900 case VKI_BLKFLSBUF:
7901 break;
7902 case VKI_BLKRASET:
7903 break;
7904 case VKI_BLKRAGET:
7905 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7906 break;
7907 case VKI_BLKFRASET:
7908 break;
7909 case VKI_BLKFRAGET:
7910 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7911 break;
7912 case VKI_BLKSECTGET:
7913 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7914 break;
7915 case VKI_BLKSSZGET:
7916 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7917 break;
7918 case VKI_BLKBSZGET:
7919 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7920 break;
7921 case VKI_BLKBSZSET:
7922 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7923 break;
7924 case VKI_BLKGETSIZE64:
7925 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7926 break;
7927 case VKI_BLKPBSZGET:
7928 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7929 break;
7930 case VKI_BLKIOMIN:
7931 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7932 break;
7933 case VKI_BLKIOOPT:
7934 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7935 break;
7936 case VKI_BLKALIGNOFF:
7937 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7938 break;
7939 case VKI_BLKDISCARDZEROES:
7940 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7941 break;
7942 case VKI_BLKREPORTZONE:
7943 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7944 sizeof(struct vki_blk_zone_report));
7945 break;
7946 case VKI_BLKRESETZONE:
7947 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7948 sizeof(struct vki_blk_zone_range));
7949 break;
7951 /* Hard disks */
7952 case VKI_HDIO_GETGEO: /* 0x0301 */
7953 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7954 break;
7955 case VKI_HDIO_GET_DMA: /* 0x030b */
7956 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7957 break;
7958 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7959 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7960 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7961 break;
7963 /* SCSI */
7964 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7965 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7966 break;
7967 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7968 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7969 break;
7971 /* CD ROM stuff (??) */
7972 case VKI_CDROM_GET_MCN:
7973 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7974 sizeof(struct vki_cdrom_mcn) );
7975 break;
7976 case VKI_CDROM_SEND_PACKET:
7977 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7978 sizeof(struct vki_cdrom_generic_command));
7979 break;
7980 case VKI_CDROMSUBCHNL:
7981 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7982 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7983 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7984 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7985 sizeof(struct vki_cdrom_subchnl));
7986 break;
7987 case VKI_CDROMREADMODE1: /*0x530d*/
7988 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7989 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7990 break;
7991 case VKI_CDROMREADMODE2: /*0x530c*/
7992 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7993 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7994 break;
7995 case VKI_CDROMREADTOCHDR:
7996 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7997 sizeof(struct vki_cdrom_tochdr));
7998 break;
7999 case VKI_CDROMREADTOCENTRY:
8000 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
8001 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
8002 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
8003 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
8004 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
8005 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
8006 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
8007 sizeof(struct vki_cdrom_tocentry));
8008 break;
8009 case VKI_CDROMMULTISESSION: /* 0x5310 */
8010 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
8011 sizeof(struct vki_cdrom_multisession));
8012 break;
8013 case VKI_CDROMVOLREAD: /* 0x5313 */
8014 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
8015 sizeof(struct vki_cdrom_volctrl));
8016 break;
8017 case VKI_CDROMREADRAW: /* 0x5314 */
8018 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
8019 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
8020 break;
8021 case VKI_CDROMREADAUDIO: /* 0x530e */
8022 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
8023 sizeof (struct vki_cdrom_read_audio));
8024 if ( ARG3 ) {
8025 /* ToDo: don't do any of the following if the structure is invalid */
8026 struct vki_cdrom_read_audio *cra =
8027 (struct vki_cdrom_read_audio *) (Addr)ARG3;
8028 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
8029 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
8031 break;
8032 case VKI_CDROMPLAYMSF:
8033 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
8034 break;
8035 /* The following two are probably bogus (should check args
8036 for readability). JRS 20021117 */
8037 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
8038 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
8039 break;
8040 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
8041 break;
8043 case VKI_FIGETBSZ:
8044 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
8045 break;
8046 case VKI_FIBMAP:
8047 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
8048 break;
8049 case VKI_FICLONE:
8050 /* The direction of FICLONE (W) is incorrectly specified
8051 * as it expects a file descriptor and not a pointer to
8052 * user data */
8053 break;
8055 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
8056 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
8057 sizeof(struct vki_fb_var_screeninfo));
8058 break;
8059 case VKI_FBIOPUT_VSCREENINFO:
8060 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
8061 sizeof(struct vki_fb_var_screeninfo));
8062 break;
8063 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
8064 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
8065 sizeof(struct vki_fb_fix_screeninfo));
8066 break;
8067 case VKI_FBIOPAN_DISPLAY:
8068 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
8069 sizeof(struct vki_fb_var_screeninfo));
8071 break;
8072 case VKI_PPCLAIM:
8073 case VKI_PPEXCL:
8074 case VKI_PPYIELD:
8075 case VKI_PPRELEASE:
8076 break;
8077 case VKI_PPSETMODE:
8078 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
8079 break;
8080 case VKI_PPGETMODE:
8081 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
8082 break;
8083 case VKI_PPSETPHASE:
8084 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
8085 break;
8086 case VKI_PPGETPHASE:
8087 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
8088 break;
8089 case VKI_PPGETMODES:
8090 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8091 break;
8092 case VKI_PPSETFLAGS:
8093 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8094 break;
8095 case VKI_PPGETFLAGS:
8096 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8097 break;
8098 case VKI_PPRSTATUS:
8099 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8100 break;
8101 case VKI_PPRDATA:
8102 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8103 break;
8104 case VKI_PPRCONTROL:
8105 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8106 break;
8107 case VKI_PPWDATA:
8108 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8109 break;
8110 case VKI_PPWCONTROL:
8111 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8112 break;
8113 case VKI_PPFCONTROL:
8114 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8115 break;
8116 case VKI_PPDATADIR:
8117 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8118 break;
8119 case VKI_PPNEGOT:
8120 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8121 break;
8122 case VKI_PPWCTLONIRQ:
8123 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8124 break;
8125 case VKI_PPCLRIRQ:
8126 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8127 break;
8128 case VKI_PPSETTIME:
8129 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8130 break;
8131 case VKI_PPGETTIME:
8132 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8133 break;
8135 case VKI_GIO_FONT:
8136 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8137 break;
8138 case VKI_PIO_FONT:
8139 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8140 break;
8142 case VKI_GIO_FONTX:
8143 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8144 if ( ARG3 ) {
8145 /* ToDo: don't do any of the following if the structure is invalid */
8146 struct vki_consolefontdesc *cfd =
8147 (struct vki_consolefontdesc *)(Addr)ARG3;
8148 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8149 32 * cfd->charcount );
8151 break;
8152 case VKI_PIO_FONTX:
8153 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8154 if ( ARG3 ) {
8155 /* ToDo: don't do any of the following if the structure is invalid */
8156 struct vki_consolefontdesc *cfd =
8157 (struct vki_consolefontdesc *)(Addr)ARG3;
8158 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8159 32 * cfd->charcount );
8161 break;
8163 case VKI_PIO_FONTRESET:
8164 break;
8166 case VKI_GIO_CMAP:
8167 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8168 break;
8169 case VKI_PIO_CMAP:
8170 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8171 break;
8173 case VKI_KIOCSOUND:
8174 case VKI_KDMKTONE:
8175 break;
8177 case VKI_KDGETLED:
8178 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8179 break;
8180 case VKI_KDSETLED:
8181 break;
8183 case VKI_KDGKBTYPE:
8184 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8185 break;
8187 case VKI_KDADDIO:
8188 case VKI_KDDELIO:
8189 case VKI_KDENABIO:
8190 case VKI_KDDISABIO:
8191 break;
8193 case VKI_KDSETMODE:
8194 break;
8195 case VKI_KDGETMODE:
8196 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8197 break;
8199 case VKI_KDMAPDISP:
8200 case VKI_KDUNMAPDISP:
8201 break;
8203 case VKI_GIO_SCRNMAP:
8204 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8205 break;
8206 case VKI_PIO_SCRNMAP:
8207 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8208 break;
8209 case VKI_GIO_UNISCRNMAP:
8210 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8211 VKI_E_TABSZ * sizeof(unsigned short) );
8212 break;
8213 case VKI_PIO_UNISCRNMAP:
8214 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8215 VKI_E_TABSZ * sizeof(unsigned short) );
8216 break;
8218 case VKI_GIO_UNIMAP:
8219 if ( ARG3 ) {
8220 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8221 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8222 sizeof(unsigned short));
8223 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8224 sizeof(struct vki_unipair *));
8225 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8226 desc->entry_ct * sizeof(struct vki_unipair));
8228 break;
8229 case VKI_PIO_UNIMAP:
8230 if ( ARG3 ) {
8231 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8232 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8233 sizeof(unsigned short) );
8234 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8235 sizeof(struct vki_unipair *) );
8236 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8237 desc->entry_ct * sizeof(struct vki_unipair) );
8239 break;
8240 case VKI_PIO_UNIMAPCLR:
8241 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8242 break;
8244 case VKI_KDGKBMODE:
8245 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8246 break;
8247 case VKI_KDSKBMODE:
8248 break;
8250 case VKI_KDGKBMETA:
8251 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8252 break;
8253 case VKI_KDSKBMETA:
8254 break;
8256 case VKI_KDGKBLED:
8257 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8258 break;
8259 case VKI_KDSKBLED:
8260 break;
8262 case VKI_KDGKBENT:
8263 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8264 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8265 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8266 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8267 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8268 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8269 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8270 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8271 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8272 break;
8273 case VKI_KDSKBENT:
8274 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8275 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8276 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8277 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8278 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8279 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8280 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8281 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8282 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8283 break;
8285 case VKI_KDGKBSENT:
8286 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8287 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8288 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8289 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8290 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8291 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8292 break;
8293 case VKI_KDSKBSENT:
8294 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8295 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8296 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8297 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8298 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8299 break;
8301 case VKI_KDGKBDIACR:
8302 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8303 break;
8304 case VKI_KDSKBDIACR:
8305 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8306 break;
8308 case VKI_KDGETKEYCODE:
8309 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8310 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8311 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8312 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8313 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8314 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8315 break;
8316 case VKI_KDSETKEYCODE:
8317 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8318 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8319 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8320 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8321 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8322 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8323 break;
8325 case VKI_KDSIGACCEPT:
8326 break;
8328 case VKI_KDKBDREP:
8329 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8330 break;
8332 case VKI_KDFONTOP:
8333 if ( ARG3 ) {
8334 struct vki_console_font_op *op =
8335 (struct vki_console_font_op *) (Addr)ARG3;
8336 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8337 sizeof(struct vki_console_font_op) );
8338 switch ( op->op ) {
8339 case VKI_KD_FONT_OP_SET:
8340 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8341 (Addr)op->data,
8342 (op->width + 7) / 8 * 32 * op->charcount );
8343 break;
8344 case VKI_KD_FONT_OP_GET:
8345 if ( op->data )
8346 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8347 (Addr)op->data,
8348 (op->width + 7) / 8 * 32 * op->charcount );
8349 break;
8350 case VKI_KD_FONT_OP_SET_DEFAULT:
8351 if ( op->data )
8352 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8353 (Addr)op->data );
8354 break;
8355 case VKI_KD_FONT_OP_COPY:
8356 break;
8359 break;
8361 case VKI_VT_OPENQRY:
8362 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8363 break;
8364 case VKI_VT_GETMODE:
8365 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8366 break;
8367 case VKI_VT_SETMODE:
8368 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8369 break;
8370 case VKI_VT_GETSTATE:
8371 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8372 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8373 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8374 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8375 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8376 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8377 break;
8378 case VKI_VT_RELDISP:
8379 case VKI_VT_ACTIVATE:
8380 case VKI_VT_WAITACTIVE:
8381 case VKI_VT_DISALLOCATE:
8382 break;
8383 case VKI_VT_RESIZE:
8384 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8385 break;
8386 case VKI_VT_RESIZEX:
8387 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8388 break;
8389 case VKI_VT_LOCKSWITCH:
8390 case VKI_VT_UNLOCKSWITCH:
8391 break;
8393 case VKI_USBDEVFS_CONTROL:
8394 if ( ARG3 ) {
8395 struct vki_usbdevfs_ctrltransfer *vkuc =
8396 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8397 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8398 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8399 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8400 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8401 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8402 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8403 if (vkuc->bRequestType & 0x80)
8404 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8405 else
8406 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8408 break;
8409 case VKI_USBDEVFS_BULK:
8410 if ( ARG3 ) {
8411 struct vki_usbdevfs_bulktransfer *vkub =
8412 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8413 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8414 if (vkub->ep & 0x80)
8415 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8416 else
8417 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8419 break;
8420 case VKI_USBDEVFS_GETDRIVER:
8421 if ( ARG3 ) {
8422 struct vki_usbdevfs_getdriver *vkugd =
8423 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8424 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8426 break;
8427 case VKI_USBDEVFS_SUBMITURB:
8428 if ( ARG3 ) {
8429 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8431 /* Not the whole struct needs to be initialized */
8432 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8433 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8434 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8435 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8436 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8437 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8438 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8439 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8440 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8441 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8442 if (vkusp->bRequestType & 0x80)
8443 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8444 else
8445 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8446 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8447 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8448 int total_length = 0;
8449 int i;
8450 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8451 for(i=0; i<vkuu->number_of_packets; i++) {
8452 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8453 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));
8454 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8455 total_length += vkuu->iso_frame_desc[i].length;
8457 if (vkuu->endpoint & 0x80)
8458 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8459 else
8460 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8461 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8462 } else {
8463 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8464 if (vkuu->endpoint & 0x80)
8465 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8466 else
8467 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8468 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8471 break;
8472 case VKI_USBDEVFS_DISCARDURB:
8473 break;
8474 case VKI_USBDEVFS_REAPURB:
8475 if ( ARG3 ) {
8476 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8478 break;
8479 case VKI_USBDEVFS_REAPURBNDELAY:
8480 if ( ARG3 ) {
8481 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8483 break;
8484 case VKI_USBDEVFS_CONNECTINFO:
8485 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8486 break;
8487 case VKI_USBDEVFS_IOCTL:
8488 if ( ARG3 ) {
8489 struct vki_usbdevfs_ioctl *vkui =
8490 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8491 UInt dir2, size2;
8492 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8493 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8494 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8495 if (size2 > 0) {
8496 if (dir2 & _VKI_IOC_WRITE)
8497 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8498 else if (dir2 & _VKI_IOC_READ)
8499 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8502 break;
8503 case VKI_USBDEVFS_RESET:
8504 break;
8506 /* I2C (/dev/i2c-*) ioctls */
8507 case VKI_I2C_SLAVE:
8508 case VKI_I2C_SLAVE_FORCE:
8509 case VKI_I2C_TENBIT:
8510 case VKI_I2C_PEC:
8511 break;
8512 case VKI_I2C_FUNCS:
8513 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8514 break;
8515 case VKI_I2C_RDWR:
8516 if ( ARG3 ) {
8517 struct vki_i2c_rdwr_ioctl_data *vkui =
8518 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8519 UInt i;
8520 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8521 for (i=0; i < vkui->nmsgs; i++) {
8522 struct vki_i2c_msg *msg = vkui->msgs + i;
8523 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8524 if (msg->flags & VKI_I2C_M_RD)
8525 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8526 else
8527 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8530 break;
8531 case VKI_I2C_SMBUS:
8532 if ( ARG3 ) {
8533 struct vki_i2c_smbus_ioctl_data *vkis
8534 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8535 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8536 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8537 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8538 (Addr)&vkis->size, sizeof(vkis->size));
8539 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8540 (Addr)&vkis->command, sizeof(vkis->command));
8541 /* i2c_smbus_write_quick hides its value in read_write, so
8542 this variable can have a different meaning */
8543 /* to make matters worse i2c_smbus_write_byte stores its
8544 value in command */
8545 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8546 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8547 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8548 /* the rest uses the byte array to store the data,
8549 some the first byte for size */
8550 UInt size;
8551 switch(vkis->size) {
8552 case VKI_I2C_SMBUS_BYTE_DATA:
8553 size = 1;
8554 break;
8555 case VKI_I2C_SMBUS_WORD_DATA:
8556 case VKI_I2C_SMBUS_PROC_CALL:
8557 size = 2;
8558 break;
8559 case VKI_I2C_SMBUS_BLOCK_DATA:
8560 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8561 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8562 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8563 size = 1 + vkis->data->block[0];
8564 break;
8565 default:
8566 size = 0;
8569 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8570 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8571 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8572 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8573 ".i2c_smbus_ioctl_data.data",
8574 (Addr)&vkis->data->block[0], size);
8575 else
8576 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8577 "i2c_smbus_ioctl_data.data",
8578 (Addr)&vkis->data->block[0], size);
8581 break;
8583 /* Wireless extensions ioctls */
8584 case VKI_SIOCSIWCOMMIT:
8585 case VKI_SIOCSIWNWID:
8586 case VKI_SIOCSIWFREQ:
8587 case VKI_SIOCSIWMODE:
8588 case VKI_SIOCSIWSENS:
8589 case VKI_SIOCSIWRANGE:
8590 case VKI_SIOCSIWPRIV:
8591 case VKI_SIOCSIWSTATS:
8592 case VKI_SIOCSIWSPY:
8593 case VKI_SIOCSIWTHRSPY:
8594 case VKI_SIOCSIWAP:
8595 case VKI_SIOCSIWSCAN:
8596 case VKI_SIOCSIWESSID:
8597 case VKI_SIOCSIWRATE:
8598 case VKI_SIOCSIWNICKN:
8599 case VKI_SIOCSIWRTS:
8600 case VKI_SIOCSIWFRAG:
8601 case VKI_SIOCSIWTXPOW:
8602 case VKI_SIOCSIWRETRY:
8603 case VKI_SIOCSIWENCODE:
8604 case VKI_SIOCSIWPOWER:
8605 case VKI_SIOCSIWGENIE:
8606 case VKI_SIOCSIWMLME:
8607 case VKI_SIOCSIWAUTH:
8608 case VKI_SIOCSIWENCODEEXT:
8609 case VKI_SIOCSIWPMKSA:
8610 break;
8611 case VKI_SIOCGIWNAME:
8612 if (ARG3) {
8613 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8614 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8615 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8617 break;
8618 case VKI_SIOCGIWNWID:
8619 case VKI_SIOCGIWSENS:
8620 case VKI_SIOCGIWRATE:
8621 case VKI_SIOCGIWRTS:
8622 case VKI_SIOCGIWFRAG:
8623 case VKI_SIOCGIWTXPOW:
8624 case VKI_SIOCGIWRETRY:
8625 case VKI_SIOCGIWPOWER:
8626 case VKI_SIOCGIWAUTH:
8627 if (ARG3) {
8628 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8629 "RETRY|PARAM|AUTH])",
8630 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8631 sizeof(struct vki_iw_param));
8633 break;
8634 case VKI_SIOCGIWFREQ:
8635 if (ARG3) {
8636 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8637 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8638 sizeof(struct vki_iw_freq));
8640 break;
8641 case VKI_SIOCGIWMODE:
8642 if (ARG3) {
8643 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8644 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8645 sizeof(__vki_u32));
8647 break;
8648 case VKI_SIOCGIWRANGE:
8649 case VKI_SIOCGIWPRIV:
8650 case VKI_SIOCGIWSTATS:
8651 case VKI_SIOCGIWSPY:
8652 case VKI_SIOCGIWTHRSPY:
8653 case VKI_SIOCGIWAPLIST:
8654 case VKI_SIOCGIWSCAN:
8655 case VKI_SIOCGIWESSID:
8656 case VKI_SIOCGIWNICKN:
8657 case VKI_SIOCGIWENCODE:
8658 case VKI_SIOCGIWGENIE:
8659 case VKI_SIOCGIWENCODEEXT:
8660 if (ARG3) {
8661 struct vki_iw_point* point;
8662 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8663 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8664 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8665 (Addr)point->pointer, point->length);
8667 break;
8668 case VKI_SIOCGIWAP:
8669 if (ARG3) {
8670 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8671 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8672 sizeof(struct vki_sockaddr));
8674 break;
8676 /* User input device creation */
8677 case VKI_UI_SET_EVBIT:
8678 case VKI_UI_SET_KEYBIT:
8679 case VKI_UI_SET_RELBIT:
8680 case VKI_UI_SET_ABSBIT:
8681 case VKI_UI_SET_MSCBIT:
8682 case VKI_UI_SET_LEDBIT:
8683 case VKI_UI_SET_SNDBIT:
8684 case VKI_UI_SET_FFBIT:
8685 case VKI_UI_SET_SWBIT:
8686 case VKI_UI_SET_PROPBIT:
8687 /* These just take an int by value */
8688 break;
8690 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8691 || defined(VGPV_mips32_linux_android) \
8692 || defined(VGPV_arm64_linux_android)
8693 /* ashmem */
8694 case VKI_ASHMEM_GET_SIZE:
8695 case VKI_ASHMEM_SET_SIZE:
8696 case VKI_ASHMEM_GET_PROT_MASK:
8697 case VKI_ASHMEM_SET_PROT_MASK:
8698 case VKI_ASHMEM_GET_PIN_STATUS:
8699 case VKI_ASHMEM_PURGE_ALL_CACHES:
8700 break;
8701 case VKI_ASHMEM_GET_NAME:
8702 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8703 break;
8704 case VKI_ASHMEM_SET_NAME:
8705 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8706 break;
8707 case VKI_ASHMEM_PIN:
8708 case VKI_ASHMEM_UNPIN:
8709 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8710 ARG3, sizeof(struct vki_ashmem_pin) );
8711 break;
8713 /* binder */
8714 case VKI_BINDER_WRITE_READ:
8715 if (ARG3) {
8716 struct vki_binder_write_read* bwr
8717 = (struct vki_binder_write_read*)(Addr)ARG3;
8719 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8720 bwr->write_buffer);
8721 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8722 bwr->write_size);
8723 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8724 bwr->write_consumed);
8725 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8726 bwr->read_buffer);
8727 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8728 bwr->read_size);
8729 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8730 bwr->read_consumed);
8732 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8733 bwr->write_consumed);
8734 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8735 bwr->read_consumed);
8737 if (bwr->read_size)
8738 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8739 (Addr)bwr->read_buffer, bwr->read_size);
8740 if (bwr->write_size)
8741 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8742 (Addr)bwr->write_buffer, bwr->write_size);
8744 break;
8746 case VKI_BINDER_SET_IDLE_TIMEOUT:
8747 case VKI_BINDER_SET_MAX_THREADS:
8748 case VKI_BINDER_SET_IDLE_PRIORITY:
8749 case VKI_BINDER_SET_CONTEXT_MGR:
8750 case VKI_BINDER_THREAD_EXIT:
8751 break;
8752 case VKI_BINDER_VERSION:
8753 if (ARG3) {
8754 struct vki_binder_version* bv =
8755 (struct vki_binder_version*)(Addr)ARG3;
8756 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8758 break;
8759 # endif /* defined(VGPV_*_linux_android) */
8761 case VKI_HCIGETDEVLIST:
8762 if (ARG3) {
8763 struct vki_hci_dev_list_req* dlr =
8764 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8765 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8766 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8767 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8768 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8769 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8771 break;
8773 case VKI_HCIINQUIRY:
8774 if (ARG3) {
8775 struct vki_hci_inquiry_req* ir =
8776 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8777 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8778 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8779 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8780 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8781 ir->num_rsp * sizeof(struct vki_inquiry_info));
8783 break;
8785 case VKI_DRM_IOCTL_VERSION:
8786 if (ARG3) {
8787 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8788 struct vg_drm_version_info* info;
8789 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8790 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8791 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8792 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8793 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8794 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8795 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8796 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8797 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8798 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8799 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8800 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8801 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8802 // To ensure we VG_(free) info even when syscall fails:
8803 *flags |= SfPostOnFail;
8804 info->data = *data;
8805 info->orig = data;
8806 ARG3 = (Addr)&info->data;
8808 break;
8809 case VKI_DRM_IOCTL_GET_UNIQUE:
8810 if (ARG3) {
8811 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8812 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8813 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8814 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8816 break;
8817 case VKI_DRM_IOCTL_GET_MAGIC:
8818 if (ARG3) {
8819 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8820 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8822 break;
8823 case VKI_DRM_IOCTL_WAIT_VBLANK:
8824 if (ARG3) {
8825 union vki_drm_wait_vblank *data =
8826 (union vki_drm_wait_vblank *)(Addr)ARG3;
8827 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8828 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8829 /* XXX: It seems request.signal isn't used */
8830 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8832 break;
8833 case VKI_DRM_IOCTL_GEM_CLOSE:
8834 if (ARG3) {
8835 struct vki_drm_gem_close *data =
8836 (struct vki_drm_gem_close *)(Addr)ARG3;
8837 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8839 break;
8840 case VKI_DRM_IOCTL_GEM_FLINK:
8841 if (ARG3) {
8842 struct vki_drm_gem_flink *data =
8843 (struct vki_drm_gem_flink *)(Addr)ARG3;
8844 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8845 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8847 break;
8848 case VKI_DRM_IOCTL_GEM_OPEN:
8849 if (ARG3) {
8850 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8851 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8852 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8853 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8855 break;
8856 case VKI_DRM_IOCTL_I915_GETPARAM:
8857 if (ARG3) {
8858 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8859 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8860 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8862 break;
8863 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8864 if (ARG3) {
8865 struct vki_drm_i915_gem_busy *data =
8866 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8867 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8868 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8870 break;
8871 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8872 if (ARG3) {
8873 struct vki_drm_i915_gem_create *data =
8874 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8875 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8876 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8878 break;
8879 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8880 if (ARG3) {
8881 struct vki_drm_i915_gem_pread *data =
8882 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8883 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8884 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8885 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8886 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8887 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8889 break;
8890 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8891 if (ARG3) {
8892 struct vki_drm_i915_gem_pwrite *data =
8893 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8894 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8895 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8896 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8897 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8898 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8899 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8900 * interleaved vertex attributes may have a wide stride with uninitialized data between
8901 * consecutive vertices) */
8903 break;
8904 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8905 if (ARG3) {
8906 struct vki_drm_i915_gem_mmap_v1 *data =
8907 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8908 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8909 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8910 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8911 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8913 break;
8914 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8915 if (ARG3) {
8916 struct vki_drm_i915_gem_mmap *data =
8917 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8918 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8919 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8920 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8921 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8922 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8924 break;
8925 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8926 if (ARG3) {
8927 struct vki_drm_i915_gem_mmap_gtt *data =
8928 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8929 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8930 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8932 break;
8933 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8934 if (ARG3) {
8935 struct vki_drm_i915_gem_set_domain *data =
8936 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8937 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8938 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8939 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8941 break;
8942 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8943 if (ARG3) {
8944 struct vki_drm_i915_gem_set_tiling *data =
8945 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8946 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8947 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8948 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8949 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8951 break;
8952 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8953 if (ARG3) {
8954 struct vki_drm_i915_gem_get_tiling *data =
8955 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8956 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8957 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8958 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8960 break;
8961 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8962 if (ARG3) {
8963 struct vki_drm_i915_gem_get_aperture *data =
8964 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8965 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8966 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8968 break;
8970 /* KVM ioctls that check for a numeric value as parameter */
8971 case VKI_KVM_GET_API_VERSION:
8972 case VKI_KVM_CREATE_VM:
8973 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8974 case VKI_KVM_CHECK_EXTENSION:
8975 case VKI_KVM_SET_TSS_ADDR:
8976 case VKI_KVM_CREATE_VCPU:
8977 case VKI_KVM_RUN:
8978 break;
8980 case VKI_KVM_S390_MEM_OP: {
8981 struct vki_kvm_s390_mem_op *args =
8982 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8983 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8984 sizeof(struct vki_kvm_s390_mem_op));
8985 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8986 break;
8987 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8988 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8989 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8990 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8992 break;
8995 #ifdef ENABLE_XEN
8996 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8997 SyscallArgs harrghs;
8998 struct vki_xen_privcmd_hypercall *args =
8999 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
9001 if (!args)
9002 break;
9004 VG_(memset)(&harrghs, 0, sizeof(harrghs));
9005 harrghs.sysno = args->op;
9006 harrghs.arg1 = args->arg[0];
9007 harrghs.arg2 = args->arg[1];
9008 harrghs.arg3 = args->arg[2];
9009 harrghs.arg4 = args->arg[3];
9010 harrghs.arg5 = args->arg[4];
9011 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
9013 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
9015 /* HACK. arg8 is used to return the number of hypercall
9016 * arguments actually consumed! */
9017 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
9018 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
9020 break;
9023 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
9024 struct vki_xen_privcmd_mmap *args =
9025 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
9026 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
9027 (Addr)&args->num, sizeof(args->num));
9028 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
9029 (Addr)&args->dom, sizeof(args->dom));
9030 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
9031 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
9032 break;
9034 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
9035 struct vki_xen_privcmd_mmapbatch *args =
9036 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
9037 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
9038 (Addr)&args->num, sizeof(args->num));
9039 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
9040 (Addr)&args->dom, sizeof(args->dom));
9041 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
9042 (Addr)&args->addr, sizeof(args->addr));
9043 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
9044 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9045 break;
9047 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
9048 struct vki_xen_privcmd_mmapbatch_v2 *args =
9049 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
9050 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
9051 (Addr)&args->num, sizeof(args->num));
9052 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
9053 (Addr)&args->dom, sizeof(args->dom));
9054 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
9055 (Addr)&args->addr, sizeof(args->addr));
9056 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
9057 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9058 break;
9061 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
9062 struct vki_xen_ioctl_evtchn_bind_virq *args =
9063 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
9064 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
9065 (Addr)&args->virq, sizeof(args->virq));
9067 break;
9068 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
9069 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
9070 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
9071 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
9072 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9073 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
9074 (Addr)&args->remote_port, sizeof(args->remote_port));
9076 break;
9077 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
9078 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
9079 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
9080 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
9081 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9083 break;
9084 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
9085 struct vki_xen_ioctl_evtchn_unbind *args =
9086 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
9087 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
9088 (Addr)&args->port, sizeof(args->port));
9090 break;
9091 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9092 struct vki_xen_ioctl_evtchn_notify *args =
9093 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9094 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9095 (Addr)&args->port, sizeof(args->port));
9097 break;
9098 case VKI_XEN_IOCTL_EVTCHN_RESET:
9099 /* No input*/
9100 break;
9101 #endif
9103 /* Lustre */
9104 case VKI_OBD_IOC_FID2PATH: {
9105 struct vki_getinfo_fid2path *gf =
9106 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9107 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9108 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9109 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9110 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9111 break;
9114 case VKI_LL_IOC_PATH2FID:
9115 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9116 break;
9118 case VKI_LL_IOC_GETPARENT: {
9119 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9120 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9121 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9122 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9123 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9124 break;
9127 /* V4L2 */
9128 case VKI_V4L2_QUERYCAP: {
9129 struct vki_v4l2_capability *data =
9130 (struct vki_v4l2_capability *)(Addr)ARG3;
9131 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9132 break;
9134 case VKI_V4L2_ENUM_FMT: {
9135 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9136 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9137 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9138 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9139 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9140 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9141 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9142 break;
9144 case VKI_V4L2_G_FMT: {
9145 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9146 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9147 switch (data->type) {
9148 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9149 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9150 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9151 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9152 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9153 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9154 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9155 break;
9156 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9157 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9158 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9159 break;
9160 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9161 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9162 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9163 break;
9164 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9165 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9166 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9167 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9168 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9169 if (data->fmt.win.clipcount && data->fmt.win.clips)
9170 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9171 (Addr)data->fmt.win.clips,
9172 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9173 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9174 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9175 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9176 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9177 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9178 break;
9179 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9180 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9181 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9182 break;
9183 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9184 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9185 break;
9187 break;
9189 case VKI_V4L2_S_FMT: {
9190 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9191 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9192 switch (data->type) {
9193 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9194 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9195 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9196 (Addr)&data->type + sizeof(data->type),
9197 sizeof(*data) - sizeof(data->type));
9198 break;
9199 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9200 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9201 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9202 break;
9203 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9204 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9205 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9206 break;
9207 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9208 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9209 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9210 if (data->fmt.win.clipcount && data->fmt.win.clips)
9211 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9212 (Addr)data->fmt.win.clips,
9213 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9214 if (data->fmt.win.bitmap)
9215 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9216 (Addr)data->fmt.win.bitmap,
9217 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9218 break;
9219 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9220 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9221 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9222 break;
9223 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9224 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9225 break;
9227 break;
9229 case VKI_V4L2_TRY_FMT: {
9230 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9231 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9232 switch (data->type) {
9233 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9234 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9235 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9236 (Addr)&data->type + sizeof(data->type),
9237 sizeof(*data) - sizeof(data->type));
9238 break;
9239 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9240 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9241 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9242 break;
9243 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9244 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9245 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9246 break;
9247 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9248 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9249 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9250 if (data->fmt.win.clipcount && data->fmt.win.clips)
9251 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9252 (Addr)data->fmt.win.clips,
9253 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9254 if (data->fmt.win.bitmap)
9255 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9256 (Addr)data->fmt.win.bitmap,
9257 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9258 break;
9259 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9260 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9261 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9262 break;
9263 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9264 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9265 break;
9267 break;
9269 case VKI_V4L2_REQBUFS: {
9270 struct vki_v4l2_requestbuffers *data =
9271 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9272 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9273 break;
9275 case VKI_V4L2_QUERYBUF: {
9276 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9277 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9278 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9279 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9280 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9281 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9282 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9283 unsigned i;
9285 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9286 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9287 for (i = 0; i < data->length; i++) {
9288 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9289 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9290 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9291 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9292 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9294 } else {
9295 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9296 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9298 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9299 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9300 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9301 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9302 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9303 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9304 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9305 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9306 break;
9308 case VKI_V4L2_G_FBUF: {
9309 struct vki_v4l2_framebuffer *data =
9310 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9311 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9312 break;
9314 case VKI_V4L2_S_FBUF: {
9315 struct vki_v4l2_framebuffer *data =
9316 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9317 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9318 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9319 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9320 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9321 break;
9323 case VKI_V4L2_OVERLAY: {
9324 int *data = (int *)(Addr)ARG3;
9325 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9326 break;
9328 case VKI_V4L2_QBUF: {
9329 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9330 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9331 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9332 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9333 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9335 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9336 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9337 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9338 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9339 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9340 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9341 if (is_output) {
9342 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9343 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9345 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9346 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9347 unsigned i;
9349 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9350 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9351 for (i = 0; i < data->length; i++) {
9352 if (is_output) {
9353 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9354 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9356 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9357 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9358 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9359 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9360 else
9361 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9362 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9364 } else {
9365 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9366 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9367 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9368 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9369 else
9370 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9371 if (is_output) {
9372 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9373 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9376 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9377 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9378 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9380 break;
9382 case VKI_V4L2_EXPBUF: {
9383 struct vki_v4l2_exportbuffer *data =
9384 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9385 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9386 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9387 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9388 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9389 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9390 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9391 break;
9393 case VKI_V4L2_DQBUF: {
9394 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9395 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9396 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9397 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9398 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9399 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9400 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9401 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9402 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9403 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9404 unsigned i;
9406 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9407 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9408 for (i = 0; i < data->length; i++) {
9409 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9410 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9411 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9412 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9413 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9415 } else {
9416 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9417 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9418 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9419 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9421 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9422 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9423 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9424 break;
9426 case VKI_V4L2_STREAMON: {
9427 int *data = (int *)(Addr)ARG3;
9428 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9429 break;
9431 case VKI_V4L2_STREAMOFF: {
9432 int *data = (int *)(Addr)ARG3;
9433 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9434 break;
9436 case VKI_V4L2_G_PARM: {
9437 struct vki_v4l2_streamparm *data =
9438 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9439 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9440 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9441 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9442 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9444 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9445 if (is_output) {
9446 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9447 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9448 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9449 } else {
9450 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9451 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9452 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9454 break;
9456 case VKI_V4L2_S_PARM: {
9457 struct vki_v4l2_streamparm *data =
9458 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9459 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9460 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9461 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9462 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9464 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9465 if (is_output)
9466 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9467 else
9468 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9469 break;
9471 case VKI_V4L2_G_STD: {
9472 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9473 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9474 break;
9476 case VKI_V4L2_S_STD: {
9477 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9478 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9479 break;
9481 case VKI_V4L2_ENUMSTD: {
9482 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9483 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9484 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9485 break;
9487 case VKI_V4L2_ENUMINPUT: {
9488 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9489 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9490 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9491 break;
9493 case VKI_V4L2_G_CTRL: {
9494 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9495 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9496 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9497 break;
9499 case VKI_V4L2_S_CTRL: {
9500 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9501 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9502 break;
9504 case VKI_V4L2_G_TUNER: {
9505 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9506 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9507 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9508 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9509 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9510 break;
9512 case VKI_V4L2_S_TUNER: {
9513 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9514 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9515 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9516 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9517 break;
9519 case VKI_V4L2_G_AUDIO: {
9520 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9521 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9522 sizeof(*data) - sizeof(data->reserved));
9523 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9524 break;
9526 case VKI_V4L2_S_AUDIO: {
9527 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9528 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9529 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9530 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9531 break;
9533 case VKI_V4L2_QUERYCTRL: {
9534 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9535 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9536 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9537 sizeof(*data) - sizeof(data->id));
9538 break;
9540 case VKI_V4L2_QUERYMENU: {
9541 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9542 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9543 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9544 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9545 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9546 break;
9548 case VKI_V4L2_G_INPUT: {
9549 int *data = (int *)(Addr)ARG3;
9550 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9551 break;
9553 case VKI_V4L2_S_INPUT: {
9554 int *data = (int *)(Addr)ARG3;
9555 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9556 break;
9558 case VKI_V4L2_G_EDID: {
9559 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9560 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9561 if (data->blocks && data->edid)
9562 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9563 break;
9565 case VKI_V4L2_S_EDID: {
9566 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9567 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9568 if (data->blocks && data->edid)
9569 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9570 break;
9572 case VKI_V4L2_G_OUTPUT: {
9573 int *data = (int *)(Addr)ARG3;
9574 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9575 break;
9577 case VKI_V4L2_S_OUTPUT: {
9578 int *data = (int *)(Addr)ARG3;
9579 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9580 break;
9582 case VKI_V4L2_ENUMOUTPUT: {
9583 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9584 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9585 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9586 break;
9588 case VKI_V4L2_G_AUDOUT: {
9589 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9590 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9591 sizeof(*data) - sizeof(data->reserved));
9592 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9593 break;
9595 case VKI_V4L2_S_AUDOUT: {
9596 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9597 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9598 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9599 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9600 break;
9602 case VKI_V4L2_G_MODULATOR: {
9603 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9604 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9605 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9606 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9607 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9608 break;
9610 case VKI_V4L2_S_MODULATOR: {
9611 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9612 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9613 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9614 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9615 break;
9617 case VKI_V4L2_G_FREQUENCY: {
9618 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9619 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9620 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9621 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9622 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9623 break;
9625 case VKI_V4L2_S_FREQUENCY: {
9626 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9627 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9628 break;
9630 case VKI_V4L2_CROPCAP: {
9631 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9632 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9633 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9634 break;
9636 case VKI_V4L2_G_CROP: {
9637 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9638 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9639 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9640 break;
9642 case VKI_V4L2_S_CROP: {
9643 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9644 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9645 break;
9647 case VKI_V4L2_G_JPEGCOMP: {
9648 struct vki_v4l2_jpegcompression *data =
9649 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9650 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9651 break;
9653 case VKI_V4L2_S_JPEGCOMP: {
9654 struct vki_v4l2_jpegcompression *data =
9655 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9656 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9657 break;
9659 case VKI_V4L2_QUERYSTD: {
9660 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9661 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9662 break;
9664 case VKI_V4L2_ENUMAUDIO: {
9665 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9666 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9667 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9668 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9669 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9670 break;
9672 case VKI_V4L2_ENUMAUDOUT: {
9673 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9674 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9675 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9676 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9677 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9678 break;
9680 case VKI_V4L2_G_PRIORITY: {
9681 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9682 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9683 break;
9685 case VKI_V4L2_S_PRIORITY: {
9686 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9687 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9688 break;
9690 case VKI_V4L2_G_SLICED_VBI_CAP: {
9691 struct vki_v4l2_sliced_vbi_cap *data =
9692 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9693 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9694 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9695 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9696 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9697 break;
9699 case VKI_V4L2_G_EXT_CTRLS: {
9700 struct vki_v4l2_ext_controls *data =
9701 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9702 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9703 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9704 if (data->count) {
9705 unsigned i;
9707 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9708 for (i = 0; i < data->count; i++) {
9709 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9710 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9711 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9712 if (data->controls[i].size) {
9713 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9714 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9715 (Addr)data->controls[i].ptr, data->controls[i].size);
9716 } else {
9717 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9718 data->controls[i].value64);
9722 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9723 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9724 break;
9726 case VKI_V4L2_S_EXT_CTRLS: {
9727 struct vki_v4l2_ext_controls *data =
9728 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9729 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9730 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9731 if (data->count) {
9732 unsigned i;
9734 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9735 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9736 data->count * sizeof(data->controls[0]));
9737 for (i = 0; i < data->count; i++) {
9738 if (data->controls[i].size) {
9739 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9740 (Addr)data->controls[i].ptr, data->controls[i].size);
9744 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9745 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9746 break;
9748 case VKI_V4L2_TRY_EXT_CTRLS: {
9749 struct vki_v4l2_ext_controls *data =
9750 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9751 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9752 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9753 if (data->count) {
9754 unsigned i;
9756 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9757 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9758 data->count * sizeof(data->controls[0]));
9759 for (i = 0; i < data->count; i++) {
9760 if (data->controls[i].size) {
9761 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9762 (Addr)data->controls[i].ptr, data->controls[i].size);
9766 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9767 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9768 break;
9770 case VKI_V4L2_ENUM_FRAMESIZES: {
9771 struct vki_v4l2_frmsizeenum *data =
9772 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9773 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9774 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9775 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9776 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9777 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9778 break;
9780 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9781 struct vki_v4l2_frmivalenum *data =
9782 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9783 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9784 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9785 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9786 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9787 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9788 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9789 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9790 break;
9792 case VKI_V4L2_G_ENC_INDEX: {
9793 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9794 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9795 break;
9797 case VKI_V4L2_ENCODER_CMD: {
9798 struct vki_v4l2_encoder_cmd *data =
9799 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9800 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9801 break;
9803 case VKI_V4L2_TRY_ENCODER_CMD: {
9804 struct vki_v4l2_encoder_cmd *data =
9805 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9806 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9807 break;
9809 case VKI_V4L2_DBG_S_REGISTER: {
9810 struct vki_v4l2_dbg_register *data =
9811 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9812 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9813 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9814 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9815 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9816 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9817 break;
9819 case VKI_V4L2_DBG_G_REGISTER: {
9820 struct vki_v4l2_dbg_register *data =
9821 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9822 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9823 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9824 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9825 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9826 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9827 break;
9829 case VKI_V4L2_S_HW_FREQ_SEEK: {
9830 struct vki_v4l2_hw_freq_seek *data =
9831 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9832 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9833 break;
9835 case VKI_V4L2_S_DV_TIMINGS: {
9836 struct vki_v4l2_dv_timings *data =
9837 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9838 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9839 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9840 break;
9842 case VKI_V4L2_G_DV_TIMINGS: {
9843 struct vki_v4l2_dv_timings *data =
9844 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9845 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9846 break;
9848 case VKI_V4L2_DQEVENT: {
9849 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9850 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9851 break;
9853 case VKI_V4L2_SUBSCRIBE_EVENT: {
9854 struct vki_v4l2_event_subscription *data =
9855 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9856 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9857 break;
9859 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9860 struct vki_v4l2_event_subscription *data =
9861 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9862 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9863 break;
9865 case VKI_V4L2_CREATE_BUFS: {
9866 struct vki_v4l2_create_buffers *data =
9867 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9868 struct vki_v4l2_format *fmt = &data->format;
9869 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9870 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9871 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9872 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9873 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9874 switch (fmt->type) {
9875 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9876 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9877 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9878 break;
9879 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9880 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9881 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9882 break;
9883 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9884 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9885 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9886 break;
9887 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9888 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9889 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9890 break;
9891 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9892 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9893 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9894 break;
9895 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9896 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9897 break;
9899 break;
9901 case VKI_V4L2_PREPARE_BUF: {
9902 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9903 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9904 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9905 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9906 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9907 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9908 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9909 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9910 unsigned i;
9912 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9913 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9914 for (i = 0; i < data->length; i++) {
9915 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9918 break;
9920 case VKI_V4L2_G_SELECTION: {
9921 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9922 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9923 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9924 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9925 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9926 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9927 break;
9929 case VKI_V4L2_S_SELECTION: {
9930 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9931 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9932 break;
9934 case VKI_V4L2_DECODER_CMD: {
9935 struct vki_v4l2_decoder_cmd *data =
9936 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9937 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9938 break;
9940 case VKI_V4L2_TRY_DECODER_CMD: {
9941 struct vki_v4l2_decoder_cmd *data =
9942 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9943 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9944 break;
9946 case VKI_V4L2_ENUM_DV_TIMINGS: {
9947 struct vki_v4l2_enum_dv_timings *data =
9948 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9949 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9950 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9951 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9952 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9953 break;
9955 case VKI_V4L2_QUERY_DV_TIMINGS: {
9956 struct vki_v4l2_dv_timings *data =
9957 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9958 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9959 break;
9961 case VKI_V4L2_DV_TIMINGS_CAP: {
9962 struct vki_v4l2_dv_timings_cap *data =
9963 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9964 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9965 break;
9967 case VKI_V4L2_ENUM_FREQ_BANDS: {
9968 struct vki_v4l2_frequency_band *data =
9969 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9970 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9971 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9972 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9973 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9974 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9975 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9976 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9977 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9978 break;
9980 case VKI_V4L2_DBG_G_CHIP_INFO: {
9981 struct vki_v4l2_dbg_chip_info *data =
9982 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9983 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9984 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9985 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9986 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9987 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9988 break;
9990 case VKI_V4L2_QUERY_EXT_CTRL: {
9991 struct vki_v4l2_query_ext_ctrl *data =
9992 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9993 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9994 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9995 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9996 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9997 break;
9999 case VKI_V4L2_SUBDEV_G_FMT: {
10000 struct vki_v4l2_subdev_format *data =
10001 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10002 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
10003 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
10004 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
10005 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
10006 break;
10008 case VKI_V4L2_SUBDEV_S_FMT: {
10009 struct vki_v4l2_subdev_format *data =
10010 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10011 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
10012 break;
10014 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10015 struct vki_v4l2_subdev_frame_interval *data =
10016 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10017 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
10018 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
10019 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
10020 break;
10022 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
10023 struct vki_v4l2_subdev_frame_interval *data =
10024 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10025 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
10026 break;
10028 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10029 struct vki_v4l2_subdev_mbus_code_enum *data =
10030 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
10031 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
10032 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
10033 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
10034 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
10035 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
10036 break;
10038 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10039 struct vki_v4l2_subdev_frame_size_enum *data =
10040 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
10041 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
10042 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
10043 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
10044 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
10045 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
10046 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
10047 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
10048 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
10049 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
10050 break;
10052 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10053 struct vki_v4l2_subdev_frame_interval_enum *data =
10054 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
10055 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
10056 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
10057 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
10058 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
10059 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
10060 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
10061 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
10062 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
10063 break;
10065 case VKI_V4L2_SUBDEV_G_CROP: {
10066 struct vki_v4l2_subdev_crop *data =
10067 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10068 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
10069 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
10070 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
10071 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
10072 break;
10074 case VKI_V4L2_SUBDEV_S_CROP: {
10075 struct vki_v4l2_subdev_crop *data =
10076 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10077 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
10078 break;
10080 case VKI_V4L2_SUBDEV_G_SELECTION: {
10081 struct vki_v4l2_subdev_selection *data =
10082 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10083 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
10084 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
10085 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
10086 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
10087 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
10088 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
10089 break;
10091 case VKI_V4L2_SUBDEV_S_SELECTION: {
10092 struct vki_v4l2_subdev_selection *data =
10093 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10094 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10095 break;
10097 case VKI_MEDIA_IOC_DEVICE_INFO: {
10098 struct vki_media_device_info *data =
10099 (struct vki_media_device_info *)(Addr)ARG3;
10100 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10101 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10102 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10103 break;
10105 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10106 struct vki_media_entity_desc *data =
10107 (struct vki_media_entity_desc *)(Addr)ARG3;
10108 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10109 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10110 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10111 break;
10113 case VKI_MEDIA_IOC_ENUM_LINKS: {
10114 struct vki_media_links_enum *data =
10115 (struct vki_media_links_enum *)(Addr)ARG3;
10116 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10117 break;
10119 case VKI_MEDIA_IOC_SETUP_LINK: {
10120 struct vki_media_link_desc *data =
10121 (struct vki_media_link_desc *)(Addr)ARG3;
10122 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10123 break;
10126 /* Serial */
10127 case VKI_TIOCGSERIAL: {
10128 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10129 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10130 break;
10132 case VKI_TIOCSSERIAL: {
10133 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10134 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10135 break;
10138 case VKI_PERF_EVENT_IOC_RESET:
10139 case VKI_PERF_EVENT_IOC_REFRESH:
10140 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10141 case VKI_PERF_EVENT_IOC_SET_BPF:
10142 /* These take scalar arguments, so already handled above */
10143 break;
10145 case VKI_PERF_EVENT_IOC_PERIOD:
10146 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10147 break;
10149 case VKI_PERF_EVENT_IOC_SET_FILTER:
10150 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10151 break;
10153 case VKI_PERF_EVENT_IOC_ID:
10154 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10155 break;
10157 /* Pulse Per Second (PPS) */
10158 case VKI_PPS_GETPARAMS: {
10159 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10160 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10161 break;
10163 case VKI_PPS_SETPARAMS: {
10164 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10165 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10166 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10167 data->assert_off_tu.sec);
10168 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10169 data->assert_off_tu.nsec);
10170 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10171 data->clear_off_tu.sec);
10172 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10173 data->clear_off_tu.nsec);
10174 break;
10176 case VKI_PPS_GETCAP:
10177 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10178 break;
10179 case VKI_PPS_FETCH: {
10180 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10181 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10182 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10183 break;
10185 case VKI_PPS_KC_BIND: {
10186 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10187 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10188 break;
10191 /* PTP Hardware Clock */
10192 case VKI_PTP_CLOCK_GETCAPS: {
10193 struct vki_ptp_clock_caps *data =
10194 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10195 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10196 break;
10198 case VKI_PTP_EXTTS_REQUEST: {
10199 struct vki_ptp_extts_request *data =
10200 (struct vki_ptp_extts_request *)(Addr)ARG3;
10201 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10202 break;
10204 case VKI_PTP_PEROUT_REQUEST: {
10205 struct vki_ptp_perout_request *data =
10206 (struct vki_ptp_perout_request *)(Addr)ARG3;
10207 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10208 break;
10210 case VKI_PTP_ENABLE_PPS:
10211 break;
10212 case VKI_PTP_SYS_OFFSET: {
10213 struct vki_ptp_sys_offset *data =
10214 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10215 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10216 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10217 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10218 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10219 break;
10221 case VKI_PTP_PIN_GETFUNC: {
10222 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10223 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10224 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10225 break;
10227 case VKI_PTP_PIN_SETFUNC: {
10228 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10229 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10230 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10231 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10232 break;
10234 case VKI_PTP_SYS_OFFSET_PRECISE: {
10235 struct vki_ptp_sys_offset_precise *data =
10236 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10237 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10238 break;
10240 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10241 struct vki_ptp_sys_offset_extended *data =
10242 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10243 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10244 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10245 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10246 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10247 3 * data->n_samples * sizeof(data->ts[0][0]));
10248 break;
10251 default:
10252 /* EVIOC* are variable length and return size written on success */
10253 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10254 case VKI_EVIOCGNAME(0):
10255 case VKI_EVIOCGPHYS(0):
10256 case VKI_EVIOCGUNIQ(0):
10257 case VKI_EVIOCGKEY(0):
10258 case VKI_EVIOCGLED(0):
10259 case VKI_EVIOCGSND(0):
10260 case VKI_EVIOCGSW(0):
10261 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10262 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10263 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10264 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10265 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10266 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10267 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10268 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10269 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10270 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10271 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10272 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10273 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10274 break;
10275 default:
10276 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10277 break;
10279 break;
10283 POST(sys_ioctl)
10285 ARG2 = (UInt)ARG2;
10287 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10289 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10291 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10292 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10293 VG_(clo_kernel_variant))) {
10295 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10296 /* What's going on here: there appear to be a bunch of ioctls
10297 of the form 0xC01C67xx which are undocumented, and if
10298 unhandled give rise to a vast number of false positives in
10299 Memcheck.
10301 The "normal" interpretation of an ioctl of this form would
10302 be that the 3rd arg is a pointer to an area of size 0x1C
10303 (28 bytes) which is filled in by the kernel. Hence you
10304 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10305 But it doesn't.
10307 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10308 One interpretation of this is that ARG3 really does point
10309 to a 28 byte struct, but inside that are pointers to other
10310 areas also filled in by the kernel. If these happen to be
10311 allocated just back up the stack then the 256 byte paint
10312 might cover them too, somewhat indiscriminately.
10314 By printing out ARG3 and also the 28 bytes that it points
10315 at, it's possible to guess that the 7 word structure has
10316 this form
10318 0 1 2 3 4 5 6
10319 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10321 Unfortunately that doesn't seem to work for some reason,
10322 so stay with the blunt-instrument approach for the time
10323 being.
10325 if (1) {
10326 /* blunt-instrument approach */
10327 POST_MEM_WRITE(ARG3, 256);
10328 } else {
10329 /* be a bit more sophisticated */
10330 POST_MEM_WRITE(ARG3, 28);
10331 UInt* word = (UInt*)(Addr)ARG3;
10332 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10333 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10334 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10335 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10337 goto post_sys_ioctl__out;
10340 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10342 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10343 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10344 VG_(clo_kernel_variant))) {
10345 if (ARG2 == 0xC00C0902) {
10346 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10347 goto post_sys_ioctl__out;
10350 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10352 /* --- END special IOCTL handlers for specific Android hardware --- */
10354 /* --- normal handling --- */
10355 switch (ARG2 /* request */) {
10357 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10358 this is pretty poor given that there's no pre-handling to check
10359 that writable areas are addressable. */
10360 case VKI_ION_IOC_ALLOC: {
10361 struct vki_ion_allocation_data* data
10362 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10363 POST_FIELD_WRITE(data->handle);
10364 break;
10366 case VKI_ION_IOC_MAP: {
10367 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10368 POST_FIELD_WRITE(data->fd);
10369 break;
10371 case VKI_ION_IOC_FREE: // is this necessary?
10372 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10373 break;
10374 case VKI_ION_IOC_SHARE:
10375 break;
10376 case VKI_ION_IOC_IMPORT: {
10377 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10378 POST_FIELD_WRITE(data->handle);
10379 break;
10381 case VKI_ION_IOC_SYNC:
10382 break;
10383 case VKI_ION_IOC_CUSTOM: // is this necessary?
10384 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10385 break;
10387 case VKI_SYNC_IOC_MERGE: {
10388 struct vki_sync_merge_data* data =
10389 (struct vki_sync_merge_data*)(Addr)ARG3;
10390 POST_FIELD_WRITE(data->fence);
10391 break;
10394 case VKI_TCSETS:
10395 case VKI_TCSETSW:
10396 case VKI_TCSETSF:
10397 case VKI_IB_USER_MAD_ENABLE_PKEY:
10398 break;
10399 case VKI_TCGETS:
10400 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10401 break;
10402 case VKI_TCSETA:
10403 case VKI_TCSETAW:
10404 case VKI_TCSETAF:
10405 break;
10406 case VKI_TCGETA:
10407 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10408 break;
10409 case VKI_TCSBRK:
10410 case VKI_TCXONC:
10411 case VKI_TCSBRKP:
10412 case VKI_TCFLSH:
10413 case VKI_TIOCSIG:
10414 break;
10415 case VKI_TIOCGWINSZ:
10416 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10417 break;
10418 case VKI_TIOCSWINSZ:
10419 case VKI_TIOCMBIS:
10420 case VKI_TIOCMBIC:
10421 case VKI_TIOCMSET:
10422 break;
10423 case VKI_TIOCMGET:
10424 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10425 break;
10426 case VKI_TIOCLINUX:
10427 POST_MEM_WRITE( ARG3, sizeof(char *) );
10428 break;
10429 case VKI_TIOCGPGRP:
10430 /* Get process group ID for foreground processing group. */
10431 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10432 break;
10433 case VKI_TIOCSPGRP:
10434 /* Set a process group ID? */
10435 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10436 break;
10437 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10438 POST_MEM_WRITE( ARG3, sizeof(int));
10439 break;
10440 case VKI_TIOCSCTTY:
10441 break;
10442 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10443 break;
10444 case VKI_FIONBIO:
10445 break;
10446 case VKI_FIONCLEX:
10447 break;
10448 case VKI_FIOCLEX:
10449 break;
10450 case VKI_TIOCNOTTY:
10451 break;
10452 case VKI_FIOASYNC:
10453 break;
10454 case VKI_FIONREAD: /* identical to SIOCINQ */
10455 POST_MEM_WRITE( ARG3, sizeof(int) );
10456 break;
10457 case VKI_FIOQSIZE:
10458 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10459 break;
10461 case VKI_TIOCSERGETLSR:
10462 POST_MEM_WRITE( ARG3, sizeof(int) );
10463 break;
10464 case VKI_TIOCGICOUNT:
10465 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10466 break;
10468 case VKI_SG_SET_COMMAND_Q:
10469 break;
10470 case VKI_SG_IO:
10472 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10473 if ( sgio->sbp ) {
10474 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10476 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10477 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10478 int transferred = sgio->dxfer_len - sgio->resid;
10479 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10482 break;
10483 case VKI_SG_GET_SCSI_ID:
10484 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10485 break;
10486 case VKI_SG_SET_RESERVED_SIZE:
10487 break;
10488 case VKI_SG_SET_TIMEOUT:
10489 break;
10490 case VKI_SG_GET_RESERVED_SIZE:
10491 POST_MEM_WRITE(ARG3, sizeof(int));
10492 break;
10493 case VKI_SG_GET_TIMEOUT:
10494 break;
10495 case VKI_SG_GET_VERSION_NUM:
10496 POST_MEM_WRITE(ARG3, sizeof(int));
10497 break;
10498 case VKI_SG_EMULATED_HOST:
10499 POST_MEM_WRITE(ARG3, sizeof(int));
10500 break;
10501 case VKI_SG_GET_SG_TABLESIZE:
10502 POST_MEM_WRITE(ARG3, sizeof(int));
10503 break;
10505 case VKI_IIOCGETCPS:
10506 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10507 break;
10508 case VKI_IIOCNETGPN:
10509 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10510 break;
10512 /* These all use struct ifreq AFAIK */
10513 case VKI_SIOCGIFINDEX: /* get iface index */
10514 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10515 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10516 break;
10517 case VKI_SIOCGIFFLAGS: /* get flags */
10518 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10519 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10520 break;
10521 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10522 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10523 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10524 break;
10525 case VKI_SIOCGIFMTU: /* get MTU size */
10526 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10527 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10528 break;
10529 case VKI_SIOCGIFADDR: /* get PA address */
10530 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10531 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10532 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10533 POST_MEM_WRITE(
10534 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10535 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10536 break;
10537 case VKI_SIOCGIFMETRIC: /* get metric */
10538 POST_MEM_WRITE(
10539 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10540 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10541 break;
10542 case VKI_SIOCGIFMAP: /* Get device parameters */
10543 POST_MEM_WRITE(
10544 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10545 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10546 break;
10547 break;
10548 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10549 POST_MEM_WRITE(
10550 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10551 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10552 break;
10553 case VKI_SIOCGIFNAME: /* get iface name */
10554 POST_MEM_WRITE(
10555 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10556 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10557 break;
10558 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10559 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10560 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10561 case VKI_ETHTOOL_GSET:
10562 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10563 break;
10564 case VKI_ETHTOOL_SSET:
10565 break;
10566 case VKI_ETHTOOL_GDRVINFO:
10567 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10568 break;
10569 case VKI_ETHTOOL_GREGS:
10570 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10571 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10572 break;
10573 case VKI_ETHTOOL_GWOL:
10574 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10575 break;
10576 case VKI_ETHTOOL_SWOL:
10577 break;
10578 case VKI_ETHTOOL_GMSGLVL:
10579 case VKI_ETHTOOL_GLINK:
10580 case VKI_ETHTOOL_GRXCSUM:
10581 case VKI_ETHTOOL_GSG:
10582 case VKI_ETHTOOL_GTSO:
10583 case VKI_ETHTOOL_GUFO:
10584 case VKI_ETHTOOL_GGSO:
10585 case VKI_ETHTOOL_GFLAGS:
10586 case VKI_ETHTOOL_GGRO:
10587 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10588 break;
10589 case VKI_ETHTOOL_SMSGLVL:
10590 case VKI_ETHTOOL_SRXCSUM:
10591 case VKI_ETHTOOL_SSG:
10592 case VKI_ETHTOOL_STSO:
10593 case VKI_ETHTOOL_SUFO:
10594 case VKI_ETHTOOL_SGSO:
10595 case VKI_ETHTOOL_SFLAGS:
10596 case VKI_ETHTOOL_SGRO:
10597 break;
10598 case VKI_ETHTOOL_NWAY_RST:
10599 break;
10600 case VKI_ETHTOOL_GRINGPARAM:
10601 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10602 break;
10603 case VKI_ETHTOOL_SRINGPARAM:
10604 break;
10605 case VKI_ETHTOOL_TEST:
10606 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10607 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10608 break;
10609 case VKI_ETHTOOL_PHYS_ID:
10610 break;
10611 case VKI_ETHTOOL_GPERMADDR:
10612 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10613 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10614 break;
10615 case VKI_ETHTOOL_RESET:
10616 break;
10617 case VKI_ETHTOOL_GSSET_INFO:
10618 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10619 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10620 break;
10621 case VKI_ETHTOOL_GFEATURES:
10622 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10623 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10624 break;
10625 case VKI_ETHTOOL_SFEATURES:
10626 break;
10627 case VKI_ETHTOOL_GCHANNELS:
10628 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10629 break;
10630 case VKI_ETHTOOL_SCHANNELS:
10631 break;
10632 case VKI_ETHTOOL_GET_TS_INFO:
10633 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10634 break;
10636 break;
10638 case VKI_SIOCGMIIPHY: /* get hardware entry */
10639 POST_MEM_WRITE(
10640 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10641 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10642 break;
10643 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10644 POST_MEM_WRITE(
10645 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10646 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10647 break;
10649 /* tun/tap related ioctls */
10650 case VKI_TUNSETIFF:
10651 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10652 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10653 break;
10654 case VKI_TUNGETFEATURES:
10655 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10656 break;
10657 case VKI_TUNGETIFF:
10658 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10659 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10660 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10661 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10662 break;
10663 case VKI_TUNGETSNDBUF:
10664 POST_MEM_WRITE( ARG3, sizeof(int) );
10665 break;
10666 case VKI_TUNGETVNETHDRSZ:
10667 POST_MEM_WRITE( ARG3, sizeof(int) );
10668 break;
10670 case VKI_SIOCGIFCONF: /* get iface list */
10671 /* WAS:
10672 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10673 KERNEL_DO_SYSCALL(tid,RES);
10674 if (!VG_(is_kerror)(RES) && RES == 0)
10675 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10677 if (RES == 0 && ARG3 ) {
10678 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10679 if (ifc->vki_ifc_buf != NULL)
10680 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10682 break;
10683 case VKI_SIOCGSTAMP:
10684 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10685 break;
10686 case VKI_SIOCGSTAMPNS:
10687 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10688 break;
10689 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10690 the number of bytes currently in that socket's send buffer.
10691 It writes this value as an int to the memory location
10692 indicated by the third argument of ioctl(2). */
10693 case VKI_SIOCOUTQ:
10694 POST_MEM_WRITE(ARG3, sizeof(int));
10695 break;
10696 case VKI_SIOCGRARP: /* get RARP table entry */
10697 case VKI_SIOCGARP: /* get ARP table entry */
10698 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10699 break;
10701 case VKI_SIOCSIFFLAGS: /* set flags */
10702 case VKI_SIOCSIFMAP: /* Set device parameters */
10703 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10704 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10705 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10706 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10707 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10708 case VKI_SIOCSIFMETRIC: /* set metric */
10709 case VKI_SIOCSIFADDR: /* set PA address */
10710 case VKI_SIOCSIFMTU: /* set MTU size */
10711 case VKI_SIOCSIFHWADDR: /* set hardware address */
10712 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10713 break;
10714 /* Routing table calls. */
10715 case VKI_SIOCADDRT: /* add routing table entry */
10716 case VKI_SIOCDELRT: /* delete routing table entry */
10717 break;
10719 /* RARP cache control calls. */
10720 case VKI_SIOCDRARP: /* delete RARP table entry */
10721 case VKI_SIOCSRARP: /* set RARP table entry */
10722 /* ARP cache control calls. */
10723 case VKI_SIOCSARP: /* set ARP table entry */
10724 case VKI_SIOCDARP: /* delete ARP table entry */
10725 break;
10727 case VKI_SIOCGPGRP:
10728 POST_MEM_WRITE(ARG3, sizeof(int));
10729 break;
10730 case VKI_SIOCSPGRP:
10731 break;
10733 case VKI_SIOCATMARK:
10734 POST_MEM_WRITE(ARG3, sizeof(int));
10735 break;
10737 /* linux/soundcard interface (OSS) */
10738 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10739 case VKI_SNDCTL_SEQ_GETINCOUNT:
10740 case VKI_SNDCTL_SEQ_PERCMODE:
10741 case VKI_SNDCTL_SEQ_TESTMIDI:
10742 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10743 case VKI_SNDCTL_SEQ_NRSYNTHS:
10744 case VKI_SNDCTL_SEQ_NRMIDIS:
10745 case VKI_SNDCTL_SEQ_GETTIME:
10746 case VKI_SNDCTL_DSP_GETBLKSIZE:
10747 case VKI_SNDCTL_DSP_GETFMTS:
10748 case VKI_SNDCTL_DSP_SETFMT:
10749 case VKI_SNDCTL_DSP_GETTRIGGER:
10750 case VKI_SNDCTL_DSP_GETODELAY:
10751 case VKI_SNDCTL_DSP_GETSPDIF:
10752 case VKI_SNDCTL_DSP_GETCAPS:
10753 case VKI_SOUND_PCM_READ_RATE:
10754 case VKI_SOUND_PCM_READ_CHANNELS:
10755 case VKI_SOUND_PCM_READ_BITS:
10756 case VKI_SOUND_PCM_READ_FILTER:
10757 POST_MEM_WRITE(ARG3, sizeof(int));
10758 break;
10759 case VKI_SNDCTL_SEQ_CTRLRATE:
10760 case VKI_SNDCTL_DSP_SPEED:
10761 case VKI_SNDCTL_DSP_STEREO:
10762 case VKI_SNDCTL_DSP_CHANNELS:
10763 case VKI_SOUND_PCM_WRITE_FILTER:
10764 case VKI_SNDCTL_DSP_SUBDIVIDE:
10765 case VKI_SNDCTL_DSP_SETFRAGMENT:
10766 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10767 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10768 case VKI_SNDCTL_TMR_TIMEBASE:
10769 case VKI_SNDCTL_TMR_TEMPO:
10770 case VKI_SNDCTL_TMR_SOURCE:
10771 case VKI_SNDCTL_MIDI_PRETIME:
10772 case VKI_SNDCTL_MIDI_MPUMODE:
10773 break;
10774 case VKI_SNDCTL_DSP_GETOSPACE:
10775 case VKI_SNDCTL_DSP_GETISPACE:
10776 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10777 break;
10778 case VKI_SNDCTL_DSP_NONBLOCK:
10779 break;
10780 case VKI_SNDCTL_DSP_SETTRIGGER:
10781 break;
10783 case VKI_SNDCTL_DSP_POST:
10784 case VKI_SNDCTL_DSP_RESET:
10785 case VKI_SNDCTL_DSP_SYNC:
10786 case VKI_SNDCTL_DSP_SETSYNCRO:
10787 case VKI_SNDCTL_DSP_SETDUPLEX:
10788 break;
10790 /* linux/soundcard interface (ALSA) */
10791 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10792 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10793 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10794 case VKI_SNDRV_PCM_IOCTL_RESET:
10795 case VKI_SNDRV_PCM_IOCTL_START:
10796 case VKI_SNDRV_PCM_IOCTL_DROP:
10797 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10798 case VKI_SNDRV_PCM_IOCTL_RESUME:
10799 case VKI_SNDRV_PCM_IOCTL_XRUN:
10800 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10801 case VKI_SNDRV_TIMER_IOCTL_START:
10802 case VKI_SNDRV_TIMER_IOCTL_STOP:
10803 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10804 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10805 break;
10807 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10808 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10809 break;
10811 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10812 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10813 break;
10814 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10815 struct vki_snd_ctl_elem_list *data =
10816 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10817 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10818 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10819 if (data->pids) {
10820 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10822 break;
10824 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10825 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10826 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10827 break;
10829 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10830 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10831 break;
10833 /* SCSI no operand */
10834 case VKI_SCSI_IOCTL_DOORLOCK:
10835 case VKI_SCSI_IOCTL_DOORUNLOCK:
10836 break;
10838 /* Real Time Clock (/dev/rtc) ioctls */
10839 case VKI_RTC_UIE_ON:
10840 case VKI_RTC_UIE_OFF:
10841 case VKI_RTC_AIE_ON:
10842 case VKI_RTC_AIE_OFF:
10843 case VKI_RTC_PIE_ON:
10844 case VKI_RTC_PIE_OFF:
10845 case VKI_RTC_IRQP_SET:
10846 break;
10847 case VKI_RTC_RD_TIME:
10848 case VKI_RTC_ALM_READ:
10849 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10850 break;
10851 case VKI_RTC_ALM_SET:
10852 break;
10853 case VKI_RTC_IRQP_READ:
10854 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10855 break;
10857 /* Loopback devices */
10858 case VKI_LOOP_CTL_ADD:
10859 case VKI_LOOP_CTL_REMOVE:
10860 case VKI_LOOP_CTL_GET_FREE:
10861 break;
10862 /* Loopback device */
10863 case VKI_LOOP_SET_FD:
10864 case VKI_LOOP_CLR_FD:
10865 case VKI_LOOP_CHANGE_FD:
10866 case VKI_LOOP_SET_CAPACITY:
10867 case VKI_LOOP_SET_DIRECT_IO:
10868 case VKI_LOOP_SET_BLOCK_SIZE:
10869 break;
10870 case VKI_LOOP_SET_STATUS:
10871 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
10872 break;
10873 case VKI_LOOP_GET_STATUS:
10874 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
10875 break;
10876 case VKI_LOOP_SET_STATUS64:
10877 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
10878 break;
10879 case VKI_LOOP_GET_STATUS64:
10880 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
10881 break;
10884 /* Block devices */
10885 case VKI_BLKROSET:
10886 break;
10887 case VKI_BLKROGET:
10888 POST_MEM_WRITE(ARG3, sizeof(int));
10889 break;
10890 case VKI_BLKGETSIZE:
10891 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10892 break;
10893 case VKI_BLKFLSBUF:
10894 break;
10895 case VKI_BLKRASET:
10896 break;
10897 case VKI_BLKRAGET:
10898 POST_MEM_WRITE(ARG3, sizeof(long));
10899 break;
10900 case VKI_BLKFRASET:
10901 break;
10902 case VKI_BLKFRAGET:
10903 POST_MEM_WRITE(ARG3, sizeof(long));
10904 break;
10905 case VKI_BLKSECTGET:
10906 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10907 break;
10908 case VKI_BLKSSZGET:
10909 POST_MEM_WRITE(ARG3, sizeof(int));
10910 break;
10911 case VKI_BLKBSZGET:
10912 POST_MEM_WRITE(ARG3, sizeof(int));
10913 break;
10914 case VKI_BLKBSZSET:
10915 break;
10916 case VKI_BLKGETSIZE64:
10917 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10918 break;
10919 case VKI_BLKPBSZGET:
10920 POST_MEM_WRITE(ARG3, sizeof(int));
10921 break;
10922 case VKI_BLKIOMIN:
10923 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10924 break;
10925 case VKI_BLKIOOPT:
10926 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10927 break;
10928 case VKI_BLKALIGNOFF:
10929 POST_MEM_WRITE(ARG3, sizeof(int));
10930 break;
10931 case VKI_BLKDISCARDZEROES:
10932 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10933 break;
10934 case VKI_BLKREPORTZONE: {
10935 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10937 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10938 break;
10940 case VKI_BLKRESETZONE:
10941 break;
10943 /* Hard disks */
10944 case VKI_HDIO_GETGEO: /* 0x0301 */
10945 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10946 break;
10947 case VKI_HDIO_GET_DMA: /* 0x030b */
10948 POST_MEM_WRITE(ARG3, sizeof(long));
10949 break;
10950 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10951 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10952 break;
10954 /* SCSI */
10955 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10956 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10957 break;
10958 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10959 POST_MEM_WRITE(ARG3, sizeof(int));
10960 break;
10962 /* CD ROM stuff (??) */
10963 case VKI_CDROM_DISC_STATUS:
10964 case VKI_CDROMSTOP:
10965 break;
10966 case VKI_CDROMSUBCHNL:
10967 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10968 break;
10969 case VKI_CDROMREADTOCHDR:
10970 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10971 break;
10972 case VKI_CDROMREADTOCENTRY:
10973 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10974 break;
10975 case VKI_CDROMMULTISESSION:
10976 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10977 break;
10978 case VKI_CDROMVOLREAD:
10979 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10980 break;
10981 case VKI_CDROMREADMODE1:
10982 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10983 break;
10984 case VKI_CDROMREADMODE2:
10985 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10986 break;
10987 case VKI_CDROMREADRAW:
10988 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10989 break;
10990 case VKI_CDROMREADAUDIO:
10992 struct vki_cdrom_read_audio *cra =
10993 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10994 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10995 break;
10998 case VKI_CDROMPLAYMSF:
10999 break;
11000 /* The following two are probably bogus (should check args
11001 for readability). JRS 20021117 */
11002 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
11003 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
11004 break;
11005 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
11006 break;
11008 /* DVD stuff */
11009 case VKI_DVD_READ_STRUCT:
11010 break;
11012 case VKI_FIGETBSZ:
11013 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
11014 break;
11015 case VKI_FIBMAP:
11016 POST_MEM_WRITE(ARG3, sizeof(int));
11017 break;
11018 case VKI_FICLONE:
11019 break;
11021 case VKI_FBIOGET_VSCREENINFO: //0x4600
11022 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
11023 break;
11024 case VKI_FBIOGET_FSCREENINFO: //0x4602
11025 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
11026 break;
11028 case VKI_PPCLAIM:
11029 case VKI_PPEXCL:
11030 case VKI_PPYIELD:
11031 case VKI_PPRELEASE:
11032 case VKI_PPSETMODE:
11033 case VKI_PPSETPHASE:
11034 case VKI_PPSETFLAGS:
11035 case VKI_PPWDATA:
11036 case VKI_PPWCONTROL:
11037 case VKI_PPFCONTROL:
11038 case VKI_PPDATADIR:
11039 case VKI_PPNEGOT:
11040 case VKI_PPWCTLONIRQ:
11041 case VKI_PPSETTIME:
11042 break;
11043 case VKI_PPGETMODE:
11044 POST_MEM_WRITE( ARG3, sizeof(int) );
11045 break;
11046 case VKI_PPGETPHASE:
11047 POST_MEM_WRITE( ARG3, sizeof(int) );
11048 break;
11049 case VKI_PPGETMODES:
11050 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
11051 break;
11052 case VKI_PPGETFLAGS:
11053 POST_MEM_WRITE( ARG3, sizeof(int) );
11054 break;
11055 case VKI_PPRSTATUS:
11056 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11057 break;
11058 case VKI_PPRDATA:
11059 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11060 break;
11061 case VKI_PPRCONTROL:
11062 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11063 break;
11064 case VKI_PPCLRIRQ:
11065 POST_MEM_WRITE( ARG3, sizeof(int) );
11066 break;
11067 case VKI_PPGETTIME:
11068 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
11069 break;
11071 case VKI_GIO_FONT:
11072 POST_MEM_WRITE( ARG3, 32 * 256 );
11073 break;
11074 case VKI_PIO_FONT:
11075 break;
11077 case VKI_GIO_FONTX:
11078 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
11079 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
11080 break;
11081 case VKI_PIO_FONTX:
11082 break;
11084 case VKI_PIO_FONTRESET:
11085 break;
11087 case VKI_GIO_CMAP:
11088 POST_MEM_WRITE( ARG3, 16 * 3 );
11089 break;
11090 case VKI_PIO_CMAP:
11091 break;
11093 case VKI_KIOCSOUND:
11094 case VKI_KDMKTONE:
11095 break;
11097 case VKI_KDGETLED:
11098 POST_MEM_WRITE( ARG3, sizeof(char) );
11099 break;
11100 case VKI_KDSETLED:
11101 break;
11103 case VKI_KDGKBTYPE:
11104 POST_MEM_WRITE( ARG3, sizeof(char) );
11105 break;
11107 case VKI_KDADDIO:
11108 case VKI_KDDELIO:
11109 case VKI_KDENABIO:
11110 case VKI_KDDISABIO:
11111 break;
11113 case VKI_KDSETMODE:
11114 break;
11115 case VKI_KDGETMODE:
11116 POST_MEM_WRITE( ARG3, sizeof(int) );
11117 break;
11119 case VKI_KDMAPDISP:
11120 case VKI_KDUNMAPDISP:
11121 break;
11123 case VKI_GIO_SCRNMAP:
11124 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11125 break;
11126 case VKI_PIO_SCRNMAP:
11127 break;
11128 case VKI_GIO_UNISCRNMAP:
11129 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11130 break;
11131 case VKI_PIO_UNISCRNMAP:
11132 break;
11134 case VKI_GIO_UNIMAP:
11135 if ( ARG3 ) {
11136 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11137 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11138 POST_MEM_WRITE( (Addr)desc->entries,
11139 desc->entry_ct * sizeof(struct vki_unipair) );
11141 break;
11142 case VKI_PIO_UNIMAP:
11143 break;
11144 case VKI_PIO_UNIMAPCLR:
11145 break;
11147 case VKI_KDGKBMODE:
11148 POST_MEM_WRITE( ARG3, sizeof(int) );
11149 break;
11150 case VKI_KDSKBMODE:
11151 break;
11153 case VKI_KDGKBMETA:
11154 POST_MEM_WRITE( ARG3, sizeof(int) );
11155 break;
11156 case VKI_KDSKBMETA:
11157 break;
11159 case VKI_KDGKBLED:
11160 POST_MEM_WRITE( ARG3, sizeof(char) );
11161 break;
11162 case VKI_KDSKBLED:
11163 break;
11165 case VKI_KDGKBENT:
11166 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11167 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11168 break;
11169 case VKI_KDSKBENT:
11170 break;
11172 case VKI_KDGKBSENT:
11173 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11174 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11175 break;
11176 case VKI_KDSKBSENT:
11177 break;
11179 case VKI_KDGKBDIACR:
11180 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11181 break;
11182 case VKI_KDSKBDIACR:
11183 break;
11185 case VKI_KDGETKEYCODE:
11186 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11187 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11188 break;
11189 case VKI_KDSETKEYCODE:
11190 break;
11192 case VKI_KDSIGACCEPT:
11193 break;
11195 case VKI_KDKBDREP:
11196 break;
11198 case VKI_KDFONTOP:
11199 if ( ARG3 ) {
11200 struct vki_console_font_op *op =
11201 (struct vki_console_font_op *) (Addr)ARG3;
11202 switch ( op->op ) {
11203 case VKI_KD_FONT_OP_SET:
11204 break;
11205 case VKI_KD_FONT_OP_GET:
11206 if ( op->data )
11207 POST_MEM_WRITE( (Addr) op->data,
11208 (op->width + 7) / 8 * 32 * op->charcount );
11209 break;
11210 case VKI_KD_FONT_OP_SET_DEFAULT:
11211 break;
11212 case VKI_KD_FONT_OP_COPY:
11213 break;
11215 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11217 break;
11219 case VKI_VT_OPENQRY:
11220 POST_MEM_WRITE( ARG3, sizeof(int) );
11221 break;
11222 case VKI_VT_GETMODE:
11223 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11224 break;
11225 case VKI_VT_SETMODE:
11226 break;
11227 case VKI_VT_GETSTATE:
11228 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11229 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11230 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11231 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11232 break;
11233 case VKI_VT_RELDISP:
11234 case VKI_VT_ACTIVATE:
11235 case VKI_VT_WAITACTIVE:
11236 case VKI_VT_DISALLOCATE:
11237 break;
11238 case VKI_VT_RESIZE:
11239 break;
11240 case VKI_VT_RESIZEX:
11241 break;
11242 case VKI_VT_LOCKSWITCH:
11243 case VKI_VT_UNLOCKSWITCH:
11244 break;
11246 case VKI_USBDEVFS_CONTROL:
11247 if ( ARG3 ) {
11248 struct vki_usbdevfs_ctrltransfer *vkuc =
11249 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11250 if (vkuc->bRequestType & 0x80)
11251 POST_MEM_WRITE((Addr)vkuc->data, RES);
11253 break;
11254 case VKI_USBDEVFS_BULK:
11255 if ( ARG3 ) {
11256 struct vki_usbdevfs_bulktransfer *vkub =
11257 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11258 if (vkub->ep & 0x80)
11259 POST_MEM_WRITE((Addr)vkub->data, RES);
11261 break;
11262 case VKI_USBDEVFS_GETDRIVER:
11263 if ( ARG3 ) {
11264 struct vki_usbdevfs_getdriver *vkugd =
11265 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11266 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11268 break;
11269 case VKI_USBDEVFS_REAPURB:
11270 case VKI_USBDEVFS_REAPURBNDELAY:
11271 if ( ARG3 ) {
11272 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11273 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11274 if (!*vkuu)
11275 break;
11276 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11277 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11278 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11279 if (vkusp->bRequestType & 0x80)
11280 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11281 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11282 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11283 char *bp = (*vkuu)->buffer;
11284 int i;
11285 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11286 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11287 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11288 if ((*vkuu)->endpoint & 0x80)
11289 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11290 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11292 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11293 } else {
11294 if ((*vkuu)->endpoint & 0x80)
11295 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11296 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11299 break;
11300 case VKI_USBDEVFS_CONNECTINFO:
11301 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11302 break;
11303 case VKI_USBDEVFS_IOCTL:
11304 if ( ARG3 ) {
11305 struct vki_usbdevfs_ioctl *vkui =
11306 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11307 UInt dir2, size2;
11308 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11309 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11310 if (size2 > 0) {
11311 if (dir2 & _VKI_IOC_READ)
11312 POST_MEM_WRITE((Addr)vkui->data, size2);
11315 break;
11317 /* I2C (/dev/i2c-*) ioctls */
11318 case VKI_I2C_SLAVE:
11319 case VKI_I2C_SLAVE_FORCE:
11320 case VKI_I2C_TENBIT:
11321 case VKI_I2C_PEC:
11322 break;
11323 case VKI_I2C_FUNCS:
11324 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11325 break;
11326 case VKI_I2C_RDWR:
11327 if ( ARG3 ) {
11328 struct vki_i2c_rdwr_ioctl_data *vkui =
11329 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11330 UInt i;
11331 for (i=0; i < vkui->nmsgs; i++) {
11332 struct vki_i2c_msg *msg = vkui->msgs + i;
11333 if (msg->flags & VKI_I2C_M_RD)
11334 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11337 break;
11338 case VKI_I2C_SMBUS:
11339 if ( ARG3 ) {
11340 struct vki_i2c_smbus_ioctl_data *vkis
11341 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11342 /* i2c_smbus_write_quick hides its value in read_write, so
11343 this variable can have a different meaning */
11344 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11345 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11346 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11347 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11348 UInt size;
11349 switch(vkis->size) {
11350 case VKI_I2C_SMBUS_BYTE:
11351 case VKI_I2C_SMBUS_BYTE_DATA:
11352 size = 1;
11353 break;
11354 case VKI_I2C_SMBUS_WORD_DATA:
11355 case VKI_I2C_SMBUS_PROC_CALL:
11356 size = 2;
11357 break;
11358 case VKI_I2C_SMBUS_BLOCK_DATA:
11359 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11360 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11361 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11362 size = 1 + vkis->data->block[0];
11363 break;
11364 default:
11365 size = 0;
11367 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11371 break;
11373 /* Wireless extensions ioctls */
11374 case VKI_SIOCSIWCOMMIT:
11375 case VKI_SIOCSIWNWID:
11376 case VKI_SIOCSIWFREQ:
11377 case VKI_SIOCSIWMODE:
11378 case VKI_SIOCSIWSENS:
11379 case VKI_SIOCSIWRANGE:
11380 case VKI_SIOCSIWPRIV:
11381 case VKI_SIOCSIWSTATS:
11382 case VKI_SIOCSIWSPY:
11383 case VKI_SIOCSIWTHRSPY:
11384 case VKI_SIOCSIWAP:
11385 case VKI_SIOCSIWSCAN:
11386 case VKI_SIOCSIWESSID:
11387 case VKI_SIOCSIWRATE:
11388 case VKI_SIOCSIWNICKN:
11389 case VKI_SIOCSIWRTS:
11390 case VKI_SIOCSIWFRAG:
11391 case VKI_SIOCSIWTXPOW:
11392 case VKI_SIOCSIWRETRY:
11393 case VKI_SIOCSIWENCODE:
11394 case VKI_SIOCSIWPOWER:
11395 case VKI_SIOCSIWGENIE:
11396 case VKI_SIOCSIWMLME:
11397 case VKI_SIOCSIWAUTH:
11398 case VKI_SIOCSIWENCODEEXT:
11399 case VKI_SIOCSIWPMKSA:
11400 break;
11401 case VKI_SIOCGIWNAME:
11402 if (ARG3) {
11403 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11404 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11406 break;
11407 case VKI_SIOCGIWNWID:
11408 case VKI_SIOCGIWSENS:
11409 case VKI_SIOCGIWRATE:
11410 case VKI_SIOCGIWRTS:
11411 case VKI_SIOCGIWFRAG:
11412 case VKI_SIOCGIWTXPOW:
11413 case VKI_SIOCGIWRETRY:
11414 case VKI_SIOCGIWPOWER:
11415 case VKI_SIOCGIWAUTH:
11416 if (ARG3) {
11417 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11418 sizeof(struct vki_iw_param));
11420 break;
11421 case VKI_SIOCGIWFREQ:
11422 if (ARG3) {
11423 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11424 sizeof(struct vki_iw_freq));
11426 break;
11427 case VKI_SIOCGIWMODE:
11428 if (ARG3) {
11429 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11430 sizeof(__vki_u32));
11432 break;
11433 case VKI_SIOCGIWRANGE:
11434 case VKI_SIOCGIWPRIV:
11435 case VKI_SIOCGIWSTATS:
11436 case VKI_SIOCGIWSPY:
11437 case VKI_SIOCGIWTHRSPY:
11438 case VKI_SIOCGIWAPLIST:
11439 case VKI_SIOCGIWSCAN:
11440 case VKI_SIOCGIWESSID:
11441 case VKI_SIOCGIWNICKN:
11442 case VKI_SIOCGIWENCODE:
11443 case VKI_SIOCGIWGENIE:
11444 case VKI_SIOCGIWENCODEEXT:
11445 if (ARG3) {
11446 struct vki_iw_point* point;
11447 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11448 POST_MEM_WRITE((Addr)point->pointer, point->length);
11450 break;
11451 case VKI_SIOCGIWAP:
11452 if (ARG3) {
11453 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11454 sizeof(struct vki_sockaddr));
11456 break;
11458 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11459 || defined(VGPV_mips32_linux_android) \
11460 || defined(VGPV_arm64_linux_android)
11461 /* ashmem */
11462 case VKI_ASHMEM_GET_SIZE:
11463 case VKI_ASHMEM_SET_SIZE:
11464 case VKI_ASHMEM_GET_PROT_MASK:
11465 case VKI_ASHMEM_SET_PROT_MASK:
11466 case VKI_ASHMEM_GET_PIN_STATUS:
11467 case VKI_ASHMEM_PURGE_ALL_CACHES:
11468 case VKI_ASHMEM_SET_NAME:
11469 case VKI_ASHMEM_PIN:
11470 case VKI_ASHMEM_UNPIN:
11471 break;
11472 case VKI_ASHMEM_GET_NAME:
11473 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11474 break;
11476 /* binder */
11477 case VKI_BINDER_WRITE_READ:
11478 if (ARG3) {
11479 struct vki_binder_write_read* bwr
11480 = (struct vki_binder_write_read*)(Addr)ARG3;
11481 POST_FIELD_WRITE(bwr->write_consumed);
11482 POST_FIELD_WRITE(bwr->read_consumed);
11484 if (bwr->read_size)
11485 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11487 break;
11489 case VKI_BINDER_SET_IDLE_TIMEOUT:
11490 case VKI_BINDER_SET_MAX_THREADS:
11491 case VKI_BINDER_SET_IDLE_PRIORITY:
11492 case VKI_BINDER_SET_CONTEXT_MGR:
11493 case VKI_BINDER_THREAD_EXIT:
11494 break;
11495 case VKI_BINDER_VERSION:
11496 if (ARG3) {
11497 struct vki_binder_version* bv =
11498 (struct vki_binder_version*)(Addr)ARG3;
11499 POST_FIELD_WRITE(bv->protocol_version);
11501 break;
11502 # endif /* defined(VGPV_*_linux_android) */
11504 case VKI_HCIGETDEVLIST:
11505 if (ARG3) {
11506 struct vki_hci_dev_list_req* dlr =
11507 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11508 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11509 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11511 break;
11513 case VKI_HCIINQUIRY:
11514 if (ARG3) {
11515 struct vki_hci_inquiry_req* ir =
11516 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11517 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11518 ir->num_rsp * sizeof(struct vki_inquiry_info));
11520 break;
11522 case VKI_DRM_IOCTL_VERSION:
11523 if (ARG3) {
11524 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11525 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11526 const vki_size_t orig_name_len = info->orig->name_len;
11527 const vki_size_t orig_date_len = info->orig->date_len;
11528 const vki_size_t orig_desc_len = info->orig->desc_len;
11529 *info->orig = info->data;
11530 ARG3 = (Addr)info->orig;
11531 data = info->orig;
11532 VG_(free)(info);
11533 if (SUCCESS) {
11534 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11535 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11536 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11537 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11538 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11539 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11540 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11541 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11542 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11545 break;
11546 case VKI_DRM_IOCTL_GET_UNIQUE:
11547 if (ARG3) {
11548 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11549 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11551 break;
11552 case VKI_DRM_IOCTL_GET_MAGIC:
11553 if (ARG3) {
11554 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11555 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11557 break;
11558 case VKI_DRM_IOCTL_WAIT_VBLANK:
11559 if (ARG3) {
11560 union vki_drm_wait_vblank *data =
11561 (union vki_drm_wait_vblank *)(Addr)ARG3;
11562 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11564 break;
11565 case VKI_DRM_IOCTL_GEM_FLINK:
11566 if (ARG3) {
11567 struct vki_drm_gem_flink *data =
11568 (struct vki_drm_gem_flink *)(Addr)ARG3;
11569 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11571 break;
11572 case VKI_DRM_IOCTL_GEM_OPEN:
11573 if (ARG3) {
11574 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11575 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11576 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11578 break;
11579 case VKI_DRM_IOCTL_I915_GETPARAM:
11580 if (ARG3) {
11581 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11582 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11584 break;
11585 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11586 if (ARG3) {
11587 struct vki_drm_i915_gem_busy *data =
11588 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11589 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11591 break;
11592 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11593 if (ARG3) {
11594 struct vki_drm_i915_gem_create *data =
11595 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11596 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11598 break;
11599 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11600 if (ARG3) {
11601 struct vki_drm_i915_gem_pread *data =
11602 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11603 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11605 break;
11606 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11607 if (ARG3) {
11608 struct vki_drm_i915_gem_mmap_v1 *data =
11609 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11610 Addr addr = data->addr_ptr;
11611 SizeT size = data->size;
11612 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11613 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11614 ML_(notify_core_and_tool_of_mmap)(addr, size,
11615 VKI_PROT_READ | VKI_PROT_WRITE,
11616 VKI_MAP_ANONYMOUS, -1, 0 );
11617 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11619 break;
11620 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11621 if (ARG3) {
11622 struct vki_drm_i915_gem_mmap *data =
11623 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11624 Addr addr = data->addr_ptr;
11625 SizeT size = data->size;
11626 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11627 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11628 ML_(notify_core_and_tool_of_mmap)(addr, size,
11629 VKI_PROT_READ | VKI_PROT_WRITE,
11630 VKI_MAP_ANONYMOUS, -1, 0 );
11631 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11633 break;
11634 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11635 if (ARG3) {
11636 struct vki_drm_i915_gem_mmap_gtt *data =
11637 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11638 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11640 break;
11641 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11642 if (ARG3) {
11643 struct vki_drm_i915_gem_set_tiling *data =
11644 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11645 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11646 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11647 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11649 break;
11650 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11651 if (ARG3) {
11652 struct vki_drm_i915_gem_get_tiling *data =
11653 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11654 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11655 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11657 break;
11658 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11659 if (ARG3) {
11660 struct vki_drm_i915_gem_get_aperture *data =
11661 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11662 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11663 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11665 break;
11667 /* KVM ioctls that only write the system call return value */
11668 case VKI_KVM_GET_API_VERSION:
11669 case VKI_KVM_CREATE_VM:
11670 case VKI_KVM_CHECK_EXTENSION:
11671 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11672 case VKI_KVM_S390_ENABLE_SIE:
11673 case VKI_KVM_CREATE_VCPU:
11674 case VKI_KVM_SET_TSS_ADDR:
11675 case VKI_KVM_CREATE_IRQCHIP:
11676 case VKI_KVM_RUN:
11677 case VKI_KVM_S390_INITIAL_RESET:
11678 case VKI_KVM_KVMCLOCK_CTRL:
11679 break;
11681 case VKI_KVM_S390_MEM_OP: {
11682 struct vki_kvm_s390_mem_op *args =
11683 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11684 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11685 break;
11686 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11687 POST_MEM_WRITE((Addr)args->buf, args->size);
11689 break;
11691 #ifdef ENABLE_XEN
11692 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11693 SyscallArgs harrghs;
11694 struct vki_xen_privcmd_hypercall *args =
11695 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11697 if (!args)
11698 break;
11700 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11701 harrghs.sysno = args->op;
11702 harrghs.arg1 = args->arg[0];
11703 harrghs.arg2 = args->arg[1];
11704 harrghs.arg3 = args->arg[2];
11705 harrghs.arg4 = args->arg[3];
11706 harrghs.arg5 = args->arg[4];
11707 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11709 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11711 break;
11713 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11714 break;
11715 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11716 struct vki_xen_privcmd_mmapbatch *args =
11717 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11718 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11720 break;
11721 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11722 struct vki_xen_privcmd_mmapbatch_v2 *args =
11723 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11724 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11726 break;
11728 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11729 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11730 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11731 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11732 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11733 case VKI_XEN_IOCTL_EVTCHN_RESET:
11734 /* No output */
11735 break;
11736 #endif
11738 /* Lustre */
11739 case VKI_OBD_IOC_FID2PATH: {
11740 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11741 POST_FIELD_WRITE(args->gf_recno);
11742 POST_FIELD_WRITE(args->gf_linkno);
11743 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11744 break;
11747 case VKI_LL_IOC_PATH2FID:
11748 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11749 break;
11751 case VKI_LL_IOC_GETPARENT: {
11752 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11753 POST_FIELD_WRITE(gp->gp_fid);
11754 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11755 break;
11758 /* V4L2 */
11759 case VKI_V4L2_S_FMT:
11760 case VKI_V4L2_TRY_FMT:
11761 case VKI_V4L2_REQBUFS:
11762 case VKI_V4L2_OVERLAY:
11763 case VKI_V4L2_STREAMON:
11764 case VKI_V4L2_STREAMOFF:
11765 case VKI_V4L2_S_PARM:
11766 case VKI_V4L2_S_STD:
11767 case VKI_V4L2_S_FREQUENCY:
11768 case VKI_V4L2_S_CTRL:
11769 case VKI_V4L2_S_TUNER:
11770 case VKI_V4L2_S_AUDIO:
11771 case VKI_V4L2_S_INPUT:
11772 case VKI_V4L2_S_EDID:
11773 case VKI_V4L2_S_OUTPUT:
11774 case VKI_V4L2_S_AUDOUT:
11775 case VKI_V4L2_S_MODULATOR:
11776 case VKI_V4L2_S_JPEGCOMP:
11777 case VKI_V4L2_S_CROP:
11778 case VKI_V4L2_S_PRIORITY:
11779 case VKI_V4L2_S_HW_FREQ_SEEK:
11780 case VKI_V4L2_S_DV_TIMINGS:
11781 case VKI_V4L2_SUBSCRIBE_EVENT:
11782 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11783 case VKI_V4L2_PREPARE_BUF:
11784 break;
11785 case VKI_V4L2_QUERYCAP: {
11786 struct vki_v4l2_capability *data =
11787 (struct vki_v4l2_capability *)(Addr)ARG3;
11788 POST_MEM_WRITE((Addr)data, sizeof(*data));
11789 break;
11791 case VKI_V4L2_ENUM_FMT: {
11792 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11793 POST_FIELD_WRITE(data->flags);
11794 POST_FIELD_WRITE(data->description);
11795 POST_FIELD_WRITE(data->pixelformat);
11796 POST_FIELD_WRITE(data->reserved);
11797 break;
11799 case VKI_V4L2_G_FMT: {
11800 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11801 switch (data->type) {
11802 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11803 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11804 POST_FIELD_WRITE(data->fmt.pix);
11805 break;
11806 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11807 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11808 POST_FIELD_WRITE(data->fmt.vbi);
11809 break;
11810 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11811 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11812 POST_FIELD_WRITE(data->fmt.sliced);
11813 break;
11814 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11815 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11816 POST_FIELD_WRITE(data->fmt.win);
11817 break;
11818 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11819 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11820 POST_FIELD_WRITE(data->fmt.pix_mp);
11821 break;
11822 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11823 POST_FIELD_WRITE(data->fmt.sdr);
11824 break;
11826 break;
11828 case VKI_V4L2_QUERYBUF: {
11829 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11830 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11831 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11832 unsigned i;
11834 for (i = 0; i < data->length; i++) {
11835 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11836 POST_FIELD_WRITE(data->m.planes[i].length);
11837 POST_FIELD_WRITE(data->m.planes[i].m);
11838 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11839 POST_FIELD_WRITE(data->m.planes[i].reserved);
11841 } else {
11842 POST_FIELD_WRITE(data->m);
11843 POST_FIELD_WRITE(data->length);
11845 POST_FIELD_WRITE(data->bytesused);
11846 POST_FIELD_WRITE(data->flags);
11847 POST_FIELD_WRITE(data->field);
11848 POST_FIELD_WRITE(data->timestamp);
11849 POST_FIELD_WRITE(data->timecode);
11850 POST_FIELD_WRITE(data->sequence);
11851 POST_FIELD_WRITE(data->memory);
11852 POST_FIELD_WRITE(data->sequence);
11853 break;
11855 case VKI_V4L2_G_FBUF: {
11856 struct vki_v4l2_framebuffer *data =
11857 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11858 POST_MEM_WRITE((Addr)data, sizeof(*data));
11859 break;
11861 case VKI_V4L2_S_FBUF: {
11862 struct vki_v4l2_framebuffer *data =
11863 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11864 POST_FIELD_WRITE(data->capability);
11865 POST_FIELD_WRITE(data->flags);
11866 POST_FIELD_WRITE(data->fmt);
11867 break;
11869 case VKI_V4L2_QBUF: {
11870 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11872 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11873 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11874 unsigned i;
11876 for (i = 0; i < data->length; i++) {
11877 POST_FIELD_WRITE(data->m.planes[i].length);
11878 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11879 POST_FIELD_WRITE(data->m.planes[i].m);
11881 } else {
11882 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11883 POST_FIELD_WRITE(data->m);
11884 POST_FIELD_WRITE(data->length);
11886 break;
11888 case VKI_V4L2_EXPBUF: {
11889 struct vki_v4l2_exportbuffer *data =
11890 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11891 POST_FIELD_WRITE(data->fd);
11892 break;
11894 case VKI_V4L2_DQBUF: {
11895 struct vki_v4l2_buffer *data =
11896 (struct vki_v4l2_buffer *)(Addr)ARG3;
11897 POST_FIELD_WRITE(data->index);
11898 POST_FIELD_WRITE(data->bytesused);
11899 POST_FIELD_WRITE(data->field);
11900 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11901 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11902 unsigned i;
11904 for (i = 0; i < data->length; i++) {
11905 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11906 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11907 POST_FIELD_WRITE(data->m.planes[i].length);
11908 POST_FIELD_WRITE(data->m.planes[i].m);
11910 } else {
11911 POST_FIELD_WRITE(data->m);
11912 POST_FIELD_WRITE(data->length);
11913 POST_FIELD_WRITE(data->bytesused);
11914 POST_FIELD_WRITE(data->field);
11916 POST_FIELD_WRITE(data->timestamp);
11917 POST_FIELD_WRITE(data->timecode);
11918 POST_FIELD_WRITE(data->sequence);
11919 break;
11921 case VKI_V4L2_G_PARM: {
11922 struct vki_v4l2_streamparm *data =
11923 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11924 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11925 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11926 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11927 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11929 if (is_output)
11930 POST_MEM_WRITE((Addr)&data->parm.output,
11931 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11932 else
11933 POST_MEM_WRITE((Addr)&data->parm.capture,
11934 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11935 break;
11937 case VKI_V4L2_G_STD: {
11938 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11939 POST_MEM_WRITE((Addr)data, sizeof(*data));
11940 break;
11942 case VKI_V4L2_ENUMSTD: {
11943 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11944 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11945 break;
11947 case VKI_V4L2_ENUMINPUT: {
11948 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11949 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11950 break;
11952 case VKI_V4L2_G_CTRL: {
11953 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11954 POST_FIELD_WRITE(data->value);
11955 break;
11957 case VKI_V4L2_G_TUNER: {
11958 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11959 POST_MEM_WRITE((Addr)data->name,
11960 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11961 break;
11963 case VKI_V4L2_G_AUDIO: {
11964 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11965 POST_MEM_WRITE((Addr)data,
11966 sizeof(*data) - sizeof(data->reserved));
11967 break;
11969 case VKI_V4L2_QUERYCTRL: {
11970 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11971 POST_MEM_WRITE((Addr)&data->type,
11972 sizeof(*data) - sizeof(data->id));
11973 break;
11975 case VKI_V4L2_QUERYMENU: {
11976 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11977 POST_MEM_WRITE((Addr)data->name,
11978 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11979 break;
11981 case VKI_V4L2_G_INPUT: {
11982 int *data = (int *)(Addr)ARG3;
11983 POST_MEM_WRITE((Addr)data, sizeof(*data));
11984 break;
11986 case VKI_V4L2_G_EDID: {
11987 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11988 if (data->blocks && data->edid)
11989 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11990 break;
11992 case VKI_V4L2_G_OUTPUT: {
11993 int *data = (int *)(Addr)ARG3;
11994 POST_MEM_WRITE((Addr)data, sizeof(*data));
11995 break;
11997 case VKI_V4L2_ENUMOUTPUT: {
11998 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11999 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
12000 break;
12002 case VKI_V4L2_G_AUDOUT: {
12003 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12004 POST_MEM_WRITE((Addr)data,
12005 sizeof(*data) - sizeof(data->reserved));
12006 break;
12008 case VKI_V4L2_G_MODULATOR: {
12009 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
12010 POST_MEM_WRITE((Addr)data->name,
12011 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12012 break;
12014 case VKI_V4L2_G_FREQUENCY: {
12015 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
12016 POST_FIELD_WRITE(data->type);
12017 POST_FIELD_WRITE(data->frequency);
12018 break;
12020 case VKI_V4L2_CROPCAP: {
12021 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
12022 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
12023 break;
12025 case VKI_V4L2_G_CROP: {
12026 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
12027 POST_FIELD_WRITE(data->c);
12028 break;
12030 case VKI_V4L2_G_JPEGCOMP: {
12031 struct vki_v4l2_jpegcompression *data =
12032 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
12033 POST_MEM_WRITE((Addr)data, sizeof(*data));
12034 break;
12036 case VKI_V4L2_QUERYSTD: {
12037 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
12038 POST_MEM_WRITE((Addr)data, sizeof(*data));
12039 break;
12041 case VKI_V4L2_ENUMAUDIO: {
12042 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
12043 POST_MEM_WRITE((Addr)data->name,
12044 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12045 break;
12047 case VKI_V4L2_ENUMAUDOUT: {
12048 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12049 POST_MEM_WRITE((Addr)data->name,
12050 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12051 break;
12053 case VKI_V4L2_G_PRIORITY: {
12054 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
12055 POST_MEM_WRITE((Addr)data, sizeof(*data));
12056 break;
12058 case VKI_V4L2_G_SLICED_VBI_CAP: {
12059 struct vki_v4l2_sliced_vbi_cap *data =
12060 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
12061 POST_MEM_WRITE((Addr)data,
12062 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
12063 break;
12065 case VKI_V4L2_G_EXT_CTRLS: {
12066 struct vki_v4l2_ext_controls *data =
12067 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12068 if (data->count) {
12069 unsigned i;
12071 for (i = 0; i < data->count; i++) {
12072 if (data->controls[i].size)
12073 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
12074 else
12075 POST_FIELD_WRITE(data->controls[i].value64);
12078 POST_FIELD_WRITE(data->error_idx);
12079 break;
12081 case VKI_V4L2_S_EXT_CTRLS: {
12082 struct vki_v4l2_ext_controls *data =
12083 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12084 POST_FIELD_WRITE(data->error_idx);
12085 break;
12087 case VKI_V4L2_TRY_EXT_CTRLS: {
12088 struct vki_v4l2_ext_controls *data =
12089 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12090 POST_FIELD_WRITE(data->error_idx);
12091 break;
12093 case VKI_V4L2_ENUM_FRAMESIZES: {
12094 struct vki_v4l2_frmsizeenum *data =
12095 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
12096 POST_FIELD_WRITE(data->type);
12097 POST_FIELD_WRITE(data->stepwise);
12098 break;
12100 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
12101 struct vki_v4l2_frmivalenum *data =
12102 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
12103 POST_FIELD_WRITE(data->type);
12104 POST_FIELD_WRITE(data->stepwise);
12105 break;
12107 case VKI_V4L2_G_ENC_INDEX: {
12108 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
12109 POST_MEM_WRITE((Addr)data, sizeof(*data));
12110 break;
12112 case VKI_V4L2_ENCODER_CMD: {
12113 struct vki_v4l2_encoder_cmd *data =
12114 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12115 POST_FIELD_WRITE(data->flags);
12116 break;
12118 case VKI_V4L2_TRY_ENCODER_CMD: {
12119 struct vki_v4l2_encoder_cmd *data =
12120 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12121 POST_FIELD_WRITE(data->flags);
12122 break;
12124 case VKI_V4L2_DBG_S_REGISTER: {
12125 struct vki_v4l2_dbg_register *data =
12126 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12127 POST_FIELD_WRITE(data->size);
12128 break;
12130 case VKI_V4L2_DBG_G_REGISTER: {
12131 struct vki_v4l2_dbg_register *data =
12132 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12133 POST_FIELD_WRITE(data->val);
12134 POST_FIELD_WRITE(data->size);
12135 break;
12137 case VKI_V4L2_G_DV_TIMINGS: {
12138 struct vki_v4l2_dv_timings *data =
12139 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12140 POST_MEM_WRITE((Addr)data, sizeof(*data));
12141 break;
12143 case VKI_V4L2_DQEVENT: {
12144 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12145 POST_MEM_WRITE((Addr)data, sizeof(*data));
12146 break;
12148 case VKI_V4L2_CREATE_BUFS: {
12149 struct vki_v4l2_create_buffers *data =
12150 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12151 POST_FIELD_WRITE(data->index);
12152 break;
12154 case VKI_V4L2_G_SELECTION: {
12155 struct vki_v4l2_selection *data =
12156 (struct vki_v4l2_selection *)(Addr)ARG3;
12157 POST_FIELD_WRITE(data->r);
12158 break;
12160 case VKI_V4L2_S_SELECTION: {
12161 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12162 POST_FIELD_WRITE(data->r);
12163 break;
12165 case VKI_V4L2_DECODER_CMD: {
12166 struct vki_v4l2_decoder_cmd *data =
12167 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12168 POST_FIELD_WRITE(data->flags);
12169 break;
12171 case VKI_V4L2_TRY_DECODER_CMD: {
12172 struct vki_v4l2_decoder_cmd *data =
12173 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12174 POST_FIELD_WRITE(data->flags);
12175 break;
12177 case VKI_V4L2_ENUM_DV_TIMINGS: {
12178 struct vki_v4l2_enum_dv_timings *data =
12179 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12180 POST_FIELD_WRITE(data->timings);
12181 break;
12183 case VKI_V4L2_QUERY_DV_TIMINGS: {
12184 struct vki_v4l2_dv_timings *data =
12185 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12186 POST_MEM_WRITE((Addr)data, sizeof(*data));
12187 break;
12189 case VKI_V4L2_DV_TIMINGS_CAP: {
12190 struct vki_v4l2_dv_timings_cap *data =
12191 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12192 POST_MEM_WRITE((Addr)data, sizeof(*data));
12193 break;
12195 case VKI_V4L2_ENUM_FREQ_BANDS: {
12196 struct vki_v4l2_frequency_band *data =
12197 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12198 POST_FIELD_WRITE(data->capability);
12199 POST_FIELD_WRITE(data->rangelow);
12200 POST_FIELD_WRITE(data->rangehigh);
12201 POST_FIELD_WRITE(data->modulation);
12202 break;
12204 case VKI_V4L2_DBG_G_CHIP_INFO: {
12205 struct vki_v4l2_dbg_chip_info *data =
12206 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12207 POST_FIELD_WRITE(data->name);
12208 POST_FIELD_WRITE(data->flags);
12209 break;
12211 case VKI_V4L2_QUERY_EXT_CTRL: {
12212 struct vki_v4l2_query_ext_ctrl *data =
12213 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12214 POST_MEM_WRITE((Addr)&data->type,
12215 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12216 break;
12219 case VKI_V4L2_SUBDEV_S_FMT:
12220 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12221 case VKI_V4L2_SUBDEV_S_CROP:
12222 case VKI_V4L2_SUBDEV_S_SELECTION:
12223 break;
12225 case VKI_V4L2_SUBDEV_G_FMT: {
12226 struct vki_v4l2_subdev_format *data =
12227 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12228 POST_FIELD_WRITE(data->format);
12229 break;
12231 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12232 struct vki_v4l2_subdev_frame_interval *data =
12233 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12234 POST_FIELD_WRITE(data->interval);
12235 break;
12237 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12238 struct vki_v4l2_subdev_mbus_code_enum *data =
12239 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12240 POST_FIELD_WRITE(data->code);
12241 break;
12243 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12244 struct vki_v4l2_subdev_frame_size_enum *data =
12245 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12246 POST_FIELD_WRITE(data->min_width);
12247 POST_FIELD_WRITE(data->min_height);
12248 POST_FIELD_WRITE(data->max_width);
12249 POST_FIELD_WRITE(data->max_height);
12250 break;
12252 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12253 struct vki_v4l2_subdev_frame_interval_enum *data =
12254 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12255 POST_FIELD_WRITE(data->interval);
12256 break;
12258 case VKI_V4L2_SUBDEV_G_CROP: {
12259 struct vki_v4l2_subdev_crop *data =
12260 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12261 POST_FIELD_WRITE(data->rect);
12262 break;
12264 case VKI_V4L2_SUBDEV_G_SELECTION: {
12265 struct vki_v4l2_subdev_selection *data =
12266 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12267 POST_FIELD_WRITE(data->r);
12268 break;
12270 case VKI_MEDIA_IOC_DEVICE_INFO: {
12271 struct vki_media_device_info *data =
12272 (struct vki_media_device_info *)(Addr)ARG3;
12273 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12274 break;
12276 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12277 struct vki_media_entity_desc *data =
12278 (struct vki_media_entity_desc *)(Addr)ARG3;
12279 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12280 break;
12282 case VKI_MEDIA_IOC_ENUM_LINKS:
12284 * This ioctl does write to the provided pointers, but it's not
12285 * possible to deduce the size of the array those pointers point to.
12287 break;
12288 case VKI_MEDIA_IOC_SETUP_LINK:
12289 break;
12291 /* Serial */
12292 case VKI_TIOCGSERIAL: {
12293 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12294 POST_MEM_WRITE((Addr)data, sizeof(*data));
12295 break;
12297 case VKI_TIOCSSERIAL:
12298 break;
12300 case VKI_PERF_EVENT_IOC_ENABLE:
12301 case VKI_PERF_EVENT_IOC_DISABLE:
12302 case VKI_PERF_EVENT_IOC_REFRESH:
12303 case VKI_PERF_EVENT_IOC_RESET:
12304 case VKI_PERF_EVENT_IOC_PERIOD:
12305 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12306 case VKI_PERF_EVENT_IOC_SET_FILTER:
12307 case VKI_PERF_EVENT_IOC_SET_BPF:
12308 break;
12310 case VKI_PERF_EVENT_IOC_ID:
12311 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12312 break;
12314 /* Pulse Per Second (PPS) */
12315 case VKI_PPS_GETPARAMS: {
12316 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12317 POST_MEM_WRITE((Addr)data, sizeof(*data));
12318 break;
12320 case VKI_PPS_GETCAP:
12321 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12322 break;
12323 case VKI_PPS_FETCH: {
12324 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12325 POST_FIELD_WRITE(data->info);
12326 break;
12328 case VKI_PPS_SETPARAMS:
12329 case VKI_PPS_KC_BIND:
12330 break;
12332 /* PTP Hardware Clock */
12333 case VKI_PTP_CLOCK_GETCAPS: {
12334 struct vki_ptp_clock_caps *data =
12335 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12336 POST_MEM_WRITE((Addr)data, sizeof(*data));
12337 break;
12339 case VKI_PTP_SYS_OFFSET: {
12340 struct vki_ptp_sys_offset *data =
12341 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12342 POST_MEM_WRITE((Addr)data->ts,
12343 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12344 break;
12346 case VKI_PTP_PIN_GETFUNC: {
12347 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12348 POST_MEM_WRITE((Addr)data, sizeof(*data));
12349 break;
12351 case VKI_PTP_SYS_OFFSET_PRECISE: {
12352 struct vki_ptp_sys_offset_precise *data =
12353 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12354 POST_MEM_WRITE((Addr)data, sizeof(*data));
12355 break;
12357 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12358 struct vki_ptp_sys_offset_extended *data =
12359 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12360 POST_MEM_WRITE((Addr)data->ts,
12361 3 * data->n_samples * sizeof(data->ts[0][0]));
12362 break;
12364 case VKI_PTP_EXTTS_REQUEST:
12365 case VKI_PTP_PEROUT_REQUEST:
12366 case VKI_PTP_ENABLE_PPS:
12367 case VKI_PTP_PIN_SETFUNC:
12368 break;
12370 default:
12371 /* EVIOC* are variable length and return size written on success */
12372 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12373 case VKI_EVIOCGNAME(0):
12374 case VKI_EVIOCGPHYS(0):
12375 case VKI_EVIOCGUNIQ(0):
12376 case VKI_EVIOCGKEY(0):
12377 case VKI_EVIOCGLED(0):
12378 case VKI_EVIOCGSND(0):
12379 case VKI_EVIOCGSW(0):
12380 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12381 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12382 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12383 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12384 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12385 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12386 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12387 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12388 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12389 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12390 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12391 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12392 if (RES > 0)
12393 POST_MEM_WRITE(ARG3, RES);
12394 break;
12395 default:
12396 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12397 break;
12399 break;
12402 post_sys_ioctl__out:
12403 {} /* keep C compilers happy */
12406 /* ---------------------------------------------------------------------
12407 socketcall wrapper helpers
12408 ------------------------------------------------------------------ */
12410 void
12411 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12412 UWord arg0, UWord arg1, UWord arg2,
12413 UWord arg3, UWord arg4 )
12415 /* int getsockopt(int s, int level, int optname,
12416 void *optval, socklen_t *optlen); */
12417 Addr optval_p = arg3;
12418 Addr optlen_p = arg4;
12419 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12420 if (optval_p != (Addr)NULL) {
12421 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12422 "socketcall.getsockopt(optval)",
12423 "socketcall.getsockopt(optlen)" );
12424 if (arg1 == VKI_SOL_SCTP &&
12425 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12426 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12428 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12429 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12430 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12431 (Addr)ga->addrs, address_bytes );
12436 void
12437 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12438 SysRes res,
12439 UWord arg0, UWord arg1, UWord arg2,
12440 UWord arg3, UWord arg4 )
12442 Addr optval_p = arg3;
12443 Addr optlen_p = arg4;
12444 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12445 if (optval_p != (Addr)NULL) {
12446 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12447 "socketcall.getsockopt(optlen_out)" );
12448 if (arg1 == VKI_SOL_SCTP &&
12449 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12450 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12452 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12453 struct vki_sockaddr *a = ga->addrs;
12454 int i;
12455 for (i = 0; i < ga->addr_num; i++) {
12456 int sl = 0;
12457 if (a->sa_family == VKI_AF_INET)
12458 sl = sizeof(struct vki_sockaddr_in);
12459 else if (a->sa_family == VKI_AF_INET6)
12460 sl = sizeof(struct vki_sockaddr_in6);
12461 else {
12462 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12463 "address type %d\n", a->sa_family);
12465 a = (struct vki_sockaddr*)((char*)a + sl);
12467 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12472 void
12473 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12474 UWord arg0, UWord arg1, UWord arg2,
12475 UWord arg3, UWord arg4 )
12477 /* int setsockopt(int s, int level, int optname,
12478 const void *optval, socklen_t optlen); */
12479 Addr optval_p = arg3;
12480 if (optval_p != (Addr)NULL) {
12482 * OK, let's handle at least some setsockopt levels and options
12483 * ourselves, so we don't get false claims of references to
12484 * uninitialized memory (such as padding in structures) and *do*
12485 * check what pointers in the argument point to.
12487 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12489 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12492 * struct sock_fprog has a 16-bit count of instructions,
12493 * followed by a pointer to an array of those instructions.
12494 * There's padding between those two elements.
12496 * So that we don't bogusly complain about the padding bytes,
12497 * we just report that we read len and and filter.
12499 * We then make sure that what filter points to is valid.
12501 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12502 (Addr)&fp->len, sizeof(fp->len) );
12503 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12504 (Addr)&fp->filter, sizeof(fp->filter) );
12506 /* len * sizeof (*filter) */
12507 if (fp->filter != NULL)
12509 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12510 (Addr)(fp->filter),
12511 fp->len * sizeof(*fp->filter) );
12514 else
12516 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12517 arg3, /* optval */
12518 arg4 /* optlen */ );
12523 void
12524 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12525 UWord arg1, UWord arg2, UWord arg3,
12526 UWord arg4, UWord arg5 )
12528 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12529 HChar name[40]; // large enough
12530 UInt i;
12531 for (i = 0; i < arg3; i++) {
12532 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12533 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12534 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12535 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12537 if (arg5)
12538 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12541 void
12542 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12543 UWord arg1, UWord arg2, UWord arg3,
12544 UWord arg4, UWord arg5 )
12546 if (res > 0) {
12547 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12548 HChar name[32]; // large enough
12549 UInt i;
12550 for (i = 0; i < res; i++) {
12551 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12552 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12553 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12558 void
12559 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12560 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12562 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12563 HChar name[40]; // large enough
12564 UInt i;
12565 for (i = 0; i < arg3; i++) {
12566 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12567 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12568 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12569 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12573 void
12574 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12575 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12577 if (res > 0) {
12578 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12579 UInt i;
12580 for (i = 0; i < res; i++) {
12581 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12586 /* ---------------------------------------------------------------------
12587 ptrace wrapper helpers
12588 ------------------------------------------------------------------ */
12590 void
12591 ML_(linux_POST_traceme) ( ThreadId tid )
12593 ThreadState *tst = VG_(get_ThreadState)(tid);
12594 tst->ptrace = VKI_PT_PTRACED;
12597 void
12598 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12600 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12602 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12603 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12604 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12605 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12606 (Addr) iov->iov_base, iov->iov_len);
12610 void
12611 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12613 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12615 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12616 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12617 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12618 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12619 (Addr) iov->iov_base, iov->iov_len);
12623 void
12624 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12626 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12628 /* XXX: The actual amount of data written by the kernel might be
12629 less than iov_len, depending on the regset (arg3). */
12630 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12633 PRE(sys_kcmp)
12635 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12636 SARG1, SARG2, SARG3, ARG4, ARG5);
12637 switch (ARG3) {
12638 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12639 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12640 /* Most of the comparison types don't look at |idx1| or
12641 |idx2|. */
12642 PRE_REG_READ3(long, "kcmp",
12643 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12644 break;
12645 case VKI_KCMP_FILE:
12646 default:
12647 PRE_REG_READ5(long, "kcmp",
12648 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12649 unsigned long, idx1, unsigned long, idx2);
12650 break;
12654 /* ---------------------------------------------------------------------
12655 bpf wrappers
12656 ------------------------------------------------------------------ */
12658 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12660 HChar path[32], buf[1024]; /* large enough */
12661 SysRes sres;
12662 HChar *comp;
12663 Int proc_fd;
12665 *key_size = 0;
12666 *value_size = 0;
12668 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12669 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12670 if (sr_isError(sres))
12671 return False;
12672 proc_fd = sr_Res(sres);
12674 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12675 return False;
12676 VG_(close)(proc_fd);
12678 comp = VG_(strstr)(buf, "key_size:");
12679 if (comp)
12680 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12682 comp = VG_(strstr)(buf, "value_size:");
12683 if (comp)
12684 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12686 return (*key_size && *value_size);
12690 * From a file descriptor for an eBPF object, try to determine the size of the
12691 * struct that will be written, i.e. determine if object is a map or a program.
12692 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12693 * search for strings "prog_type" or "map_type".
12695 static UInt bpf_obj_get_info_size(Int fd)
12697 HChar path[32], buf[1024]; /* large enough */
12698 SysRes sres;
12699 Int proc_fd;
12701 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12702 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12703 if (sr_isError(sres))
12704 return 0;
12705 proc_fd = sr_Res(sres);
12707 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12708 return 0;
12709 VG_(close)(proc_fd);
12711 if (VG_(strstr)(buf, "prog_type:"))
12712 return sizeof(struct vki_bpf_prog_info);
12714 if (VG_(strstr)(buf, "map_type:"))
12715 return sizeof(struct vki_bpf_map_info);
12717 return 0;
12720 PRE(sys_bpf)
12722 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12723 UInt res, key_size, value_size;
12725 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12726 (Word)ARG1, ARG2, ARG3);
12727 PRE_REG_READ3(long, "bpf",
12728 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12729 switch (ARG1) {
12730 case VKI_BPF_PROG_GET_NEXT_ID:
12731 case VKI_BPF_MAP_GET_NEXT_ID:
12732 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12733 break;
12734 case VKI_BPF_PROG_GET_FD_BY_ID:
12735 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12736 break;
12737 case VKI_BPF_MAP_GET_FD_BY_ID:
12738 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12739 break;
12740 case VKI_BPF_BTF_GET_FD_BY_ID:
12741 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12742 break;
12743 case VKI_BPF_MAP_CREATE:
12744 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12745 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12746 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12747 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12748 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12749 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12750 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12751 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12752 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12753 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12754 switch (attr->map_type) {
12755 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12756 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12757 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12758 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12759 SET_STATUS_Failure(VKI_EBADF);
12760 break;
12761 case VKI_BPF_MAP_TYPE_ARRAY:
12762 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12763 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12764 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12765 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12766 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12767 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12768 SET_STATUS_Failure(VKI_EBADF);
12769 break;
12773 break;
12774 case VKI_BPF_MAP_TYPE_UNSPEC:
12775 case VKI_BPF_MAP_TYPE_HASH:
12776 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12777 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12778 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12779 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12780 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12781 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12782 case VKI_BPF_MAP_TYPE_LRU_HASH:
12783 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12784 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12785 case VKI_BPF_MAP_TYPE_DEVMAP:
12786 case VKI_BPF_MAP_TYPE_SOCKMAP:
12787 case VKI_BPF_MAP_TYPE_CPUMAP:
12788 case VKI_BPF_MAP_TYPE_XSKMAP:
12789 case VKI_BPF_MAP_TYPE_SOCKHASH:
12790 default:
12791 break;
12793 break;
12794 case VKI_BPF_MAP_LOOKUP_ELEM:
12795 /* Perform a lookup on an eBPF map. Read key, write value. */
12796 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12797 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12798 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12799 if (ML_(safe_to_deref)(attr, ARG3)) {
12800 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12801 SET_STATUS_Failure(VKI_EBADF);
12802 break;
12804 /* Get size of key and value for this map. */
12805 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12806 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12807 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12810 break;
12811 case VKI_BPF_MAP_UPDATE_ELEM:
12812 /* Add or update a map element in kernel. Read key, read value. */
12813 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12814 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12815 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12816 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12817 if (ML_(safe_to_deref)(attr, ARG3)) {
12818 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12819 SET_STATUS_Failure(VKI_EBADF);
12820 break;
12822 /* Get size of key and value for this map. */
12823 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12824 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12825 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12828 break;
12829 case VKI_BPF_MAP_DELETE_ELEM:
12830 /* Delete a map element in kernel. Read key from user space. */
12831 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12832 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12833 if (ML_(safe_to_deref)(attr, ARG3)) {
12834 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12835 SET_STATUS_Failure(VKI_EBADF);
12836 break;
12838 /* Get size of key for this map. */
12839 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12840 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12842 break;
12843 case VKI_BPF_MAP_GET_NEXT_KEY:
12844 /* From a key, get next key for the map. Read key, write next key. */
12845 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12846 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12847 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12848 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12849 if (ML_(safe_to_deref)(attr, ARG3)) {
12850 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12851 SET_STATUS_Failure(VKI_EBADF);
12852 break;
12854 /* Get size of key for this map. */
12855 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12856 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12857 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12860 break;
12861 case VKI_BPF_PROG_LOAD:
12862 /* Load a program into the kernel from an array of instructions. */
12863 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12864 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12865 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12866 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12867 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12868 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12869 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12870 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12871 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12872 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12873 if (ML_(safe_to_deref)(attr, ARG3)) {
12874 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12875 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12876 /* Read instructions, license, program name. */
12877 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12878 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12879 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12880 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12881 /* Possibly write up to log_len into user space log buffer. */
12882 if (attr->log_level || attr->log_size || attr->log_buf)
12883 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12885 break;
12886 case VKI_BPF_OBJ_PIN:
12887 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12888 /* fall through */
12889 case VKI_BPF_OBJ_GET:
12890 /* Get pinned eBPF program or map. Read path name. */
12891 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12892 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12893 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12894 if (ML_(safe_to_deref)(attr, ARG3)) {
12895 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12896 SET_STATUS_Failure(VKI_EBADF);
12897 break;
12899 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12901 break;
12902 case VKI_BPF_PROG_ATTACH:
12903 case VKI_BPF_PROG_DETACH:
12904 /* Detach eBPF program from kernel attach point. */
12905 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12906 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12907 if (ML_(safe_to_deref)(attr, ARG3)) {
12908 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12909 SET_STATUS_Failure(VKI_EBADF);
12910 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12911 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12912 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12913 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12914 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12915 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12916 SET_STATUS_Failure(VKI_EBADF);
12919 break;
12920 case VKI_BPF_PROG_TEST_RUN:
12921 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12922 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12923 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12924 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12925 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12926 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12927 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12928 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12929 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12930 if (ML_(safe_to_deref)(attr, ARG3)) {
12931 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12932 SET_STATUS_Failure(VKI_EBADF);
12933 break;
12935 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12936 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12937 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12939 break;
12940 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12941 /* Get info for eBPF map or program. Write info. */
12942 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12943 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12944 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12945 if (ML_(safe_to_deref)(attr, ARG3)) {
12946 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12947 SET_STATUS_Failure(VKI_EBADF);
12948 break;
12950 /* Get size of struct to write: is object a program or a map? */
12951 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12952 if (res)
12953 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12954 VG_MIN(attr->info.info_len, res));
12955 else
12956 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12957 VG_MIN(attr->info.info_len,
12958 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12959 sizeof(struct vki_bpf_map_info)),
12960 sizeof(struct vki_bpf_btf_info))));
12962 break;
12963 case VKI_BPF_PROG_QUERY:
12965 * Query list of eBPF program attached to cgroup.
12966 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12968 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12969 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12970 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12971 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12972 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12973 if (ML_(safe_to_deref)(attr, ARG3)) {
12974 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12975 SET_STATUS_Failure(VKI_EBADF);
12976 break;
12978 if (attr->query.prog_cnt > 0) {
12979 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12980 if (attr->query.prog_ids) {
12981 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12982 attr->query.prog_cnt * sizeof(__vki_u32));
12986 break;
12987 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12988 /* Open raw tracepoint. Read tracepoint name. */
12989 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12990 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12991 if (ML_(safe_to_deref)(attr, ARG3)) {
12992 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12993 "bpf", tid, False)) {
12994 SET_STATUS_Failure(VKI_EBADF);
12995 break;
12997 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12998 if (attr->raw_tracepoint.name != 0)
12999 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
13000 "bpf(attr->raw_tracepoint.name)");
13002 break;
13003 case VKI_BPF_BTF_LOAD:
13004 /* Load BTF information about a program into the kernel. */
13005 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
13006 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
13007 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
13008 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
13009 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
13010 if (ML_(safe_to_deref)(attr, ARG3)) {
13011 /* Read BTF data. */
13012 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
13013 /* Possibly write up to btf_log_len into user space log buffer. */
13014 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
13015 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
13016 attr->btf_log_buf, attr->btf_log_size);
13018 break;
13019 case VKI_BPF_TASK_FD_QUERY:
13020 /* Get info about the task. Write collected info. */
13021 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
13022 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
13023 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
13024 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
13025 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
13026 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13027 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13028 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13029 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13030 if (ML_(safe_to_deref)(attr, ARG3)) {
13031 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
13032 SET_STATUS_Failure(VKI_EBADF);
13033 break;
13035 if (attr->task_fd_query.buf_len > 0) {
13036 /* Write task or perf event name. */
13037 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
13038 attr->task_fd_query.buf,
13039 attr->task_fd_query.buf_len);
13042 break;
13043 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13044 /* Perform a lookup on an eBPF map. Read key, write value (delete key) */
13045 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13046 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
13047 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13048 if (ML_(safe_to_deref)(attr, ARG3)) {
13049 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13050 SET_STATUS_Failure(VKI_EBADF);
13051 break;
13053 /* Get size of key and value for this map. */
13054 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
13055 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13056 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
13059 break;
13060 case VKI_BPF_MAP_FREEZE:
13061 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13062 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13063 break;
13064 default:
13065 VG_(message)(Vg_DebugMsg,
13066 "WARNING: unhandled eBPF command %lu\n", ARG1);
13067 break;
13071 POST(sys_bpf)
13073 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
13074 UInt key_size, value_size;
13076 vg_assert(SUCCESS);
13078 switch (ARG1) {
13079 case VKI_BPF_PROG_GET_NEXT_ID:
13080 case VKI_BPF_MAP_GET_NEXT_ID:
13081 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
13082 break;
13083 case VKI_BPF_MAP_UPDATE_ELEM:
13084 case VKI_BPF_MAP_DELETE_ELEM:
13085 case VKI_BPF_OBJ_PIN:
13086 case VKI_BPF_PROG_ATTACH:
13087 case VKI_BPF_PROG_DETACH:
13088 break;
13089 /* Following commands have bpf() return a file descriptor. */
13090 case VKI_BPF_MAP_CREATE:
13091 case VKI_BPF_OBJ_GET:
13092 case VKI_BPF_PROG_GET_FD_BY_ID:
13093 case VKI_BPF_MAP_GET_FD_BY_ID:
13094 case VKI_BPF_BTF_GET_FD_BY_ID:
13095 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13096 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13097 VG_(close)(RES);
13098 SET_STATUS_Failure(VKI_EMFILE);
13099 } else {
13100 if (VG_(clo_track_fds))
13101 ML_(record_fd_open_nameless)(tid, RES);
13103 break;
13105 * TODO: Is there a way to pass information between PRE and POST hooks?
13106 * To avoid querying again for the size of keys and values.
13108 case VKI_BPF_MAP_LOOKUP_ELEM:
13109 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13110 POST_MEM_WRITE(attr->value, value_size);
13111 break;
13112 case VKI_BPF_MAP_GET_NEXT_KEY:
13113 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13114 POST_MEM_WRITE(attr->next_key, key_size);
13115 break;
13116 case VKI_BPF_PROG_LOAD:
13117 /* Return a file descriptor for loaded program, write into log_buf. */
13118 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13119 VG_(close)(RES);
13120 SET_STATUS_Failure(VKI_EMFILE);
13121 } else {
13122 if (VG_(clo_track_fds))
13123 ML_(record_fd_open_nameless)(tid, RES);
13125 if (attr->log_level || attr->log_size || attr->log_buf)
13126 POST_MEM_WRITE(attr->log_buf, attr->log_size);
13127 break;
13128 case VKI_BPF_PROG_TEST_RUN:
13129 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
13130 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13131 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
13132 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
13133 break;
13134 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13135 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
13136 break;
13137 case VKI_BPF_PROG_QUERY:
13138 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13139 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13140 if (attr->query.prog_ids)
13141 POST_MEM_WRITE(attr->query.prog_ids,
13142 attr->query.prog_cnt * sizeof(__vki_u32));
13143 break;
13144 case VKI_BPF_BTF_LOAD:
13145 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13146 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13147 VG_(close)(RES);
13148 SET_STATUS_Failure(VKI_EMFILE);
13149 } else {
13150 if (VG_(clo_track_fds))
13151 ML_(record_fd_open_nameless)(tid, RES);
13153 if (attr->btf_log_level)
13154 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13155 break;
13156 case VKI_BPF_TASK_FD_QUERY:
13157 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13158 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13159 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13160 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13161 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13162 break;
13163 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13164 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13165 POST_MEM_WRITE(attr->value, value_size);
13166 break;
13167 case VKI_BPF_MAP_FREEZE:
13168 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13169 break;
13170 default:
13171 VG_(message)(Vg_DebugMsg,
13172 "WARNING: unhandled eBPF command %lu\n", ARG1);
13173 break;
13177 PRE(sys_copy_file_range)
13179 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13180 ARG4, ARG5, ARG6);
13182 PRE_REG_READ6(vki_size_t, "copy_file_range",
13183 int, "fd_in",
13184 vki_loff_t *, "off_in",
13185 int, "fd_out",
13186 vki_loff_t *, "off_out",
13187 vki_size_t, "len",
13188 unsigned int, "flags");
13190 /* File descriptors are "specially" tracked by valgrind.
13191 valgrind itself uses some, so make sure someone didn't
13192 put in one of our own... */
13193 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13194 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13195 SET_STATUS_Failure( VKI_EBADF );
13196 } else {
13197 /* Now see if the offsets are defined. PRE_MEM_READ will
13198 double check it can dereference them. */
13199 if (ARG2 != 0)
13200 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13201 if (ARG4 != 0)
13202 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13206 PRE(sys_pkey_alloc)
13208 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13210 PRE_REG_READ2(long, "pkey_alloc",
13211 unsigned long, "flags",
13212 unsigned long, "access_rights");
13214 /* The kernel says: pkey_alloc() is always safe to call regardless of
13215 whether or not the operating system supports protection keys. It can be
13216 used in lieu of any other mechanism for detecting pkey support and will
13217 simply fail with the error ENOSPC if the operating system has no pkey
13218 support.
13220 So we simply always return ENOSPC to signal memory protection keys are
13221 not supported under valgrind, unless there are unknown flags, then we
13222 return EINVAL. */
13223 unsigned long pkey_flags = ARG1;
13224 if (pkey_flags != 0)
13225 SET_STATUS_Failure( VKI_EINVAL );
13226 else
13227 SET_STATUS_Failure( VKI_ENOSPC );
13230 PRE(sys_pkey_free)
13232 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13234 PRE_REG_READ1(long, "pkey_free",
13235 unsigned long, "pkey");
13237 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13238 always an error. */
13239 SET_STATUS_Failure( VKI_EINVAL );
13242 PRE(sys_pkey_mprotect)
13244 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13245 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13246 PRE_REG_READ4(long, "pkey_mprotect",
13247 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13248 unsigned long, pkey);
13250 Addr addr = ARG1;
13251 SizeT len = ARG2;
13252 Int prot = ARG3;
13253 Int pkey = ARG4;
13255 /* Since pkey_alloc () can never succeed, see above, any pkey is
13256 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13257 if (pkey != -1)
13258 SET_STATUS_Failure( VKI_EINVAL );
13259 else
13260 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13262 ARG1 = addr;
13263 ARG2 = len;
13264 ARG3 = prot;
13267 POST(sys_pkey_mprotect)
13269 Addr addr = ARG1;
13270 SizeT len = ARG2;
13271 Int prot = ARG3;
13273 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13276 PRE(sys_io_uring_setup)
13278 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13279 ARG1, ARG2);
13280 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13281 struct vki_io_uring_params *, p);
13282 if (ARG2)
13283 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13284 offsetof(struct vki_io_uring_params, sq_off));
13287 POST(sys_io_uring_setup)
13289 vg_assert(SUCCESS);
13290 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13291 VG_(close)(RES);
13292 SET_STATUS_Failure( VKI_EMFILE );
13293 } else {
13294 if (VG_(clo_track_fds))
13295 ML_(record_fd_open_nameless)(tid, RES);
13296 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13297 sizeof(struct vki_io_sqring_offsets) +
13298 sizeof(struct vki_io_cqring_offsets));
13302 PRE(sys_io_uring_enter)
13304 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13305 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13306 FMT_REGWORD "u )",
13307 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13308 PRE_REG_READ6(long, "io_uring_enter",
13309 unsigned int, fd, unsigned int, to_submit,
13310 unsigned int, min_complete, unsigned int, flags,
13311 const void *, sig, unsigned long, sigsz);
13312 if (ARG5)
13313 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13316 POST(sys_io_uring_enter)
13320 PRE(sys_io_uring_register)
13322 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13323 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13324 PRE_REG_READ4(long, "io_uring_register",
13325 unsigned int, fd, unsigned int, opcode,
13326 void *, arg, unsigned int, nr_args);
13327 switch (ARG2) {
13328 case VKI_IORING_REGISTER_BUFFERS:
13329 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13330 break;
13331 case VKI_IORING_UNREGISTER_BUFFERS:
13332 break;
13333 case VKI_IORING_REGISTER_FILES:
13334 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13335 break;
13336 case VKI_IORING_UNREGISTER_FILES:
13337 break;
13338 case VKI_IORING_REGISTER_EVENTFD:
13339 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13340 break;
13341 case VKI_IORING_UNREGISTER_EVENTFD:
13342 break;
13346 POST(sys_io_uring_register)
13350 PRE(sys_execveat)
13352 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13353 PRE_REG_READ5(vki_off_t, "execveat",
13354 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13355 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13357 #if !defined(__NR_execveat)
13358 SET_STATUS_Failure(VKI_ENOSYS);
13359 return;
13360 #endif
13362 const HChar *path = (const HChar*) ARG2;
13363 Addr arg_2 = ARG3;
13364 Addr arg_3 = ARG4;
13365 const HChar *buf;
13366 HChar *abs_path = NULL;
13367 Bool check_at_symlink = False;
13368 Bool check_pathptr = True;
13370 if (ML_(safe_to_deref) (path, 1)) {
13371 /* If pathname is absolute, we'll ignore dirfd
13372 * and just pass the pathname, try to determine
13373 * the absolute path otherwise. */
13374 if (path[0] != '/') {
13375 /* Check dirfd is a valid fd. */
13376 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13377 SET_STATUS_Failure( VKI_EBADF );
13378 return;
13380 /* If pathname is empty and AT_EMPTY_PATH is
13381 set then dirfd describes the whole path. */
13382 if (path[0] == '\0') {
13383 if (ARG5 & VKI_AT_EMPTY_PATH) {
13384 if (VG_(resolve_filename)(ARG1, &buf)) {
13385 path = buf;
13386 check_pathptr = False;
13390 else if (ARG1 == VKI_AT_FDCWD) {
13391 check_at_symlink = True;
13392 } else
13393 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13394 check_at_symlink = True;
13395 else if (VG_(resolve_filename)(ARG1, &buf)) {
13396 abs_path = VG_(malloc)("execveat",
13397 (VG_(strlen)(buf) + 1
13398 + VG_(strlen)(path) + 1));
13399 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13400 path = abs_path;
13401 check_pathptr = False;
13403 else
13404 path = NULL;
13405 if (check_at_symlink) {
13406 struct vg_stat statbuf;
13407 SysRes statres;
13409 statres = VG_(stat)(path, &statbuf);
13410 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13411 SET_STATUS_Failure( VKI_ELOOP );
13412 return;
13416 } else {
13417 SET_STATUS_Failure(VKI_EFAULT);
13418 return;
13421 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, EXECVEAT,
13422 check_pathptr);
13424 /* The exec failed, we keep running... cleanup. */
13425 VG_(free)(abs_path);
13430 PRE(sys_close_range)
13432 SysRes res = VG_(mk_SysRes_Success)(0);
13433 unsigned int beg, end;
13434 unsigned int last = ARG2;
13436 FUSE_COMPATIBLE_MAY_BLOCK();
13437 PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
13438 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
13439 PRE_REG_READ3(long, "close_range",
13440 unsigned int, first, unsigned int, last,
13441 unsigned int, flags);
13443 if (ARG1 > last) {
13444 SET_STATUS_Failure( VKI_EINVAL );
13445 return;
13448 if (last >= VG_(fd_hard_limit))
13449 last = VG_(fd_hard_limit) - 1;
13451 if (ARG1 > last) {
13452 SET_STATUS_Success ( 0 );
13453 return;
13456 beg = end = ARG1;
13457 do {
13458 if (end > last
13459 || (end == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
13460 || end == VG_(log_output_sink).fd
13461 || end == VG_(xml_output_sink).fd) {
13462 /* Split the range if it contains a file descriptor we're not
13463 * supposed to close. */
13464 if (end - 1 >= beg)
13465 res = VG_(do_syscall3)(__NR_close_range, (UWord)beg, (UWord)end - 1, ARG3 );
13466 beg = end + 1;
13468 } while (end++ <= last);
13470 /* If it failed along the way, it's presumably the flags being wrong. */
13471 SET_STATUS_from_SysRes (res);
13474 POST(sys_close_range)
13476 unsigned int fd;
13477 unsigned int last = ARG2;
13479 if (!VG_(clo_track_fds)
13480 || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
13481 return;
13483 if (last >= VG_(fd_hard_limit))
13484 last = VG_(fd_hard_limit) - 1;
13486 for (fd = ARG1; fd <= last; fd++)
13487 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
13488 && fd != VG_(log_output_sink).fd
13489 && fd != VG_(xml_output_sink).fd)
13490 ML_(record_fd_close)(fd);
13494 #define VKI_O_DIRECTORY 00200000
13495 #define VKI___O_TMPFILE 020000000
13496 #define VKI_O_TMPFILE (VKI___O_TMPFILE | VKI_O_DIRECTORY)
13498 // long syscall(SYS_openat2, int dirfd, const char *pathname,
13499 // struct open_how *how, size_t size);
13500 PRE(sys_openat2)
13502 HChar name[30]; // large enough
13503 SysRes sres;
13504 struct vki_open_how * how;
13506 PRINT("sys_openat2 ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %ld )",
13507 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, SARG4);
13508 PRE_REG_READ4(long, "openat2",
13509 int, dfd, const char *, filename, struct vki_open_how *, how, vki_size_t, size);
13511 PRE_MEM_RASCIIZ( "openat2(filename)", ARG2 );
13512 PRE_MEM_READ( "openat2(how)", ARG3, sizeof(struct vki_open_how));
13514 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
13515 filename is relative to cwd. When comparing dfd against AT_FDCWD,
13516 be sure only to compare the bottom 32 bits. */
13517 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13518 && *(Char *)(Addr)ARG2 != '/'
13519 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13520 && !ML_(fd_allowed)(ARG1, "openat2", tid, False))
13521 SET_STATUS_Failure( VKI_EBADF );
13523 how = (struct vki_open_how *)ARG3;
13525 if (how && ML_(safe_to_deref) (how, sizeof(struct vki_open_how))) {
13526 if (how->vki_mode) {
13527 if (!(how->vki_flags & ((vki_uint64_t)VKI_O_CREAT | VKI_O_TMPFILE))) {
13528 SET_STATUS_Failure( VKI_EINVAL );
13531 if (how->vki_resolve & ~((vki_uint64_t)VKI_RESOLVE_NO_XDEV |
13532 VKI_RESOLVE_NO_MAGICLINKS |
13533 VKI_RESOLVE_NO_SYMLINKS |
13534 VKI_RESOLVE_BENEATH |
13535 VKI_RESOLVE_IN_ROOT |
13536 VKI_RESOLVE_CACHED)) {
13537 SET_STATUS_Failure( VKI_EINVAL );
13541 /* Handle the case where the open is of /proc/self/cmdline or
13542 /proc/<pid>/cmdline, and just give it a copy of the fd for the
13543 fake file we cooked up at startup (in m_main). Also, seek the
13544 cloned fd back to the start. */
13546 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
13547 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13548 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13549 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
13550 sres = VG_(dup)( VG_(cl_cmdline_fd) );
13551 SET_STATUS_from_SysRes( sres );
13552 if (!sr_isError(sres)) {
13553 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13554 if (off < 0)
13555 SET_STATUS_Failure( VKI_EMFILE );
13557 return;
13560 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
13562 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
13563 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13564 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13565 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
13566 sres = VG_(dup)( VG_(cl_auxv_fd) );
13567 SET_STATUS_from_SysRes( sres );
13568 if (!sr_isError(sres)) {
13569 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13570 if (off < 0)
13571 SET_STATUS_Failure( VKI_EMFILE );
13573 return;
13576 /* And for /proc/self/exe or /proc/<pid>/exe case. */
13578 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
13579 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13580 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13581 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
13582 sres = VG_(dup)( VG_(cl_exec_fd) );
13583 SET_STATUS_from_SysRes( sres );
13584 if (!sr_isError(sres)) {
13585 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13586 if (off < 0)
13587 SET_STATUS_Failure( VKI_EMFILE );
13589 return;
13592 /* Otherwise handle normally */
13593 *flags |= SfMayBlock;
13596 POST(sys_openat2)
13598 vg_assert(SUCCESS);
13599 if (!ML_(fd_allowed)(RES, "openat2", tid, True)) {
13600 VG_(close)(RES);
13601 SET_STATUS_Failure( VKI_EMFILE );
13602 } else {
13603 if (VG_(clo_track_fds))
13604 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
13608 PRE(sys_pidfd_open)
13610 PRINT("sys_pidfd_open ( %ld, %lu )", SARG1, ARG2);
13613 POST(sys_pidfd_open)
13615 if (!ML_(fd_allowed)(RES, "pidfd", tid, True)) {
13616 VG_(close)(RES);
13617 SET_STATUS_Failure( VKI_EMFILE );
13618 } else {
13619 if (VG_(clo_track_fds))
13620 ML_(record_fd_open_nameless) (tid, RES);
13624 #undef PRE
13625 #undef POST
13627 #endif // defined(VGO_linux)
13629 /*--------------------------------------------------------------------*/
13630 /*--- end ---*/
13631 /*--------------------------------------------------------------------*/