syswrap openat2 for all linux arches
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob18286c488446b846b31a57a4e4a43389dd695322
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 if (ufds[i].fd >= 0) {
1988 PRE_MEM_READ( "ppoll(ufds.events)",
1989 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1991 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1992 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1995 if (ARG3) {
1996 if (is_time64) {
1997 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
1998 } else {
1999 PRE_MEM_READ( "ppoll(tsp)", ARG3,
2000 sizeof(struct vki_timespec) );
2003 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
2004 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
2005 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
2006 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
2007 ARG4 = 1; /* Something recognisable to POST() hook. */
2008 } else {
2009 vki_sigset_t *vg_sigmask =
2010 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
2011 ARG4 = (Addr)vg_sigmask;
2012 *vg_sigmask = *guest_sigmask;
2013 VG_(sanitize_client_sigmask)(vg_sigmask);
2018 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2019 SyscallStatus* status )
2021 vg_assert(SUCCESS || FAILURE);
2022 if (SUCCESS && (RES >= 0)) {
2023 UInt i;
2024 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2025 for (i = 0; i < ARG2; i++)
2026 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2028 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
2029 VG_(free)((vki_sigset_t *) (Addr)ARG4);
2033 PRE(sys_ppoll)
2035 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2036 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2037 ARG1, ARG2, ARG3, ARG4, ARG5);
2038 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2041 POST(sys_ppoll)
2043 ppoll_post_helper (tid, arrghs, status);
2046 PRE(sys_ppoll_time64)
2048 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2049 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2050 ARG1, ARG2, ARG3, ARG4, ARG5);
2051 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2054 POST(sys_ppoll_time64)
2056 ppoll_post_helper (tid, arrghs, status);
2060 /* ---------------------------------------------------------------------
2061 epoll_* wrappers
2062 ------------------------------------------------------------------ */
2064 PRE(sys_epoll_create)
2066 PRINT("sys_epoll_create ( %ld )", SARG1);
2067 PRE_REG_READ1(long, "epoll_create", int, size);
2069 POST(sys_epoll_create)
2071 vg_assert(SUCCESS);
2072 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2073 VG_(close)(RES);
2074 SET_STATUS_Failure( VKI_EMFILE );
2075 } else {
2076 if (VG_(clo_track_fds))
2077 ML_(record_fd_open_nameless) (tid, RES);
2081 PRE(sys_epoll_create1)
2083 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2084 PRE_REG_READ1(long, "epoll_create1", int, flags);
2086 POST(sys_epoll_create1)
2088 vg_assert(SUCCESS);
2089 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2090 VG_(close)(RES);
2091 SET_STATUS_Failure( VKI_EMFILE );
2092 } else {
2093 if (VG_(clo_track_fds))
2094 ML_(record_fd_open_nameless) (tid, RES);
2098 PRE(sys_epoll_ctl)
2100 static const HChar* epoll_ctl_s[3] = {
2101 "EPOLL_CTL_ADD",
2102 "EPOLL_CTL_DEL",
2103 "EPOLL_CTL_MOD"
2105 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2106 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2107 PRE_REG_READ4(long, "epoll_ctl",
2108 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2109 if (ARG2 != VKI_EPOLL_CTL_DEL) {
2110 /* Just check the events field, the data field is for user space and
2111 unused by the kernel. */
2112 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2113 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2114 sizeof(__vki_u32) );
2118 /* RES event records have been written (exclude padding). */
2119 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2120 SyscallStatus* status )
2122 vg_assert(SUCCESS);
2123 if (RES > 0) {
2124 Int i;
2125 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2126 for (i = 0; i < RES; i++) {
2127 /* Assume both events and data are set (data is user space only). */
2128 POST_FIELD_WRITE(events[i].events);
2129 POST_FIELD_WRITE(events[i].data);
2134 PRE(sys_epoll_wait)
2136 *flags |= SfMayBlock;
2137 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2138 SARG1, ARG2, SARG3, SARG4);
2139 PRE_REG_READ4(long, "epoll_wait",
2140 int, epfd, struct vki_epoll_event *, events,
2141 int, maxevents, int, timeout);
2142 /* Assume all (maxevents) events records should be (fully) writable. */
2143 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2145 POST(sys_epoll_wait)
2147 epoll_post_helper (tid, arrghs, status);
2150 PRE(sys_epoll_pwait)
2152 *flags |= SfMayBlock;
2153 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2154 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2155 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2156 PRE_REG_READ6(long, "epoll_pwait",
2157 int, epfd, struct vki_epoll_event *, events,
2158 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2159 vki_size_t, sigsetsize);
2160 /* Assume all (maxevents) events records should be (fully) writable. */
2161 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2162 if (ARG5)
2163 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2165 POST(sys_epoll_pwait)
2167 epoll_post_helper (tid, arrghs, status);
2170 PRE(sys_epoll_pwait2)
2172 *flags |= SfMayBlock;
2173 PRINT("sys_epoll_pwait2 ( %ld, %#" FMT_REGWORD "x, %ld, %#"
2174 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2175 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
2176 PRE_REG_READ6(long, "epoll_pwait2",
2177 int, epfd, struct vki_epoll_event *, events,
2178 int, maxevents, const struct timespec64 *, timeout,
2179 vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
2180 /* Assume all (maxevents) events records should be (fully) writable. */
2181 PRE_MEM_WRITE( "epoll_pwait2(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2182 /* epoll_pwait2 only supports 64bit timespec. */
2183 if (ARG4)
2184 pre_read_timespec64(tid, "epoll_pwait2(timeout)", ARG4);
2185 if (ARG5)
2186 PRE_MEM_READ( "epoll_pwait2(sigmask)", ARG5, sizeof(vki_sigset_t) );
2188 POST(sys_epoll_pwait2)
2190 epoll_post_helper (tid, arrghs, status);
2193 PRE(sys_eventfd)
2195 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2196 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2198 POST(sys_eventfd)
2200 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2201 VG_(close)(RES);
2202 SET_STATUS_Failure( VKI_EMFILE );
2203 } else {
2204 if (VG_(clo_track_fds))
2205 ML_(record_fd_open_nameless) (tid, RES);
2209 PRE(sys_eventfd2)
2211 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2212 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2214 POST(sys_eventfd2)
2216 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2217 VG_(close)(RES);
2218 SET_STATUS_Failure( VKI_EMFILE );
2219 } else {
2220 if (VG_(clo_track_fds))
2221 ML_(record_fd_open_nameless) (tid, RES);
2225 PRE(sys_fallocate)
2227 *flags |= SfMayBlock;
2228 #if VG_WORDSIZE == 4
2229 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2230 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2231 PRE_REG_READ6(long, "fallocate",
2232 int, fd, int, mode,
2233 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2234 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2235 #elif VG_WORDSIZE == 8
2236 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2237 SARG1, SARG2, SARG3, SARG4);
2238 PRE_REG_READ4(long, "fallocate",
2239 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2240 #else
2241 # error Unexpected word size
2242 #endif
2243 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2244 SET_STATUS_Failure( VKI_EBADF );
2247 PRE(sys_prlimit64)
2249 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2250 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2251 PRE_REG_READ4(long, "prlimit64",
2252 vki_pid_t, pid, unsigned int, resource,
2253 const struct rlimit64 *, new_rlim,
2254 struct rlimit64 *, old_rlim);
2255 if (ARG3)
2256 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2257 if (ARG4)
2258 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2260 if (ARG3 &&
2261 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2262 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2263 SET_STATUS_Failure( VKI_EINVAL );
2265 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2266 switch (ARG2) {
2267 case VKI_RLIMIT_NOFILE:
2268 SET_STATUS_Success( 0 );
2269 if (ARG4) {
2270 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2271 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2273 if (ARG3) {
2274 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2275 > VG_(fd_hard_limit) ||
2276 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2277 != VG_(fd_hard_limit)) {
2278 SET_STATUS_Failure( VKI_EPERM );
2280 else {
2281 VG_(fd_soft_limit) =
2282 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2285 break;
2287 case VKI_RLIMIT_DATA:
2288 SET_STATUS_Success( 0 );
2289 if (ARG4) {
2290 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2291 VG_(client_rlimit_data).rlim_cur;
2292 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2293 VG_(client_rlimit_data).rlim_max;
2295 if (ARG3) {
2296 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2297 > VG_(client_rlimit_data).rlim_max ||
2298 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2299 > VG_(client_rlimit_data).rlim_max) {
2300 SET_STATUS_Failure( VKI_EPERM );
2302 else {
2303 VG_(client_rlimit_data).rlim_cur =
2304 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2305 VG_(client_rlimit_data).rlim_max =
2306 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2309 break;
2311 case VKI_RLIMIT_STACK:
2312 SET_STATUS_Success( 0 );
2313 if (ARG4) {
2314 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2315 VG_(client_rlimit_stack).rlim_cur;
2316 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2317 VG_(client_rlimit_stack).rlim_max;
2319 if (ARG3) {
2320 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2321 > VG_(client_rlimit_stack).rlim_max ||
2322 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2323 > VG_(client_rlimit_stack).rlim_max) {
2324 SET_STATUS_Failure( VKI_EPERM );
2326 else {
2327 VG_(threads)[tid].client_stack_szB =
2328 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2329 VG_(client_rlimit_stack).rlim_cur =
2330 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2331 VG_(client_rlimit_stack).rlim_max =
2332 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2335 break;
2340 POST(sys_prlimit64)
2342 if (ARG4)
2343 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2346 /* ---------------------------------------------------------------------
2347 tid-related wrappers
2348 ------------------------------------------------------------------ */
2350 PRE(sys_gettid)
2352 PRINT("sys_gettid ()");
2353 PRE_REG_READ0(long, "gettid");
2356 PRE(sys_set_tid_address)
2358 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2359 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2362 PRE(sys_tkill)
2364 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2365 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2366 if (!ML_(client_signal_OK)(ARG2)) {
2367 SET_STATUS_Failure( VKI_EINVAL );
2368 return;
2371 /* Check to see if this kill gave us a pending signal */
2372 *flags |= SfPollAfter;
2374 if (VG_(clo_trace_signals))
2375 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2376 SARG2, SARG1);
2378 /* If we're sending SIGKILL, check to see if the target is one of
2379 our threads and handle it specially. */
2380 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2381 SET_STATUS_Success(0);
2382 return;
2385 /* Ask to handle this syscall via the slow route, since that's the
2386 only one that sets tst->status to VgTs_WaitSys. If the result
2387 of doing the syscall is an immediate run of
2388 async_signalhandler() in m_signals, then we need the thread to
2389 be properly tidied away. I have the impression the previous
2390 version of this wrapper worked on x86/amd64 only because the
2391 kernel did not immediately deliver the async signal to this
2392 thread (on ppc it did, which broke the assertion re tst->status
2393 at the top of async_signalhandler()). */
2394 *flags |= SfMayBlock;
2396 POST(sys_tkill)
2398 if (VG_(clo_trace_signals))
2399 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2400 SARG2, SARG1);
2403 PRE(sys_tgkill)
2405 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2406 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2407 if (!ML_(client_signal_OK)(ARG3)) {
2408 SET_STATUS_Failure( VKI_EINVAL );
2409 return;
2412 /* Check to see if this kill gave us a pending signal */
2413 *flags |= SfPollAfter;
2415 if (VG_(clo_trace_signals))
2416 VG_(message)(Vg_DebugMsg,
2417 "tgkill: sending signal %ld to pid %ld/%ld\n",
2418 SARG3, SARG1, SARG2);
2420 /* If we're sending SIGKILL, check to see if the target is one of
2421 our threads and handle it specially. */
2422 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2423 SET_STATUS_Success(0);
2424 return;
2427 /* Ask to handle this syscall via the slow route, since that's the
2428 only one that sets tst->status to VgTs_WaitSys. If the result
2429 of doing the syscall is an immediate run of
2430 async_signalhandler() in m_signals, then we need the thread to
2431 be properly tidied away. I have the impression the previous
2432 version of this wrapper worked on x86/amd64 only because the
2433 kernel did not immediately deliver the async signal to this
2434 thread (on ppc it did, which broke the assertion re tst->status
2435 at the top of async_signalhandler()). */
2436 *flags |= SfMayBlock;
2438 POST(sys_tgkill)
2440 if (VG_(clo_trace_signals))
2441 VG_(message)(Vg_DebugMsg,
2442 "tgkill: sent signal %ld to pid %ld/%ld\n",
2443 SARG3, SARG1, SARG2);
2446 /* ---------------------------------------------------------------------
2447 fadvise64* wrappers
2448 ------------------------------------------------------------------ */
2450 PRE(sys_fadvise64)
2452 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2453 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2454 PRE_REG_READ5(long, "fadvise64",
2455 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2456 vki_size_t, len, int, advice);
2459 PRE(sys_fadvise64_64)
2461 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2462 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2463 PRE_REG_READ6(long, "fadvise64_64",
2464 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2465 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2468 /* ---------------------------------------------------------------------
2469 io_* wrappers
2470 ------------------------------------------------------------------ */
2472 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2473 // and this allows us to control exactly the code that gets run while
2474 // the padding is in place.
2476 PRE(sys_io_setup)
2478 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2479 PRE_REG_READ2(long, "io_setup",
2480 unsigned, nr_events, vki_aio_context_t *, ctxp);
2481 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2484 POST(sys_io_setup)
2486 SizeT size;
2487 struct vki_aio_ring *r;
2489 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2490 ARG1*sizeof(struct vki_io_event));
2491 r = *(struct vki_aio_ring **)(Addr)ARG2;
2492 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2494 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2495 VKI_PROT_READ | VKI_PROT_WRITE,
2496 VKI_MAP_ANONYMOUS, -1, 0 );
2498 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2501 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2502 // after the syscall. We must get 'size' from the aio_ring structure,
2503 // before the syscall, while the aio_ring structure still exists. (And we
2504 // know that we must look at the aio_ring structure because Tom inspected the
2505 // kernel and glibc sources to see what they do, yuk.)
2507 // XXX This segment can be implicitly unmapped when aio
2508 // file-descriptors are closed...
2509 PRE(sys_io_destroy)
2511 SizeT size = 0;
2513 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2514 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2516 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2517 // possible...
2518 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2519 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2520 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2521 r->nr*sizeof(struct vki_io_event));
2524 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2526 if (SUCCESS && RES == 0) {
2527 Bool d = VG_(am_notify_munmap)( ARG1, size );
2528 VG_TRACK( die_mem_munmap, ARG1, size );
2529 if (d)
2530 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2531 "PRE(sys_io_destroy)" );
2535 PRE(sys_io_getevents)
2537 *flags |= SfMayBlock;
2538 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2539 FMT_REGWORD "x )",
2540 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2541 PRE_REG_READ5(long, "io_getevents",
2542 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2543 struct io_event *, events,
2544 struct timespec *, timeout);
2545 if (ARG3 > 0)
2546 PRE_MEM_WRITE( "io_getevents(events)",
2547 ARG4, sizeof(struct vki_io_event)*ARG3 );
2548 if (ARG5 != 0)
2549 PRE_MEM_READ( "io_getevents(timeout)",
2550 ARG5, sizeof(struct vki_timespec));
2552 POST(sys_io_getevents)
2554 Int i;
2555 vg_assert(SUCCESS);
2556 if (RES > 0) {
2557 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2558 for (i = 0; i < RES; i++) {
2559 const struct vki_io_event *vev =
2560 ((struct vki_io_event *)(Addr)ARG4) + i;
2561 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2563 switch (cb->aio_lio_opcode) {
2564 case VKI_IOCB_CMD_PREAD:
2565 if (vev->result > 0)
2566 POST_MEM_WRITE( cb->aio_buf, vev->result );
2567 break;
2569 case VKI_IOCB_CMD_PWRITE:
2570 break;
2572 case VKI_IOCB_CMD_FSYNC:
2573 break;
2575 case VKI_IOCB_CMD_FDSYNC:
2576 break;
2578 case VKI_IOCB_CMD_PREADV:
2579 if (vev->result > 0) {
2580 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2581 Int remains = vev->result;
2582 Int j;
2584 for (j = 0; j < cb->aio_nbytes; j++) {
2585 Int nReadThisBuf = vec[j].iov_len;
2586 if (nReadThisBuf > remains) nReadThisBuf = remains;
2587 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2588 remains -= nReadThisBuf;
2589 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2592 break;
2594 case VKI_IOCB_CMD_PWRITEV:
2595 break;
2597 default:
2598 VG_(message)(Vg_DebugMsg,
2599 "Warning: unhandled io_getevents opcode: %u\n",
2600 cb->aio_lio_opcode);
2601 break;
2607 PRE(sys_io_submit)
2609 Int i, j;
2611 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2612 ARG1, SARG2, ARG3);
2613 PRE_REG_READ3(long, "io_submit",
2614 vki_aio_context_t, ctx_id, long, nr,
2615 struct iocb **, iocbpp);
2616 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2617 if (ARG3 != 0) {
2618 for (i = 0; i < ARG2; i++) {
2619 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2620 struct vki_iovec *iov;
2622 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2623 switch (cb->aio_lio_opcode) {
2624 case VKI_IOCB_CMD_PREAD:
2625 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2626 break;
2628 case VKI_IOCB_CMD_PWRITE:
2629 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2630 break;
2632 case VKI_IOCB_CMD_FSYNC:
2633 break;
2635 case VKI_IOCB_CMD_FDSYNC:
2636 break;
2638 case VKI_IOCB_CMD_PREADV:
2639 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2640 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2641 for (j = 0; j < cb->aio_nbytes; j++)
2642 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2643 break;
2645 case VKI_IOCB_CMD_PWRITEV:
2646 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2647 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2648 for (j = 0; j < cb->aio_nbytes; j++)
2649 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2650 break;
2652 default:
2653 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2654 cb->aio_lio_opcode);
2655 break;
2661 PRE(sys_io_cancel)
2663 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2664 (ULong)ARG1, ARG2, ARG3);
2665 PRE_REG_READ3(long, "io_cancel",
2666 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2667 struct io_event *, result);
2668 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2669 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2671 POST(sys_io_cancel)
2673 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2676 /* ---------------------------------------------------------------------
2677 *_mempolicy wrappers
2678 ------------------------------------------------------------------ */
2680 PRE(sys_mbind)
2682 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2683 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2684 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2685 PRE_REG_READ6(long, "mbind",
2686 unsigned long, start, unsigned long, len,
2687 unsigned long, policy, unsigned long *, nodemask,
2688 unsigned long, maxnode, unsigned, flags);
2689 if (ARG1 != 0)
2690 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2691 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2694 PRE(sys_set_mempolicy)
2696 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2697 SARG1, ARG2, ARG3);
2698 PRE_REG_READ3(long, "set_mempolicy",
2699 int, policy, unsigned long *, nodemask,
2700 unsigned long, maxnode);
2701 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2702 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2705 PRE(sys_get_mempolicy)
2707 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2708 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2709 ARG1, ARG2, ARG3, ARG4, ARG5);
2710 PRE_REG_READ5(long, "get_mempolicy",
2711 int *, policy, unsigned long *, nodemask,
2712 unsigned long, maxnode, unsigned long, addr,
2713 unsigned long, flags);
2714 if (ARG1 != 0)
2715 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2716 if (ARG2 != 0)
2717 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2718 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2720 POST(sys_get_mempolicy)
2722 if (ARG1 != 0)
2723 POST_MEM_WRITE( ARG1, sizeof(Int) );
2724 if (ARG2 != 0)
2725 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2728 /* ---------------------------------------------------------------------
2729 fanotify_* wrappers
2730 ------------------------------------------------------------------ */
2732 PRE(sys_fanotify_init)
2734 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2735 ARG1, ARG2);
2736 PRE_REG_READ2(long, "fanotify_init",
2737 unsigned int, flags, unsigned int, event_f_flags);
2740 POST(sys_fanotify_init)
2742 vg_assert(SUCCESS);
2743 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2744 VG_(close)(RES);
2745 SET_STATUS_Failure( VKI_EMFILE );
2746 } else {
2747 if (VG_(clo_track_fds))
2748 ML_(record_fd_open_nameless) (tid, RES);
2752 PRE(sys_fanotify_mark)
2754 #if VG_WORDSIZE == 4
2755 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2756 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2757 (HChar *)(Addr)ARG6);
2758 PRE_REG_READ6(long, "sys_fanotify_mark",
2759 int, fanotify_fd, unsigned int, flags,
2760 __vki_u32, mask0, __vki_u32, mask1,
2761 int, dfd, const char *, pathname);
2762 if (ARG6)
2763 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2764 #elif VG_WORDSIZE == 8
2765 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2766 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2767 PRE_REG_READ5(long, "sys_fanotify_mark",
2768 int, fanotify_fd, unsigned int, flags,
2769 __vki_u64, mask,
2770 int, dfd, const char *, pathname);
2771 if (ARG5)
2772 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2773 #else
2774 # error Unexpected word size
2775 #endif
2778 /* ---------------------------------------------------------------------
2779 inotify_* wrappers
2780 ------------------------------------------------------------------ */
2782 PRE(sys_inotify_init)
2784 PRINT("sys_inotify_init ( )");
2785 PRE_REG_READ0(long, "inotify_init");
2787 POST(sys_inotify_init)
2789 vg_assert(SUCCESS);
2790 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2791 VG_(close)(RES);
2792 SET_STATUS_Failure( VKI_EMFILE );
2793 } else {
2794 if (VG_(clo_track_fds))
2795 ML_(record_fd_open_nameless) (tid, RES);
2799 PRE(sys_inotify_init1)
2801 PRINT("sys_inotify_init ( %ld )", SARG1);
2802 PRE_REG_READ1(long, "inotify_init", int, flag);
2805 POST(sys_inotify_init1)
2807 vg_assert(SUCCESS);
2808 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2809 VG_(close)(RES);
2810 SET_STATUS_Failure( VKI_EMFILE );
2811 } else {
2812 if (VG_(clo_track_fds))
2813 ML_(record_fd_open_nameless) (tid, RES);
2817 PRE(sys_inotify_add_watch)
2819 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2820 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2821 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2822 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2825 PRE(sys_inotify_rm_watch)
2827 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2828 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2831 /* ---------------------------------------------------------------------
2832 mq_* wrappers
2833 ------------------------------------------------------------------ */
2835 PRE(sys_mq_open)
2837 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2838 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2839 PRE_REG_READ4(long, "mq_open",
2840 const char *, name, int, oflag, vki_mode_t, mode,
2841 struct mq_attr *, attr);
2842 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2843 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2844 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2845 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2846 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2847 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2848 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2851 POST(sys_mq_open)
2853 vg_assert(SUCCESS);
2854 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2855 VG_(close)(RES);
2856 SET_STATUS_Failure( VKI_EMFILE );
2857 } else {
2858 if (VG_(clo_track_fds))
2859 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2863 PRE(sys_mq_unlink)
2865 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2866 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2867 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2870 PRE(sys_mq_timedsend)
2872 *flags |= SfMayBlock;
2873 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2874 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2875 SARG1,ARG2,ARG3,ARG4,ARG5);
2876 PRE_REG_READ5(long, "mq_timedsend",
2877 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2878 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2879 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2880 SET_STATUS_Failure( VKI_EBADF );
2881 } else {
2882 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2883 if (ARG5 != 0)
2884 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2885 sizeof(struct vki_timespec) );
2889 PRE(sys_mq_timedsend_time64)
2891 *flags |= SfMayBlock;
2892 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2893 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2894 SARG1,ARG2,ARG3,ARG4,ARG5);
2895 PRE_REG_READ5(long, "mq_timedsend_time64",
2896 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2897 unsigned int, msg_prio,
2898 const struct vki_timespec64 *, abs_timeout);
2899 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2900 SET_STATUS_Failure( VKI_EBADF );
2901 } else {
2902 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2903 if (ARG5 != 0)
2904 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2908 PRE(sys_mq_timedreceive)
2910 *flags |= SfMayBlock;
2911 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2912 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2913 SARG1,ARG2,ARG3,ARG4,ARG5);
2914 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2915 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2916 unsigned int *, msg_prio,
2917 const struct timespec *, abs_timeout);
2918 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2919 SET_STATUS_Failure( VKI_EBADF );
2920 } else {
2921 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2922 if (ARG4 != 0)
2923 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2924 ARG4, sizeof(unsigned int) );
2925 if (ARG5 != 0)
2926 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2927 ARG5, sizeof(struct vki_timespec) );
2930 POST(sys_mq_timedreceive)
2932 POST_MEM_WRITE( ARG2, RES );
2933 if (ARG4 != 0)
2934 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2937 PRE(sys_mq_timedreceive_time64)
2939 *flags |= SfMayBlock;
2940 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2941 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2942 SARG1,ARG2,ARG3,ARG4,ARG5);
2943 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2944 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2945 unsigned int *, msg_prio,
2946 const struct vki_timespec64 *, abs_timeout);
2947 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2948 SET_STATUS_Failure( VKI_EBADF );
2949 } else {
2950 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2951 if (ARG4 != 0)
2952 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2953 ARG4, sizeof(unsigned int) );
2954 if (ARG5 != 0)
2955 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2959 POST(sys_mq_timedreceive_time64)
2961 POST_MEM_WRITE( ARG2, RES );
2962 if (ARG4 != 0)
2963 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2966 PRE(sys_mq_notify)
2968 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2969 PRE_REG_READ2(long, "mq_notify",
2970 vki_mqd_t, mqdes, const struct sigevent *, notification);
2971 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2972 SET_STATUS_Failure( VKI_EBADF );
2973 else if (ARG2 != 0)
2974 PRE_MEM_READ( "mq_notify(notification)",
2975 ARG2, sizeof(struct vki_sigevent) );
2978 PRE(sys_mq_getsetattr)
2980 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2981 SARG1, ARG2, ARG3 );
2982 PRE_REG_READ3(long, "mq_getsetattr",
2983 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2984 struct mq_attr *, omqstat);
2985 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2986 SET_STATUS_Failure( VKI_EBADF );
2987 } else {
2988 if (ARG2 != 0) {
2989 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2990 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2991 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2993 if (ARG3 != 0)
2994 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2995 sizeof(struct vki_mq_attr) );
2998 POST(sys_mq_getsetattr)
3000 if (ARG3 != 0)
3001 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
3004 /* ---------------------------------------------------------------------
3005 clock_* wrappers
3006 ------------------------------------------------------------------ */
3008 PRE(sys_clock_settime)
3010 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3011 PRE_REG_READ2(long, "clock_settime",
3012 vki_clockid_t, clk_id, const struct timespec *, tp);
3013 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
3016 PRE(sys_clock_settime64)
3018 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3019 PRE_REG_READ2(long, "clock_settime64",
3020 vki_clockid_t, clk_id, const struct timespec64 *, tp);
3021 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
3024 PRE(sys_clock_gettime)
3026 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3027 PRE_REG_READ2(long, "clock_gettime",
3028 vki_clockid_t, clk_id, struct timespec *, tp);
3029 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3031 POST(sys_clock_gettime)
3033 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3036 PRE(sys_clock_gettime64)
3038 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3039 PRE_REG_READ2(long, "clock_gettime64",
3040 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3041 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3042 sizeof(struct vki_timespec64) );
3044 POST(sys_clock_gettime64)
3046 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3049 PRE(sys_clock_getres)
3051 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3052 // Nb: we can't use "RES" as the param name because that's a macro
3053 // defined above!
3054 PRE_REG_READ2(long, "clock_getres",
3055 vki_clockid_t, clk_id, struct timespec *, res);
3056 if (ARG2 != 0)
3057 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3059 POST(sys_clock_getres)
3061 if (ARG2 != 0)
3062 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3065 PRE(sys_clock_getres_time64)
3067 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3068 // Nb: we can't use "RES" as the param name because that's a macro
3069 // defined above!
3070 PRE_REG_READ2(long, "clock_getres_time64",
3071 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3072 if (ARG2 != 0)
3073 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3074 sizeof(struct vki_timespec64) );
3076 POST(sys_clock_getres_time64)
3078 if (ARG2 != 0)
3079 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3082 PRE(sys_clock_nanosleep)
3084 *flags |= SfMayBlock|SfPostOnFail;
3085 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3086 FMT_REGWORD "x )",
3087 SARG1, SARG2, ARG3, ARG4);
3088 PRE_REG_READ4(int32_t, "clock_nanosleep",
3089 vki_clockid_t, clkid, int, flags,
3090 const struct timespec *, rqtp, struct timespec *, rmtp);
3091 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3092 if (ARG4 != 0)
3093 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3095 POST(sys_clock_nanosleep)
3097 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3098 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3101 PRE(sys_clock_nanosleep_time64)
3103 *flags |= SfMayBlock|SfPostOnFail;
3104 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3105 FMT_REGWORD "x )",
3106 SARG1, SARG2, ARG3, ARG4);
3107 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3108 vki_clockid_t, clkid, int, flags,
3109 const struct vki_timespec64 *, rqtp,
3110 struct vki_timespec64 *, rmtp);
3111 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3112 if (ARG4 != 0)
3113 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3114 sizeof(struct vki_timespec64) );
3116 POST(sys_clock_nanosleep_time64)
3118 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3119 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3122 /* ---------------------------------------------------------------------
3123 timer_* wrappers
3124 ------------------------------------------------------------------ */
3126 PRE(sys_timer_create)
3128 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3129 SARG1, ARG2, ARG3);
3130 PRE_REG_READ3(long, "timer_create",
3131 vki_clockid_t, clockid, struct sigevent *, evp,
3132 vki_timer_t *, timerid);
3133 if (ARG2 != 0) {
3134 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3135 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3136 sizeof(vki_sigval_t) );
3137 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3138 sizeof(int) );
3139 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3140 sizeof(int) );
3141 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3142 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3143 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3144 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3146 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3148 POST(sys_timer_create)
3150 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3153 PRE(sys_timer_settime)
3155 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3156 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3157 PRE_REG_READ4(long, "timer_settime",
3158 vki_timer_t, timerid, int, flags,
3159 const struct itimerspec *, value,
3160 struct itimerspec *, ovalue);
3161 PRE_MEM_READ( "timer_settime(value)", ARG3,
3162 sizeof(struct vki_itimerspec) );
3163 if (ARG4 != 0)
3164 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3165 sizeof(struct vki_itimerspec) );
3167 POST(sys_timer_settime)
3169 if (ARG4 != 0)
3170 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3173 PRE(sys_timer_settime64)
3175 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3176 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3177 PRE_REG_READ4(long, "timer_settime64",
3178 vki_timer_t, timerid, int, flags,
3179 const struct vki_itimerspec64 *, value,
3180 struct vki_itimerspec64 *, ovalue);
3181 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3182 sizeof(struct vki_itimerspec64) );
3183 if (ARG4 != 0)
3184 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3185 sizeof(struct vki_itimerspec64) );
3187 POST(sys_timer_settime64)
3189 if (ARG4 != 0)
3190 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3193 PRE(sys_timer_gettime)
3195 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3196 PRE_REG_READ2(long, "timer_gettime",
3197 vki_timer_t, timerid, struct itimerspec *, value);
3198 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3199 sizeof(struct vki_itimerspec));
3201 POST(sys_timer_gettime)
3203 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3206 PRE(sys_timer_gettime64)
3208 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3209 PRE_REG_READ2(long, "timer_gettime64",
3210 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3211 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3212 sizeof(struct vki_itimerspec64));
3214 POST(sys_timer_gettime64)
3216 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3219 PRE(sys_timer_getoverrun)
3221 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3222 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3225 PRE(sys_timer_delete)
3227 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3228 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3231 /* ---------------------------------------------------------------------
3232 timerfd* wrappers
3233 See also http://lwn.net/Articles/260172/ for an overview.
3234 See also /usr/src/linux/fs/timerfd.c for the implementation.
3235 ------------------------------------------------------------------ */
3237 /* Returns True if running on 2.6.22, else False (or False if
3238 cannot be determined). */
3239 static Bool linux_kernel_2_6_22(void)
3241 static Int result = -1;
3242 Int fd, read;
3243 HChar release[64]; // large enough
3244 SysRes res;
3246 if (result == -1) {
3247 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3248 if (sr_isError(res))
3249 return False;
3250 fd = sr_Res(res);
3251 read = VG_(read)(fd, release, sizeof(release) - 1);
3252 if (read < 0)
3253 return False;
3254 release[read] = 0;
3255 VG_(close)(fd);
3256 //VG_(printf)("kernel release = %s\n", release);
3257 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3258 && ! VG_(isdigit)(release[6]);
3260 vg_assert(result == 0 || result == 1);
3261 return result == 1;
3264 PRE(sys_timerfd_create)
3266 if (linux_kernel_2_6_22()) {
3267 /* 2.6.22 kernel: timerfd system call. */
3268 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3269 PRE_REG_READ3(long, "sys_timerfd",
3270 int, fd, int, clockid, const struct itimerspec *, tmr);
3271 PRE_MEM_READ("timerfd(tmr)", ARG3,
3272 sizeof(struct vki_itimerspec) );
3273 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3274 SET_STATUS_Failure( VKI_EBADF );
3275 } else {
3276 /* 2.6.24 and later kernels: timerfd_create system call. */
3277 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3278 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3281 POST(sys_timerfd_create)
3283 if (linux_kernel_2_6_22())
3285 /* 2.6.22 kernel: timerfd system call. */
3286 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3287 VG_(close)(RES);
3288 SET_STATUS_Failure( VKI_EMFILE );
3289 } else {
3290 if (VG_(clo_track_fds))
3291 ML_(record_fd_open_nameless) (tid, RES);
3294 else
3296 /* 2.6.24 and later kernels: timerfd_create system call. */
3297 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3298 VG_(close)(RES);
3299 SET_STATUS_Failure( VKI_EMFILE );
3300 } else {
3301 if (VG_(clo_track_fds))
3302 ML_(record_fd_open_nameless) (tid, RES);
3307 PRE(sys_timerfd_gettime)
3309 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3310 PRE_REG_READ2(long, "timerfd_gettime",
3311 int, fd,
3312 struct vki_itimerspec*, curr_value);
3313 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3314 SET_STATUS_Failure(VKI_EBADF);
3315 else
3316 PRE_MEM_WRITE("timerfd_gettime(curr_value)",
3317 ARG2, sizeof(struct vki_itimerspec));
3319 POST(sys_timerfd_gettime)
3321 if (RES == 0)
3322 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3325 PRE(sys_timerfd_gettime64)
3327 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3328 PRE_REG_READ2(long, "timerfd_gettime64",
3329 int, ufd,
3330 struct vki_itimerspec64*, otmr);
3331 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3332 SET_STATUS_Failure(VKI_EBADF);
3333 else
3334 PRE_MEM_WRITE("timerfd_gettime64(result)",
3335 ARG2, sizeof(struct vki_itimerspec64));
3337 POST(sys_timerfd_gettime64)
3339 if (RES == 0)
3340 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3343 PRE(sys_timerfd_settime)
3345 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3346 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3347 PRE_REG_READ4(long, "timerfd_settime",
3348 int, fd,
3349 int, flags,
3350 const struct vki_itimerspec*, new_value,
3351 struct vki_itimerspec*, old_value);
3352 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3353 SET_STATUS_Failure(VKI_EBADF);
3354 else
3356 PRE_MEM_READ("timerfd_settime(new_value)",
3357 ARG3, sizeof(struct vki_itimerspec));
3358 if (ARG4)
3360 PRE_MEM_WRITE("timerfd_settime(old_value)",
3361 ARG4, sizeof(struct vki_itimerspec));
3365 POST(sys_timerfd_settime)
3367 if (RES == 0 && ARG4 != 0)
3368 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3371 PRE(sys_timerfd_settime64)
3373 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3374 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3375 PRE_REG_READ4(long, "timerfd_settime64",
3376 int, ufd,
3377 int, flags,
3378 const struct vki_itimerspec64*, utmr,
3379 struct vki_itimerspec64*, otmr);
3380 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3381 SET_STATUS_Failure(VKI_EBADF);
3382 else
3384 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3385 if (ARG4)
3387 PRE_MEM_WRITE("timerfd_settime64(result)",
3388 ARG4, sizeof(struct vki_itimerspec64));
3392 POST(sys_timerfd_settime64)
3394 if (RES == 0 && ARG4 != 0)
3395 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3398 /* ---------------------------------------------------------------------
3399 capabilities wrappers
3400 ------------------------------------------------------------------ */
3402 PRE(sys_capget)
3404 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3405 PRE_REG_READ2(long, "capget",
3406 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3407 PRE_MEM_READ( "capget(header)", ARG1,
3408 sizeof(struct __vki_user_cap_header_struct) );
3409 if (ARG2 != (Addr)NULL)
3410 PRE_MEM_WRITE( "capget(data)", ARG2,
3411 sizeof(struct __vki_user_cap_data_struct) );
3413 POST(sys_capget)
3415 if (ARG2 != (Addr)NULL)
3416 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3419 PRE(sys_capset)
3421 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3422 PRE_REG_READ2(long, "capset",
3423 vki_cap_user_header_t, header,
3424 const vki_cap_user_data_t, data);
3425 PRE_MEM_READ( "capset(header)",
3426 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3427 PRE_MEM_READ( "capset(data)",
3428 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3431 /* ---------------------------------------------------------------------
3432 16-bit uid/gid/groups wrappers
3433 ------------------------------------------------------------------ */
3435 PRE(sys_getuid16)
3437 PRINT("sys_getuid16 ( )");
3438 PRE_REG_READ0(long, "getuid16");
3441 PRE(sys_setuid16)
3443 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3444 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3447 PRE(sys_getgid16)
3449 PRINT("sys_getgid16 ( )");
3450 PRE_REG_READ0(long, "getgid16");
3453 PRE(sys_setgid16)
3455 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3456 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3459 PRE(sys_geteuid16)
3461 PRINT("sys_geteuid16 ( )");
3462 PRE_REG_READ0(long, "geteuid16");
3465 PRE(sys_getegid16)
3467 PRINT("sys_getegid16 ( )");
3468 PRE_REG_READ0(long, "getegid16");
3471 PRE(sys_setreuid16)
3473 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3474 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3477 PRE(sys_setregid16)
3479 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3480 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3483 PRE(sys_getgroups16)
3485 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3486 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3487 if (ARG1 > 0)
3488 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3490 POST(sys_getgroups16)
3492 vg_assert(SUCCESS);
3493 if (ARG1 > 0 && RES > 0)
3494 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3497 PRE(sys_setgroups16)
3499 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3500 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3501 if (ARG1 > 0)
3502 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3505 /* ---------------------------------------------------------------------
3506 *chown16 wrappers
3507 ------------------------------------------------------------------ */
3509 PRE(sys_chown16)
3511 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3512 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3513 PRE_REG_READ3(long, "chown16",
3514 const char *, path,
3515 vki_old_uid_t, owner, vki_old_gid_t, group);
3516 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3519 PRE(sys_fchown16)
3521 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3522 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3523 PRE_REG_READ3(long, "fchown16",
3524 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3527 /* ---------------------------------------------------------------------
3528 *xattr wrappers
3529 ------------------------------------------------------------------ */
3531 PRE(sys_setxattr)
3533 *flags |= SfMayBlock;
3534 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3535 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3536 ARG4, SARG5);
3537 PRE_REG_READ5(long, "setxattr",
3538 char *, path, char *, name,
3539 void *, value, vki_size_t, size, int, flags);
3540 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3541 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3542 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3545 PRE(sys_lsetxattr)
3547 *flags |= SfMayBlock;
3548 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3549 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3550 ARG1, ARG2, ARG3, ARG4, SARG5);
3551 PRE_REG_READ5(long, "lsetxattr",
3552 char *, path, char *, name,
3553 void *, value, vki_size_t, size, int, flags);
3554 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3555 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3556 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3559 PRE(sys_fsetxattr)
3561 *flags |= SfMayBlock;
3562 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3563 FMT_REGWORD "u, %ld )",
3564 SARG1, ARG2, ARG3, ARG4, SARG5);
3565 PRE_REG_READ5(long, "fsetxattr",
3566 int, fd, char *, name, void *, value,
3567 vki_size_t, size, int, flags);
3568 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3569 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3572 PRE(sys_getxattr)
3574 *flags |= SfMayBlock;
3575 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3576 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3577 PRE_REG_READ4(ssize_t, "getxattr",
3578 char *, path, char *, name, void *, value, vki_size_t, size);
3579 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3580 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3581 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3583 POST(sys_getxattr)
3585 vg_assert(SUCCESS);
3586 if (RES > 0 && ARG3 != (Addr)NULL) {
3587 POST_MEM_WRITE( ARG3, RES );
3591 PRE(sys_lgetxattr)
3593 *flags |= SfMayBlock;
3594 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3595 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3596 PRE_REG_READ4(ssize_t, "lgetxattr",
3597 char *, path, char *, name, void *, value, vki_size_t, size);
3598 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3599 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3600 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3602 POST(sys_lgetxattr)
3604 vg_assert(SUCCESS);
3605 if (RES > 0 && ARG3 != (Addr)NULL) {
3606 POST_MEM_WRITE( ARG3, RES );
3610 PRE(sys_fgetxattr)
3612 *flags |= SfMayBlock;
3613 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3614 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3615 PRE_REG_READ4(ssize_t, "fgetxattr",
3616 int, fd, char *, name, void *, value, vki_size_t, size);
3617 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3618 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3620 POST(sys_fgetxattr)
3622 if (RES > 0 && ARG3 != (Addr)NULL)
3623 POST_MEM_WRITE( ARG3, RES );
3626 PRE(sys_listxattr)
3628 *flags |= SfMayBlock;
3629 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3630 ARG1, ARG2, (ULong)ARG3);
3631 PRE_REG_READ3(ssize_t, "listxattr",
3632 char *, path, char *, list, vki_size_t, size);
3633 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3634 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3636 POST(sys_listxattr)
3638 if (RES > 0 && ARG2 != (Addr)NULL)
3639 POST_MEM_WRITE( ARG2, RES );
3642 PRE(sys_llistxattr)
3644 *flags |= SfMayBlock;
3645 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3646 ARG1, ARG2, (ULong)ARG3);
3647 PRE_REG_READ3(ssize_t, "llistxattr",
3648 char *, path, char *, list, vki_size_t, size);
3649 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3650 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3652 POST(sys_llistxattr)
3654 if (RES > 0 && ARG2 != (Addr)NULL)
3655 POST_MEM_WRITE( ARG2, RES );
3658 PRE(sys_flistxattr)
3660 *flags |= SfMayBlock;
3661 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3662 SARG1, ARG2, ARG3);
3663 PRE_REG_READ3(ssize_t, "flistxattr",
3664 int, fd, char *, list, vki_size_t, size);
3665 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3667 POST(sys_flistxattr)
3669 if (RES > 0 && ARG2 != (Addr)NULL)
3670 POST_MEM_WRITE( ARG2, RES );
3673 PRE(sys_removexattr)
3675 *flags |= SfMayBlock;
3676 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3677 ARG1, ARG2);
3678 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3679 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3680 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3683 PRE(sys_lremovexattr)
3685 *flags |= SfMayBlock;
3686 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3687 ARG1, ARG2);
3688 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3689 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3690 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3693 PRE(sys_fremovexattr)
3695 *flags |= SfMayBlock;
3696 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3697 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3698 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3701 /* ---------------------------------------------------------------------
3702 sched_* wrappers
3703 ------------------------------------------------------------------ */
3705 PRE(sys_sched_setparam)
3707 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3708 PRE_REG_READ2(long, "sched_setparam",
3709 vki_pid_t, pid, struct sched_param *, p);
3710 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3712 POST(sys_sched_setparam)
3714 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3717 PRE(sys_sched_getparam)
3719 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3720 PRE_REG_READ2(long, "sched_getparam",
3721 vki_pid_t, pid, struct sched_param *, p);
3722 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3724 POST(sys_sched_getparam)
3726 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3729 PRE(sys_sched_setattr)
3731 struct vki_sched_attr *attr;
3732 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3733 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3734 PRE_REG_READ3(long, "sched_setattr",
3735 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3736 /* We need to be able to read at least the size field. */
3737 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3738 attr = (struct vki_sched_attr *)(Addr)ARG2;
3739 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3740 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3743 PRE(sys_sched_getattr)
3745 struct vki_sched_attr *attr;
3746 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3747 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3748 PRE_REG_READ4(long, "sched_getattr",
3749 vki_pid_t, pid, struct sched_attr *, p,
3750 unsigned int, size, unsigned int, flags);
3751 /* We need to be able to read at least the size field. */
3752 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3753 /* And the kernel needs to be able to write to the whole struct size. */
3754 attr = (struct vki_sched_attr *)(Addr)ARG2;
3755 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3756 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3758 POST(sys_sched_getattr)
3760 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3761 POST_MEM_WRITE( (Addr)attr, attr->size );
3764 PRE(sys_sched_getscheduler)
3766 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3767 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3770 PRE(sys_sched_setscheduler)
3772 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3773 SARG1, SARG2, ARG3);
3774 PRE_REG_READ3(long, "sched_setscheduler",
3775 vki_pid_t, pid, int, policy, struct sched_param *, p);
3776 if (ARG3 != 0)
3777 PRE_MEM_READ( "sched_setscheduler(p)",
3778 ARG3, sizeof(struct vki_sched_param));
3781 PRE(sys_sched_yield)
3783 *flags |= SfMayBlock;
3784 PRINT("sched_yield()");
3785 PRE_REG_READ0(long, "sys_sched_yield");
3788 PRE(sys_sched_get_priority_max)
3790 PRINT("sched_get_priority_max ( %ld )", SARG1);
3791 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3794 PRE(sys_sched_get_priority_min)
3796 PRINT("sched_get_priority_min ( %ld )", SARG1);
3797 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3800 PRE(sys_sched_rr_get_interval)
3802 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3803 PRE_REG_READ2(int, "sched_rr_get_interval",
3804 vki_pid_t, pid,
3805 struct vki_timespec *, tp);
3806 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3807 ARG2, sizeof(struct vki_timespec));
3810 POST(sys_sched_rr_get_interval)
3812 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3815 PRE(sys_sched_rr_get_interval_time64)
3817 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3818 SARG1, ARG2);
3819 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3820 vki_pid_t, pid,
3821 struct vki_timespec *, tp);
3822 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3823 ARG2, sizeof(struct vki_timespec64));
3826 POST(sys_sched_rr_get_interval_time64)
3828 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3831 PRE(sys_sched_setaffinity)
3833 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3834 SARG1, ARG2, ARG3);
3835 PRE_REG_READ3(long, "sched_setaffinity",
3836 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3837 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3840 PRE(sys_sched_getaffinity)
3842 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3843 SARG1, ARG2, ARG3);
3844 PRE_REG_READ3(long, "sched_getaffinity",
3845 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3846 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3848 POST(sys_sched_getaffinity)
3850 POST_MEM_WRITE(ARG3, ARG2);
3853 PRE(sys_unshare)
3855 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3856 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3859 PRE(sys_setns)
3861 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3862 PRE_REG_READ2(int, "setns",
3863 int, fd,
3864 int, nstype);
3865 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3866 SET_STATUS_Failure( VKI_EBADF );
3870 /* ---------------------------------------------------------------------
3871 miscellaneous wrappers
3872 ------------------------------------------------------------------ */
3874 PRE(sys_munlockall)
3876 *flags |= SfMayBlock;
3877 PRINT("sys_munlockall ( )");
3878 PRE_REG_READ0(long, "munlockall");
3881 // This has different signatures for different platforms.
3883 // x86: int sys_pipe(unsigned long __user *fildes);
3884 // AMD64: long sys_pipe(int *fildes);
3885 // ppc32: int sys_pipe(int __user *fildes);
3886 // ppc64: int sys_pipe(int __user *fildes);
3888 // The type of the argument is most important, and it is an array of 32 bit
3889 // values in all cases. (The return type differs across platforms, but it
3890 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3891 // was caused by using an array of 'unsigned long's, which didn't work on
3892 // AMD64.
3893 PRE(sys_pipe)
3895 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3896 PRE_REG_READ1(int, "pipe", int *, filedes);
3897 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3899 POST(sys_pipe)
3901 Int *p = (Int *)(Addr)ARG1;
3902 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3903 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3904 VG_(close)(p[0]);
3905 VG_(close)(p[1]);
3906 SET_STATUS_Failure( VKI_EMFILE );
3907 } else {
3908 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3909 if (VG_(clo_track_fds)) {
3910 ML_(record_fd_open_nameless)(tid, p[0]);
3911 ML_(record_fd_open_nameless)(tid, p[1]);
3916 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3917 there's a second arg containing flags to be applied to the new file
3918 descriptors. It hardly seems worth the effort to factor out the
3919 duplicated code, hence: */
3920 PRE(sys_pipe2)
3922 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3923 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3924 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3926 POST(sys_pipe2)
3928 Int *p = (Int *)(Addr)ARG1;
3929 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3930 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3931 VG_(close)(p[0]);
3932 VG_(close)(p[1]);
3933 SET_STATUS_Failure( VKI_EMFILE );
3934 } else {
3935 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3936 if (VG_(clo_track_fds)) {
3937 ML_(record_fd_open_nameless)(tid, p[0]);
3938 ML_(record_fd_open_nameless)(tid, p[1]);
3943 PRE(sys_dup3)
3945 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3946 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3947 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3948 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3949 SET_STATUS_Failure( VKI_EBADF );
3952 POST(sys_dup3)
3954 vg_assert(SUCCESS);
3955 if (VG_(clo_track_fds))
3956 ML_(record_fd_open_named)(tid, RES);
3959 PRE(sys_quotactl)
3961 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3962 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3963 PRE_REG_READ4(long, "quotactl",
3964 unsigned int, cmd, const char *, special, vki_qid_t, id,
3965 void *, addr);
3966 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3969 PRE(sys_waitid)
3971 *flags |= SfMayBlock;
3972 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3973 SARG1, SARG2, ARG3, SARG4, ARG5);
3974 PRE_REG_READ5(int32_t, "sys_waitid",
3975 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3976 int, options, struct vki_rusage *, ru);
3977 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3978 if (ARG5 != 0)
3979 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3981 POST(sys_waitid)
3983 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3984 if (ARG5 != 0)
3985 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3988 PRE(sys_sync_file_range)
3990 *flags |= SfMayBlock;
3991 #if VG_WORDSIZE == 4
3992 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3993 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3994 PRE_REG_READ6(long, "sync_file_range",
3995 int, fd,
3996 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3997 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3998 unsigned int, flags);
3999 #elif VG_WORDSIZE == 8
4000 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
4001 SARG1, SARG2, SARG3, ARG4);
4002 PRE_REG_READ4(long, "sync_file_range",
4003 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
4004 unsigned int, flags);
4005 #else
4006 # error Unexpected word size
4007 #endif
4008 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
4009 SET_STATUS_Failure( VKI_EBADF );
4012 PRE(sys_sync_file_range2)
4014 *flags |= SfMayBlock;
4015 #if VG_WORDSIZE == 4
4016 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
4017 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
4018 PRE_REG_READ6(long, "sync_file_range2",
4019 int, fd, unsigned int, flags,
4020 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
4021 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
4022 #elif VG_WORDSIZE == 8
4023 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
4024 SARG1, ARG2, SARG3, SARG4);
4025 PRE_REG_READ4(long, "sync_file_range2",
4026 int, fd, unsigned int, flags,
4027 vki_loff_t, offset, vki_loff_t, nbytes);
4028 #else
4029 # error Unexpected word size
4030 #endif
4031 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4032 SET_STATUS_Failure( VKI_EBADF );
4035 PRE(sys_stime)
4037 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4038 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4039 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4042 PRE(sys_perf_event_open)
4044 struct vki_perf_event_attr *attr;
4045 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4046 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4047 PRE_REG_READ5(long, "perf_event_open",
4048 struct vki_perf_event_attr *, attr,
4049 vki_pid_t, pid, int, cpu, int, group_fd,
4050 unsigned long, flags);
4051 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4052 PRE_MEM_READ( "perf_event_open(attr->size)",
4053 (Addr)&attr->size, sizeof(attr->size) );
4054 PRE_MEM_READ( "perf_event_open(attr)",
4055 (Addr)attr, attr->size );
4058 POST(sys_perf_event_open)
4060 vg_assert(SUCCESS);
4061 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4062 VG_(close)(RES);
4063 SET_STATUS_Failure( VKI_EMFILE );
4064 } else {
4065 if (VG_(clo_track_fds))
4066 ML_(record_fd_open_nameless)(tid, RES);
4070 PRE(sys_getcpu)
4072 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4073 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4074 PRE_REG_READ3(int, "getcpu",
4075 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4076 if (ARG1 != 0)
4077 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4078 if (ARG2 != 0)
4079 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4080 if (ARG3 != 0)
4081 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4084 POST(sys_getcpu)
4086 if (ARG1 != 0)
4087 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4088 if (ARG2 != 0)
4089 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4090 if (ARG3 != 0)
4091 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4094 PRE(sys_move_pages)
4096 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4097 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4098 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4099 PRE_REG_READ6(int, "move_pages",
4100 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4101 const int *, nodes, int *, status, int, flags);
4102 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4103 if (ARG4)
4104 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4105 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4108 POST(sys_move_pages)
4110 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4113 PRE(sys_getrandom)
4115 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4116 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4117 PRE_REG_READ3(int, "getrandom",
4118 char *, buf, vki_size_t, count, unsigned int, flags);
4119 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4122 POST(sys_getrandom)
4124 POST_MEM_WRITE( ARG1, ARG2 );
4127 PRE(sys_memfd_create)
4129 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4130 ARG1, ARG2);
4131 PRE_REG_READ2(int, "memfd_create",
4132 char *, uname, unsigned int, flags);
4133 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4136 POST(sys_memfd_create)
4138 vg_assert(SUCCESS);
4139 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4140 VG_(close)(RES);
4141 SET_STATUS_Failure( VKI_EMFILE );
4142 } else {
4143 if (VG_(clo_track_fds))
4144 ML_(record_fd_open_nameless)(tid, RES);
4148 PRE(sys_memfd_secret)
4150 PRINT("sys_memfd_secret ( %#" FMT_REGWORD "x )", ARG1);
4151 PRE_REG_READ1(int, "memfd_secret", unsigned int, flags);
4154 POST(sys_memfd_secret)
4156 vg_assert(SUCCESS);
4157 if (!ML_(fd_allowed)(RES, "memfd_secret", tid, True)) {
4158 VG_(close)(RES);
4159 SET_STATUS_Failure( VKI_EMFILE );
4160 } else {
4161 if (VG_(clo_track_fds))
4162 ML_(record_fd_open_nameless)(tid, RES);
4166 PRE(sys_membarrier)
4168 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4169 PRE_REG_READ1(int, "membarrier", int, flags);
4172 PRE(sys_syncfs)
4174 *flags |= SfMayBlock;
4175 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4176 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4179 PRE(sys_statx)
4181 FUSE_COMPATIBLE_MAY_BLOCK();
4182 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4183 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4184 PRE_REG_READ5(long, "statx",
4185 int, dirfd, char *, filename, int, flags,
4186 unsigned int, mask, struct statx *, buf);
4187 // Work around Rust's dubious use of statx, as described here:
4188 // https://github.com/rust-lang/rust/blob/
4189 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4190 // src/libstd/sys/unix/fs.rs#L128-L142
4191 // in which it passes NULL for both filename and buf, and then looks at the
4192 // return value, so as to determine whether or not this syscall is supported.
4193 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4194 if (!both_filename_and_buf_are_null) {
4195 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4196 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4199 POST(sys_statx)
4201 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4204 /* ---------------------------------------------------------------------
4205 utime wrapper
4206 ------------------------------------------------------------------ */
4208 PRE(sys_utime)
4210 *flags |= SfMayBlock;
4211 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4212 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4213 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4214 if (ARG2 != 0)
4215 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4218 /* ---------------------------------------------------------------------
4219 lseek wrapper
4220 ------------------------------------------------------------------ */
4222 PRE(sys_lseek)
4224 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4225 ARG1, SARG2, ARG3);
4226 PRE_REG_READ3(vki_off_t, "lseek",
4227 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4230 /* ---------------------------------------------------------------------
4231 readahead wrapper
4232 ------------------------------------------------------------------ */
4234 PRE(sys_readahead)
4236 *flags |= SfMayBlock;
4237 #if VG_WORDSIZE == 4
4238 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4239 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4240 PRE_REG_READ4(vki_off_t, "readahead",
4241 int, fd, unsigned, MERGE64_FIRST(offset),
4242 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4243 #elif VG_WORDSIZE == 8
4244 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4245 PRE_REG_READ3(vki_off_t, "readahead",
4246 int, fd, vki_loff_t, offset, vki_size_t, count);
4247 #else
4248 # error Unexpected word size
4249 #endif
4250 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4251 SET_STATUS_Failure( VKI_EBADF );
4254 /* ---------------------------------------------------------------------
4255 sig* wrappers
4256 ------------------------------------------------------------------ */
4258 PRE(sys_sigpending)
4260 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4261 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4262 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4264 POST(sys_sigpending)
4266 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4269 // This syscall is not used on amd64/Linux -- it only provides
4270 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4271 // This wrapper is only suitable for 32-bit architectures.
4272 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4273 // conditional compilation like this?)
4274 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4275 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4276 || defined(VGP_nanomips_linux)
4277 PRE(sys_sigprocmask)
4279 vki_old_sigset_t* set;
4280 vki_old_sigset_t* oldset;
4281 vki_sigset_t bigger_set;
4282 vki_sigset_t bigger_oldset;
4284 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4285 PRE_REG_READ3(long, "sigprocmask",
4286 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4287 if (ARG2 != 0)
4288 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4289 if (ARG3 != 0)
4290 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4292 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4293 // vki_sigset_t params.
4294 set = (vki_old_sigset_t*)(Addr)ARG2;
4295 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4297 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4298 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4299 if (set)
4300 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4302 SET_STATUS_from_SysRes(
4303 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4304 set ? &bigger_set : NULL,
4305 oldset ? &bigger_oldset : NULL)
4308 if (oldset)
4309 *oldset = bigger_oldset.sig[0];
4311 if (SUCCESS)
4312 *flags |= SfPollAfter;
4314 POST(sys_sigprocmask)
4316 vg_assert(SUCCESS);
4317 if (RES == 0 && ARG3 != 0)
4318 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4321 /* Convert from non-RT to RT sigset_t's */
4322 static
4323 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4325 VG_(sigemptyset)(set);
4326 set->sig[0] = *oldset;
4328 PRE(sys_sigaction)
4330 vki_sigaction_toK_t new, *newp;
4331 vki_sigaction_fromK_t old, *oldp;
4333 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4334 PRE_REG_READ3(int, "sigaction",
4335 int, signum, const struct old_sigaction *, act,
4336 struct old_sigaction *, oldact);
4338 newp = oldp = NULL;
4340 if (ARG2 != 0) {
4341 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4342 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4343 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4344 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4345 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4346 && (sa->sa_flags & VKI_SA_RESTORER))
4347 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4350 if (ARG3 != 0) {
4351 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4352 oldp = &old;
4355 /* If the new or old sigaction is not NULL, but the structs
4356 aren't accessible then sigaction returns EFAULT and we cannot
4357 use either struct for our own bookkeeping. Just fail early. */
4358 if (ARG2 != 0
4359 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4360 sizeof(struct vki_old_sigaction))) {
4361 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4362 (void *)(Addr)ARG2);
4363 SET_STATUS_Failure ( VKI_EFAULT );
4364 } else if ((ARG3 != 0
4365 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4366 sizeof(struct vki_old_sigaction)))) {
4367 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4368 (void *)(Addr)ARG3);
4369 SET_STATUS_Failure ( VKI_EFAULT );
4370 } else {
4371 if (ARG2 != 0) {
4372 struct vki_old_sigaction *oldnew =
4373 (struct vki_old_sigaction *)(Addr)ARG2;
4375 new.ksa_handler = oldnew->ksa_handler;
4376 new.sa_flags = oldnew->sa_flags;
4377 new.sa_restorer = oldnew->sa_restorer;
4378 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4379 newp = &new;
4382 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4384 if (ARG3 != 0 && SUCCESS && RES == 0) {
4385 struct vki_old_sigaction *oldold =
4386 (struct vki_old_sigaction *)(Addr)ARG3;
4388 oldold->ksa_handler = oldp->ksa_handler;
4389 oldold->sa_flags = oldp->sa_flags;
4390 oldold->sa_restorer = oldp->sa_restorer;
4391 oldold->sa_mask = oldp->sa_mask.sig[0];
4395 POST(sys_sigaction)
4397 vg_assert(SUCCESS);
4398 if (RES == 0 && ARG3 != 0)
4399 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4401 #endif
4403 PRE(sys_signalfd)
4405 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4406 (ULong)ARG3);
4407 PRE_REG_READ3(long, "sys_signalfd",
4408 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4409 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4410 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4411 SET_STATUS_Failure( VKI_EBADF );
4413 POST(sys_signalfd)
4415 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4416 VG_(close)(RES);
4417 SET_STATUS_Failure( VKI_EMFILE );
4418 } else {
4419 if (VG_(clo_track_fds))
4420 ML_(record_fd_open_nameless) (tid, RES);
4424 PRE(sys_signalfd4)
4426 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4427 SARG1, ARG2, ARG3, SARG4);
4428 PRE_REG_READ4(long, "sys_signalfd4",
4429 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4430 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4431 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4432 SET_STATUS_Failure( VKI_EBADF );
4434 POST(sys_signalfd4)
4436 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4437 VG_(close)(RES);
4438 SET_STATUS_Failure( VKI_EMFILE );
4439 } else {
4440 if (VG_(clo_track_fds))
4441 ML_(record_fd_open_nameless) (tid, RES);
4446 /* ---------------------------------------------------------------------
4447 rt_sig* wrappers
4448 ------------------------------------------------------------------ */
4450 PRE(sys_rt_sigaction)
4452 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4453 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4454 PRE_REG_READ4(long, "rt_sigaction",
4455 int, signum, const struct sigaction *, act,
4456 struct sigaction *, oldact, vki_size_t, sigsetsize);
4458 if (ARG2 != 0) {
4459 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4460 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4461 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4462 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4463 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4464 && (sa->sa_flags & VKI_SA_RESTORER))
4465 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4467 if (ARG3 != 0)
4468 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4470 /* If the new or old sigaction is not NULL, but the structs
4471 aren't accessible then sigaction returns EFAULT and we cannot
4472 use either struct for our own bookkeeping. Just fail early. */
4473 if (ARG2 != 0
4474 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4475 sizeof(vki_sigaction_toK_t))) {
4476 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4477 (void *)(Addr)ARG2);
4478 SET_STATUS_Failure ( VKI_EFAULT );
4479 } else if ((ARG3 != 0
4480 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4481 sizeof(vki_sigaction_fromK_t)))) {
4482 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4483 (void *)(Addr)ARG3);
4484 SET_STATUS_Failure ( VKI_EFAULT );
4485 } else {
4487 // XXX: doesn't seem right to be calling do_sys_sigaction for
4488 // sys_rt_sigaction... perhaps this function should be renamed
4489 // VG_(do_sys_rt_sigaction)() --njn
4491 SET_STATUS_from_SysRes(
4492 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4493 (vki_sigaction_fromK_t *)(Addr)ARG3)
4497 POST(sys_rt_sigaction)
4499 vg_assert(SUCCESS);
4500 if (RES == 0 && ARG3 != 0)
4501 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4504 PRE(sys_rt_sigprocmask)
4506 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4507 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4508 PRE_REG_READ4(long, "rt_sigprocmask",
4509 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4510 vki_size_t, sigsetsize);
4511 if (ARG2 != 0)
4512 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4513 if (ARG3 != 0)
4514 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4516 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4517 // Since we want to use the set and oldset for bookkeeping we also want
4518 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4519 if (sizeof(vki_sigset_t) != ARG4)
4520 SET_STATUS_Failure( VKI_EINVAL );
4521 else if (ARG2 != 0
4522 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4523 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4524 (void *)(Addr)ARG2);
4525 SET_STATUS_Failure ( VKI_EFAULT );
4527 else if (ARG3 != 0
4528 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4529 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4530 (void *)(Addr)ARG3);
4531 SET_STATUS_Failure ( VKI_EFAULT );
4534 else {
4535 SET_STATUS_from_SysRes(
4536 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4537 (vki_sigset_t*) (Addr)ARG2,
4538 (vki_sigset_t*) (Addr)ARG3 )
4542 if (SUCCESS)
4543 *flags |= SfPollAfter;
4545 POST(sys_rt_sigprocmask)
4547 vg_assert(SUCCESS);
4548 if (RES == 0 && ARG3 != 0)
4549 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4552 PRE(sys_rt_sigpending)
4554 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4555 PRE_REG_READ2(long, "rt_sigpending",
4556 vki_sigset_t *, set, vki_size_t, sigsetsize);
4557 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4559 POST(sys_rt_sigpending)
4561 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4564 PRE(sys_rt_sigtimedwait)
4566 *flags |= SfMayBlock;
4567 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4568 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4569 ARG1, ARG2, ARG3, ARG4);
4570 PRE_REG_READ4(long, "rt_sigtimedwait",
4571 const vki_sigset_t *, set, vki_siginfo_t *, info,
4572 const struct timespec *, timeout, vki_size_t, sigsetsize);
4573 if (ARG1 != 0)
4574 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4575 if (ARG2 != 0)
4576 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4577 if (ARG3 != 0)
4578 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4579 ARG3, sizeof(struct vki_timespec) );
4581 POST(sys_rt_sigtimedwait)
4583 if (ARG2 != 0)
4584 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4587 PRE(sys_rt_sigtimedwait_time64)
4589 *flags |= SfMayBlock;
4590 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4591 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4592 ARG1, ARG2, ARG3, ARG4);
4593 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4594 const vki_sigset_t *, set, vki_siginfo_t *, info,
4595 const struct vki_timespec64 *, timeout,
4596 vki_size_t, sigsetsize);
4597 if (ARG1 != 0)
4598 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4599 if (ARG2 != 0)
4600 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4601 sizeof(vki_siginfo_t) );
4602 if (ARG3 != 0)
4603 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4605 POST(sys_rt_sigtimedwait_time64)
4607 if (ARG2 != 0)
4608 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4611 PRE(sys_rt_sigqueueinfo)
4613 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4614 SARG1, SARG2, ARG3);
4615 PRE_REG_READ3(long, "rt_sigqueueinfo",
4616 int, pid, int, sig, vki_siginfo_t *, uinfo);
4617 if (ARG2 != 0)
4618 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4620 POST(sys_rt_sigqueueinfo)
4622 if (!ML_(client_signal_OK)(ARG2))
4623 SET_STATUS_Failure( VKI_EINVAL );
4626 PRE(sys_rt_tgsigqueueinfo)
4628 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4629 SARG1, SARG2, SARG3, ARG4);
4630 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4631 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4632 if (ARG3 != 0)
4633 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4636 POST(sys_rt_tgsigqueueinfo)
4638 if (!ML_(client_signal_OK)(ARG3))
4639 SET_STATUS_Failure( VKI_EINVAL );
4642 // XXX: x86-specific? The kernel prototypes for the different archs are
4643 // hard to decipher.
4644 PRE(sys_rt_sigsuspend)
4646 /* The C library interface to sigsuspend just takes a pointer to
4647 a signal mask but this system call has two arguments - a pointer
4648 to the mask and the number of bytes used by it. The kernel insists
4649 on the size being equal to sizeof(sigset_t) however and will just
4650 return EINVAL if it isn't.
4652 *flags |= SfMayBlock;
4653 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4654 ARG1, ARG2 );
4655 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4656 if (ARG1 != (Addr)NULL) {
4657 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4658 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4659 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4660 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4661 be killable by VG_(nuke_all_threads_except).
4662 We thus silently ignore the user request to mask this signal.
4663 Note that this is similar to what is done for e.g.
4664 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4665 } else {
4666 SET_STATUS_Failure(VKI_EFAULT);
4671 /* ---------------------------------------------------------------------
4672 linux msg* wrapper helpers
4673 ------------------------------------------------------------------ */
4675 void
4676 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4677 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4679 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4680 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4681 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4682 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4685 void
4686 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4687 UWord arg0, UWord arg1, UWord arg2,
4688 UWord arg3, UWord arg4 )
4690 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4691 long msgtyp, int msgflg); */
4692 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4693 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4694 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4696 void
4697 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4698 UWord res,
4699 UWord arg0, UWord arg1, UWord arg2,
4700 UWord arg3, UWord arg4 )
4702 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4703 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4704 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4707 void
4708 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4709 UWord arg0, UWord arg1, UWord arg2 )
4711 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4712 switch (arg1 /* cmd */) {
4713 case VKI_IPC_INFO:
4714 case VKI_MSG_INFO:
4715 case VKI_IPC_INFO|VKI_IPC_64:
4716 case VKI_MSG_INFO|VKI_IPC_64:
4717 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4718 arg2, sizeof(struct vki_msginfo) );
4719 break;
4720 case VKI_IPC_STAT:
4721 case VKI_MSG_STAT:
4722 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4723 arg2, sizeof(struct vki_msqid_ds) );
4724 break;
4725 case VKI_IPC_STAT|VKI_IPC_64:
4726 case VKI_MSG_STAT|VKI_IPC_64:
4727 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4728 arg2, sizeof(struct vki_msqid64_ds) );
4729 break;
4730 case VKI_IPC_SET:
4731 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4732 arg2, sizeof(struct vki_msqid_ds) );
4733 break;
4734 case VKI_IPC_SET|VKI_IPC_64:
4735 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4736 arg2, sizeof(struct vki_msqid64_ds) );
4737 break;
4740 void
4741 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4742 UWord res,
4743 UWord arg0, UWord arg1, UWord arg2 )
4745 switch (arg1 /* cmd */) {
4746 case VKI_IPC_INFO:
4747 case VKI_MSG_INFO:
4748 case VKI_IPC_INFO|VKI_IPC_64:
4749 case VKI_MSG_INFO|VKI_IPC_64:
4750 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4751 break;
4752 case VKI_IPC_STAT:
4753 case VKI_MSG_STAT:
4754 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4755 break;
4756 case VKI_IPC_STAT|VKI_IPC_64:
4757 case VKI_MSG_STAT|VKI_IPC_64:
4758 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4759 break;
4763 /* ---------------------------------------------------------------------
4764 Generic handler for sys_ipc
4765 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4766 are either direct system calls, or are all implemented via sys_ipc.
4767 ------------------------------------------------------------------ */
4768 #ifdef __NR_ipc
4769 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4771 Addr* a_p = (Addr*)a;
4772 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4773 return *a_p;
4776 static Bool semctl_cmd_has_4args (UWord cmd)
4778 switch (cmd & ~VKI_IPC_64)
4780 case VKI_IPC_INFO:
4781 case VKI_SEM_INFO:
4782 case VKI_IPC_STAT:
4783 case VKI_SEM_STAT:
4784 case VKI_IPC_SET:
4785 case VKI_GETALL:
4786 case VKI_SETALL:
4787 return True;
4788 default:
4789 return False;
4793 PRE(sys_ipc)
4795 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4796 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4798 switch (ARG1 /* call */) {
4799 case VKI_SEMOP:
4800 PRE_REG_READ5(int, "ipc",
4801 vki_uint, call, int, first, int, second, int, third,
4802 void *, ptr);
4803 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4804 *flags |= SfMayBlock;
4805 break;
4806 case VKI_SEMGET:
4807 PRE_REG_READ4(int, "ipc",
4808 vki_uint, call, int, first, int, second, int, third);
4809 break;
4810 case VKI_SEMCTL:
4812 PRE_REG_READ5(int, "ipc",
4813 vki_uint, call, int, first, int, second, int, third,
4814 void *, ptr);
4815 UWord arg;
4816 if (semctl_cmd_has_4args(ARG4))
4817 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4818 else
4819 arg = 0;
4820 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4821 break;
4823 case VKI_SEMTIMEDOP:
4824 #ifdef VGP_s390x_linux
4825 /* On s390x Linux platforms the sys_ipc semtimedop call has four instead
4826 of five parameters, where the timeout is passed in the third instead of
4827 the fifth. */
4828 PRE_REG_READ5(int, "ipc",
4829 vki_uint, call, int, first, int, second, long, third,
4830 void *, ptr);
4831 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG4 );
4832 #else
4833 PRE_REG_READ6(int, "ipc",
4834 vki_uint, call, int, first, int, second, int, third,
4835 void *, ptr, long, fifth);
4836 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4837 #endif
4838 *flags |= SfMayBlock;
4839 break;
4840 case VKI_MSGSND:
4841 PRE_REG_READ5(int, "ipc",
4842 vki_uint, call, int, first, int, second, int, third,
4843 void *, ptr);
4844 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4845 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4846 *flags |= SfMayBlock;
4847 break;
4848 case VKI_MSGRCV:
4850 PRE_REG_READ5(int, "ipc",
4851 vki_uint, call, int, first, int, second, int, third,
4852 void *, ptr);
4853 Addr msgp;
4854 Word msgtyp;
4856 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4857 "msgrcv(msgp)" );
4858 msgtyp = deref_Addr( tid,
4859 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4860 "msgrcv(msgp)" );
4862 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4864 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4865 *flags |= SfMayBlock;
4866 break;
4868 case VKI_MSGGET:
4869 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4870 break;
4871 case VKI_MSGCTL:
4872 PRE_REG_READ5(int, "ipc",
4873 vki_uint, call, int, first, int, second, int, third,
4874 void *, ptr);
4875 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4876 break;
4877 case VKI_SHMAT:
4879 PRE_REG_READ5(int, "ipc",
4880 vki_uint, call, int, first, int, second, int, third,
4881 void *, ptr);
4882 UWord w;
4883 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4884 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4885 if (w == 0)
4886 SET_STATUS_Failure( VKI_EINVAL );
4887 else
4888 ARG5 = w;
4889 break;
4891 case VKI_SHMDT:
4892 PRE_REG_READ5(int, "ipc",
4893 vki_uint, call, int, first, int, second, int, third,
4894 void *, ptr);
4895 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4896 SET_STATUS_Failure( VKI_EINVAL );
4897 break;
4898 case VKI_SHMGET:
4899 PRE_REG_READ4(int, "ipc",
4900 vki_uint, call, int, first, int, second, int, third);
4901 if (ARG4 & VKI_SHM_HUGETLB) {
4902 static Bool warning_given = False;
4903 ARG4 &= ~VKI_SHM_HUGETLB;
4904 if (!warning_given) {
4905 warning_given = True;
4906 VG_(umsg)(
4907 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4910 break;
4911 case VKI_SHMCTL: /* IPCOP_shmctl */
4912 PRE_REG_READ5(int, "ipc",
4913 vki_uint, call, int, first, int, second, int, third,
4914 void *, ptr);
4915 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4916 break;
4917 default:
4918 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4919 VG_(core_panic)("... bye!\n");
4920 break; /*NOTREACHED*/
4924 POST(sys_ipc)
4926 vg_assert(SUCCESS);
4927 switch (ARG1 /* call */) {
4928 case VKI_SEMOP:
4929 case VKI_SEMGET:
4930 break;
4931 case VKI_SEMCTL:
4933 UWord arg;
4934 if (semctl_cmd_has_4args(ARG4))
4935 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4936 else
4937 arg = 0;
4938 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4939 break;
4941 case VKI_SEMTIMEDOP:
4942 case VKI_MSGSND:
4943 break;
4944 case VKI_MSGRCV:
4946 Addr msgp;
4947 Word msgtyp;
4949 msgp = deref_Addr( tid,
4950 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4951 "msgrcv(msgp)" );
4952 msgtyp = deref_Addr( tid,
4953 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4954 "msgrcv(msgp)" );
4956 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4957 break;
4959 case VKI_MSGGET:
4960 break;
4961 case VKI_MSGCTL:
4962 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4963 break;
4964 case VKI_SHMAT:
4966 Addr addr;
4968 /* force readability. before the syscall it is
4969 * indeed uninitialized, as can be seen in
4970 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4971 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4973 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4974 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4975 break;
4977 case VKI_SHMDT:
4978 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4979 break;
4980 case VKI_SHMGET:
4981 break;
4982 case VKI_SHMCTL:
4983 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4984 break;
4985 default:
4986 VG_(message)(Vg_DebugMsg,
4987 "FATAL: unhandled syscall(ipc) %lu\n",
4988 ARG1 );
4989 VG_(core_panic)("... bye!\n");
4990 break; /*NOTREACHED*/
4993 #endif
4995 PRE(sys_semget)
4997 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4998 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
5001 PRE(sys_semop)
5003 *flags |= SfMayBlock;
5004 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5005 SARG1, ARG2, ARG3);
5006 PRE_REG_READ3(long, "semop",
5007 int, semid, struct sembuf *, sops, unsigned, nsoops);
5008 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
5011 PRE(sys_semctl)
5013 switch (ARG3 & ~VKI_IPC_64) {
5014 case VKI_IPC_INFO:
5015 case VKI_SEM_INFO:
5016 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5017 SARG3, ARG4);
5018 PRE_REG_READ4(long, "semctl",
5019 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
5020 break;
5021 case VKI_IPC_STAT:
5022 case VKI_SEM_STAT:
5023 case VKI_IPC_SET:
5024 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5025 SARG3, ARG4);
5026 PRE_REG_READ4(long, "semctl",
5027 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
5028 break;
5029 case VKI_GETALL:
5030 case VKI_SETALL:
5031 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5032 SARG3, ARG4);
5033 PRE_REG_READ4(long, "semctl",
5034 int, semid, int, semnum, int, cmd, unsigned short *, arg);
5035 break;
5036 default:
5037 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5038 PRE_REG_READ3(long, "semctl",
5039 int, semid, int, semnum, int, cmd);
5040 break;
5042 #ifdef VGP_amd64_linux
5043 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5044 #else
5045 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
5046 #endif
5049 POST(sys_semctl)
5051 #ifdef VGP_amd64_linux
5052 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5053 #else
5054 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
5055 #endif
5058 PRE(sys_semtimedop)
5060 *flags |= SfMayBlock;
5061 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5062 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5063 PRE_REG_READ4(long, "semtimedop",
5064 int, semid, struct sembuf *, sops, unsigned, nsoops,
5065 struct timespec *, timeout);
5066 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5069 PRE(sys_semtimedop_time64)
5071 *flags |= SfMayBlock;
5072 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5073 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5074 PRE_REG_READ4(long, "semtimedop_time64",
5075 int, semid, struct sembuf *, sops, unsigned, nsoops,
5076 struct vki_timespec64 *, timeout);
5077 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5078 ARG2 * sizeof(struct vki_sembuf) );
5079 if (ARG3 != 0)
5080 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5083 PRE(sys_msgget)
5085 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5086 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5089 PRE(sys_msgsnd)
5091 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5092 SARG1, ARG2, ARG3, SARG4);
5093 PRE_REG_READ4(long, "msgsnd",
5094 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5095 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5096 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5097 *flags |= SfMayBlock;
5100 PRE(sys_msgrcv)
5102 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5103 SARG1, ARG2, ARG3, SARG4, SARG5);
5104 PRE_REG_READ5(long, "msgrcv",
5105 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5106 long, msgytp, int, msgflg);
5107 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5108 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5109 *flags |= SfMayBlock;
5111 POST(sys_msgrcv)
5113 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5116 PRE(sys_msgctl)
5118 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5119 PRE_REG_READ3(long, "msgctl",
5120 int, msqid, int, cmd, struct msqid_ds *, buf);
5121 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5124 POST(sys_msgctl)
5126 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5129 PRE(sys_shmget)
5131 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5132 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5133 if (ARG3 & VKI_SHM_HUGETLB) {
5134 static Bool warning_given = False;
5135 ARG3 &= ~VKI_SHM_HUGETLB;
5136 if (!warning_given) {
5137 warning_given = True;
5138 VG_(umsg)(
5139 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5144 PRE(sys_shmat)
5146 UWord arg2tmp;
5147 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5148 PRE_REG_READ3(long, "shmat",
5149 int, shmid, const void *, shmaddr, int, shmflg);
5150 #if defined(VGP_arm_linux)
5151 /* Round the attach address down to an VKI_SHMLBA boundary if the
5152 client requested rounding. See #222545. This is necessary only
5153 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5154 other linux targets it is the same as the page size. */
5155 if (ARG3 & VKI_SHM_RND)
5156 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5157 #endif
5158 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5159 if (arg2tmp == 0)
5160 SET_STATUS_Failure( VKI_EINVAL );
5161 else
5162 ARG2 = arg2tmp; // used in POST
5165 POST(sys_shmat)
5167 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5170 PRE(sys_shmdt)
5172 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5173 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5174 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5175 SET_STATUS_Failure( VKI_EINVAL );
5178 POST(sys_shmdt)
5180 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5183 PRE(sys_shmctl)
5185 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5186 PRE_REG_READ3(long, "shmctl",
5187 int, shmid, int, cmd, struct shmid_ds *, buf);
5188 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5189 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5190 #else
5191 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5192 #endif
5195 POST(sys_shmctl)
5197 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5198 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5199 #else
5200 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5201 #endif
5205 /* ---------------------------------------------------------------------
5206 Generic handler for sys_socketcall
5207 Depending on the platform, some socket related syscalls (e.g. socketpair,
5208 socket, bind, ...)
5209 are either direct system calls, or are all implemented via sys_socketcall.
5210 ------------------------------------------------------------------ */
5211 #ifdef __NR_socketcall
5212 PRE(sys_socketcall)
5214 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5215 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5216 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5217 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5218 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5219 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5221 // call PRE_MEM_READ and check for EFAULT result.
5222 #define PRE_MEM_READ_ef(msg, arg, size) \
5224 PRE_MEM_READ( msg, arg, size); \
5225 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5226 SET_STATUS_Failure( VKI_EFAULT ); \
5227 break; \
5231 *flags |= SfMayBlock;
5232 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5233 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5235 switch (ARG1 /* request */) {
5237 case VKI_SYS_SOCKETPAIR:
5238 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5239 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5240 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5241 break;
5243 case VKI_SYS_SOCKET:
5244 /* int socket(int domain, int type, int protocol); */
5245 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5246 break;
5248 case VKI_SYS_BIND:
5249 /* int bind(int sockfd, struct sockaddr *my_addr,
5250 int addrlen); */
5251 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5252 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5253 break;
5255 case VKI_SYS_LISTEN:
5256 /* int listen(int s, int backlog); */
5257 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5258 break;
5260 case VKI_SYS_ACCEPT:
5261 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5262 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5263 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5264 break;
5266 case VKI_SYS_ACCEPT4:
5267 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5268 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5269 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5270 break;
5272 case VKI_SYS_SENDTO:
5273 /* int sendto(int s, const void *msg, int len,
5274 unsigned int flags,
5275 const struct sockaddr *to, int tolen); */
5276 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5277 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5278 ARG2_3, ARG2_4, ARG2_5 );
5279 break;
5281 case VKI_SYS_SEND:
5282 /* int send(int s, const void *msg, size_t len, int flags); */
5283 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5284 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5285 break;
5287 case VKI_SYS_RECVFROM:
5288 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5289 struct sockaddr *from, int *fromlen); */
5290 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5291 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5292 ARG2_3, ARG2_4, ARG2_5 );
5293 break;
5295 case VKI_SYS_RECV:
5296 /* int recv(int s, void *buf, int len, unsigned int flags); */
5297 /* man 2 recv says:
5298 The recv call is normally used only on a connected socket
5299 (see connect(2)) and is identical to recvfrom with a NULL
5300 from parameter.
5302 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5303 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5304 break;
5306 case VKI_SYS_CONNECT:
5307 /* int connect(int sockfd,
5308 struct sockaddr *serv_addr, int addrlen ); */
5309 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5310 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5311 break;
5313 case VKI_SYS_SETSOCKOPT:
5314 /* int setsockopt(int s, int level, int optname,
5315 const void *optval, int optlen); */
5316 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5317 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5318 ARG2_3, ARG2_4 );
5319 break;
5321 case VKI_SYS_GETSOCKOPT:
5322 /* int getsockopt(int s, int level, int optname,
5323 void *optval, socklen_t *optlen); */
5324 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5325 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5326 ARG2_3, ARG2_4 );
5327 break;
5329 case VKI_SYS_GETSOCKNAME:
5330 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5331 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5332 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5333 break;
5335 case VKI_SYS_GETPEERNAME:
5336 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5337 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5338 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5339 break;
5341 case VKI_SYS_SHUTDOWN:
5342 /* int shutdown(int s, int how); */
5343 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5344 break;
5346 case VKI_SYS_SENDMSG:
5347 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5348 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5349 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5350 (struct vki_msghdr *)(Addr)ARG2_1 );
5351 break;
5353 case VKI_SYS_RECVMSG:
5354 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5355 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5356 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5357 (struct vki_msghdr *)(Addr)ARG2_1 );
5358 break;
5360 case VKI_SYS_RECVMMSG:
5361 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5362 struct timespec *timeout); */
5363 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5364 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5365 ARG2_4 );
5366 break;
5368 case VKI_SYS_SENDMMSG:
5369 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5370 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5371 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5372 break;
5374 default:
5375 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5376 SET_STATUS_Failure( VKI_EINVAL );
5377 break;
5379 # undef ARG2_0
5380 # undef ARG2_1
5381 # undef ARG2_2
5382 # undef ARG2_3
5383 # undef ARG2_4
5384 # undef ARG2_5
5387 POST(sys_socketcall)
5389 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5390 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5391 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5392 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5393 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5394 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5396 SysRes r;
5397 vg_assert(SUCCESS);
5398 switch (ARG1 /* request */) {
5400 case VKI_SYS_SOCKETPAIR:
5401 r = ML_(generic_POST_sys_socketpair)(
5402 tid, VG_(mk_SysRes_Success)(RES),
5403 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5405 SET_STATUS_from_SysRes(r);
5406 break;
5408 case VKI_SYS_SOCKET:
5409 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5410 SET_STATUS_from_SysRes(r);
5411 break;
5413 case VKI_SYS_BIND:
5414 /* int bind(int sockfd, struct sockaddr *my_addr,
5415 int addrlen); */
5416 break;
5418 case VKI_SYS_LISTEN:
5419 /* int listen(int s, int backlog); */
5420 break;
5422 case VKI_SYS_ACCEPT:
5423 case VKI_SYS_ACCEPT4:
5424 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5425 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5426 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5427 ARG2_0, ARG2_1, ARG2_2 );
5428 SET_STATUS_from_SysRes(r);
5429 break;
5431 case VKI_SYS_SENDTO:
5432 break;
5434 case VKI_SYS_SEND:
5435 break;
5437 case VKI_SYS_RECVFROM:
5438 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5439 ARG2_0, ARG2_1, ARG2_2,
5440 ARG2_3, ARG2_4, ARG2_5 );
5441 break;
5443 case VKI_SYS_RECV:
5444 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5445 break;
5447 case VKI_SYS_CONNECT:
5448 break;
5450 case VKI_SYS_SETSOCKOPT:
5451 break;
5453 case VKI_SYS_GETSOCKOPT:
5454 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5455 ARG2_0, ARG2_1,
5456 ARG2_2, ARG2_3, ARG2_4 );
5457 break;
5459 case VKI_SYS_GETSOCKNAME:
5460 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5461 ARG2_0, ARG2_1, ARG2_2 );
5462 break;
5464 case VKI_SYS_GETPEERNAME:
5465 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5466 ARG2_0, ARG2_1, ARG2_2 );
5467 break;
5469 case VKI_SYS_SHUTDOWN:
5470 break;
5472 case VKI_SYS_SENDMSG:
5473 break;
5475 case VKI_SYS_RECVMSG:
5476 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5477 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5478 break;
5480 case VKI_SYS_RECVMMSG:
5481 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5482 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5483 break;
5485 case VKI_SYS_SENDMMSG:
5486 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5487 break;
5489 default:
5490 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5491 VG_(core_panic)("... bye!\n");
5492 break; /*NOTREACHED*/
5494 # undef ARG2_0
5495 # undef ARG2_1
5496 # undef ARG2_2
5497 # undef ARG2_3
5498 # undef ARG2_4
5499 # undef ARG2_5
5501 #endif
5503 PRE(sys_socket)
5505 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5506 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5508 POST(sys_socket)
5510 SysRes r;
5511 vg_assert(SUCCESS);
5512 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5513 SET_STATUS_from_SysRes(r);
5516 PRE(sys_setsockopt)
5518 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5519 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5520 PRE_REG_READ5(long, "setsockopt",
5521 int, s, int, level, int, optname,
5522 const void *, optval, unsigned, optlen); // socklen_t
5523 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5526 PRE(sys_getsockopt)
5528 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5529 SARG1, SARG2, SARG3, ARG4, SARG5);
5530 PRE_REG_READ5(long, "getsockopt",
5531 int, s, int, level, int, optname,
5532 void *, optval, int, *optlen);
5533 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5535 POST(sys_getsockopt)
5537 vg_assert(SUCCESS);
5538 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5539 ARG1,ARG2,ARG3,ARG4,ARG5);
5542 PRE(sys_connect)
5544 *flags |= SfMayBlock;
5545 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5546 PRE_REG_READ3(long, "connect",
5547 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5548 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5551 PRE(sys_accept)
5553 *flags |= SfMayBlock;
5554 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5555 SARG1, ARG2, ARG3);
5556 PRE_REG_READ3(long, "accept",
5557 int, s, struct sockaddr *, addr, int *, addrlen);
5558 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5560 POST(sys_accept)
5562 SysRes r;
5563 vg_assert(SUCCESS);
5564 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5565 ARG1,ARG2,ARG3);
5566 SET_STATUS_from_SysRes(r);
5569 PRE(sys_accept4)
5571 *flags |= SfMayBlock;
5572 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5573 SARG1, ARG2, ARG3, SARG4);
5574 PRE_REG_READ4(long, "accept4",
5575 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5576 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5578 POST(sys_accept4)
5580 SysRes r;
5581 vg_assert(SUCCESS);
5582 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5583 ARG1,ARG2,ARG3);
5584 SET_STATUS_from_SysRes(r);
5587 PRE(sys_send)
5589 *flags |= SfMayBlock;
5590 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5591 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5592 PRE_REG_READ4(long, "send",
5593 int, s, const void *, msg, vki_size_t, len,
5594 int, flags);
5596 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5599 PRE(sys_sendto)
5601 *flags |= SfMayBlock;
5602 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5603 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5604 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5605 PRE_REG_READ6(long, "sendto",
5606 int, s, const void *, msg, vki_size_t, len,
5607 unsigned int, flags,
5608 const struct sockaddr *, to, int, tolen);
5609 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5612 PRE (sys_recv)
5614 *flags |= SfMayBlock;
5615 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5616 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5617 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5618 unsigned int, flags);
5619 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5622 POST (sys_recv)
5624 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5627 PRE(sys_recvfrom)
5629 *flags |= SfMayBlock;
5630 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5631 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5632 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5633 PRE_REG_READ6(long, "recvfrom",
5634 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5635 struct sockaddr *, from, int *, fromlen);
5636 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5638 POST(sys_recvfrom)
5640 vg_assert(SUCCESS);
5641 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5642 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5645 PRE(sys_sendmsg)
5647 *flags |= SfMayBlock;
5648 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5649 SARG1, ARG2, ARG3);
5650 PRE_REG_READ3(long, "sendmsg",
5651 int, s, const struct msghdr *, msg, unsigned int, flags);
5652 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5655 PRE(sys_recvmsg)
5657 *flags |= SfMayBlock;
5658 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5659 SARG1, ARG2, ARG3);
5660 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5661 unsigned int, flags);
5662 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5664 POST(sys_recvmsg)
5666 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5667 RES);
5670 PRE(sys_shutdown)
5672 *flags |= SfMayBlock;
5673 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5674 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5677 PRE(sys_bind)
5679 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5680 PRE_REG_READ3(long, "bind",
5681 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5682 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5685 PRE(sys_listen)
5687 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5688 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5691 PRE(sys_getsockname)
5693 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5694 SARG1, ARG2, ARG3);
5695 PRE_REG_READ3(long, "getsockname",
5696 int, s, struct sockaddr *, name, int *, namelen);
5697 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5699 POST(sys_getsockname)
5701 vg_assert(SUCCESS);
5702 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5703 ARG1,ARG2,ARG3);
5706 PRE(sys_getpeername)
5708 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5709 SARG1, ARG2, ARG3);
5710 PRE_REG_READ3(long, "getpeername",
5711 int, s, struct sockaddr *, name, int *, namelen);
5712 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5714 POST(sys_getpeername)
5716 vg_assert(SUCCESS);
5717 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5718 ARG1,ARG2,ARG3);
5721 PRE(sys_socketpair)
5723 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5724 SARG3, ARG4);
5725 PRE_REG_READ4(long, "socketpair",
5726 int, d, int, type, int, protocol, int*, sv);
5727 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5729 POST(sys_socketpair)
5731 vg_assert(SUCCESS);
5732 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5733 ARG1,ARG2,ARG3,ARG4);
5737 /* ---------------------------------------------------------------------
5738 *at wrappers
5739 ------------------------------------------------------------------ */
5741 PRE(sys_openat)
5743 HChar name[30]; // large enough
5744 SysRes sres;
5746 if (ARG3 & VKI_O_CREAT) {
5747 // 4-arg version
5748 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5749 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5750 PRE_REG_READ4(long, "openat",
5751 int, dfd, const char *, filename, int, flags, int, mode);
5752 } else {
5753 // 3-arg version
5754 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5755 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5756 PRE_REG_READ3(long, "openat",
5757 int, dfd, const char *, filename, int, flags);
5760 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5762 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5763 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5764 be sure only to compare the bottom 32 bits. */
5765 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5766 && *(Char *)(Addr)ARG2 != '/'
5767 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5768 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5769 SET_STATUS_Failure( VKI_EBADF );
5771 /* Handle the case where the open is of /proc/self/cmdline or
5772 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5773 fake file we cooked up at startup (in m_main). Also, seek the
5774 cloned fd back to the start. */
5776 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5777 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5778 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5779 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5780 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5781 SET_STATUS_from_SysRes( sres );
5782 if (!sr_isError(sres)) {
5783 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5784 if (off < 0)
5785 SET_STATUS_Failure( VKI_EMFILE );
5787 return;
5790 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5792 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5793 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5794 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5795 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5796 sres = VG_(dup)( VG_(cl_auxv_fd) );
5797 SET_STATUS_from_SysRes( sres );
5798 if (!sr_isError(sres)) {
5799 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5800 if (off < 0)
5801 SET_STATUS_Failure( VKI_EMFILE );
5803 return;
5806 /* And for /proc/self/exe or /proc/<pid>/exe case. */
5808 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5809 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5810 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5811 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5812 sres = VG_(dup)( VG_(cl_exec_fd) );
5813 SET_STATUS_from_SysRes( sres );
5814 if (!sr_isError(sres)) {
5815 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5816 if (off < 0)
5817 SET_STATUS_Failure( VKI_EMFILE );
5819 return;
5822 /* Otherwise handle normally */
5823 *flags |= SfMayBlock;
5826 POST(sys_openat)
5828 vg_assert(SUCCESS);
5829 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5830 VG_(close)(RES);
5831 SET_STATUS_Failure( VKI_EMFILE );
5832 } else {
5833 if (VG_(clo_track_fds))
5834 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5838 PRE(sys_mkdirat)
5840 *flags |= SfMayBlock;
5841 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5842 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5843 PRE_REG_READ3(long, "mkdirat",
5844 int, dfd, const char *, pathname, int, mode);
5845 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5848 PRE(sys_mknodat)
5850 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5851 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5852 PRE_REG_READ4(long, "mknodat",
5853 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5854 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5857 PRE(sys_fchownat)
5859 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5860 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5861 PRE_REG_READ4(long, "fchownat",
5862 int, dfd, const char *, path,
5863 vki_uid_t, owner, vki_gid_t, group);
5864 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5867 PRE(sys_futimesat)
5869 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5870 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5871 PRE_REG_READ3(long, "futimesat",
5872 int, dfd, char *, filename, struct timeval *, tvp);
5873 if (ARG2 != 0)
5874 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5875 if (ARG3 != 0)
5876 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5879 PRE(sys_utimensat)
5881 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5882 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5883 PRE_REG_READ4(long, "utimensat",
5884 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5885 if (ARG2 != 0)
5886 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5887 if (ARG3 != 0) {
5888 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5889 then the tv_sec field is ignored. */
5890 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5891 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5892 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5893 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5894 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5895 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5896 if (times[0].tv_nsec != VKI_UTIME_NOW
5897 && times[0].tv_nsec != VKI_UTIME_OMIT)
5898 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5899 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5900 if (times[1].tv_nsec != VKI_UTIME_NOW
5901 && times[1].tv_nsec != VKI_UTIME_OMIT)
5902 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5903 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5908 PRE(sys_utimensat_time64)
5910 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5911 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5912 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5913 PRE_REG_READ4(long, "utimensat_time64",
5914 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5915 if (ARG2 != 0)
5916 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5917 if (ARG3 != 0) {
5918 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5919 then the tv_sec field is ignored. */
5920 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5921 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5922 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5923 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5924 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5925 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5926 if (times[0].tv_nsec != VKI_UTIME_NOW
5927 && times[0].tv_nsec != VKI_UTIME_OMIT)
5928 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5929 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5930 if (times[1].tv_nsec != VKI_UTIME_NOW
5931 && times[1].tv_nsec != VKI_UTIME_OMIT)
5932 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5933 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5938 #if !defined(VGP_nanomips_linux)
5939 PRE(sys_newfstatat)
5941 FUSE_COMPATIBLE_MAY_BLOCK();
5942 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5943 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5944 PRE_REG_READ3(long, "fstatat",
5945 int, dfd, char *, file_name, struct stat *, buf);
5946 // See the comment about Rust in PRE(sys_statx). When glibc does support
5947 // statx rust uses that instead of the system call, but glibc's statx is
5948 // implemented in terms of fstatat, so the filename being NULL is
5949 // transferred here.
5950 if (ARG2 != 0) {
5951 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5952 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5956 POST(sys_newfstatat)
5958 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5960 #endif
5962 PRE(sys_unlinkat)
5964 *flags |= SfMayBlock;
5965 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5966 (HChar*)(Addr)ARG2);
5967 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5968 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5971 PRE(sys_renameat)
5973 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5974 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5975 ARG4, (HChar*)(Addr)ARG4);
5976 PRE_REG_READ4(long, "renameat",
5977 int, olddfd, const char *, oldpath,
5978 int, newdfd, const char *, newpath);
5979 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5980 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5983 PRE(sys_renameat2)
5985 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5986 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5987 ARG4, (HChar*)(Addr)ARG4, ARG5);
5988 PRE_REG_READ5(long, "renameat2",
5989 int, olddfd, const char *, oldpath,
5990 int, newdfd, const char *, newpath,
5991 unsigned int, flags);
5992 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5993 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5996 PRE(sys_linkat)
5998 *flags |= SfMayBlock;
5999 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
6000 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
6001 (HChar*)(Addr)ARG4, SARG5);
6002 PRE_REG_READ5(long, "linkat",
6003 int, olddfd, const char *, oldpath,
6004 int, newdfd, const char *, newpath,
6005 int, flags);
6006 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
6007 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
6010 PRE(sys_symlinkat)
6012 *flags |= SfMayBlock;
6013 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
6014 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
6015 PRE_REG_READ3(long, "symlinkat",
6016 const char *, oldpath, int, newdfd, const char *, newpath);
6017 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
6018 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
6021 PRE(sys_readlinkat)
6023 HChar name[30]; // large enough
6024 Word saved = SYSNO;
6026 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
6027 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
6028 PRE_REG_READ4(long, "readlinkat",
6029 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
6030 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
6031 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
6034 * Handle the case where readlinkat is looking at /proc/self/exe or
6035 * /proc/<pid>/exe.
6037 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
6038 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
6039 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
6040 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
6041 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
6042 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
6043 ARG3, ARG4));
6044 } else {
6045 /* Normal case */
6046 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
6049 if (SUCCESS && RES > 0)
6050 POST_MEM_WRITE( ARG3, RES );
6053 PRE(sys_fchmodat)
6055 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
6056 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6057 PRE_REG_READ3(long, "fchmodat",
6058 int, dfd, const char *, path, vki_mode_t, mode);
6059 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
6062 PRE(sys_faccessat)
6064 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
6065 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
6066 PRE_REG_READ3(long, "faccessat",
6067 int, dfd, const char *, pathname, int, mode);
6068 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
6071 PRE(sys_faccessat2)
6073 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
6074 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
6075 PRE_REG_READ4(long, "faccessat2",
6076 int, dfd, const char *, pathname, int, mode, int, flags);
6077 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6080 PRE(sys_name_to_handle_at)
6082 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6083 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6084 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6085 PRE_REG_READ5(int, "name_to_handle_at",
6086 int, dfd, const char *, name,
6087 struct vki_file_handle *, handle,
6088 int *, mnt_id, int, flag);
6089 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6090 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6091 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6092 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6093 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6095 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6098 POST(sys_name_to_handle_at)
6100 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6101 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6102 POST_MEM_WRITE( ARG4, sizeof(int) );
6105 PRE(sys_open_by_handle_at)
6107 *flags |= SfMayBlock;
6108 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6109 ARG2, SARG3);
6110 PRE_REG_READ3(int, "open_by_handle_at",
6111 int, mountdirfd,
6112 struct vki_file_handle *, handle,
6113 int, flags);
6114 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6115 sizeof(struct vki_file_handle) +
6116 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6119 POST(sys_open_by_handle_at)
6121 vg_assert(SUCCESS);
6122 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6123 VG_(close)(RES);
6124 SET_STATUS_Failure( VKI_EMFILE );
6125 } else {
6126 if (VG_(clo_track_fds))
6127 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6131 /* ---------------------------------------------------------------------
6132 p{read,write}v wrappers
6133 ------------------------------------------------------------------ */
6134 /* This handles the common part of the PRE macro for preadv and preadv2. */
6135 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6136 Int fd, Addr vector, Int count, const char *str)
6138 struct vki_iovec * vec;
6139 Int i;
6140 /* safe size for the "preadv/preadv2(vector[i])" string */
6141 char tmp[30];
6143 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6144 SET_STATUS_Failure( VKI_EBADF );
6145 } else if (count > 0) {
6146 VG_(strcpy) (tmp, str);
6147 VG_(strcat) (tmp, "(vector)");
6148 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6150 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6151 count * sizeof(struct vki_iovec))) {
6152 vec = (struct vki_iovec *)(Addr)vector;
6153 for (i = 0; i < count; i++) {
6154 /* Note: building such a dynamic error string is *not*
6155 a pattern to follow. See bug 417075. */
6156 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6157 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6163 /* This handles the common part of the POST macro for preadv and preadv2. */
6164 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6166 vg_assert(SUCCESS);
6167 if (RES > 0) {
6168 Int i;
6169 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6170 Int remains = RES;
6172 /* RES holds the number of bytes read. */
6173 for (i = 0; i < count; i++) {
6174 Int nReadThisBuf = vec[i].iov_len;
6175 if (nReadThisBuf > remains) nReadThisBuf = remains;
6176 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6177 remains -= nReadThisBuf;
6178 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6183 PRE(sys_preadv)
6185 *flags |= SfMayBlock;
6186 const char *str = "preadv";
6187 #if VG_WORDSIZE == 4
6188 /* Note that the offset argument here is in lo+hi order on both
6189 big and little endian platforms... */
6190 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6191 "u, %lld )",
6192 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6193 PRE_REG_READ5(ssize_t, "preadv",
6194 unsigned long, fd, const struct iovec *, vector,
6195 unsigned long, count, vki_u32, offset_low,
6196 vki_u32, offset_high);
6197 #elif VG_WORDSIZE == 8
6198 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6199 PRE_REG_READ4(ssize_t, "preadv",
6200 unsigned long, fd, const struct iovec *, vector,
6201 unsigned long, count, Word, offset);
6202 #else
6203 # error Unexpected word size
6204 #endif
6205 Int fd = ARG1;
6206 Addr vector = ARG2;
6207 Int count = ARG3;
6209 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6213 POST(sys_preadv)
6215 Addr vector = ARG2;
6216 Int count = ARG3;
6218 handle_post_sys_preadv(tid, status, vector, count);
6221 PRE(sys_preadv2)
6223 *flags |= SfMayBlock;
6224 const char *str = "preadv2";
6225 #if VG_WORDSIZE == 4
6226 /* Note that the offset argument here is in lo+hi order on both
6227 big and little endian platforms... */
6228 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6229 "u, %lld, %" FMT_REGWORD "u )",
6230 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6231 PRE_REG_READ6(ssize_t, "preadv2",
6232 unsigned long, fd, const struct iovec *, vector,
6233 unsigned long, count, vki_u32, offset_low,
6234 vki_u32, offset_high, unsigned long, flags);
6235 #elif VG_WORDSIZE == 8
6236 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6237 PRE_REG_READ5(ssize_t, "preadv2",
6238 unsigned long, fd, const struct iovec *, vector,
6239 unsigned long, count, Word, offset, unsigned long, flags);
6240 #else
6241 # error Unexpected word size
6242 #endif
6243 Int fd = ARG1;
6244 Addr vector = ARG2;
6245 Int count = ARG3;
6247 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6250 POST(sys_preadv2)
6252 Addr vector = ARG2;
6253 Int count = ARG3;
6255 handle_post_sys_preadv(tid, status, vector, count);
6258 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6259 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6260 Int fd, Addr vector, Int count, const char *str)
6262 Int i;
6263 struct vki_iovec * vec;
6264 /* safe size for the "preadv/preadv2(vector[i])" string */
6265 char tmp[30];
6267 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6268 SET_STATUS_Failure( VKI_EBADF );
6269 } else if (count > 0) {
6270 VG_(strcpy) (tmp, str);
6271 VG_(strcat) (tmp, "(vector)");
6272 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6273 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6274 count * sizeof(struct vki_iovec))) {
6275 vec = (struct vki_iovec *)(Addr)vector;
6276 for (i = 0; i < count; i++) {
6277 /* Note: building such a dynamic error string is *not*
6278 a pattern to follow. See bug 417075. */
6279 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6280 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6286 PRE(sys_pwritev)
6288 *flags |= SfMayBlock;
6289 const char *str = "pwritev";
6290 #if VG_WORDSIZE == 4
6291 /* Note that the offset argument here is in lo+hi order on both
6292 big and little endian platforms... */
6293 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6294 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6295 PRE_REG_READ5(ssize_t, "pwritev",
6296 unsigned long, fd, const struct iovec *, vector,
6297 unsigned long, count, vki_u32, offset_low,
6298 vki_u32, offset_high);
6299 #elif VG_WORDSIZE == 8
6300 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6301 PRE_REG_READ4(ssize_t, "pwritev",
6302 unsigned long, fd, const struct iovec *, vector,
6303 unsigned long, count, Word, offset);
6304 #else
6305 # error Unexpected word size
6306 #endif
6307 Int fd = ARG1;
6308 Addr vector = ARG2;
6309 Int count = ARG3;
6311 handle_sys_pwritev(tid, status, fd, vector, count, str);
6314 PRE(sys_pwritev2)
6316 *flags |= SfMayBlock;
6317 const char *str = "pwritev2";
6318 #if VG_WORDSIZE == 4
6319 /* Note that the offset argument here is in lo+hi order on both
6320 big and little endian platforms... */
6321 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6322 "u, %lld, %" FMT_REGWORD "u )",
6323 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6324 PRE_REG_READ6(ssize_t, "pwritev2",
6325 unsigned long, fd, const struct iovec *, vector,
6326 unsigned long, count, vki_u32, offset_low,
6327 vki_u32, offset_high, unsigned long, flags);
6328 #elif VG_WORDSIZE == 8
6329 /* Note offset_high isn't actually used? */
6330 PRE_REG_READ6(ssize_t, "pwritev2",
6331 unsigned long, fd, const struct iovec *, vector,
6332 unsigned long, count, Word, offset,
6333 Word, offset_high, unsigned long, flags);
6334 #else
6335 # error Unexpected word size
6336 #endif
6337 Int fd = ARG1;
6338 Addr vector = ARG2;
6339 Int count = ARG3;
6341 handle_sys_pwritev(tid, status, fd, vector, count, str);
6344 /* ---------------------------------------------------------------------
6345 process_vm_{read,write}v wrappers
6346 ------------------------------------------------------------------ */
6348 PRE(sys_process_vm_readv)
6350 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6351 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6352 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6353 PRE_REG_READ6(ssize_t, "process_vm_readv",
6354 vki_pid_t, pid,
6355 const struct iovec *, lvec,
6356 unsigned long, liovcnt,
6357 const struct iovec *, rvec,
6358 unsigned long, riovcnt,
6359 unsigned long, flags);
6360 PRE_MEM_READ( "process_vm_readv(lvec)",
6361 ARG2, ARG3 * sizeof(struct vki_iovec) );
6362 PRE_MEM_READ( "process_vm_readv(rvec)",
6363 ARG4, ARG5 * sizeof(struct vki_iovec) );
6364 if (ARG2 != 0
6365 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6366 sizeof(struct vki_iovec) * ARG3)) {
6367 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6368 UInt i;
6369 for (i = 0; i < ARG3; i++)
6370 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6371 (Addr)vec[i].iov_base, vec[i].iov_len );
6375 POST(sys_process_vm_readv)
6377 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6378 UInt remains = RES;
6379 UInt i;
6380 for (i = 0; i < ARG3; i++) {
6381 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6382 vec[i].iov_len : remains;
6383 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6384 remains -= nReadThisBuf;
6388 PRE(sys_process_vm_writev)
6390 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6391 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6392 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6393 PRE_REG_READ6(ssize_t, "process_vm_writev",
6394 vki_pid_t, pid,
6395 const struct iovec *, lvec,
6396 unsigned long, liovcnt,
6397 const struct iovec *, rvec,
6398 unsigned long, riovcnt,
6399 unsigned long, flags);
6400 PRE_MEM_READ( "process_vm_writev(lvec)",
6401 ARG2, ARG3 * sizeof(struct vki_iovec) );
6402 PRE_MEM_READ( "process_vm_writev(rvec)",
6403 ARG4, ARG5 * sizeof(struct vki_iovec) );
6404 if (ARG2 != 0
6405 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6406 sizeof(struct vki_iovec) * ARG3)) {
6407 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6408 UInt i;
6409 for (i = 0; i < ARG3; i++)
6410 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6411 (Addr)vec[i].iov_base, vec[i].iov_len );
6415 /* ---------------------------------------------------------------------
6416 {send,recv}mmsg wrappers
6417 ------------------------------------------------------------------ */
6419 PRE(sys_sendmmsg)
6421 *flags |= SfMayBlock;
6422 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6423 SARG3, SARG4);
6424 PRE_REG_READ4(long, "sendmmsg",
6425 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6426 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6429 POST(sys_sendmmsg)
6431 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6434 PRE(sys_recvmmsg)
6436 *flags |= SfMayBlock;
6437 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6438 FMT_REGWORD "x )",
6439 SARG1, ARG2, SARG3, SARG4, ARG5);
6440 PRE_REG_READ5(long, "recvmmsg",
6441 int, s, struct mmsghdr *, mmsg, int, vlen,
6442 int, flags, struct timespec *, timeout);
6443 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6446 POST(sys_recvmmsg)
6448 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6451 PRE(sys_recvmmsg_time64)
6453 *flags |= SfMayBlock;
6454 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6455 FMT_REGWORD "x )",
6456 SARG1, ARG2, SARG3, SARG4, ARG5);
6457 PRE_REG_READ5(long, "recvmmsg_time64",
6458 int, s, struct mmsghdr *, mmsg, int, vlen,
6459 int, flags, struct vki_timespec64 *, timeout);
6460 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6461 HChar name[40]; // large enough
6462 UInt i;
6463 for (i = 0; i < ARG3; i++) {
6464 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6465 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6466 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6467 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6469 if (ARG5)
6470 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6473 POST(sys_recvmmsg_time64)
6475 /* ARG5 isn't actually used, so just use the generic POST. */
6476 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6479 /* ---------------------------------------------------------------------
6480 key retention service wrappers
6481 ------------------------------------------------------------------ */
6483 PRE(sys_request_key)
6485 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6486 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6487 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6488 PRE_REG_READ4(long, "request_key",
6489 const char *, type, const char *, description,
6490 const char *, callout_info, vki_key_serial_t, keyring);
6491 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6492 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6493 if (ARG3 != (UWord)NULL)
6494 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6497 PRE(sys_add_key)
6499 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6500 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6501 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6502 PRE_REG_READ5(long, "add_key",
6503 const char *, type, const char *, description,
6504 const void *, payload, vki_size_t, plen,
6505 vki_key_serial_t, keyring);
6506 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6507 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6508 if (ARG3 != (UWord)NULL)
6509 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6512 PRE(sys_keyctl)
6514 switch (ARG1 /* option */) {
6515 case VKI_KEYCTL_GET_KEYRING_ID:
6516 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6517 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6518 int, option, vki_key_serial_t, id, int, create);
6519 break;
6520 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6521 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6522 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6523 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6524 int, option, const char *, name);
6525 if (ARG2 != (UWord)NULL)
6526 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6527 break;
6528 case VKI_KEYCTL_UPDATE:
6529 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6530 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6531 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6532 int, option, vki_key_serial_t, key,
6533 const void *, payload, vki_size_t, plen);
6534 if (ARG3 != (UWord)NULL)
6535 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6536 break;
6537 case VKI_KEYCTL_REVOKE:
6538 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6539 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6540 int, option, vki_key_serial_t, id);
6541 break;
6542 case VKI_KEYCTL_CHOWN:
6543 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6544 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6545 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6546 int, option, vki_key_serial_t, id,
6547 vki_uid_t, uid, vki_gid_t, gid);
6548 break;
6549 case VKI_KEYCTL_SETPERM:
6550 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6551 SARG2, ARG3);
6552 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6553 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6554 break;
6555 case VKI_KEYCTL_DESCRIBE:
6556 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6557 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6558 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6559 int, option, vki_key_serial_t, id,
6560 char *, buffer, vki_size_t, buflen);
6561 if (ARG3 != (UWord)NULL)
6562 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6563 break;
6564 case VKI_KEYCTL_CLEAR:
6565 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6566 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6567 int, option, vki_key_serial_t, keyring);
6568 break;
6569 case VKI_KEYCTL_LINK:
6570 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6571 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6572 vki_key_serial_t, keyring, vki_key_serial_t, key);
6573 break;
6574 case VKI_KEYCTL_UNLINK:
6575 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6576 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6577 vki_key_serial_t, keyring, vki_key_serial_t, key);
6578 break;
6579 case VKI_KEYCTL_SEARCH:
6580 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6581 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6582 ARG4, (HChar*)(Addr)ARG4, SARG5);
6583 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6584 int, option, vki_key_serial_t, keyring,
6585 const char *, type, const char *, description,
6586 vki_key_serial_t, destring);
6587 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6588 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6589 break;
6590 case VKI_KEYCTL_READ:
6591 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6592 "u )", SARG2, ARG3, ARG4);
6593 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6594 int, option, vki_key_serial_t, keyring,
6595 char *, buffer, vki_size_t, buflen);
6596 if (ARG3 != (UWord)NULL)
6597 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6598 break;
6599 case VKI_KEYCTL_INSTANTIATE:
6600 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6601 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6602 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6603 int, option, vki_key_serial_t, key,
6604 char *, payload, vki_size_t, plen,
6605 vki_key_serial_t, keyring);
6606 if (ARG3 != (UWord)NULL)
6607 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6608 break;
6609 case VKI_KEYCTL_NEGATE:
6610 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6611 SARG2, ARG3, SARG4);
6612 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6613 int, option, vki_key_serial_t, key,
6614 unsigned, timeout, vki_key_serial_t, keyring);
6615 break;
6616 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6617 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6618 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6619 int, option, int, reqkey_defl);
6620 break;
6621 case VKI_KEYCTL_SET_TIMEOUT:
6622 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6623 SARG2, ARG3);
6624 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6625 int, option, vki_key_serial_t, key, unsigned, timeout);
6626 break;
6627 case VKI_KEYCTL_ASSUME_AUTHORITY:
6628 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6629 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6630 int, option, vki_key_serial_t, key);
6631 break;
6632 default:
6633 PRINT("sys_keyctl ( %ld ) ", SARG1);
6634 PRE_REG_READ1(long, "keyctl", int, option);
6635 break;
6639 POST(sys_keyctl)
6641 vg_assert(SUCCESS);
6642 switch (ARG1 /* option */) {
6643 case VKI_KEYCTL_DESCRIBE:
6644 case VKI_KEYCTL_READ:
6645 if (RES > ARG4)
6646 POST_MEM_WRITE(ARG3, ARG4);
6647 else
6648 POST_MEM_WRITE(ARG3, RES);
6649 break;
6650 default:
6651 break;
6655 /* ---------------------------------------------------------------------
6656 ioprio_ wrappers
6657 ------------------------------------------------------------------ */
6659 PRE(sys_ioprio_set)
6661 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6662 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6665 PRE(sys_ioprio_get)
6667 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6668 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6671 /* ---------------------------------------------------------------------
6672 _module wrappers
6673 ------------------------------------------------------------------ */
6675 PRE(sys_init_module)
6677 *flags |= SfMayBlock;
6678 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6679 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6680 PRE_REG_READ3(long, "init_module",
6681 void *, umod, unsigned long, len, const char *, uargs);
6682 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6683 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6686 PRE(sys_finit_module)
6688 *flags |= SfMayBlock;
6690 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6691 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6692 PRE_REG_READ3(long, "finit_module",
6693 int, fd, const char *, params, int, flags);
6694 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6697 PRE(sys_delete_module)
6699 *flags |= SfMayBlock;
6700 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6701 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6702 PRE_REG_READ2(long, "delete_module",
6703 const char *, name_user, unsigned int, flags);
6704 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6707 /* ---------------------------------------------------------------------
6708 splice wrappers
6709 ------------------------------------------------------------------ */
6711 PRE(sys_splice)
6713 *flags |= SfMayBlock;
6714 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6715 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6716 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6717 PRE_REG_READ6(vki_ssize_t, "splice",
6718 int, fd_in, vki_loff_t *, off_in,
6719 int, fd_out, vki_loff_t *, off_out,
6720 vki_size_t, len, unsigned int, flags);
6721 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6722 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6723 SET_STATUS_Failure( VKI_EBADF );
6724 } else {
6725 if (ARG2 != 0)
6726 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6727 if (ARG4 != 0)
6728 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6732 PRE(sys_tee)
6734 *flags |= SfMayBlock;
6735 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6736 SARG1, SARG2, ARG3, ARG4);
6737 PRE_REG_READ4(vki_ssize_t, "tee",
6738 int, fd_in, int, fd_out,
6739 vki_size_t, len, unsigned int, flags);
6740 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6741 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6742 SET_STATUS_Failure( VKI_EBADF );
6746 PRE(sys_vmsplice)
6748 Int fdfl;
6749 *flags |= SfMayBlock;
6750 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6751 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6752 PRE_REG_READ4(vki_ssize_t, "splice",
6753 int, fd, struct vki_iovec *, iov,
6754 unsigned long, nr_segs, unsigned int, flags);
6755 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6756 SET_STATUS_Failure( VKI_EBADF );
6757 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6758 SET_STATUS_Failure( VKI_EBADF );
6759 } else {
6760 const struct vki_iovec *iov;
6761 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6762 for (iov = (struct vki_iovec *)(Addr)ARG2;
6763 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6765 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6766 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6767 PRE_MEM_WRITE( "vmsplice(iov[...])",
6768 (Addr)iov->iov_base, iov->iov_len );
6769 else
6770 PRE_MEM_READ( "vmsplice(iov[...])",
6771 (Addr)iov->iov_base, iov->iov_len );
6777 POST(sys_vmsplice)
6779 vg_assert(SUCCESS);
6780 if (RES > 0) {
6781 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6782 vg_assert(fdfl >= 0);
6783 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6785 const struct vki_iovec *iov;
6786 for (iov = (struct vki_iovec *)(Addr)ARG2;
6787 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6789 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6795 /* ---------------------------------------------------------------------
6796 oprofile-related wrappers
6797 ------------------------------------------------------------------ */
6799 #if defined(VGP_x86_linux)
6800 PRE(sys_lookup_dcookie)
6802 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6803 MERGE64(ARG1,ARG2), ARG3, ARG4);
6804 PRE_REG_READ4(long, "lookup_dcookie",
6805 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6806 char *, buf, vki_size_t, len);
6807 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6809 POST(sys_lookup_dcookie)
6811 vg_assert(SUCCESS);
6812 if (ARG3 != (Addr)NULL)
6813 POST_MEM_WRITE( ARG3, RES);
6815 #endif
6817 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6818 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6819 PRE(sys_lookup_dcookie)
6821 *flags |= SfMayBlock;
6822 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6823 PRE_REG_READ3(int, "lookup_dcookie",
6824 unsigned long long, cookie, char *, buf, vki_size_t, len);
6826 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6829 POST(sys_lookup_dcookie)
6831 vg_assert(SUCCESS);
6832 if (ARG2 != (Addr)NULL)
6833 POST_MEM_WRITE( ARG2, RES );
6835 #endif
6837 /* ---------------------------------------------------------------------
6838 fcntl wrappers
6839 ------------------------------------------------------------------ */
6841 PRE(sys_fcntl)
6843 switch (ARG2) {
6844 // These ones ignore ARG3.
6845 case VKI_F_GETFD:
6846 case VKI_F_GETFL:
6847 case VKI_F_GETOWN:
6848 case VKI_F_GETSIG:
6849 case VKI_F_GETLEASE:
6850 case VKI_F_GETPIPE_SZ:
6851 case VKI_F_GET_SEALS:
6852 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6853 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6854 break;
6856 // These ones use ARG3 as "arg".
6857 case VKI_F_DUPFD:
6858 case VKI_F_DUPFD_CLOEXEC:
6859 case VKI_F_SETFD:
6860 case VKI_F_SETFL:
6861 case VKI_F_SETLEASE:
6862 case VKI_F_NOTIFY:
6863 case VKI_F_SETOWN:
6864 case VKI_F_SETSIG:
6865 case VKI_F_SETPIPE_SZ:
6866 case VKI_F_ADD_SEALS:
6867 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6868 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6869 PRE_REG_READ3(long, "fcntl",
6870 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6871 break;
6873 // These ones use ARG3 as "lock".
6874 case VKI_F_GETLK:
6875 case VKI_F_SETLK:
6876 case VKI_F_SETLKW:
6877 case VKI_F_OFD_GETLK:
6878 case VKI_F_OFD_SETLK:
6879 case VKI_F_OFD_SETLKW:
6880 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6881 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6882 PRE_REG_READ3(long, "fcntl",
6883 unsigned int, fd, unsigned int, cmd,
6884 struct vki_flock *, lock);
6886 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6887 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6888 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6889 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6890 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6891 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6892 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6895 break;
6897 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6898 case VKI_F_GETLK64:
6899 case VKI_F_SETLK64:
6900 case VKI_F_SETLKW64:
6901 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6902 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6903 PRE_REG_READ3(long, "fcntl",
6904 unsigned int, fd, unsigned int, cmd,
6905 struct flock64 *, lock);
6907 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6908 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6909 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6910 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6911 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6912 if (ARG2 == VKI_F_GETLK64) {
6913 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6916 break;
6917 # endif
6919 case VKI_F_SETOWN_EX:
6920 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6921 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6922 PRE_REG_READ3(long, "fcntl",
6923 unsigned int, fd, unsigned int, cmd,
6924 struct vki_f_owner_ex *, arg);
6925 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6926 break;
6928 case VKI_F_GETOWN_EX:
6929 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6930 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6931 PRE_REG_READ3(long, "fcntl",
6932 unsigned int, fd, unsigned int, cmd,
6933 struct vki_f_owner_ex *, arg);
6934 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6935 break;
6937 default:
6938 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6939 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6940 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6941 ARG2);
6942 SET_STATUS_Failure( VKI_EINVAL );
6943 break;
6946 # if defined(VGP_x86_linux)
6947 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6948 # else
6949 if (ARG2 == VKI_F_SETLKW)
6950 # endif
6951 *flags |= SfMayBlock;
6954 POST(sys_fcntl)
6956 vg_assert(SUCCESS);
6957 if (ARG2 == VKI_F_DUPFD) {
6958 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6959 VG_(close)(RES);
6960 SET_STATUS_Failure( VKI_EMFILE );
6961 } else {
6962 if (VG_(clo_track_fds))
6963 ML_(record_fd_open_named)(tid, RES);
6966 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6967 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6968 VG_(close)(RES);
6969 SET_STATUS_Failure( VKI_EMFILE );
6970 } else {
6971 if (VG_(clo_track_fds))
6972 ML_(record_fd_open_named)(tid, RES);
6974 } else if (ARG2 == VKI_F_GETOWN_EX) {
6975 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6976 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6977 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6978 POST_FIELD_WRITE(lock->l_pid);
6979 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6980 } else if (ARG2 == VKI_F_GETLK64) {
6981 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6982 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6983 # endif
6987 // XXX: wrapper only suitable for 32-bit systems
6988 PRE(sys_fcntl64)
6990 switch (ARG2) {
6991 // These ones ignore ARG3.
6992 case VKI_F_GETFD:
6993 case VKI_F_GETFL:
6994 case VKI_F_GETOWN:
6995 case VKI_F_SETOWN:
6996 case VKI_F_GETSIG:
6997 case VKI_F_SETSIG:
6998 case VKI_F_GETLEASE:
6999 case VKI_F_GET_SEALS:
7000 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
7001 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
7002 break;
7004 // These ones use ARG3 as "arg".
7005 case VKI_F_DUPFD:
7006 case VKI_F_DUPFD_CLOEXEC:
7007 case VKI_F_SETFD:
7008 case VKI_F_SETFL:
7009 case VKI_F_SETLEASE:
7010 case VKI_F_NOTIFY:
7011 case VKI_F_ADD_SEALS:
7012 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7013 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7014 PRE_REG_READ3(long, "fcntl64",
7015 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
7016 break;
7018 // These ones use ARG3 as "lock".
7019 case VKI_F_GETLK:
7020 case VKI_F_SETLK:
7021 case VKI_F_SETLKW:
7022 # if defined(VGP_x86_linux)
7023 case VKI_F_GETLK64:
7024 case VKI_F_SETLK64:
7025 case VKI_F_SETLKW64:
7026 # endif
7027 case VKI_F_OFD_GETLK:
7028 case VKI_F_OFD_SETLK:
7029 case VKI_F_OFD_SETLKW:
7030 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7031 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7032 PRE_REG_READ3(long, "fcntl64",
7033 unsigned int, fd, unsigned int, cmd,
7034 struct flock64 *, lock);
7035 break;
7037 case VKI_F_SETOWN_EX:
7038 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7039 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7040 PRE_REG_READ3(long, "fcntl",
7041 unsigned int, fd, unsigned int, cmd,
7042 struct vki_f_owner_ex *, arg);
7043 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7044 break;
7046 case VKI_F_GETOWN_EX:
7047 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7048 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7049 PRE_REG_READ3(long, "fcntl",
7050 unsigned int, fd, unsigned int, cmd,
7051 struct vki_f_owner_ex *, arg);
7052 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7053 break;
7056 # if defined(VGP_x86_linux)
7057 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7058 # else
7059 if (ARG2 == VKI_F_SETLKW)
7060 # endif
7061 *flags |= SfMayBlock;
7064 POST(sys_fcntl64)
7066 vg_assert(SUCCESS);
7067 if (ARG2 == VKI_F_DUPFD) {
7068 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
7069 VG_(close)(RES);
7070 SET_STATUS_Failure( VKI_EMFILE );
7071 } else {
7072 if (VG_(clo_track_fds))
7073 ML_(record_fd_open_named)(tid, RES);
7076 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7077 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
7078 VG_(close)(RES);
7079 SET_STATUS_Failure( VKI_EMFILE );
7080 } else {
7081 if (VG_(clo_track_fds))
7082 ML_(record_fd_open_named)(tid, RES);
7084 } else if (ARG2 == VKI_F_GETOWN_EX) {
7085 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7089 /* ---------------------------------------------------------------------
7090 ioctl wrappers
7091 ------------------------------------------------------------------ */
7093 struct vg_drm_version_info {
7094 struct vki_drm_version data;
7095 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7098 PRE(sys_ioctl)
7100 *flags |= SfMayBlock;
7102 ARG2 = (UInt)ARG2;
7104 // We first handle the ones that don't use ARG3 (even as a
7105 // scalar/non-pointer argument).
7106 switch (ARG2 /* request */) {
7108 /* asm-generic/ioctls.h */
7109 case VKI_FIOCLEX:
7110 case VKI_FIONCLEX:
7111 case VKI_TIOCNOTTY:
7113 /* linux perf_event ioctls */
7114 case VKI_PERF_EVENT_IOC_ENABLE:
7115 case VKI_PERF_EVENT_IOC_DISABLE:
7117 /* linux/soundcard interface (ALSA) */
7118 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7119 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7120 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7121 case VKI_SNDRV_PCM_IOCTL_RESET:
7122 case VKI_SNDRV_PCM_IOCTL_START:
7123 case VKI_SNDRV_PCM_IOCTL_DROP:
7124 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7125 case VKI_SNDRV_PCM_IOCTL_RESUME:
7126 case VKI_SNDRV_PCM_IOCTL_XRUN:
7127 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7128 case VKI_SNDRV_TIMER_IOCTL_START:
7129 case VKI_SNDRV_TIMER_IOCTL_STOP:
7130 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7131 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7133 /* SCSI no operand */
7134 case VKI_SCSI_IOCTL_DOORLOCK:
7135 case VKI_SCSI_IOCTL_DOORUNLOCK:
7137 /* CDROM stuff. */
7138 case VKI_CDROM_DISC_STATUS:
7139 case VKI_CDROMSTOP:
7141 /* DVD stuff */
7142 case VKI_DVD_READ_STRUCT:
7144 /* KVM ioctls that don't check for a numeric value as parameter */
7145 case VKI_KVM_S390_ENABLE_SIE:
7146 case VKI_KVM_CREATE_IRQCHIP:
7147 case VKI_KVM_S390_INITIAL_RESET:
7148 case VKI_KVM_KVMCLOCK_CTRL:
7150 /* vhost without parameter */
7151 case VKI_VHOST_SET_OWNER:
7152 case VKI_VHOST_RESET_OWNER:
7154 /* User input device creation */
7155 case VKI_UI_DEV_CREATE:
7156 case VKI_UI_DEV_DESTROY:
7158 /* InfiniBand */
7159 case VKI_IB_USER_MAD_ENABLE_PKEY:
7161 /* Lustre */
7162 case VKI_LL_IOC_GROUP_LOCK:
7163 case VKI_LL_IOC_GROUP_UNLOCK:
7165 /* V4L2 */
7166 case VKI_V4L2_LOG_STATUS:
7168 /* Mesa */
7169 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7171 /* DVB */
7172 case VKI_DMX_STOP:
7173 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7174 PRE_REG_READ2(long, "ioctl",
7175 unsigned int, fd, unsigned int, request);
7176 return;
7178 default:
7179 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7180 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7181 PRE_REG_READ3(long, "ioctl",
7182 unsigned int, fd, unsigned int, request, unsigned long, arg);
7183 break;
7186 // We now handle those that do look at ARG3 (and unknown ones fall into
7187 // this category). Nb: some of these may well belong in the
7188 // doesn't-use-ARG3 switch above.
7189 switch (ARG2 /* request */) {
7191 case VKI_ION_IOC_ALLOC: {
7192 struct vki_ion_allocation_data* data
7193 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7194 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7195 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7196 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7197 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7198 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7199 break;
7201 case VKI_ION_IOC_MAP: {
7202 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7203 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7204 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7205 break;
7207 case VKI_ION_IOC_IMPORT: {
7208 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7209 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7210 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7211 break;
7214 case VKI_SYNC_IOC_MERGE: {
7215 struct vki_sync_merge_data* data =
7216 (struct vki_sync_merge_data*)(Addr)ARG3;
7217 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7218 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7219 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7220 break;
7223 case VKI_TCSETS:
7224 case VKI_TCSETSW:
7225 case VKI_TCSETSF:
7226 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7227 break;
7228 case VKI_TCGETS:
7229 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7230 break;
7231 case VKI_TCSETA:
7232 case VKI_TCSETAW:
7233 case VKI_TCSETAF:
7234 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7235 break;
7236 case VKI_TCGETA:
7237 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7238 break;
7239 case VKI_TCSBRK:
7240 case VKI_TCXONC:
7241 case VKI_TCSBRKP:
7242 case VKI_TCFLSH:
7243 case VKI_TIOCSIG:
7244 /* These just take an int by value */
7245 break;
7246 case VKI_TIOCGWINSZ:
7247 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7248 break;
7249 case VKI_TIOCSWINSZ:
7250 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7251 break;
7252 case VKI_TIOCMBIS:
7253 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7254 break;
7255 case VKI_TIOCMBIC:
7256 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7257 break;
7258 case VKI_TIOCMSET:
7259 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7260 break;
7261 case VKI_TIOCMGET:
7262 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7263 break;
7264 case VKI_TIOCLINUX:
7265 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7266 if (*(char *)(Addr)ARG3 == 11) {
7267 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7269 break;
7270 case VKI_TIOCGPGRP:
7271 /* Get process group ID for foreground processing group. */
7272 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7273 break;
7274 case VKI_TIOCSPGRP:
7275 /* Set a process group ID? */
7276 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7277 break;
7278 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7279 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7280 break;
7281 case VKI_TIOCSCTTY:
7282 /* Just takes an int value. */
7283 break;
7284 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7285 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7286 break;
7287 case VKI_FIONBIO:
7288 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7289 break;
7290 case VKI_FIOASYNC:
7291 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7292 break;
7293 case VKI_FIONREAD: /* identical to SIOCINQ */
7294 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7295 break;
7296 case VKI_FIOQSIZE:
7297 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7298 break;
7300 case VKI_TIOCSERGETLSR:
7301 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7302 break;
7303 case VKI_TIOCGICOUNT:
7304 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7305 sizeof(struct vki_serial_icounter_struct) );
7306 break;
7308 case VKI_SG_SET_COMMAND_Q:
7309 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7310 break;
7311 case VKI_SG_IO:
7312 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7314 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7315 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7316 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7317 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7318 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7321 break;
7322 case VKI_SG_GET_SCSI_ID:
7323 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7324 break;
7325 case VKI_SG_SET_RESERVED_SIZE:
7326 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7327 break;
7328 case VKI_SG_SET_TIMEOUT:
7329 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7330 break;
7331 case VKI_SG_GET_RESERVED_SIZE:
7332 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7333 break;
7334 case VKI_SG_GET_TIMEOUT:
7335 break;
7336 case VKI_SG_GET_VERSION_NUM:
7337 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7338 break;
7339 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7340 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7341 break;
7342 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7343 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7344 break;
7346 case VKI_IIOCGETCPS:
7347 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7348 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7349 break;
7350 case VKI_IIOCNETGPN:
7351 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7352 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7353 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7354 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7355 sizeof(vki_isdn_net_ioctl_phone) );
7356 break;
7358 /* These all use struct ifreq AFAIK */
7359 case VKI_SIOCGIFINDEX: /* get iface index */
7360 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7361 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7362 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7363 break;
7364 case VKI_SIOCGIFFLAGS: /* get flags */
7365 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7366 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7367 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7368 break;
7369 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7370 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7371 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7372 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7373 break;
7374 case VKI_SIOCGIFMTU: /* get MTU size */
7375 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7376 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7377 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7378 break;
7379 case VKI_SIOCGIFADDR: /* get PA address */
7380 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7381 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7382 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7383 break;
7384 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7385 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7386 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7387 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7388 break;
7389 case VKI_SIOCGIFMETRIC: /* get metric */
7390 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7391 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7392 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7393 break;
7394 case VKI_SIOCGIFMAP: /* Get device parameters */
7395 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7396 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7397 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7398 break;
7399 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7400 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7401 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7402 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7403 break;
7404 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7405 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7406 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7407 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7408 break;
7409 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7410 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7411 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7412 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7413 break;
7414 case VKI_SIOCGIFNAME: /* get iface name */
7415 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7416 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7417 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7418 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7419 break;
7421 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7422 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7423 // The kernel will have to look at ifr_data to determine which operation
7424 // to perform.
7425 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7426 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7428 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7430 // Is this correct? Is ifr_name *always* looked at?
7431 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7432 (Addr)ir->vki_ifr_name );
7434 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7435 // the whole structure is defined. So in this case, just check it's
7436 // accessible.
7437 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7438 case VKI_ETHTOOL_GSET:
7439 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7440 (Addr)ir, sizeof(struct vki_ifreq) );
7441 break;
7442 default:
7443 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7444 (Addr)ir, sizeof(struct vki_ifreq) );
7445 break;
7448 // Now perform the relevant pre-action for the operation.
7449 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7450 case VKI_ETHTOOL_GSET:
7451 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7452 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7453 break;
7454 case VKI_ETHTOOL_SSET:
7455 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7456 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7457 break;
7458 case VKI_ETHTOOL_GDRVINFO:
7459 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7460 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7461 break;
7462 case VKI_ETHTOOL_GREGS:
7463 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7464 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7465 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7466 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7467 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7468 break;
7469 case VKI_ETHTOOL_GWOL:
7470 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7471 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7472 break;
7473 case VKI_ETHTOOL_SWOL:
7474 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7475 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7476 break;
7477 case VKI_ETHTOOL_GMSGLVL:
7478 case VKI_ETHTOOL_GLINK:
7479 case VKI_ETHTOOL_GRXCSUM:
7480 case VKI_ETHTOOL_GSG:
7481 case VKI_ETHTOOL_GTSO:
7482 case VKI_ETHTOOL_GUFO:
7483 case VKI_ETHTOOL_GGSO:
7484 case VKI_ETHTOOL_GFLAGS:
7485 case VKI_ETHTOOL_GGRO:
7486 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7487 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7488 break;
7489 case VKI_ETHTOOL_SMSGLVL:
7490 case VKI_ETHTOOL_SRXCSUM:
7491 case VKI_ETHTOOL_SSG:
7492 case VKI_ETHTOOL_STSO:
7493 case VKI_ETHTOOL_SUFO:
7494 case VKI_ETHTOOL_SGSO:
7495 case VKI_ETHTOOL_SFLAGS:
7496 case VKI_ETHTOOL_SGRO:
7497 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7498 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7499 break;
7500 case VKI_ETHTOOL_NWAY_RST:
7501 break;
7502 case VKI_ETHTOOL_GRINGPARAM:
7503 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7504 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7505 break;
7506 case VKI_ETHTOOL_SRINGPARAM:
7507 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7508 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7509 break;
7510 case VKI_ETHTOOL_TEST:
7511 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7512 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7513 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7514 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7515 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7516 break;
7517 case VKI_ETHTOOL_PHYS_ID:
7518 break;
7519 case VKI_ETHTOOL_GPERMADDR:
7520 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7521 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7522 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7523 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7524 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7525 break;
7526 case VKI_ETHTOOL_RESET:
7527 break;
7528 case VKI_ETHTOOL_GSSET_INFO:
7529 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7530 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7531 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7532 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7533 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7534 break;
7535 case VKI_ETHTOOL_GFEATURES:
7536 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7537 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7538 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7539 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7540 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7541 break;
7542 case VKI_ETHTOOL_SFEATURES:
7543 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7544 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7545 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7546 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7547 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7548 break;
7549 case VKI_ETHTOOL_GCHANNELS:
7550 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7551 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7552 break;
7553 case VKI_ETHTOOL_SCHANNELS:
7554 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7555 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7556 break;
7557 case VKI_ETHTOOL_GET_TS_INFO:
7558 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7559 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7560 break;
7562 break;
7563 } /* case VKI_SIOCETHTOOL */
7565 case VKI_SIOCGMIIPHY: /* get hardware entry */
7566 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7567 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7568 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7569 break;
7570 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7571 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7572 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7573 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7574 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7575 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7576 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7577 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7578 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7579 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7580 sizeof(struct vki_ifreq));
7581 break;
7582 case VKI_SIOCGIFCONF: /* get iface list */
7583 /* WAS:
7584 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7585 KERNEL_DO_SYSCALL(tid,RES);
7586 if (!VG_(is_kerror)(RES) && RES == 0)
7587 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7589 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7590 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7591 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7592 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7593 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7594 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7595 if ( ARG3 ) {
7596 // TODO len must be readable and writable
7597 // buf pointer only needs to be readable
7598 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7599 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7600 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7602 break;
7603 case VKI_SIOCGSTAMP:
7604 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7605 break;
7606 case VKI_SIOCGSTAMPNS:
7607 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7608 break;
7609 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7610 the number of bytes currently in that socket's send buffer.
7611 It writes this value as an int to the memory location
7612 indicated by the third argument of ioctl(2). */
7613 case VKI_SIOCOUTQ:
7614 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7615 break;
7616 case VKI_SIOCGRARP: /* get RARP table entry */
7617 case VKI_SIOCGARP: /* get ARP table entry */
7618 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7619 break;
7621 case VKI_SIOCSIFFLAGS: /* set flags */
7622 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7623 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7624 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7625 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7626 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7627 break;
7628 case VKI_SIOCSIFMAP: /* Set device parameters */
7629 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7630 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7631 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7632 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7633 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7634 break;
7635 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7636 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7637 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7638 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7639 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7640 sizeof(struct vki_hwtstamp_config) );
7641 break;
7642 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7643 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7644 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7645 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7646 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7647 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7648 break;
7649 case VKI_SIOCSIFADDR: /* set PA address */
7650 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7651 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7652 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7653 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7654 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7655 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7656 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7657 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7658 break;
7659 case VKI_SIOCSIFMETRIC: /* set metric */
7660 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7661 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7662 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7663 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7664 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7665 break;
7666 case VKI_SIOCSIFMTU: /* set MTU size */
7667 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7668 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7669 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7670 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7671 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7672 break;
7673 case VKI_SIOCSIFHWADDR: /* set hardware address */
7674 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7675 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7676 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7677 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7678 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7679 break;
7680 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7681 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7682 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7683 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7684 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7685 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7686 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7687 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7688 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7689 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7690 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7691 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7692 break;
7693 /* Routing table calls. */
7694 case VKI_SIOCADDRT: /* add routing table entry */
7695 case VKI_SIOCDELRT: /* delete routing table entry */
7696 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7697 sizeof(struct vki_rtentry));
7698 break;
7700 /* tun/tap related ioctls */
7701 case VKI_TUNSETNOCSUM:
7702 case VKI_TUNSETDEBUG:
7703 break;
7704 case VKI_TUNSETIFF:
7705 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7706 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7707 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7708 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7709 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7710 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7711 break;
7712 case VKI_TUNSETPERSIST:
7713 case VKI_TUNSETOWNER:
7714 case VKI_TUNSETLINK:
7715 case VKI_TUNSETGROUP:
7716 break;
7717 case VKI_TUNGETFEATURES:
7718 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7719 break;
7720 case VKI_TUNSETOFFLOAD:
7721 break;
7722 case VKI_TUNGETIFF:
7723 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7724 break;
7725 case VKI_TUNGETSNDBUF:
7726 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7727 break;
7728 case VKI_TUNSETSNDBUF:
7729 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7730 break;
7731 case VKI_TUNGETVNETHDRSZ:
7732 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7733 break;
7734 case VKI_TUNSETVNETHDRSZ:
7735 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7736 break;
7737 case VKI_TUNSETQUEUE:
7738 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7739 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7740 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7741 break;
7742 case VKI_TUNSETIFINDEX:
7743 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7744 break;
7746 /* RARP cache control calls. */
7747 case VKI_SIOCDRARP: /* delete RARP table entry */
7748 case VKI_SIOCSRARP: /* set RARP table entry */
7749 /* ARP cache control calls. */
7750 case VKI_SIOCSARP: /* set ARP table entry */
7751 case VKI_SIOCDARP: /* delete ARP table entry */
7752 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7753 break;
7755 case VKI_SIOCGPGRP:
7756 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7757 break;
7758 case VKI_SIOCSPGRP:
7759 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7760 //tst->sys_flags &= ~SfMayBlock;
7761 break;
7763 case VKI_SIOCATMARK:
7764 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7765 break;
7767 /* linux/soundcard interface (OSS) */
7768 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7769 case VKI_SNDCTL_SEQ_GETINCOUNT:
7770 case VKI_SNDCTL_SEQ_PERCMODE:
7771 case VKI_SNDCTL_SEQ_TESTMIDI:
7772 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7773 case VKI_SNDCTL_SEQ_NRSYNTHS:
7774 case VKI_SNDCTL_SEQ_NRMIDIS:
7775 case VKI_SNDCTL_SEQ_GETTIME:
7776 case VKI_SNDCTL_DSP_GETBLKSIZE:
7777 case VKI_SNDCTL_DSP_GETFMTS:
7778 case VKI_SNDCTL_DSP_GETTRIGGER:
7779 case VKI_SNDCTL_DSP_GETODELAY:
7780 case VKI_SNDCTL_DSP_GETSPDIF:
7781 case VKI_SNDCTL_DSP_GETCAPS:
7782 case VKI_SOUND_PCM_READ_RATE:
7783 case VKI_SOUND_PCM_READ_CHANNELS:
7784 case VKI_SOUND_PCM_READ_BITS:
7785 case VKI_SOUND_PCM_READ_FILTER:
7786 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7787 ARG3, sizeof(int));
7788 break;
7789 case VKI_SNDCTL_SEQ_CTRLRATE:
7790 case VKI_SNDCTL_DSP_SPEED:
7791 case VKI_SNDCTL_DSP_STEREO:
7792 case VKI_SNDCTL_DSP_CHANNELS:
7793 case VKI_SOUND_PCM_WRITE_FILTER:
7794 case VKI_SNDCTL_DSP_SUBDIVIDE:
7795 case VKI_SNDCTL_DSP_SETFRAGMENT:
7796 case VKI_SNDCTL_DSP_SETFMT:
7797 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7798 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7799 case VKI_SNDCTL_TMR_TIMEBASE:
7800 case VKI_SNDCTL_TMR_TEMPO:
7801 case VKI_SNDCTL_TMR_SOURCE:
7802 case VKI_SNDCTL_MIDI_PRETIME:
7803 case VKI_SNDCTL_MIDI_MPUMODE:
7804 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7805 ARG3, sizeof(int));
7806 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7807 ARG3, sizeof(int));
7808 break;
7809 case VKI_SNDCTL_DSP_GETOSPACE:
7810 case VKI_SNDCTL_DSP_GETISPACE:
7811 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7812 ARG3, sizeof(vki_audio_buf_info));
7813 break;
7814 case VKI_SNDCTL_DSP_NONBLOCK:
7815 break;
7816 case VKI_SNDCTL_DSP_SETTRIGGER:
7817 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7818 ARG3, sizeof(int));
7819 break;
7821 case VKI_SNDCTL_DSP_POST:
7822 case VKI_SNDCTL_DSP_RESET:
7823 case VKI_SNDCTL_DSP_SYNC:
7824 case VKI_SNDCTL_DSP_SETSYNCRO:
7825 case VKI_SNDCTL_DSP_SETDUPLEX:
7826 break;
7828 /* linux/soundcard interface (ALSA) */
7829 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7830 case VKI_SNDRV_PCM_IOCTL_LINK:
7831 /* these just take an int by value */
7832 break;
7833 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7834 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7835 break;
7836 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7837 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7838 break;
7839 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7840 struct vki_snd_ctl_elem_list *data =
7841 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7842 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7843 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7844 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7845 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7846 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7847 if (data->pids) {
7848 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7850 break;
7852 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7853 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7854 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7855 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7856 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7857 break;
7859 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7860 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7861 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7862 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7863 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7864 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7865 break;
7868 /* Real Time Clock (/dev/rtc) ioctls */
7869 case VKI_RTC_UIE_ON:
7870 case VKI_RTC_UIE_OFF:
7871 case VKI_RTC_AIE_ON:
7872 case VKI_RTC_AIE_OFF:
7873 case VKI_RTC_PIE_ON:
7874 case VKI_RTC_PIE_OFF:
7875 case VKI_RTC_IRQP_SET:
7876 break;
7877 case VKI_RTC_RD_TIME:
7878 case VKI_RTC_ALM_READ:
7879 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7880 ARG3, sizeof(struct vki_rtc_time));
7881 break;
7882 case VKI_RTC_ALM_SET:
7883 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7884 break;
7885 case VKI_RTC_IRQP_READ:
7886 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7887 break;
7889 /* Loopback control */
7890 case VKI_LOOP_CTL_ADD:
7891 case VKI_LOOP_CTL_REMOVE:
7892 case VKI_LOOP_CTL_GET_FREE:
7893 break;
7894 /* Loopback device */
7895 case VKI_LOOP_SET_FD:
7896 case VKI_LOOP_CLR_FD:
7897 case VKI_LOOP_CHANGE_FD:
7898 case VKI_LOOP_SET_CAPACITY:
7899 case VKI_LOOP_SET_DIRECT_IO:
7900 case VKI_LOOP_SET_BLOCK_SIZE:
7901 break;
7902 case VKI_LOOP_SET_STATUS:
7903 PRE_MEM_READ("ioctl(LOOP_SET_STATUS)", ARG3, sizeof(struct vki_loop_info));
7904 break;
7905 case VKI_LOOP_GET_STATUS:
7906 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS)", ARG3, sizeof(struct vki_loop_info));
7907 break;
7908 case VKI_LOOP_SET_STATUS64:
7909 PRE_MEM_READ("ioctl(LOOP_SET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
7910 break;
7911 case VKI_LOOP_GET_STATUS64:
7912 PRE_MEM_WRITE("ioctl(LOOP_GET_STATUS64)", ARG3, sizeof(struct vki_loop_info64));
7913 break;
7915 /* Block devices */
7916 case VKI_BLKROSET:
7917 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7918 break;
7919 case VKI_BLKROGET:
7920 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7921 break;
7922 case VKI_BLKGETSIZE:
7923 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7924 break;
7925 case VKI_BLKFLSBUF:
7926 break;
7927 case VKI_BLKRASET:
7928 break;
7929 case VKI_BLKRAGET:
7930 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7931 break;
7932 case VKI_BLKFRASET:
7933 break;
7934 case VKI_BLKFRAGET:
7935 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7936 break;
7937 case VKI_BLKSECTGET:
7938 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7939 break;
7940 case VKI_BLKSSZGET:
7941 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7942 break;
7943 case VKI_BLKBSZGET:
7944 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7945 break;
7946 case VKI_BLKBSZSET:
7947 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7948 break;
7949 case VKI_BLKGETSIZE64:
7950 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7951 break;
7952 case VKI_BLKPBSZGET:
7953 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7954 break;
7955 case VKI_BLKIOMIN:
7956 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7957 break;
7958 case VKI_BLKIOOPT:
7959 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7960 break;
7961 case VKI_BLKALIGNOFF:
7962 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7963 break;
7964 case VKI_BLKDISCARDZEROES:
7965 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7966 break;
7967 case VKI_BLKREPORTZONE:
7968 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7969 sizeof(struct vki_blk_zone_report));
7970 break;
7971 case VKI_BLKRESETZONE:
7972 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7973 sizeof(struct vki_blk_zone_range));
7974 break;
7976 /* Hard disks */
7977 case VKI_HDIO_GETGEO: /* 0x0301 */
7978 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7979 break;
7980 case VKI_HDIO_GET_DMA: /* 0x030b */
7981 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7982 break;
7983 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7984 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7985 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7986 break;
7988 /* SCSI */
7989 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7990 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7991 break;
7992 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7993 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7994 break;
7996 /* CD ROM stuff (??) */
7997 case VKI_CDROM_GET_MCN:
7998 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7999 sizeof(struct vki_cdrom_mcn) );
8000 break;
8001 case VKI_CDROM_SEND_PACKET:
8002 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
8003 sizeof(struct vki_cdrom_generic_command));
8004 break;
8005 case VKI_CDROMSUBCHNL:
8006 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
8007 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
8008 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
8009 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
8010 sizeof(struct vki_cdrom_subchnl));
8011 break;
8012 case VKI_CDROMREADMODE1: /*0x530d*/
8013 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
8014 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
8015 break;
8016 case VKI_CDROMREADMODE2: /*0x530c*/
8017 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
8018 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
8019 break;
8020 case VKI_CDROMREADTOCHDR:
8021 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
8022 sizeof(struct vki_cdrom_tochdr));
8023 break;
8024 case VKI_CDROMREADTOCENTRY:
8025 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
8026 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
8027 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
8028 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
8029 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
8030 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
8031 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
8032 sizeof(struct vki_cdrom_tocentry));
8033 break;
8034 case VKI_CDROMMULTISESSION: /* 0x5310 */
8035 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
8036 sizeof(struct vki_cdrom_multisession));
8037 break;
8038 case VKI_CDROMVOLREAD: /* 0x5313 */
8039 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
8040 sizeof(struct vki_cdrom_volctrl));
8041 break;
8042 case VKI_CDROMREADRAW: /* 0x5314 */
8043 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
8044 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
8045 break;
8046 case VKI_CDROMREADAUDIO: /* 0x530e */
8047 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
8048 sizeof (struct vki_cdrom_read_audio));
8049 if ( ARG3 ) {
8050 /* ToDo: don't do any of the following if the structure is invalid */
8051 struct vki_cdrom_read_audio *cra =
8052 (struct vki_cdrom_read_audio *) (Addr)ARG3;
8053 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
8054 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
8056 break;
8057 case VKI_CDROMPLAYMSF:
8058 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
8059 break;
8060 /* The following two are probably bogus (should check args
8061 for readability). JRS 20021117 */
8062 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
8063 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
8064 break;
8065 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
8066 break;
8068 case VKI_FIGETBSZ:
8069 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
8070 break;
8071 case VKI_FIBMAP:
8072 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
8073 break;
8074 case VKI_FICLONE:
8075 /* The direction of FICLONE (W) is incorrectly specified
8076 * as it expects a file descriptor and not a pointer to
8077 * user data */
8078 break;
8080 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
8081 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
8082 sizeof(struct vki_fb_var_screeninfo));
8083 break;
8084 case VKI_FBIOPUT_VSCREENINFO:
8085 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
8086 sizeof(struct vki_fb_var_screeninfo));
8087 break;
8088 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
8089 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
8090 sizeof(struct vki_fb_fix_screeninfo));
8091 break;
8092 case VKI_FBIOPAN_DISPLAY:
8093 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
8094 sizeof(struct vki_fb_var_screeninfo));
8096 break;
8097 case VKI_PPCLAIM:
8098 case VKI_PPEXCL:
8099 case VKI_PPYIELD:
8100 case VKI_PPRELEASE:
8101 break;
8102 case VKI_PPSETMODE:
8103 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
8104 break;
8105 case VKI_PPGETMODE:
8106 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
8107 break;
8108 case VKI_PPSETPHASE:
8109 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
8110 break;
8111 case VKI_PPGETPHASE:
8112 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
8113 break;
8114 case VKI_PPGETMODES:
8115 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8116 break;
8117 case VKI_PPSETFLAGS:
8118 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8119 break;
8120 case VKI_PPGETFLAGS:
8121 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8122 break;
8123 case VKI_PPRSTATUS:
8124 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8125 break;
8126 case VKI_PPRDATA:
8127 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8128 break;
8129 case VKI_PPRCONTROL:
8130 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8131 break;
8132 case VKI_PPWDATA:
8133 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8134 break;
8135 case VKI_PPWCONTROL:
8136 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8137 break;
8138 case VKI_PPFCONTROL:
8139 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8140 break;
8141 case VKI_PPDATADIR:
8142 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8143 break;
8144 case VKI_PPNEGOT:
8145 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8146 break;
8147 case VKI_PPWCTLONIRQ:
8148 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8149 break;
8150 case VKI_PPCLRIRQ:
8151 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8152 break;
8153 case VKI_PPSETTIME:
8154 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8155 break;
8156 case VKI_PPGETTIME:
8157 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8158 break;
8160 case VKI_GIO_FONT:
8161 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8162 break;
8163 case VKI_PIO_FONT:
8164 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8165 break;
8167 case VKI_GIO_FONTX:
8168 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8169 if ( ARG3 ) {
8170 /* ToDo: don't do any of the following if the structure is invalid */
8171 struct vki_consolefontdesc *cfd =
8172 (struct vki_consolefontdesc *)(Addr)ARG3;
8173 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8174 32 * cfd->charcount );
8176 break;
8177 case VKI_PIO_FONTX:
8178 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8179 if ( ARG3 ) {
8180 /* ToDo: don't do any of the following if the structure is invalid */
8181 struct vki_consolefontdesc *cfd =
8182 (struct vki_consolefontdesc *)(Addr)ARG3;
8183 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8184 32 * cfd->charcount );
8186 break;
8188 case VKI_PIO_FONTRESET:
8189 break;
8191 case VKI_GIO_CMAP:
8192 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8193 break;
8194 case VKI_PIO_CMAP:
8195 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8196 break;
8198 case VKI_KIOCSOUND:
8199 case VKI_KDMKTONE:
8200 break;
8202 case VKI_KDGETLED:
8203 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8204 break;
8205 case VKI_KDSETLED:
8206 break;
8208 case VKI_KDGKBTYPE:
8209 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8210 break;
8212 case VKI_KDADDIO:
8213 case VKI_KDDELIO:
8214 case VKI_KDENABIO:
8215 case VKI_KDDISABIO:
8216 break;
8218 case VKI_KDSETMODE:
8219 break;
8220 case VKI_KDGETMODE:
8221 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8222 break;
8224 case VKI_KDMAPDISP:
8225 case VKI_KDUNMAPDISP:
8226 break;
8228 case VKI_GIO_SCRNMAP:
8229 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8230 break;
8231 case VKI_PIO_SCRNMAP:
8232 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8233 break;
8234 case VKI_GIO_UNISCRNMAP:
8235 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8236 VKI_E_TABSZ * sizeof(unsigned short) );
8237 break;
8238 case VKI_PIO_UNISCRNMAP:
8239 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8240 VKI_E_TABSZ * sizeof(unsigned short) );
8241 break;
8243 case VKI_GIO_UNIMAP:
8244 if ( ARG3 ) {
8245 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8246 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8247 sizeof(unsigned short));
8248 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8249 sizeof(struct vki_unipair *));
8250 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8251 desc->entry_ct * sizeof(struct vki_unipair));
8253 break;
8254 case VKI_PIO_UNIMAP:
8255 if ( ARG3 ) {
8256 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8257 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8258 sizeof(unsigned short) );
8259 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8260 sizeof(struct vki_unipair *) );
8261 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8262 desc->entry_ct * sizeof(struct vki_unipair) );
8264 break;
8265 case VKI_PIO_UNIMAPCLR:
8266 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8267 break;
8269 case VKI_KDGKBMODE:
8270 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8271 break;
8272 case VKI_KDSKBMODE:
8273 break;
8275 case VKI_KDGKBMETA:
8276 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8277 break;
8278 case VKI_KDSKBMETA:
8279 break;
8281 case VKI_KDGKBLED:
8282 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8283 break;
8284 case VKI_KDSKBLED:
8285 break;
8287 case VKI_KDGKBENT:
8288 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8289 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8290 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8291 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8292 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8293 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8294 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8295 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8296 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8297 break;
8298 case VKI_KDSKBENT:
8299 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8300 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8301 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8302 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8303 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8304 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8305 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8306 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8307 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8308 break;
8310 case VKI_KDGKBSENT:
8311 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8312 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8313 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8314 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8315 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8316 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8317 break;
8318 case VKI_KDSKBSENT:
8319 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8320 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8321 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8322 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8323 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8324 break;
8326 case VKI_KDGKBDIACR:
8327 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8328 break;
8329 case VKI_KDSKBDIACR:
8330 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8331 break;
8333 case VKI_KDGETKEYCODE:
8334 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8335 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8336 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8337 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8338 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8339 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8340 break;
8341 case VKI_KDSETKEYCODE:
8342 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8343 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8344 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8345 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8346 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8347 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8348 break;
8350 case VKI_KDSIGACCEPT:
8351 break;
8353 case VKI_KDKBDREP:
8354 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8355 break;
8357 case VKI_KDFONTOP:
8358 if ( ARG3 ) {
8359 struct vki_console_font_op *op =
8360 (struct vki_console_font_op *) (Addr)ARG3;
8361 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8362 sizeof(struct vki_console_font_op) );
8363 switch ( op->op ) {
8364 case VKI_KD_FONT_OP_SET:
8365 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8366 (Addr)op->data,
8367 (op->width + 7) / 8 * 32 * op->charcount );
8368 break;
8369 case VKI_KD_FONT_OP_GET:
8370 if ( op->data )
8371 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8372 (Addr)op->data,
8373 (op->width + 7) / 8 * 32 * op->charcount );
8374 break;
8375 case VKI_KD_FONT_OP_SET_DEFAULT:
8376 if ( op->data )
8377 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8378 (Addr)op->data );
8379 break;
8380 case VKI_KD_FONT_OP_COPY:
8381 break;
8384 break;
8386 case VKI_VT_OPENQRY:
8387 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8388 break;
8389 case VKI_VT_GETMODE:
8390 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8391 break;
8392 case VKI_VT_SETMODE:
8393 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8394 break;
8395 case VKI_VT_GETSTATE:
8396 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8397 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8398 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8399 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8400 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8401 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8402 break;
8403 case VKI_VT_RELDISP:
8404 case VKI_VT_ACTIVATE:
8405 case VKI_VT_WAITACTIVE:
8406 case VKI_VT_DISALLOCATE:
8407 break;
8408 case VKI_VT_RESIZE:
8409 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8410 break;
8411 case VKI_VT_RESIZEX:
8412 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8413 break;
8414 case VKI_VT_LOCKSWITCH:
8415 case VKI_VT_UNLOCKSWITCH:
8416 break;
8418 case VKI_USBDEVFS_CONTROL:
8419 if ( ARG3 ) {
8420 struct vki_usbdevfs_ctrltransfer *vkuc =
8421 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8422 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8423 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8424 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8425 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8426 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8427 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8428 if (vkuc->bRequestType & 0x80)
8429 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8430 else
8431 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8433 break;
8434 case VKI_USBDEVFS_BULK:
8435 if ( ARG3 ) {
8436 struct vki_usbdevfs_bulktransfer *vkub =
8437 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8438 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8439 if (vkub->ep & 0x80)
8440 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8441 else
8442 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8444 break;
8445 case VKI_USBDEVFS_GETDRIVER:
8446 if ( ARG3 ) {
8447 struct vki_usbdevfs_getdriver *vkugd =
8448 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8449 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8451 break;
8452 case VKI_USBDEVFS_SUBMITURB:
8453 if ( ARG3 ) {
8454 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8456 /* Not the whole struct needs to be initialized */
8457 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8458 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8459 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8460 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8461 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8462 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8463 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8464 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8465 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8466 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8467 if (vkusp->bRequestType & 0x80)
8468 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8469 else
8470 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8471 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8472 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8473 int total_length = 0;
8474 int i;
8475 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8476 for(i=0; i<vkuu->number_of_packets; i++) {
8477 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8478 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));
8479 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8480 total_length += vkuu->iso_frame_desc[i].length;
8482 if (vkuu->endpoint & 0x80)
8483 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8484 else
8485 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8486 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8487 } else {
8488 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8489 if (vkuu->endpoint & 0x80)
8490 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8491 else
8492 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8493 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8496 break;
8497 case VKI_USBDEVFS_DISCARDURB:
8498 break;
8499 case VKI_USBDEVFS_REAPURB:
8500 if ( ARG3 ) {
8501 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8503 break;
8504 case VKI_USBDEVFS_REAPURBNDELAY:
8505 if ( ARG3 ) {
8506 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8508 break;
8509 case VKI_USBDEVFS_CONNECTINFO:
8510 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8511 break;
8512 case VKI_USBDEVFS_IOCTL:
8513 if ( ARG3 ) {
8514 struct vki_usbdevfs_ioctl *vkui =
8515 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8516 UInt dir2, size2;
8517 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8518 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8519 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8520 if (size2 > 0) {
8521 if (dir2 & _VKI_IOC_WRITE)
8522 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8523 else if (dir2 & _VKI_IOC_READ)
8524 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8527 break;
8528 case VKI_USBDEVFS_RESET:
8529 break;
8531 /* I2C (/dev/i2c-*) ioctls */
8532 case VKI_I2C_SLAVE:
8533 case VKI_I2C_SLAVE_FORCE:
8534 case VKI_I2C_TENBIT:
8535 case VKI_I2C_PEC:
8536 break;
8537 case VKI_I2C_FUNCS:
8538 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8539 break;
8540 case VKI_I2C_RDWR:
8541 if ( ARG3 ) {
8542 struct vki_i2c_rdwr_ioctl_data *vkui =
8543 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8544 UInt i;
8545 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8546 for (i=0; i < vkui->nmsgs; i++) {
8547 struct vki_i2c_msg *msg = vkui->msgs + i;
8548 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8549 if (msg->flags & VKI_I2C_M_RD)
8550 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8551 else
8552 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8555 break;
8556 case VKI_I2C_SMBUS:
8557 if ( ARG3 ) {
8558 struct vki_i2c_smbus_ioctl_data *vkis
8559 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8560 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8561 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8562 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8563 (Addr)&vkis->size, sizeof(vkis->size));
8564 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8565 (Addr)&vkis->command, sizeof(vkis->command));
8566 /* i2c_smbus_write_quick hides its value in read_write, so
8567 this variable can have a different meaning */
8568 /* to make matters worse i2c_smbus_write_byte stores its
8569 value in command */
8570 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8571 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8572 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8573 /* the rest uses the byte array to store the data,
8574 some the first byte for size */
8575 UInt size;
8576 switch(vkis->size) {
8577 case VKI_I2C_SMBUS_BYTE_DATA:
8578 size = 1;
8579 break;
8580 case VKI_I2C_SMBUS_WORD_DATA:
8581 case VKI_I2C_SMBUS_PROC_CALL:
8582 size = 2;
8583 break;
8584 case VKI_I2C_SMBUS_BLOCK_DATA:
8585 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8586 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8587 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8588 size = 1 + vkis->data->block[0];
8589 break;
8590 default:
8591 size = 0;
8594 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8595 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8596 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8597 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8598 ".i2c_smbus_ioctl_data.data",
8599 (Addr)&vkis->data->block[0], size);
8600 else
8601 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8602 "i2c_smbus_ioctl_data.data",
8603 (Addr)&vkis->data->block[0], size);
8606 break;
8608 /* Wireless extensions ioctls */
8609 case VKI_SIOCSIWCOMMIT:
8610 case VKI_SIOCSIWNWID:
8611 case VKI_SIOCSIWFREQ:
8612 case VKI_SIOCSIWMODE:
8613 case VKI_SIOCSIWSENS:
8614 case VKI_SIOCSIWRANGE:
8615 case VKI_SIOCSIWPRIV:
8616 case VKI_SIOCSIWSTATS:
8617 case VKI_SIOCSIWSPY:
8618 case VKI_SIOCSIWTHRSPY:
8619 case VKI_SIOCSIWAP:
8620 case VKI_SIOCSIWSCAN:
8621 case VKI_SIOCSIWESSID:
8622 case VKI_SIOCSIWRATE:
8623 case VKI_SIOCSIWNICKN:
8624 case VKI_SIOCSIWRTS:
8625 case VKI_SIOCSIWFRAG:
8626 case VKI_SIOCSIWTXPOW:
8627 case VKI_SIOCSIWRETRY:
8628 case VKI_SIOCSIWENCODE:
8629 case VKI_SIOCSIWPOWER:
8630 case VKI_SIOCSIWGENIE:
8631 case VKI_SIOCSIWMLME:
8632 case VKI_SIOCSIWAUTH:
8633 case VKI_SIOCSIWENCODEEXT:
8634 case VKI_SIOCSIWPMKSA:
8635 break;
8636 case VKI_SIOCGIWNAME:
8637 if (ARG3) {
8638 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8639 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8640 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8642 break;
8643 case VKI_SIOCGIWNWID:
8644 case VKI_SIOCGIWSENS:
8645 case VKI_SIOCGIWRATE:
8646 case VKI_SIOCGIWRTS:
8647 case VKI_SIOCGIWFRAG:
8648 case VKI_SIOCGIWTXPOW:
8649 case VKI_SIOCGIWRETRY:
8650 case VKI_SIOCGIWPOWER:
8651 case VKI_SIOCGIWAUTH:
8652 if (ARG3) {
8653 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8654 "RETRY|PARAM|AUTH])",
8655 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8656 sizeof(struct vki_iw_param));
8658 break;
8659 case VKI_SIOCGIWFREQ:
8660 if (ARG3) {
8661 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8662 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8663 sizeof(struct vki_iw_freq));
8665 break;
8666 case VKI_SIOCGIWMODE:
8667 if (ARG3) {
8668 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8669 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8670 sizeof(__vki_u32));
8672 break;
8673 case VKI_SIOCGIWRANGE:
8674 case VKI_SIOCGIWPRIV:
8675 case VKI_SIOCGIWSTATS:
8676 case VKI_SIOCGIWSPY:
8677 case VKI_SIOCGIWTHRSPY:
8678 case VKI_SIOCGIWAPLIST:
8679 case VKI_SIOCGIWSCAN:
8680 case VKI_SIOCGIWESSID:
8681 case VKI_SIOCGIWNICKN:
8682 case VKI_SIOCGIWENCODE:
8683 case VKI_SIOCGIWGENIE:
8684 case VKI_SIOCGIWENCODEEXT:
8685 if (ARG3) {
8686 struct vki_iw_point* point;
8687 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8688 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8689 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8690 (Addr)point->pointer, point->length);
8692 break;
8693 case VKI_SIOCGIWAP:
8694 if (ARG3) {
8695 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8696 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8697 sizeof(struct vki_sockaddr));
8699 break;
8701 /* User input device creation */
8702 case VKI_UI_SET_EVBIT:
8703 case VKI_UI_SET_KEYBIT:
8704 case VKI_UI_SET_RELBIT:
8705 case VKI_UI_SET_ABSBIT:
8706 case VKI_UI_SET_MSCBIT:
8707 case VKI_UI_SET_LEDBIT:
8708 case VKI_UI_SET_SNDBIT:
8709 case VKI_UI_SET_FFBIT:
8710 case VKI_UI_SET_SWBIT:
8711 case VKI_UI_SET_PROPBIT:
8712 /* These just take an int by value */
8713 break;
8715 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8716 || defined(VGPV_mips32_linux_android) \
8717 || defined(VGPV_arm64_linux_android)
8718 /* ashmem */
8719 case VKI_ASHMEM_GET_SIZE:
8720 case VKI_ASHMEM_SET_SIZE:
8721 case VKI_ASHMEM_GET_PROT_MASK:
8722 case VKI_ASHMEM_SET_PROT_MASK:
8723 case VKI_ASHMEM_GET_PIN_STATUS:
8724 case VKI_ASHMEM_PURGE_ALL_CACHES:
8725 break;
8726 case VKI_ASHMEM_GET_NAME:
8727 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8728 break;
8729 case VKI_ASHMEM_SET_NAME:
8730 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8731 break;
8732 case VKI_ASHMEM_PIN:
8733 case VKI_ASHMEM_UNPIN:
8734 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8735 ARG3, sizeof(struct vki_ashmem_pin) );
8736 break;
8738 /* binder */
8739 case VKI_BINDER_WRITE_READ:
8740 if (ARG3) {
8741 struct vki_binder_write_read* bwr
8742 = (struct vki_binder_write_read*)(Addr)ARG3;
8744 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8745 bwr->write_buffer);
8746 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8747 bwr->write_size);
8748 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8749 bwr->write_consumed);
8750 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8751 bwr->read_buffer);
8752 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8753 bwr->read_size);
8754 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8755 bwr->read_consumed);
8757 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8758 bwr->write_consumed);
8759 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8760 bwr->read_consumed);
8762 if (bwr->read_size)
8763 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8764 (Addr)bwr->read_buffer, bwr->read_size);
8765 if (bwr->write_size)
8766 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8767 (Addr)bwr->write_buffer, bwr->write_size);
8769 break;
8771 case VKI_BINDER_SET_IDLE_TIMEOUT:
8772 case VKI_BINDER_SET_MAX_THREADS:
8773 case VKI_BINDER_SET_IDLE_PRIORITY:
8774 case VKI_BINDER_SET_CONTEXT_MGR:
8775 case VKI_BINDER_THREAD_EXIT:
8776 break;
8777 case VKI_BINDER_VERSION:
8778 if (ARG3) {
8779 struct vki_binder_version* bv =
8780 (struct vki_binder_version*)(Addr)ARG3;
8781 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8783 break;
8784 # endif /* defined(VGPV_*_linux_android) */
8786 case VKI_HCIGETDEVLIST:
8787 if (ARG3) {
8788 struct vki_hci_dev_list_req* dlr =
8789 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8790 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8791 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8792 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8793 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8794 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8796 break;
8798 case VKI_HCIINQUIRY:
8799 if (ARG3) {
8800 struct vki_hci_inquiry_req* ir =
8801 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8802 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8803 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8804 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8805 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8806 ir->num_rsp * sizeof(struct vki_inquiry_info));
8808 break;
8810 case VKI_DRM_IOCTL_VERSION:
8811 if (ARG3) {
8812 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8813 struct vg_drm_version_info* info;
8814 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8815 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8816 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8817 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8818 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8819 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8820 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8821 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8822 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8823 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8824 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8825 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8826 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8827 // To ensure we VG_(free) info even when syscall fails:
8828 *flags |= SfPostOnFail;
8829 info->data = *data;
8830 info->orig = data;
8831 ARG3 = (Addr)&info->data;
8833 break;
8834 case VKI_DRM_IOCTL_GET_UNIQUE:
8835 if (ARG3) {
8836 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8837 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8838 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8839 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8841 break;
8842 case VKI_DRM_IOCTL_GET_MAGIC:
8843 if (ARG3) {
8844 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8845 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8847 break;
8848 case VKI_DRM_IOCTL_WAIT_VBLANK:
8849 if (ARG3) {
8850 union vki_drm_wait_vblank *data =
8851 (union vki_drm_wait_vblank *)(Addr)ARG3;
8852 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8853 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8854 /* XXX: It seems request.signal isn't used */
8855 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8857 break;
8858 case VKI_DRM_IOCTL_GEM_CLOSE:
8859 if (ARG3) {
8860 struct vki_drm_gem_close *data =
8861 (struct vki_drm_gem_close *)(Addr)ARG3;
8862 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8864 break;
8865 case VKI_DRM_IOCTL_GEM_FLINK:
8866 if (ARG3) {
8867 struct vki_drm_gem_flink *data =
8868 (struct vki_drm_gem_flink *)(Addr)ARG3;
8869 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8870 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8872 break;
8873 case VKI_DRM_IOCTL_GEM_OPEN:
8874 if (ARG3) {
8875 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8876 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8877 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8878 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8880 break;
8881 case VKI_DRM_IOCTL_I915_GETPARAM:
8882 if (ARG3) {
8883 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8884 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8885 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8887 break;
8888 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8889 if (ARG3) {
8890 struct vki_drm_i915_gem_busy *data =
8891 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8892 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8893 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8895 break;
8896 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8897 if (ARG3) {
8898 struct vki_drm_i915_gem_create *data =
8899 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8900 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8901 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8903 break;
8904 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8905 if (ARG3) {
8906 struct vki_drm_i915_gem_pread *data =
8907 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8908 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8909 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8910 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8911 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8912 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8914 break;
8915 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8916 if (ARG3) {
8917 struct vki_drm_i915_gem_pwrite *data =
8918 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8919 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8920 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8921 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8922 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8923 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8924 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8925 * interleaved vertex attributes may have a wide stride with uninitialized data between
8926 * consecutive vertices) */
8928 break;
8929 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8930 if (ARG3) {
8931 struct vki_drm_i915_gem_mmap_v1 *data =
8932 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8933 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8934 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8935 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8936 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8938 break;
8939 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8940 if (ARG3) {
8941 struct vki_drm_i915_gem_mmap *data =
8942 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8943 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8944 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8945 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8946 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8947 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8949 break;
8950 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8951 if (ARG3) {
8952 struct vki_drm_i915_gem_mmap_gtt *data =
8953 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8954 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8955 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8957 break;
8958 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8959 if (ARG3) {
8960 struct vki_drm_i915_gem_set_domain *data =
8961 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8962 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8963 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8964 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8966 break;
8967 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8968 if (ARG3) {
8969 struct vki_drm_i915_gem_set_tiling *data =
8970 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8971 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8972 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8973 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8974 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8976 break;
8977 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8978 if (ARG3) {
8979 struct vki_drm_i915_gem_get_tiling *data =
8980 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8981 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8982 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8983 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8985 break;
8986 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8987 if (ARG3) {
8988 struct vki_drm_i915_gem_get_aperture *data =
8989 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8990 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8991 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8993 break;
8995 /* KVM ioctls that check for a numeric value as parameter */
8996 case VKI_KVM_GET_API_VERSION:
8997 case VKI_KVM_CREATE_VM:
8998 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8999 case VKI_KVM_CHECK_EXTENSION:
9000 case VKI_KVM_SET_TSS_ADDR:
9001 case VKI_KVM_CREATE_VCPU:
9002 case VKI_KVM_RUN:
9003 break;
9005 case VKI_KVM_S390_MEM_OP: {
9006 struct vki_kvm_s390_mem_op *args =
9007 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
9008 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
9009 sizeof(struct vki_kvm_s390_mem_op));
9010 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
9011 break;
9012 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
9013 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
9014 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
9015 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
9017 break;
9020 #ifdef ENABLE_XEN
9021 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
9022 SyscallArgs harrghs;
9023 struct vki_xen_privcmd_hypercall *args =
9024 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
9026 if (!args)
9027 break;
9029 VG_(memset)(&harrghs, 0, sizeof(harrghs));
9030 harrghs.sysno = args->op;
9031 harrghs.arg1 = args->arg[0];
9032 harrghs.arg2 = args->arg[1];
9033 harrghs.arg3 = args->arg[2];
9034 harrghs.arg4 = args->arg[3];
9035 harrghs.arg5 = args->arg[4];
9036 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
9038 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
9040 /* HACK. arg8 is used to return the number of hypercall
9041 * arguments actually consumed! */
9042 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
9043 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
9045 break;
9048 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
9049 struct vki_xen_privcmd_mmap *args =
9050 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
9051 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
9052 (Addr)&args->num, sizeof(args->num));
9053 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
9054 (Addr)&args->dom, sizeof(args->dom));
9055 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
9056 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
9057 break;
9059 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
9060 struct vki_xen_privcmd_mmapbatch *args =
9061 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
9062 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
9063 (Addr)&args->num, sizeof(args->num));
9064 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
9065 (Addr)&args->dom, sizeof(args->dom));
9066 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
9067 (Addr)&args->addr, sizeof(args->addr));
9068 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
9069 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9070 break;
9072 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
9073 struct vki_xen_privcmd_mmapbatch_v2 *args =
9074 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
9075 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
9076 (Addr)&args->num, sizeof(args->num));
9077 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
9078 (Addr)&args->dom, sizeof(args->dom));
9079 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
9080 (Addr)&args->addr, sizeof(args->addr));
9081 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
9082 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9083 break;
9086 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
9087 struct vki_xen_ioctl_evtchn_bind_virq *args =
9088 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
9089 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
9090 (Addr)&args->virq, sizeof(args->virq));
9092 break;
9093 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
9094 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
9095 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
9096 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
9097 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9098 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
9099 (Addr)&args->remote_port, sizeof(args->remote_port));
9101 break;
9102 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
9103 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
9104 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
9105 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
9106 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9108 break;
9109 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
9110 struct vki_xen_ioctl_evtchn_unbind *args =
9111 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
9112 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
9113 (Addr)&args->port, sizeof(args->port));
9115 break;
9116 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9117 struct vki_xen_ioctl_evtchn_notify *args =
9118 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9119 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9120 (Addr)&args->port, sizeof(args->port));
9122 break;
9123 case VKI_XEN_IOCTL_EVTCHN_RESET:
9124 /* No input*/
9125 break;
9126 #endif
9128 /* Lustre */
9129 case VKI_OBD_IOC_FID2PATH: {
9130 struct vki_getinfo_fid2path *gf =
9131 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9132 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9133 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9134 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9135 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9136 break;
9139 case VKI_LL_IOC_PATH2FID:
9140 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9141 break;
9143 case VKI_LL_IOC_GETPARENT: {
9144 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9145 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9146 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9147 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9148 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9149 break;
9152 /* V4L2 */
9153 case VKI_V4L2_QUERYCAP: {
9154 struct vki_v4l2_capability *data =
9155 (struct vki_v4l2_capability *)(Addr)ARG3;
9156 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9157 break;
9159 case VKI_V4L2_ENUM_FMT: {
9160 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9161 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9162 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9163 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9164 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9165 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9166 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9167 break;
9169 case VKI_V4L2_G_FMT: {
9170 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9171 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9172 switch (data->type) {
9173 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9174 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9175 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9176 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9177 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9178 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9179 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9180 break;
9181 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9182 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9183 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9184 break;
9185 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9186 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9187 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9188 break;
9189 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9190 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9191 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9192 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9193 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9194 if (data->fmt.win.clipcount && data->fmt.win.clips)
9195 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9196 (Addr)data->fmt.win.clips,
9197 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9198 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9199 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9200 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9201 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9202 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9203 break;
9204 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9205 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9206 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9207 break;
9208 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9209 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9210 break;
9212 break;
9214 case VKI_V4L2_S_FMT: {
9215 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9216 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9217 switch (data->type) {
9218 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9219 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9220 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9221 (Addr)&data->type + sizeof(data->type),
9222 sizeof(*data) - sizeof(data->type));
9223 break;
9224 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9225 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9226 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9227 break;
9228 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9229 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9231 break;
9232 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9233 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9234 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9235 if (data->fmt.win.clipcount && data->fmt.win.clips)
9236 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9237 (Addr)data->fmt.win.clips,
9238 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9239 if (data->fmt.win.bitmap)
9240 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9241 (Addr)data->fmt.win.bitmap,
9242 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9243 break;
9244 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9245 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9246 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9247 break;
9248 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9249 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9250 break;
9252 break;
9254 case VKI_V4L2_TRY_FMT: {
9255 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9256 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9257 switch (data->type) {
9258 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9259 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9260 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9261 (Addr)&data->type + sizeof(data->type),
9262 sizeof(*data) - sizeof(data->type));
9263 break;
9264 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9265 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9266 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9267 break;
9268 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9269 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9270 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9271 break;
9272 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9273 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9274 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9275 if (data->fmt.win.clipcount && data->fmt.win.clips)
9276 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9277 (Addr)data->fmt.win.clips,
9278 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9279 if (data->fmt.win.bitmap)
9280 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9281 (Addr)data->fmt.win.bitmap,
9282 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9283 break;
9284 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9285 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9286 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9287 break;
9288 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9289 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9290 break;
9292 break;
9294 case VKI_V4L2_REQBUFS: {
9295 struct vki_v4l2_requestbuffers *data =
9296 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9297 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9298 break;
9300 case VKI_V4L2_QUERYBUF: {
9301 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9302 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9303 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9304 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9305 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9306 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9307 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9308 unsigned i;
9310 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9311 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9312 for (i = 0; i < data->length; i++) {
9313 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9314 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9315 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9316 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9317 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9319 } else {
9320 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9321 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9323 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9324 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9325 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9326 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9327 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9328 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9329 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9330 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9331 break;
9333 case VKI_V4L2_G_FBUF: {
9334 struct vki_v4l2_framebuffer *data =
9335 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9336 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9337 break;
9339 case VKI_V4L2_S_FBUF: {
9340 struct vki_v4l2_framebuffer *data =
9341 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9342 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9343 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9344 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9345 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9346 break;
9348 case VKI_V4L2_OVERLAY: {
9349 int *data = (int *)(Addr)ARG3;
9350 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9351 break;
9353 case VKI_V4L2_QBUF: {
9354 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9355 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9356 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9357 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9358 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9360 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9361 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9362 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9363 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9364 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9365 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9366 if (is_output) {
9367 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9368 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9370 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9371 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9372 unsigned i;
9374 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9375 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9376 for (i = 0; i < data->length; i++) {
9377 if (is_output) {
9378 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9379 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9381 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9382 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9383 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9384 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9385 else
9386 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9387 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9389 } else {
9390 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9391 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9392 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9393 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9394 else
9395 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9396 if (is_output) {
9397 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9398 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9401 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9402 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9403 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9405 break;
9407 case VKI_V4L2_EXPBUF: {
9408 struct vki_v4l2_exportbuffer *data =
9409 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9410 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9411 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9412 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9413 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9414 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9415 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9416 break;
9418 case VKI_V4L2_DQBUF: {
9419 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9420 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9421 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9422 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9423 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9424 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9425 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9426 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9427 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9428 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9429 unsigned i;
9431 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9432 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9433 for (i = 0; i < data->length; i++) {
9434 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9435 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9436 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9437 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9438 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9440 } else {
9441 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9442 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9443 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9444 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9446 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9447 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9448 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9449 break;
9451 case VKI_V4L2_STREAMON: {
9452 int *data = (int *)(Addr)ARG3;
9453 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9454 break;
9456 case VKI_V4L2_STREAMOFF: {
9457 int *data = (int *)(Addr)ARG3;
9458 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9459 break;
9461 case VKI_V4L2_G_PARM: {
9462 struct vki_v4l2_streamparm *data =
9463 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9464 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9465 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9466 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9467 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9469 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9470 if (is_output) {
9471 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9472 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9473 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9474 } else {
9475 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9476 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9477 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9479 break;
9481 case VKI_V4L2_S_PARM: {
9482 struct vki_v4l2_streamparm *data =
9483 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9484 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9485 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9486 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9487 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9489 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9490 if (is_output)
9491 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9492 else
9493 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9494 break;
9496 case VKI_V4L2_G_STD: {
9497 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9498 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9499 break;
9501 case VKI_V4L2_S_STD: {
9502 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9503 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9504 break;
9506 case VKI_V4L2_ENUMSTD: {
9507 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9508 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9509 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9510 break;
9512 case VKI_V4L2_ENUMINPUT: {
9513 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9514 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9515 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9516 break;
9518 case VKI_V4L2_G_CTRL: {
9519 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9520 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9521 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9522 break;
9524 case VKI_V4L2_S_CTRL: {
9525 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9526 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9527 break;
9529 case VKI_V4L2_G_TUNER: {
9530 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9531 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9532 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9533 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9534 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9535 break;
9537 case VKI_V4L2_S_TUNER: {
9538 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9539 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9540 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9541 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9542 break;
9544 case VKI_V4L2_G_AUDIO: {
9545 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9546 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9547 sizeof(*data) - sizeof(data->reserved));
9548 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9549 break;
9551 case VKI_V4L2_S_AUDIO: {
9552 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9553 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9554 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9555 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9556 break;
9558 case VKI_V4L2_QUERYCTRL: {
9559 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9560 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9561 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9562 sizeof(*data) - sizeof(data->id));
9563 break;
9565 case VKI_V4L2_QUERYMENU: {
9566 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9567 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9568 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9569 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9570 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9571 break;
9573 case VKI_V4L2_G_INPUT: {
9574 int *data = (int *)(Addr)ARG3;
9575 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9576 break;
9578 case VKI_V4L2_S_INPUT: {
9579 int *data = (int *)(Addr)ARG3;
9580 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9581 break;
9583 case VKI_V4L2_G_EDID: {
9584 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9585 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9586 if (data->blocks && data->edid)
9587 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9588 break;
9590 case VKI_V4L2_S_EDID: {
9591 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9592 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9593 if (data->blocks && data->edid)
9594 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9595 break;
9597 case VKI_V4L2_G_OUTPUT: {
9598 int *data = (int *)(Addr)ARG3;
9599 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9600 break;
9602 case VKI_V4L2_S_OUTPUT: {
9603 int *data = (int *)(Addr)ARG3;
9604 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9605 break;
9607 case VKI_V4L2_ENUMOUTPUT: {
9608 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9609 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9610 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9611 break;
9613 case VKI_V4L2_G_AUDOUT: {
9614 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9615 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9616 sizeof(*data) - sizeof(data->reserved));
9617 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9618 break;
9620 case VKI_V4L2_S_AUDOUT: {
9621 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9622 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9623 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9624 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9625 break;
9627 case VKI_V4L2_G_MODULATOR: {
9628 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9629 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9630 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9631 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9632 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9633 break;
9635 case VKI_V4L2_S_MODULATOR: {
9636 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9637 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9638 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9639 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9640 break;
9642 case VKI_V4L2_G_FREQUENCY: {
9643 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9644 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9645 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9646 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9647 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9648 break;
9650 case VKI_V4L2_S_FREQUENCY: {
9651 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9652 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9653 break;
9655 case VKI_V4L2_CROPCAP: {
9656 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9657 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9658 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9659 break;
9661 case VKI_V4L2_G_CROP: {
9662 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9663 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9664 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9665 break;
9667 case VKI_V4L2_S_CROP: {
9668 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9669 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9670 break;
9672 case VKI_V4L2_G_JPEGCOMP: {
9673 struct vki_v4l2_jpegcompression *data =
9674 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9675 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9676 break;
9678 case VKI_V4L2_S_JPEGCOMP: {
9679 struct vki_v4l2_jpegcompression *data =
9680 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9681 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9682 break;
9684 case VKI_V4L2_QUERYSTD: {
9685 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9686 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9687 break;
9689 case VKI_V4L2_ENUMAUDIO: {
9690 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9691 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9692 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9693 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9694 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9695 break;
9697 case VKI_V4L2_ENUMAUDOUT: {
9698 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9699 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9700 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9701 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9702 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9703 break;
9705 case VKI_V4L2_G_PRIORITY: {
9706 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9707 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9708 break;
9710 case VKI_V4L2_S_PRIORITY: {
9711 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9712 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9713 break;
9715 case VKI_V4L2_G_SLICED_VBI_CAP: {
9716 struct vki_v4l2_sliced_vbi_cap *data =
9717 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9718 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9719 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9720 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9721 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9722 break;
9724 case VKI_V4L2_G_EXT_CTRLS: {
9725 struct vki_v4l2_ext_controls *data =
9726 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9727 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9728 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9729 if (data->count) {
9730 unsigned i;
9732 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9733 for (i = 0; i < data->count; i++) {
9734 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9735 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9736 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9737 if (data->controls[i].size) {
9738 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9739 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9740 (Addr)data->controls[i].ptr, data->controls[i].size);
9741 } else {
9742 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9743 data->controls[i].value64);
9747 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9748 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9749 break;
9751 case VKI_V4L2_S_EXT_CTRLS: {
9752 struct vki_v4l2_ext_controls *data =
9753 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9754 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9755 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9756 if (data->count) {
9757 unsigned i;
9759 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9760 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9761 data->count * sizeof(data->controls[0]));
9762 for (i = 0; i < data->count; i++) {
9763 if (data->controls[i].size) {
9764 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9765 (Addr)data->controls[i].ptr, data->controls[i].size);
9769 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9770 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9771 break;
9773 case VKI_V4L2_TRY_EXT_CTRLS: {
9774 struct vki_v4l2_ext_controls *data =
9775 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9776 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9777 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9778 if (data->count) {
9779 unsigned i;
9781 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9782 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9783 data->count * sizeof(data->controls[0]));
9784 for (i = 0; i < data->count; i++) {
9785 if (data->controls[i].size) {
9786 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9787 (Addr)data->controls[i].ptr, data->controls[i].size);
9791 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9792 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9793 break;
9795 case VKI_V4L2_ENUM_FRAMESIZES: {
9796 struct vki_v4l2_frmsizeenum *data =
9797 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9798 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9799 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9800 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9801 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9802 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9803 break;
9805 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9806 struct vki_v4l2_frmivalenum *data =
9807 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9808 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9809 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9810 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9811 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9812 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9813 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9814 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9815 break;
9817 case VKI_V4L2_G_ENC_INDEX: {
9818 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9819 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9820 break;
9822 case VKI_V4L2_ENCODER_CMD: {
9823 struct vki_v4l2_encoder_cmd *data =
9824 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9825 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9826 break;
9828 case VKI_V4L2_TRY_ENCODER_CMD: {
9829 struct vki_v4l2_encoder_cmd *data =
9830 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9831 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9832 break;
9834 case VKI_V4L2_DBG_S_REGISTER: {
9835 struct vki_v4l2_dbg_register *data =
9836 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9837 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9838 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9839 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9840 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9841 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9842 break;
9844 case VKI_V4L2_DBG_G_REGISTER: {
9845 struct vki_v4l2_dbg_register *data =
9846 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9847 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9848 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9849 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9850 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9851 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9852 break;
9854 case VKI_V4L2_S_HW_FREQ_SEEK: {
9855 struct vki_v4l2_hw_freq_seek *data =
9856 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9857 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9858 break;
9860 case VKI_V4L2_S_DV_TIMINGS: {
9861 struct vki_v4l2_dv_timings *data =
9862 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9863 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9864 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9865 break;
9867 case VKI_V4L2_G_DV_TIMINGS: {
9868 struct vki_v4l2_dv_timings *data =
9869 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9870 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9871 break;
9873 case VKI_V4L2_DQEVENT: {
9874 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9875 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9876 break;
9878 case VKI_V4L2_SUBSCRIBE_EVENT: {
9879 struct vki_v4l2_event_subscription *data =
9880 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9881 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9882 break;
9884 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9885 struct vki_v4l2_event_subscription *data =
9886 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9887 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9888 break;
9890 case VKI_V4L2_CREATE_BUFS: {
9891 struct vki_v4l2_create_buffers *data =
9892 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9893 struct vki_v4l2_format *fmt = &data->format;
9894 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9895 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9896 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9897 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9898 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9899 switch (fmt->type) {
9900 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9901 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9902 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9903 break;
9904 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9905 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9906 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9907 break;
9908 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9909 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9910 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9911 break;
9912 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9913 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9914 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9915 break;
9916 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9917 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9918 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9919 break;
9920 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9921 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9922 break;
9924 break;
9926 case VKI_V4L2_PREPARE_BUF: {
9927 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9928 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9929 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9930 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9931 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9932 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9933 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9934 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9935 unsigned i;
9937 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9938 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9939 for (i = 0; i < data->length; i++) {
9940 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9943 break;
9945 case VKI_V4L2_G_SELECTION: {
9946 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9947 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9948 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9949 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9950 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9951 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9952 break;
9954 case VKI_V4L2_S_SELECTION: {
9955 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9956 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9957 break;
9959 case VKI_V4L2_DECODER_CMD: {
9960 struct vki_v4l2_decoder_cmd *data =
9961 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9962 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9963 break;
9965 case VKI_V4L2_TRY_DECODER_CMD: {
9966 struct vki_v4l2_decoder_cmd *data =
9967 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9968 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9969 break;
9971 case VKI_V4L2_ENUM_DV_TIMINGS: {
9972 struct vki_v4l2_enum_dv_timings *data =
9973 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9974 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9975 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9976 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9977 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9978 break;
9980 case VKI_V4L2_QUERY_DV_TIMINGS: {
9981 struct vki_v4l2_dv_timings *data =
9982 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9983 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9984 break;
9986 case VKI_V4L2_DV_TIMINGS_CAP: {
9987 struct vki_v4l2_dv_timings_cap *data =
9988 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9989 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9990 break;
9992 case VKI_V4L2_ENUM_FREQ_BANDS: {
9993 struct vki_v4l2_frequency_band *data =
9994 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9995 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9996 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9997 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9998 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9999 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
10000 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
10001 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
10002 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
10003 break;
10005 case VKI_V4L2_DBG_G_CHIP_INFO: {
10006 struct vki_v4l2_dbg_chip_info *data =
10007 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
10008 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
10009 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
10010 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
10011 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
10012 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
10013 break;
10015 case VKI_V4L2_QUERY_EXT_CTRL: {
10016 struct vki_v4l2_query_ext_ctrl *data =
10017 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
10018 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
10019 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
10020 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
10021 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
10022 break;
10024 case VKI_V4L2_SUBDEV_G_FMT: {
10025 struct vki_v4l2_subdev_format *data =
10026 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10027 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
10028 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
10029 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
10030 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
10031 break;
10033 case VKI_V4L2_SUBDEV_S_FMT: {
10034 struct vki_v4l2_subdev_format *data =
10035 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
10036 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
10037 break;
10039 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
10040 struct vki_v4l2_subdev_frame_interval *data =
10041 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10042 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
10043 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
10044 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
10045 break;
10047 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
10048 struct vki_v4l2_subdev_frame_interval *data =
10049 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
10050 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
10051 break;
10053 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
10054 struct vki_v4l2_subdev_mbus_code_enum *data =
10055 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
10056 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
10057 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
10058 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
10059 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
10060 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
10061 break;
10063 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
10064 struct vki_v4l2_subdev_frame_size_enum *data =
10065 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
10066 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
10067 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
10068 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
10069 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
10070 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
10071 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
10072 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
10073 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
10074 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
10075 break;
10077 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10078 struct vki_v4l2_subdev_frame_interval_enum *data =
10079 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
10080 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
10081 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
10082 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
10083 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
10084 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
10085 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
10086 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
10087 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
10088 break;
10090 case VKI_V4L2_SUBDEV_G_CROP: {
10091 struct vki_v4l2_subdev_crop *data =
10092 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10093 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
10094 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
10095 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
10096 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
10097 break;
10099 case VKI_V4L2_SUBDEV_S_CROP: {
10100 struct vki_v4l2_subdev_crop *data =
10101 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10102 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
10103 break;
10105 case VKI_V4L2_SUBDEV_G_SELECTION: {
10106 struct vki_v4l2_subdev_selection *data =
10107 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10108 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
10109 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
10110 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
10111 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
10112 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
10113 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
10114 break;
10116 case VKI_V4L2_SUBDEV_S_SELECTION: {
10117 struct vki_v4l2_subdev_selection *data =
10118 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10119 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10120 break;
10122 case VKI_MEDIA_IOC_DEVICE_INFO: {
10123 struct vki_media_device_info *data =
10124 (struct vki_media_device_info *)(Addr)ARG3;
10125 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10126 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10127 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10128 break;
10130 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10131 struct vki_media_entity_desc *data =
10132 (struct vki_media_entity_desc *)(Addr)ARG3;
10133 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10134 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10135 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10136 break;
10138 case VKI_MEDIA_IOC_ENUM_LINKS: {
10139 struct vki_media_links_enum *data =
10140 (struct vki_media_links_enum *)(Addr)ARG3;
10141 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10142 break;
10144 case VKI_MEDIA_IOC_SETUP_LINK: {
10145 struct vki_media_link_desc *data =
10146 (struct vki_media_link_desc *)(Addr)ARG3;
10147 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10148 break;
10151 /* Serial */
10152 case VKI_TIOCGSERIAL: {
10153 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10154 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10155 break;
10157 case VKI_TIOCSSERIAL: {
10158 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10159 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10160 break;
10163 case VKI_PERF_EVENT_IOC_RESET:
10164 case VKI_PERF_EVENT_IOC_REFRESH:
10165 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10166 case VKI_PERF_EVENT_IOC_SET_BPF:
10167 /* These take scalar arguments, so already handled above */
10168 break;
10170 case VKI_PERF_EVENT_IOC_PERIOD:
10171 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10172 break;
10174 case VKI_PERF_EVENT_IOC_SET_FILTER:
10175 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10176 break;
10178 case VKI_PERF_EVENT_IOC_ID:
10179 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10180 break;
10182 /* Pulse Per Second (PPS) */
10183 case VKI_PPS_GETPARAMS: {
10184 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10185 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10186 break;
10188 case VKI_PPS_SETPARAMS: {
10189 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10190 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10191 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10192 data->assert_off_tu.sec);
10193 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10194 data->assert_off_tu.nsec);
10195 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10196 data->clear_off_tu.sec);
10197 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10198 data->clear_off_tu.nsec);
10199 break;
10201 case VKI_PPS_GETCAP:
10202 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10203 break;
10204 case VKI_PPS_FETCH: {
10205 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10206 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10207 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10208 break;
10210 case VKI_PPS_KC_BIND: {
10211 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10212 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10213 break;
10216 /* PTP Hardware Clock */
10217 case VKI_PTP_CLOCK_GETCAPS: {
10218 struct vki_ptp_clock_caps *data =
10219 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10220 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10221 break;
10223 case VKI_PTP_EXTTS_REQUEST: {
10224 struct vki_ptp_extts_request *data =
10225 (struct vki_ptp_extts_request *)(Addr)ARG3;
10226 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10227 break;
10229 case VKI_PTP_PEROUT_REQUEST: {
10230 struct vki_ptp_perout_request *data =
10231 (struct vki_ptp_perout_request *)(Addr)ARG3;
10232 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10233 break;
10235 case VKI_PTP_ENABLE_PPS:
10236 break;
10237 case VKI_PTP_SYS_OFFSET: {
10238 struct vki_ptp_sys_offset *data =
10239 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10240 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10241 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10242 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10243 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10244 break;
10246 case VKI_PTP_PIN_GETFUNC: {
10247 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10248 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10249 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10250 break;
10252 case VKI_PTP_PIN_SETFUNC: {
10253 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10254 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10255 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10256 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10257 break;
10259 case VKI_PTP_SYS_OFFSET_PRECISE: {
10260 struct vki_ptp_sys_offset_precise *data =
10261 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10262 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10263 break;
10265 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10266 struct vki_ptp_sys_offset_extended *data =
10267 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10268 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10269 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10270 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10271 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10272 3 * data->n_samples * sizeof(data->ts[0][0]));
10273 break;
10276 default:
10277 /* EVIOC* are variable length and return size written on success */
10278 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10279 case VKI_EVIOCGNAME(0):
10280 case VKI_EVIOCGPHYS(0):
10281 case VKI_EVIOCGUNIQ(0):
10282 case VKI_EVIOCGKEY(0):
10283 case VKI_EVIOCGLED(0):
10284 case VKI_EVIOCGSND(0):
10285 case VKI_EVIOCGSW(0):
10286 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10287 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10288 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10289 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10290 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10291 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10292 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10293 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10294 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10295 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10296 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10297 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10298 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10299 break;
10300 default:
10301 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10302 break;
10304 break;
10308 POST(sys_ioctl)
10310 ARG2 = (UInt)ARG2;
10312 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10314 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10316 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10317 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10318 VG_(clo_kernel_variant))) {
10320 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10321 /* What's going on here: there appear to be a bunch of ioctls
10322 of the form 0xC01C67xx which are undocumented, and if
10323 unhandled give rise to a vast number of false positives in
10324 Memcheck.
10326 The "normal" interpretation of an ioctl of this form would
10327 be that the 3rd arg is a pointer to an area of size 0x1C
10328 (28 bytes) which is filled in by the kernel. Hence you
10329 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10330 But it doesn't.
10332 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10333 One interpretation of this is that ARG3 really does point
10334 to a 28 byte struct, but inside that are pointers to other
10335 areas also filled in by the kernel. If these happen to be
10336 allocated just back up the stack then the 256 byte paint
10337 might cover them too, somewhat indiscriminately.
10339 By printing out ARG3 and also the 28 bytes that it points
10340 at, it's possible to guess that the 7 word structure has
10341 this form
10343 0 1 2 3 4 5 6
10344 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10346 Unfortunately that doesn't seem to work for some reason,
10347 so stay with the blunt-instrument approach for the time
10348 being.
10350 if (1) {
10351 /* blunt-instrument approach */
10352 POST_MEM_WRITE(ARG3, 256);
10353 } else {
10354 /* be a bit more sophisticated */
10355 POST_MEM_WRITE(ARG3, 28);
10356 UInt* word = (UInt*)(Addr)ARG3;
10357 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10358 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10359 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10360 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10362 goto post_sys_ioctl__out;
10365 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10367 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10368 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10369 VG_(clo_kernel_variant))) {
10370 if (ARG2 == 0xC00C0902) {
10371 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10372 goto post_sys_ioctl__out;
10375 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10377 /* --- END special IOCTL handlers for specific Android hardware --- */
10379 /* --- normal handling --- */
10380 switch (ARG2 /* request */) {
10382 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10383 this is pretty poor given that there's no pre-handling to check
10384 that writable areas are addressable. */
10385 case VKI_ION_IOC_ALLOC: {
10386 struct vki_ion_allocation_data* data
10387 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10388 POST_FIELD_WRITE(data->handle);
10389 break;
10391 case VKI_ION_IOC_MAP: {
10392 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10393 POST_FIELD_WRITE(data->fd);
10394 break;
10396 case VKI_ION_IOC_FREE: // is this necessary?
10397 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10398 break;
10399 case VKI_ION_IOC_SHARE:
10400 break;
10401 case VKI_ION_IOC_IMPORT: {
10402 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10403 POST_FIELD_WRITE(data->handle);
10404 break;
10406 case VKI_ION_IOC_SYNC:
10407 break;
10408 case VKI_ION_IOC_CUSTOM: // is this necessary?
10409 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10410 break;
10412 case VKI_SYNC_IOC_MERGE: {
10413 struct vki_sync_merge_data* data =
10414 (struct vki_sync_merge_data*)(Addr)ARG3;
10415 POST_FIELD_WRITE(data->fence);
10416 break;
10419 case VKI_TCSETS:
10420 case VKI_TCSETSW:
10421 case VKI_TCSETSF:
10422 case VKI_IB_USER_MAD_ENABLE_PKEY:
10423 break;
10424 case VKI_TCGETS:
10425 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10426 break;
10427 case VKI_TCSETA:
10428 case VKI_TCSETAW:
10429 case VKI_TCSETAF:
10430 break;
10431 case VKI_TCGETA:
10432 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10433 break;
10434 case VKI_TCSBRK:
10435 case VKI_TCXONC:
10436 case VKI_TCSBRKP:
10437 case VKI_TCFLSH:
10438 case VKI_TIOCSIG:
10439 break;
10440 case VKI_TIOCGWINSZ:
10441 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10442 break;
10443 case VKI_TIOCSWINSZ:
10444 case VKI_TIOCMBIS:
10445 case VKI_TIOCMBIC:
10446 case VKI_TIOCMSET:
10447 break;
10448 case VKI_TIOCMGET:
10449 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10450 break;
10451 case VKI_TIOCLINUX:
10452 POST_MEM_WRITE( ARG3, sizeof(char *) );
10453 break;
10454 case VKI_TIOCGPGRP:
10455 /* Get process group ID for foreground processing group. */
10456 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10457 break;
10458 case VKI_TIOCSPGRP:
10459 /* Set a process group ID? */
10460 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10461 break;
10462 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10463 POST_MEM_WRITE( ARG3, sizeof(int));
10464 break;
10465 case VKI_TIOCSCTTY:
10466 break;
10467 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10468 break;
10469 case VKI_FIONBIO:
10470 break;
10471 case VKI_FIONCLEX:
10472 break;
10473 case VKI_FIOCLEX:
10474 break;
10475 case VKI_TIOCNOTTY:
10476 break;
10477 case VKI_FIOASYNC:
10478 break;
10479 case VKI_FIONREAD: /* identical to SIOCINQ */
10480 POST_MEM_WRITE( ARG3, sizeof(int) );
10481 break;
10482 case VKI_FIOQSIZE:
10483 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10484 break;
10486 case VKI_TIOCSERGETLSR:
10487 POST_MEM_WRITE( ARG3, sizeof(int) );
10488 break;
10489 case VKI_TIOCGICOUNT:
10490 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10491 break;
10493 case VKI_SG_SET_COMMAND_Q:
10494 break;
10495 case VKI_SG_IO:
10497 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10498 if ( sgio->sbp ) {
10499 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10501 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10502 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10503 int transferred = sgio->dxfer_len - sgio->resid;
10504 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10507 break;
10508 case VKI_SG_GET_SCSI_ID:
10509 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10510 break;
10511 case VKI_SG_SET_RESERVED_SIZE:
10512 break;
10513 case VKI_SG_SET_TIMEOUT:
10514 break;
10515 case VKI_SG_GET_RESERVED_SIZE:
10516 POST_MEM_WRITE(ARG3, sizeof(int));
10517 break;
10518 case VKI_SG_GET_TIMEOUT:
10519 break;
10520 case VKI_SG_GET_VERSION_NUM:
10521 POST_MEM_WRITE(ARG3, sizeof(int));
10522 break;
10523 case VKI_SG_EMULATED_HOST:
10524 POST_MEM_WRITE(ARG3, sizeof(int));
10525 break;
10526 case VKI_SG_GET_SG_TABLESIZE:
10527 POST_MEM_WRITE(ARG3, sizeof(int));
10528 break;
10530 case VKI_IIOCGETCPS:
10531 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10532 break;
10533 case VKI_IIOCNETGPN:
10534 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10535 break;
10537 /* These all use struct ifreq AFAIK */
10538 case VKI_SIOCGIFINDEX: /* get iface index */
10539 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10540 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10541 break;
10542 case VKI_SIOCGIFFLAGS: /* get flags */
10543 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10544 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10545 break;
10546 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10547 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10548 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10549 break;
10550 case VKI_SIOCGIFMTU: /* get MTU size */
10551 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10552 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10553 break;
10554 case VKI_SIOCGIFADDR: /* get PA address */
10555 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10556 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10557 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10558 POST_MEM_WRITE(
10559 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10560 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10561 break;
10562 case VKI_SIOCGIFMETRIC: /* get metric */
10563 POST_MEM_WRITE(
10564 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10565 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10566 break;
10567 case VKI_SIOCGIFMAP: /* Get device parameters */
10568 POST_MEM_WRITE(
10569 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10570 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10571 break;
10572 break;
10573 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10574 POST_MEM_WRITE(
10575 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10576 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10577 break;
10578 case VKI_SIOCGIFNAME: /* get iface name */
10579 POST_MEM_WRITE(
10580 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10581 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10582 break;
10583 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10584 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10585 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10586 case VKI_ETHTOOL_GSET:
10587 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10588 break;
10589 case VKI_ETHTOOL_SSET:
10590 break;
10591 case VKI_ETHTOOL_GDRVINFO:
10592 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10593 break;
10594 case VKI_ETHTOOL_GREGS:
10595 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10596 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10597 break;
10598 case VKI_ETHTOOL_GWOL:
10599 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10600 break;
10601 case VKI_ETHTOOL_SWOL:
10602 break;
10603 case VKI_ETHTOOL_GMSGLVL:
10604 case VKI_ETHTOOL_GLINK:
10605 case VKI_ETHTOOL_GRXCSUM:
10606 case VKI_ETHTOOL_GSG:
10607 case VKI_ETHTOOL_GTSO:
10608 case VKI_ETHTOOL_GUFO:
10609 case VKI_ETHTOOL_GGSO:
10610 case VKI_ETHTOOL_GFLAGS:
10611 case VKI_ETHTOOL_GGRO:
10612 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10613 break;
10614 case VKI_ETHTOOL_SMSGLVL:
10615 case VKI_ETHTOOL_SRXCSUM:
10616 case VKI_ETHTOOL_SSG:
10617 case VKI_ETHTOOL_STSO:
10618 case VKI_ETHTOOL_SUFO:
10619 case VKI_ETHTOOL_SGSO:
10620 case VKI_ETHTOOL_SFLAGS:
10621 case VKI_ETHTOOL_SGRO:
10622 break;
10623 case VKI_ETHTOOL_NWAY_RST:
10624 break;
10625 case VKI_ETHTOOL_GRINGPARAM:
10626 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10627 break;
10628 case VKI_ETHTOOL_SRINGPARAM:
10629 break;
10630 case VKI_ETHTOOL_TEST:
10631 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10632 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10633 break;
10634 case VKI_ETHTOOL_PHYS_ID:
10635 break;
10636 case VKI_ETHTOOL_GPERMADDR:
10637 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10638 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10639 break;
10640 case VKI_ETHTOOL_RESET:
10641 break;
10642 case VKI_ETHTOOL_GSSET_INFO:
10643 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10644 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10645 break;
10646 case VKI_ETHTOOL_GFEATURES:
10647 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10648 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10649 break;
10650 case VKI_ETHTOOL_SFEATURES:
10651 break;
10652 case VKI_ETHTOOL_GCHANNELS:
10653 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10654 break;
10655 case VKI_ETHTOOL_SCHANNELS:
10656 break;
10657 case VKI_ETHTOOL_GET_TS_INFO:
10658 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10659 break;
10661 break;
10663 case VKI_SIOCGMIIPHY: /* get hardware entry */
10664 POST_MEM_WRITE(
10665 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10666 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10667 break;
10668 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10669 POST_MEM_WRITE(
10670 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10671 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10672 break;
10674 /* tun/tap related ioctls */
10675 case VKI_TUNSETIFF:
10676 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10677 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10678 break;
10679 case VKI_TUNGETFEATURES:
10680 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10681 break;
10682 case VKI_TUNGETIFF:
10683 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10684 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10685 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10686 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10687 break;
10688 case VKI_TUNGETSNDBUF:
10689 POST_MEM_WRITE( ARG3, sizeof(int) );
10690 break;
10691 case VKI_TUNGETVNETHDRSZ:
10692 POST_MEM_WRITE( ARG3, sizeof(int) );
10693 break;
10695 case VKI_SIOCGIFCONF: /* get iface list */
10696 /* WAS:
10697 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10698 KERNEL_DO_SYSCALL(tid,RES);
10699 if (!VG_(is_kerror)(RES) && RES == 0)
10700 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10702 if (RES == 0 && ARG3 ) {
10703 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10704 if (ifc->vki_ifc_buf != NULL)
10705 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10707 break;
10708 case VKI_SIOCGSTAMP:
10709 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10710 break;
10711 case VKI_SIOCGSTAMPNS:
10712 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10713 break;
10714 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10715 the number of bytes currently in that socket's send buffer.
10716 It writes this value as an int to the memory location
10717 indicated by the third argument of ioctl(2). */
10718 case VKI_SIOCOUTQ:
10719 POST_MEM_WRITE(ARG3, sizeof(int));
10720 break;
10721 case VKI_SIOCGRARP: /* get RARP table entry */
10722 case VKI_SIOCGARP: /* get ARP table entry */
10723 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10724 break;
10726 case VKI_SIOCSIFFLAGS: /* set flags */
10727 case VKI_SIOCSIFMAP: /* Set device parameters */
10728 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10729 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10730 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10731 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10732 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10733 case VKI_SIOCSIFMETRIC: /* set metric */
10734 case VKI_SIOCSIFADDR: /* set PA address */
10735 case VKI_SIOCSIFMTU: /* set MTU size */
10736 case VKI_SIOCSIFHWADDR: /* set hardware address */
10737 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10738 break;
10739 /* Routing table calls. */
10740 case VKI_SIOCADDRT: /* add routing table entry */
10741 case VKI_SIOCDELRT: /* delete routing table entry */
10742 break;
10744 /* RARP cache control calls. */
10745 case VKI_SIOCDRARP: /* delete RARP table entry */
10746 case VKI_SIOCSRARP: /* set RARP table entry */
10747 /* ARP cache control calls. */
10748 case VKI_SIOCSARP: /* set ARP table entry */
10749 case VKI_SIOCDARP: /* delete ARP table entry */
10750 break;
10752 case VKI_SIOCGPGRP:
10753 POST_MEM_WRITE(ARG3, sizeof(int));
10754 break;
10755 case VKI_SIOCSPGRP:
10756 break;
10758 case VKI_SIOCATMARK:
10759 POST_MEM_WRITE(ARG3, sizeof(int));
10760 break;
10762 /* linux/soundcard interface (OSS) */
10763 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10764 case VKI_SNDCTL_SEQ_GETINCOUNT:
10765 case VKI_SNDCTL_SEQ_PERCMODE:
10766 case VKI_SNDCTL_SEQ_TESTMIDI:
10767 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10768 case VKI_SNDCTL_SEQ_NRSYNTHS:
10769 case VKI_SNDCTL_SEQ_NRMIDIS:
10770 case VKI_SNDCTL_SEQ_GETTIME:
10771 case VKI_SNDCTL_DSP_GETBLKSIZE:
10772 case VKI_SNDCTL_DSP_GETFMTS:
10773 case VKI_SNDCTL_DSP_SETFMT:
10774 case VKI_SNDCTL_DSP_GETTRIGGER:
10775 case VKI_SNDCTL_DSP_GETODELAY:
10776 case VKI_SNDCTL_DSP_GETSPDIF:
10777 case VKI_SNDCTL_DSP_GETCAPS:
10778 case VKI_SOUND_PCM_READ_RATE:
10779 case VKI_SOUND_PCM_READ_CHANNELS:
10780 case VKI_SOUND_PCM_READ_BITS:
10781 case VKI_SOUND_PCM_READ_FILTER:
10782 POST_MEM_WRITE(ARG3, sizeof(int));
10783 break;
10784 case VKI_SNDCTL_SEQ_CTRLRATE:
10785 case VKI_SNDCTL_DSP_SPEED:
10786 case VKI_SNDCTL_DSP_STEREO:
10787 case VKI_SNDCTL_DSP_CHANNELS:
10788 case VKI_SOUND_PCM_WRITE_FILTER:
10789 case VKI_SNDCTL_DSP_SUBDIVIDE:
10790 case VKI_SNDCTL_DSP_SETFRAGMENT:
10791 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10792 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10793 case VKI_SNDCTL_TMR_TIMEBASE:
10794 case VKI_SNDCTL_TMR_TEMPO:
10795 case VKI_SNDCTL_TMR_SOURCE:
10796 case VKI_SNDCTL_MIDI_PRETIME:
10797 case VKI_SNDCTL_MIDI_MPUMODE:
10798 break;
10799 case VKI_SNDCTL_DSP_GETOSPACE:
10800 case VKI_SNDCTL_DSP_GETISPACE:
10801 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10802 break;
10803 case VKI_SNDCTL_DSP_NONBLOCK:
10804 break;
10805 case VKI_SNDCTL_DSP_SETTRIGGER:
10806 break;
10808 case VKI_SNDCTL_DSP_POST:
10809 case VKI_SNDCTL_DSP_RESET:
10810 case VKI_SNDCTL_DSP_SYNC:
10811 case VKI_SNDCTL_DSP_SETSYNCRO:
10812 case VKI_SNDCTL_DSP_SETDUPLEX:
10813 break;
10815 /* linux/soundcard interface (ALSA) */
10816 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10817 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10818 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10819 case VKI_SNDRV_PCM_IOCTL_RESET:
10820 case VKI_SNDRV_PCM_IOCTL_START:
10821 case VKI_SNDRV_PCM_IOCTL_DROP:
10822 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10823 case VKI_SNDRV_PCM_IOCTL_RESUME:
10824 case VKI_SNDRV_PCM_IOCTL_XRUN:
10825 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10826 case VKI_SNDRV_TIMER_IOCTL_START:
10827 case VKI_SNDRV_TIMER_IOCTL_STOP:
10828 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10829 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10830 break;
10832 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10833 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10834 break;
10836 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10837 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10838 break;
10839 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10840 struct vki_snd_ctl_elem_list *data =
10841 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10842 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10843 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10844 if (data->pids) {
10845 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10847 break;
10849 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10850 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10851 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10852 break;
10854 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10855 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10856 break;
10858 /* SCSI no operand */
10859 case VKI_SCSI_IOCTL_DOORLOCK:
10860 case VKI_SCSI_IOCTL_DOORUNLOCK:
10861 break;
10863 /* Real Time Clock (/dev/rtc) ioctls */
10864 case VKI_RTC_UIE_ON:
10865 case VKI_RTC_UIE_OFF:
10866 case VKI_RTC_AIE_ON:
10867 case VKI_RTC_AIE_OFF:
10868 case VKI_RTC_PIE_ON:
10869 case VKI_RTC_PIE_OFF:
10870 case VKI_RTC_IRQP_SET:
10871 break;
10872 case VKI_RTC_RD_TIME:
10873 case VKI_RTC_ALM_READ:
10874 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10875 break;
10876 case VKI_RTC_ALM_SET:
10877 break;
10878 case VKI_RTC_IRQP_READ:
10879 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10880 break;
10882 /* Loopback devices */
10883 case VKI_LOOP_CTL_ADD:
10884 case VKI_LOOP_CTL_REMOVE:
10885 case VKI_LOOP_CTL_GET_FREE:
10886 break;
10887 /* Loopback device */
10888 case VKI_LOOP_SET_FD:
10889 case VKI_LOOP_CLR_FD:
10890 case VKI_LOOP_CHANGE_FD:
10891 case VKI_LOOP_SET_CAPACITY:
10892 case VKI_LOOP_SET_DIRECT_IO:
10893 case VKI_LOOP_SET_BLOCK_SIZE:
10894 break;
10895 case VKI_LOOP_SET_STATUS:
10896 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
10897 break;
10898 case VKI_LOOP_GET_STATUS:
10899 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info));
10900 break;
10901 case VKI_LOOP_SET_STATUS64:
10902 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
10903 break;
10904 case VKI_LOOP_GET_STATUS64:
10905 POST_MEM_WRITE(ARG3, sizeof(struct vki_loop_info64));
10906 break;
10909 /* Block devices */
10910 case VKI_BLKROSET:
10911 break;
10912 case VKI_BLKROGET:
10913 POST_MEM_WRITE(ARG3, sizeof(int));
10914 break;
10915 case VKI_BLKGETSIZE:
10916 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10917 break;
10918 case VKI_BLKFLSBUF:
10919 break;
10920 case VKI_BLKRASET:
10921 break;
10922 case VKI_BLKRAGET:
10923 POST_MEM_WRITE(ARG3, sizeof(long));
10924 break;
10925 case VKI_BLKFRASET:
10926 break;
10927 case VKI_BLKFRAGET:
10928 POST_MEM_WRITE(ARG3, sizeof(long));
10929 break;
10930 case VKI_BLKSECTGET:
10931 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10932 break;
10933 case VKI_BLKSSZGET:
10934 POST_MEM_WRITE(ARG3, sizeof(int));
10935 break;
10936 case VKI_BLKBSZGET:
10937 POST_MEM_WRITE(ARG3, sizeof(int));
10938 break;
10939 case VKI_BLKBSZSET:
10940 break;
10941 case VKI_BLKGETSIZE64:
10942 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10943 break;
10944 case VKI_BLKPBSZGET:
10945 POST_MEM_WRITE(ARG3, sizeof(int));
10946 break;
10947 case VKI_BLKIOMIN:
10948 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10949 break;
10950 case VKI_BLKIOOPT:
10951 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10952 break;
10953 case VKI_BLKALIGNOFF:
10954 POST_MEM_WRITE(ARG3, sizeof(int));
10955 break;
10956 case VKI_BLKDISCARDZEROES:
10957 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10958 break;
10959 case VKI_BLKREPORTZONE: {
10960 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10962 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10963 break;
10965 case VKI_BLKRESETZONE:
10966 break;
10968 /* Hard disks */
10969 case VKI_HDIO_GETGEO: /* 0x0301 */
10970 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10971 break;
10972 case VKI_HDIO_GET_DMA: /* 0x030b */
10973 POST_MEM_WRITE(ARG3, sizeof(long));
10974 break;
10975 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10976 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10977 break;
10979 /* SCSI */
10980 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10981 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10982 break;
10983 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10984 POST_MEM_WRITE(ARG3, sizeof(int));
10985 break;
10987 /* CD ROM stuff (??) */
10988 case VKI_CDROM_DISC_STATUS:
10989 case VKI_CDROMSTOP:
10990 break;
10991 case VKI_CDROMSUBCHNL:
10992 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10993 break;
10994 case VKI_CDROMREADTOCHDR:
10995 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10996 break;
10997 case VKI_CDROMREADTOCENTRY:
10998 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10999 break;
11000 case VKI_CDROMMULTISESSION:
11001 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
11002 break;
11003 case VKI_CDROMVOLREAD:
11004 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
11005 break;
11006 case VKI_CDROMREADMODE1:
11007 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
11008 break;
11009 case VKI_CDROMREADMODE2:
11010 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
11011 break;
11012 case VKI_CDROMREADRAW:
11013 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
11014 break;
11015 case VKI_CDROMREADAUDIO:
11017 struct vki_cdrom_read_audio *cra =
11018 (struct vki_cdrom_read_audio *) (Addr)ARG3;
11019 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
11020 break;
11023 case VKI_CDROMPLAYMSF:
11024 break;
11025 /* The following two are probably bogus (should check args
11026 for readability). JRS 20021117 */
11027 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
11028 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
11029 break;
11030 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
11031 break;
11033 /* DVD stuff */
11034 case VKI_DVD_READ_STRUCT:
11035 break;
11037 case VKI_FIGETBSZ:
11038 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
11039 break;
11040 case VKI_FIBMAP:
11041 POST_MEM_WRITE(ARG3, sizeof(int));
11042 break;
11043 case VKI_FICLONE:
11044 break;
11046 case VKI_FBIOGET_VSCREENINFO: //0x4600
11047 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
11048 break;
11049 case VKI_FBIOGET_FSCREENINFO: //0x4602
11050 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
11051 break;
11053 case VKI_PPCLAIM:
11054 case VKI_PPEXCL:
11055 case VKI_PPYIELD:
11056 case VKI_PPRELEASE:
11057 case VKI_PPSETMODE:
11058 case VKI_PPSETPHASE:
11059 case VKI_PPSETFLAGS:
11060 case VKI_PPWDATA:
11061 case VKI_PPWCONTROL:
11062 case VKI_PPFCONTROL:
11063 case VKI_PPDATADIR:
11064 case VKI_PPNEGOT:
11065 case VKI_PPWCTLONIRQ:
11066 case VKI_PPSETTIME:
11067 break;
11068 case VKI_PPGETMODE:
11069 POST_MEM_WRITE( ARG3, sizeof(int) );
11070 break;
11071 case VKI_PPGETPHASE:
11072 POST_MEM_WRITE( ARG3, sizeof(int) );
11073 break;
11074 case VKI_PPGETMODES:
11075 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
11076 break;
11077 case VKI_PPGETFLAGS:
11078 POST_MEM_WRITE( ARG3, sizeof(int) );
11079 break;
11080 case VKI_PPRSTATUS:
11081 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11082 break;
11083 case VKI_PPRDATA:
11084 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11085 break;
11086 case VKI_PPRCONTROL:
11087 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
11088 break;
11089 case VKI_PPCLRIRQ:
11090 POST_MEM_WRITE( ARG3, sizeof(int) );
11091 break;
11092 case VKI_PPGETTIME:
11093 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
11094 break;
11096 case VKI_GIO_FONT:
11097 POST_MEM_WRITE( ARG3, 32 * 256 );
11098 break;
11099 case VKI_PIO_FONT:
11100 break;
11102 case VKI_GIO_FONTX:
11103 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
11104 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
11105 break;
11106 case VKI_PIO_FONTX:
11107 break;
11109 case VKI_PIO_FONTRESET:
11110 break;
11112 case VKI_GIO_CMAP:
11113 POST_MEM_WRITE( ARG3, 16 * 3 );
11114 break;
11115 case VKI_PIO_CMAP:
11116 break;
11118 case VKI_KIOCSOUND:
11119 case VKI_KDMKTONE:
11120 break;
11122 case VKI_KDGETLED:
11123 POST_MEM_WRITE( ARG3, sizeof(char) );
11124 break;
11125 case VKI_KDSETLED:
11126 break;
11128 case VKI_KDGKBTYPE:
11129 POST_MEM_WRITE( ARG3, sizeof(char) );
11130 break;
11132 case VKI_KDADDIO:
11133 case VKI_KDDELIO:
11134 case VKI_KDENABIO:
11135 case VKI_KDDISABIO:
11136 break;
11138 case VKI_KDSETMODE:
11139 break;
11140 case VKI_KDGETMODE:
11141 POST_MEM_WRITE( ARG3, sizeof(int) );
11142 break;
11144 case VKI_KDMAPDISP:
11145 case VKI_KDUNMAPDISP:
11146 break;
11148 case VKI_GIO_SCRNMAP:
11149 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11150 break;
11151 case VKI_PIO_SCRNMAP:
11152 break;
11153 case VKI_GIO_UNISCRNMAP:
11154 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11155 break;
11156 case VKI_PIO_UNISCRNMAP:
11157 break;
11159 case VKI_GIO_UNIMAP:
11160 if ( ARG3 ) {
11161 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11162 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11163 POST_MEM_WRITE( (Addr)desc->entries,
11164 desc->entry_ct * sizeof(struct vki_unipair) );
11166 break;
11167 case VKI_PIO_UNIMAP:
11168 break;
11169 case VKI_PIO_UNIMAPCLR:
11170 break;
11172 case VKI_KDGKBMODE:
11173 POST_MEM_WRITE( ARG3, sizeof(int) );
11174 break;
11175 case VKI_KDSKBMODE:
11176 break;
11178 case VKI_KDGKBMETA:
11179 POST_MEM_WRITE( ARG3, sizeof(int) );
11180 break;
11181 case VKI_KDSKBMETA:
11182 break;
11184 case VKI_KDGKBLED:
11185 POST_MEM_WRITE( ARG3, sizeof(char) );
11186 break;
11187 case VKI_KDSKBLED:
11188 break;
11190 case VKI_KDGKBENT:
11191 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11192 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11193 break;
11194 case VKI_KDSKBENT:
11195 break;
11197 case VKI_KDGKBSENT:
11198 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11199 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11200 break;
11201 case VKI_KDSKBSENT:
11202 break;
11204 case VKI_KDGKBDIACR:
11205 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11206 break;
11207 case VKI_KDSKBDIACR:
11208 break;
11210 case VKI_KDGETKEYCODE:
11211 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11212 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11213 break;
11214 case VKI_KDSETKEYCODE:
11215 break;
11217 case VKI_KDSIGACCEPT:
11218 break;
11220 case VKI_KDKBDREP:
11221 break;
11223 case VKI_KDFONTOP:
11224 if ( ARG3 ) {
11225 struct vki_console_font_op *op =
11226 (struct vki_console_font_op *) (Addr)ARG3;
11227 switch ( op->op ) {
11228 case VKI_KD_FONT_OP_SET:
11229 break;
11230 case VKI_KD_FONT_OP_GET:
11231 if ( op->data )
11232 POST_MEM_WRITE( (Addr) op->data,
11233 (op->width + 7) / 8 * 32 * op->charcount );
11234 break;
11235 case VKI_KD_FONT_OP_SET_DEFAULT:
11236 break;
11237 case VKI_KD_FONT_OP_COPY:
11238 break;
11240 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11242 break;
11244 case VKI_VT_OPENQRY:
11245 POST_MEM_WRITE( ARG3, sizeof(int) );
11246 break;
11247 case VKI_VT_GETMODE:
11248 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11249 break;
11250 case VKI_VT_SETMODE:
11251 break;
11252 case VKI_VT_GETSTATE:
11253 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11254 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11255 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11256 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11257 break;
11258 case VKI_VT_RELDISP:
11259 case VKI_VT_ACTIVATE:
11260 case VKI_VT_WAITACTIVE:
11261 case VKI_VT_DISALLOCATE:
11262 break;
11263 case VKI_VT_RESIZE:
11264 break;
11265 case VKI_VT_RESIZEX:
11266 break;
11267 case VKI_VT_LOCKSWITCH:
11268 case VKI_VT_UNLOCKSWITCH:
11269 break;
11271 case VKI_USBDEVFS_CONTROL:
11272 if ( ARG3 ) {
11273 struct vki_usbdevfs_ctrltransfer *vkuc =
11274 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11275 if (vkuc->bRequestType & 0x80)
11276 POST_MEM_WRITE((Addr)vkuc->data, RES);
11278 break;
11279 case VKI_USBDEVFS_BULK:
11280 if ( ARG3 ) {
11281 struct vki_usbdevfs_bulktransfer *vkub =
11282 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11283 if (vkub->ep & 0x80)
11284 POST_MEM_WRITE((Addr)vkub->data, RES);
11286 break;
11287 case VKI_USBDEVFS_GETDRIVER:
11288 if ( ARG3 ) {
11289 struct vki_usbdevfs_getdriver *vkugd =
11290 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11291 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11293 break;
11294 case VKI_USBDEVFS_REAPURB:
11295 case VKI_USBDEVFS_REAPURBNDELAY:
11296 if ( ARG3 ) {
11297 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11298 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11299 if (!*vkuu)
11300 break;
11301 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11302 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11303 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11304 if (vkusp->bRequestType & 0x80)
11305 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11306 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11307 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11308 char *bp = (*vkuu)->buffer;
11309 int i;
11310 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11311 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11312 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11313 if ((*vkuu)->endpoint & 0x80)
11314 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11315 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11317 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11318 } else {
11319 if ((*vkuu)->endpoint & 0x80)
11320 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11321 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11324 break;
11325 case VKI_USBDEVFS_CONNECTINFO:
11326 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11327 break;
11328 case VKI_USBDEVFS_IOCTL:
11329 if ( ARG3 ) {
11330 struct vki_usbdevfs_ioctl *vkui =
11331 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11332 UInt dir2, size2;
11333 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11334 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11335 if (size2 > 0) {
11336 if (dir2 & _VKI_IOC_READ)
11337 POST_MEM_WRITE((Addr)vkui->data, size2);
11340 break;
11342 /* I2C (/dev/i2c-*) ioctls */
11343 case VKI_I2C_SLAVE:
11344 case VKI_I2C_SLAVE_FORCE:
11345 case VKI_I2C_TENBIT:
11346 case VKI_I2C_PEC:
11347 break;
11348 case VKI_I2C_FUNCS:
11349 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11350 break;
11351 case VKI_I2C_RDWR:
11352 if ( ARG3 ) {
11353 struct vki_i2c_rdwr_ioctl_data *vkui =
11354 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11355 UInt i;
11356 for (i=0; i < vkui->nmsgs; i++) {
11357 struct vki_i2c_msg *msg = vkui->msgs + i;
11358 if (msg->flags & VKI_I2C_M_RD)
11359 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11362 break;
11363 case VKI_I2C_SMBUS:
11364 if ( ARG3 ) {
11365 struct vki_i2c_smbus_ioctl_data *vkis
11366 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11367 /* i2c_smbus_write_quick hides its value in read_write, so
11368 this variable can have a different meaning */
11369 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11370 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11371 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11372 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11373 UInt size;
11374 switch(vkis->size) {
11375 case VKI_I2C_SMBUS_BYTE:
11376 case VKI_I2C_SMBUS_BYTE_DATA:
11377 size = 1;
11378 break;
11379 case VKI_I2C_SMBUS_WORD_DATA:
11380 case VKI_I2C_SMBUS_PROC_CALL:
11381 size = 2;
11382 break;
11383 case VKI_I2C_SMBUS_BLOCK_DATA:
11384 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11385 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11386 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11387 size = 1 + vkis->data->block[0];
11388 break;
11389 default:
11390 size = 0;
11392 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11396 break;
11398 /* Wireless extensions ioctls */
11399 case VKI_SIOCSIWCOMMIT:
11400 case VKI_SIOCSIWNWID:
11401 case VKI_SIOCSIWFREQ:
11402 case VKI_SIOCSIWMODE:
11403 case VKI_SIOCSIWSENS:
11404 case VKI_SIOCSIWRANGE:
11405 case VKI_SIOCSIWPRIV:
11406 case VKI_SIOCSIWSTATS:
11407 case VKI_SIOCSIWSPY:
11408 case VKI_SIOCSIWTHRSPY:
11409 case VKI_SIOCSIWAP:
11410 case VKI_SIOCSIWSCAN:
11411 case VKI_SIOCSIWESSID:
11412 case VKI_SIOCSIWRATE:
11413 case VKI_SIOCSIWNICKN:
11414 case VKI_SIOCSIWRTS:
11415 case VKI_SIOCSIWFRAG:
11416 case VKI_SIOCSIWTXPOW:
11417 case VKI_SIOCSIWRETRY:
11418 case VKI_SIOCSIWENCODE:
11419 case VKI_SIOCSIWPOWER:
11420 case VKI_SIOCSIWGENIE:
11421 case VKI_SIOCSIWMLME:
11422 case VKI_SIOCSIWAUTH:
11423 case VKI_SIOCSIWENCODEEXT:
11424 case VKI_SIOCSIWPMKSA:
11425 break;
11426 case VKI_SIOCGIWNAME:
11427 if (ARG3) {
11428 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11429 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11431 break;
11432 case VKI_SIOCGIWNWID:
11433 case VKI_SIOCGIWSENS:
11434 case VKI_SIOCGIWRATE:
11435 case VKI_SIOCGIWRTS:
11436 case VKI_SIOCGIWFRAG:
11437 case VKI_SIOCGIWTXPOW:
11438 case VKI_SIOCGIWRETRY:
11439 case VKI_SIOCGIWPOWER:
11440 case VKI_SIOCGIWAUTH:
11441 if (ARG3) {
11442 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11443 sizeof(struct vki_iw_param));
11445 break;
11446 case VKI_SIOCGIWFREQ:
11447 if (ARG3) {
11448 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11449 sizeof(struct vki_iw_freq));
11451 break;
11452 case VKI_SIOCGIWMODE:
11453 if (ARG3) {
11454 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11455 sizeof(__vki_u32));
11457 break;
11458 case VKI_SIOCGIWRANGE:
11459 case VKI_SIOCGIWPRIV:
11460 case VKI_SIOCGIWSTATS:
11461 case VKI_SIOCGIWSPY:
11462 case VKI_SIOCGIWTHRSPY:
11463 case VKI_SIOCGIWAPLIST:
11464 case VKI_SIOCGIWSCAN:
11465 case VKI_SIOCGIWESSID:
11466 case VKI_SIOCGIWNICKN:
11467 case VKI_SIOCGIWENCODE:
11468 case VKI_SIOCGIWGENIE:
11469 case VKI_SIOCGIWENCODEEXT:
11470 if (ARG3) {
11471 struct vki_iw_point* point;
11472 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11473 POST_MEM_WRITE((Addr)point->pointer, point->length);
11475 break;
11476 case VKI_SIOCGIWAP:
11477 if (ARG3) {
11478 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11479 sizeof(struct vki_sockaddr));
11481 break;
11483 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11484 || defined(VGPV_mips32_linux_android) \
11485 || defined(VGPV_arm64_linux_android)
11486 /* ashmem */
11487 case VKI_ASHMEM_GET_SIZE:
11488 case VKI_ASHMEM_SET_SIZE:
11489 case VKI_ASHMEM_GET_PROT_MASK:
11490 case VKI_ASHMEM_SET_PROT_MASK:
11491 case VKI_ASHMEM_GET_PIN_STATUS:
11492 case VKI_ASHMEM_PURGE_ALL_CACHES:
11493 case VKI_ASHMEM_SET_NAME:
11494 case VKI_ASHMEM_PIN:
11495 case VKI_ASHMEM_UNPIN:
11496 break;
11497 case VKI_ASHMEM_GET_NAME:
11498 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11499 break;
11501 /* binder */
11502 case VKI_BINDER_WRITE_READ:
11503 if (ARG3) {
11504 struct vki_binder_write_read* bwr
11505 = (struct vki_binder_write_read*)(Addr)ARG3;
11506 POST_FIELD_WRITE(bwr->write_consumed);
11507 POST_FIELD_WRITE(bwr->read_consumed);
11509 if (bwr->read_size)
11510 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11512 break;
11514 case VKI_BINDER_SET_IDLE_TIMEOUT:
11515 case VKI_BINDER_SET_MAX_THREADS:
11516 case VKI_BINDER_SET_IDLE_PRIORITY:
11517 case VKI_BINDER_SET_CONTEXT_MGR:
11518 case VKI_BINDER_THREAD_EXIT:
11519 break;
11520 case VKI_BINDER_VERSION:
11521 if (ARG3) {
11522 struct vki_binder_version* bv =
11523 (struct vki_binder_version*)(Addr)ARG3;
11524 POST_FIELD_WRITE(bv->protocol_version);
11526 break;
11527 # endif /* defined(VGPV_*_linux_android) */
11529 case VKI_HCIGETDEVLIST:
11530 if (ARG3) {
11531 struct vki_hci_dev_list_req* dlr =
11532 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11533 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11534 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11536 break;
11538 case VKI_HCIINQUIRY:
11539 if (ARG3) {
11540 struct vki_hci_inquiry_req* ir =
11541 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11542 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11543 ir->num_rsp * sizeof(struct vki_inquiry_info));
11545 break;
11547 case VKI_DRM_IOCTL_VERSION:
11548 if (ARG3) {
11549 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11550 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11551 const vki_size_t orig_name_len = info->orig->name_len;
11552 const vki_size_t orig_date_len = info->orig->date_len;
11553 const vki_size_t orig_desc_len = info->orig->desc_len;
11554 *info->orig = info->data;
11555 ARG3 = (Addr)info->orig;
11556 data = info->orig;
11557 VG_(free)(info);
11558 if (SUCCESS) {
11559 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11560 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11561 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11562 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11563 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11564 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11565 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11566 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11567 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11570 break;
11571 case VKI_DRM_IOCTL_GET_UNIQUE:
11572 if (ARG3) {
11573 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11574 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11576 break;
11577 case VKI_DRM_IOCTL_GET_MAGIC:
11578 if (ARG3) {
11579 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11580 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11582 break;
11583 case VKI_DRM_IOCTL_WAIT_VBLANK:
11584 if (ARG3) {
11585 union vki_drm_wait_vblank *data =
11586 (union vki_drm_wait_vblank *)(Addr)ARG3;
11587 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11589 break;
11590 case VKI_DRM_IOCTL_GEM_FLINK:
11591 if (ARG3) {
11592 struct vki_drm_gem_flink *data =
11593 (struct vki_drm_gem_flink *)(Addr)ARG3;
11594 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11596 break;
11597 case VKI_DRM_IOCTL_GEM_OPEN:
11598 if (ARG3) {
11599 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11600 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11601 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11603 break;
11604 case VKI_DRM_IOCTL_I915_GETPARAM:
11605 if (ARG3) {
11606 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11607 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11609 break;
11610 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11611 if (ARG3) {
11612 struct vki_drm_i915_gem_busy *data =
11613 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11614 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11616 break;
11617 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11618 if (ARG3) {
11619 struct vki_drm_i915_gem_create *data =
11620 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11621 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11623 break;
11624 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11625 if (ARG3) {
11626 struct vki_drm_i915_gem_pread *data =
11627 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11628 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11630 break;
11631 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11632 if (ARG3) {
11633 struct vki_drm_i915_gem_mmap_v1 *data =
11634 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11635 Addr addr = data->addr_ptr;
11636 SizeT size = data->size;
11637 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11638 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11639 ML_(notify_core_and_tool_of_mmap)(addr, size,
11640 VKI_PROT_READ | VKI_PROT_WRITE,
11641 VKI_MAP_ANONYMOUS, -1, 0 );
11642 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11644 break;
11645 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11646 if (ARG3) {
11647 struct vki_drm_i915_gem_mmap *data =
11648 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11649 Addr addr = data->addr_ptr;
11650 SizeT size = data->size;
11651 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11652 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11653 ML_(notify_core_and_tool_of_mmap)(addr, size,
11654 VKI_PROT_READ | VKI_PROT_WRITE,
11655 VKI_MAP_ANONYMOUS, -1, 0 );
11656 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11658 break;
11659 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11660 if (ARG3) {
11661 struct vki_drm_i915_gem_mmap_gtt *data =
11662 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11663 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11665 break;
11666 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11667 if (ARG3) {
11668 struct vki_drm_i915_gem_set_tiling *data =
11669 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11670 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11671 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11672 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11674 break;
11675 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11676 if (ARG3) {
11677 struct vki_drm_i915_gem_get_tiling *data =
11678 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11679 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11680 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11682 break;
11683 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11684 if (ARG3) {
11685 struct vki_drm_i915_gem_get_aperture *data =
11686 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11687 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11688 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11690 break;
11692 /* KVM ioctls that only write the system call return value */
11693 case VKI_KVM_GET_API_VERSION:
11694 case VKI_KVM_CREATE_VM:
11695 case VKI_KVM_CHECK_EXTENSION:
11696 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11697 case VKI_KVM_S390_ENABLE_SIE:
11698 case VKI_KVM_CREATE_VCPU:
11699 case VKI_KVM_SET_TSS_ADDR:
11700 case VKI_KVM_CREATE_IRQCHIP:
11701 case VKI_KVM_RUN:
11702 case VKI_KVM_S390_INITIAL_RESET:
11703 case VKI_KVM_KVMCLOCK_CTRL:
11704 break;
11706 case VKI_KVM_S390_MEM_OP: {
11707 struct vki_kvm_s390_mem_op *args =
11708 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11709 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11710 break;
11711 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11712 POST_MEM_WRITE((Addr)args->buf, args->size);
11714 break;
11716 #ifdef ENABLE_XEN
11717 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11718 SyscallArgs harrghs;
11719 struct vki_xen_privcmd_hypercall *args =
11720 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11722 if (!args)
11723 break;
11725 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11726 harrghs.sysno = args->op;
11727 harrghs.arg1 = args->arg[0];
11728 harrghs.arg2 = args->arg[1];
11729 harrghs.arg3 = args->arg[2];
11730 harrghs.arg4 = args->arg[3];
11731 harrghs.arg5 = args->arg[4];
11732 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11734 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11736 break;
11738 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11739 break;
11740 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11741 struct vki_xen_privcmd_mmapbatch *args =
11742 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11743 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11745 break;
11746 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11747 struct vki_xen_privcmd_mmapbatch_v2 *args =
11748 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11749 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11751 break;
11753 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11754 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11755 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11756 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11757 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11758 case VKI_XEN_IOCTL_EVTCHN_RESET:
11759 /* No output */
11760 break;
11761 #endif
11763 /* Lustre */
11764 case VKI_OBD_IOC_FID2PATH: {
11765 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11766 POST_FIELD_WRITE(args->gf_recno);
11767 POST_FIELD_WRITE(args->gf_linkno);
11768 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11769 break;
11772 case VKI_LL_IOC_PATH2FID:
11773 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11774 break;
11776 case VKI_LL_IOC_GETPARENT: {
11777 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11778 POST_FIELD_WRITE(gp->gp_fid);
11779 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11780 break;
11783 /* V4L2 */
11784 case VKI_V4L2_S_FMT:
11785 case VKI_V4L2_TRY_FMT:
11786 case VKI_V4L2_REQBUFS:
11787 case VKI_V4L2_OVERLAY:
11788 case VKI_V4L2_STREAMON:
11789 case VKI_V4L2_STREAMOFF:
11790 case VKI_V4L2_S_PARM:
11791 case VKI_V4L2_S_STD:
11792 case VKI_V4L2_S_FREQUENCY:
11793 case VKI_V4L2_S_CTRL:
11794 case VKI_V4L2_S_TUNER:
11795 case VKI_V4L2_S_AUDIO:
11796 case VKI_V4L2_S_INPUT:
11797 case VKI_V4L2_S_EDID:
11798 case VKI_V4L2_S_OUTPUT:
11799 case VKI_V4L2_S_AUDOUT:
11800 case VKI_V4L2_S_MODULATOR:
11801 case VKI_V4L2_S_JPEGCOMP:
11802 case VKI_V4L2_S_CROP:
11803 case VKI_V4L2_S_PRIORITY:
11804 case VKI_V4L2_S_HW_FREQ_SEEK:
11805 case VKI_V4L2_S_DV_TIMINGS:
11806 case VKI_V4L2_SUBSCRIBE_EVENT:
11807 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11808 case VKI_V4L2_PREPARE_BUF:
11809 break;
11810 case VKI_V4L2_QUERYCAP: {
11811 struct vki_v4l2_capability *data =
11812 (struct vki_v4l2_capability *)(Addr)ARG3;
11813 POST_MEM_WRITE((Addr)data, sizeof(*data));
11814 break;
11816 case VKI_V4L2_ENUM_FMT: {
11817 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11818 POST_FIELD_WRITE(data->flags);
11819 POST_FIELD_WRITE(data->description);
11820 POST_FIELD_WRITE(data->pixelformat);
11821 POST_FIELD_WRITE(data->reserved);
11822 break;
11824 case VKI_V4L2_G_FMT: {
11825 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11826 switch (data->type) {
11827 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11828 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11829 POST_FIELD_WRITE(data->fmt.pix);
11830 break;
11831 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11832 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11833 POST_FIELD_WRITE(data->fmt.vbi);
11834 break;
11835 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11836 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11837 POST_FIELD_WRITE(data->fmt.sliced);
11838 break;
11839 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11840 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11841 POST_FIELD_WRITE(data->fmt.win);
11842 break;
11843 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11844 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11845 POST_FIELD_WRITE(data->fmt.pix_mp);
11846 break;
11847 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11848 POST_FIELD_WRITE(data->fmt.sdr);
11849 break;
11851 break;
11853 case VKI_V4L2_QUERYBUF: {
11854 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11855 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11856 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11857 unsigned i;
11859 for (i = 0; i < data->length; i++) {
11860 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11861 POST_FIELD_WRITE(data->m.planes[i].length);
11862 POST_FIELD_WRITE(data->m.planes[i].m);
11863 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11864 POST_FIELD_WRITE(data->m.planes[i].reserved);
11866 } else {
11867 POST_FIELD_WRITE(data->m);
11868 POST_FIELD_WRITE(data->length);
11870 POST_FIELD_WRITE(data->bytesused);
11871 POST_FIELD_WRITE(data->flags);
11872 POST_FIELD_WRITE(data->field);
11873 POST_FIELD_WRITE(data->timestamp);
11874 POST_FIELD_WRITE(data->timecode);
11875 POST_FIELD_WRITE(data->sequence);
11876 POST_FIELD_WRITE(data->memory);
11877 POST_FIELD_WRITE(data->sequence);
11878 break;
11880 case VKI_V4L2_G_FBUF: {
11881 struct vki_v4l2_framebuffer *data =
11882 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11883 POST_MEM_WRITE((Addr)data, sizeof(*data));
11884 break;
11886 case VKI_V4L2_S_FBUF: {
11887 struct vki_v4l2_framebuffer *data =
11888 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11889 POST_FIELD_WRITE(data->capability);
11890 POST_FIELD_WRITE(data->flags);
11891 POST_FIELD_WRITE(data->fmt);
11892 break;
11894 case VKI_V4L2_QBUF: {
11895 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11897 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11898 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11899 unsigned i;
11901 for (i = 0; i < data->length; i++) {
11902 POST_FIELD_WRITE(data->m.planes[i].length);
11903 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11904 POST_FIELD_WRITE(data->m.planes[i].m);
11906 } else {
11907 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11908 POST_FIELD_WRITE(data->m);
11909 POST_FIELD_WRITE(data->length);
11911 break;
11913 case VKI_V4L2_EXPBUF: {
11914 struct vki_v4l2_exportbuffer *data =
11915 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11916 POST_FIELD_WRITE(data->fd);
11917 break;
11919 case VKI_V4L2_DQBUF: {
11920 struct vki_v4l2_buffer *data =
11921 (struct vki_v4l2_buffer *)(Addr)ARG3;
11922 POST_FIELD_WRITE(data->index);
11923 POST_FIELD_WRITE(data->bytesused);
11924 POST_FIELD_WRITE(data->field);
11925 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11926 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11927 unsigned i;
11929 for (i = 0; i < data->length; i++) {
11930 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11931 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11932 POST_FIELD_WRITE(data->m.planes[i].length);
11933 POST_FIELD_WRITE(data->m.planes[i].m);
11935 } else {
11936 POST_FIELD_WRITE(data->m);
11937 POST_FIELD_WRITE(data->length);
11938 POST_FIELD_WRITE(data->bytesused);
11939 POST_FIELD_WRITE(data->field);
11941 POST_FIELD_WRITE(data->timestamp);
11942 POST_FIELD_WRITE(data->timecode);
11943 POST_FIELD_WRITE(data->sequence);
11944 break;
11946 case VKI_V4L2_G_PARM: {
11947 struct vki_v4l2_streamparm *data =
11948 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11949 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11950 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11951 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11952 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11954 if (is_output)
11955 POST_MEM_WRITE((Addr)&data->parm.output,
11956 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11957 else
11958 POST_MEM_WRITE((Addr)&data->parm.capture,
11959 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11960 break;
11962 case VKI_V4L2_G_STD: {
11963 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11964 POST_MEM_WRITE((Addr)data, sizeof(*data));
11965 break;
11967 case VKI_V4L2_ENUMSTD: {
11968 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11969 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11970 break;
11972 case VKI_V4L2_ENUMINPUT: {
11973 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11974 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11975 break;
11977 case VKI_V4L2_G_CTRL: {
11978 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11979 POST_FIELD_WRITE(data->value);
11980 break;
11982 case VKI_V4L2_G_TUNER: {
11983 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11984 POST_MEM_WRITE((Addr)data->name,
11985 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11986 break;
11988 case VKI_V4L2_G_AUDIO: {
11989 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11990 POST_MEM_WRITE((Addr)data,
11991 sizeof(*data) - sizeof(data->reserved));
11992 break;
11994 case VKI_V4L2_QUERYCTRL: {
11995 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11996 POST_MEM_WRITE((Addr)&data->type,
11997 sizeof(*data) - sizeof(data->id));
11998 break;
12000 case VKI_V4L2_QUERYMENU: {
12001 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
12002 POST_MEM_WRITE((Addr)data->name,
12003 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
12004 break;
12006 case VKI_V4L2_G_INPUT: {
12007 int *data = (int *)(Addr)ARG3;
12008 POST_MEM_WRITE((Addr)data, sizeof(*data));
12009 break;
12011 case VKI_V4L2_G_EDID: {
12012 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
12013 if (data->blocks && data->edid)
12014 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
12015 break;
12017 case VKI_V4L2_G_OUTPUT: {
12018 int *data = (int *)(Addr)ARG3;
12019 POST_MEM_WRITE((Addr)data, sizeof(*data));
12020 break;
12022 case VKI_V4L2_ENUMOUTPUT: {
12023 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
12024 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
12025 break;
12027 case VKI_V4L2_G_AUDOUT: {
12028 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12029 POST_MEM_WRITE((Addr)data,
12030 sizeof(*data) - sizeof(data->reserved));
12031 break;
12033 case VKI_V4L2_G_MODULATOR: {
12034 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
12035 POST_MEM_WRITE((Addr)data->name,
12036 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12037 break;
12039 case VKI_V4L2_G_FREQUENCY: {
12040 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
12041 POST_FIELD_WRITE(data->type);
12042 POST_FIELD_WRITE(data->frequency);
12043 break;
12045 case VKI_V4L2_CROPCAP: {
12046 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
12047 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
12048 break;
12050 case VKI_V4L2_G_CROP: {
12051 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
12052 POST_FIELD_WRITE(data->c);
12053 break;
12055 case VKI_V4L2_G_JPEGCOMP: {
12056 struct vki_v4l2_jpegcompression *data =
12057 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
12058 POST_MEM_WRITE((Addr)data, sizeof(*data));
12059 break;
12061 case VKI_V4L2_QUERYSTD: {
12062 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
12063 POST_MEM_WRITE((Addr)data, sizeof(*data));
12064 break;
12066 case VKI_V4L2_ENUMAUDIO: {
12067 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
12068 POST_MEM_WRITE((Addr)data->name,
12069 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12070 break;
12072 case VKI_V4L2_ENUMAUDOUT: {
12073 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
12074 POST_MEM_WRITE((Addr)data->name,
12075 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
12076 break;
12078 case VKI_V4L2_G_PRIORITY: {
12079 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
12080 POST_MEM_WRITE((Addr)data, sizeof(*data));
12081 break;
12083 case VKI_V4L2_G_SLICED_VBI_CAP: {
12084 struct vki_v4l2_sliced_vbi_cap *data =
12085 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
12086 POST_MEM_WRITE((Addr)data,
12087 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
12088 break;
12090 case VKI_V4L2_G_EXT_CTRLS: {
12091 struct vki_v4l2_ext_controls *data =
12092 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12093 if (data->count) {
12094 unsigned i;
12096 for (i = 0; i < data->count; i++) {
12097 if (data->controls[i].size)
12098 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
12099 else
12100 POST_FIELD_WRITE(data->controls[i].value64);
12103 POST_FIELD_WRITE(data->error_idx);
12104 break;
12106 case VKI_V4L2_S_EXT_CTRLS: {
12107 struct vki_v4l2_ext_controls *data =
12108 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12109 POST_FIELD_WRITE(data->error_idx);
12110 break;
12112 case VKI_V4L2_TRY_EXT_CTRLS: {
12113 struct vki_v4l2_ext_controls *data =
12114 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12115 POST_FIELD_WRITE(data->error_idx);
12116 break;
12118 case VKI_V4L2_ENUM_FRAMESIZES: {
12119 struct vki_v4l2_frmsizeenum *data =
12120 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
12121 POST_FIELD_WRITE(data->type);
12122 POST_FIELD_WRITE(data->stepwise);
12123 break;
12125 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
12126 struct vki_v4l2_frmivalenum *data =
12127 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
12128 POST_FIELD_WRITE(data->type);
12129 POST_FIELD_WRITE(data->stepwise);
12130 break;
12132 case VKI_V4L2_G_ENC_INDEX: {
12133 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
12134 POST_MEM_WRITE((Addr)data, sizeof(*data));
12135 break;
12137 case VKI_V4L2_ENCODER_CMD: {
12138 struct vki_v4l2_encoder_cmd *data =
12139 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12140 POST_FIELD_WRITE(data->flags);
12141 break;
12143 case VKI_V4L2_TRY_ENCODER_CMD: {
12144 struct vki_v4l2_encoder_cmd *data =
12145 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12146 POST_FIELD_WRITE(data->flags);
12147 break;
12149 case VKI_V4L2_DBG_S_REGISTER: {
12150 struct vki_v4l2_dbg_register *data =
12151 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12152 POST_FIELD_WRITE(data->size);
12153 break;
12155 case VKI_V4L2_DBG_G_REGISTER: {
12156 struct vki_v4l2_dbg_register *data =
12157 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12158 POST_FIELD_WRITE(data->val);
12159 POST_FIELD_WRITE(data->size);
12160 break;
12162 case VKI_V4L2_G_DV_TIMINGS: {
12163 struct vki_v4l2_dv_timings *data =
12164 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12165 POST_MEM_WRITE((Addr)data, sizeof(*data));
12166 break;
12168 case VKI_V4L2_DQEVENT: {
12169 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12170 POST_MEM_WRITE((Addr)data, sizeof(*data));
12171 break;
12173 case VKI_V4L2_CREATE_BUFS: {
12174 struct vki_v4l2_create_buffers *data =
12175 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12176 POST_FIELD_WRITE(data->index);
12177 break;
12179 case VKI_V4L2_G_SELECTION: {
12180 struct vki_v4l2_selection *data =
12181 (struct vki_v4l2_selection *)(Addr)ARG3;
12182 POST_FIELD_WRITE(data->r);
12183 break;
12185 case VKI_V4L2_S_SELECTION: {
12186 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12187 POST_FIELD_WRITE(data->r);
12188 break;
12190 case VKI_V4L2_DECODER_CMD: {
12191 struct vki_v4l2_decoder_cmd *data =
12192 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12193 POST_FIELD_WRITE(data->flags);
12194 break;
12196 case VKI_V4L2_TRY_DECODER_CMD: {
12197 struct vki_v4l2_decoder_cmd *data =
12198 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12199 POST_FIELD_WRITE(data->flags);
12200 break;
12202 case VKI_V4L2_ENUM_DV_TIMINGS: {
12203 struct vki_v4l2_enum_dv_timings *data =
12204 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12205 POST_FIELD_WRITE(data->timings);
12206 break;
12208 case VKI_V4L2_QUERY_DV_TIMINGS: {
12209 struct vki_v4l2_dv_timings *data =
12210 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12211 POST_MEM_WRITE((Addr)data, sizeof(*data));
12212 break;
12214 case VKI_V4L2_DV_TIMINGS_CAP: {
12215 struct vki_v4l2_dv_timings_cap *data =
12216 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12217 POST_MEM_WRITE((Addr)data, sizeof(*data));
12218 break;
12220 case VKI_V4L2_ENUM_FREQ_BANDS: {
12221 struct vki_v4l2_frequency_band *data =
12222 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12223 POST_FIELD_WRITE(data->capability);
12224 POST_FIELD_WRITE(data->rangelow);
12225 POST_FIELD_WRITE(data->rangehigh);
12226 POST_FIELD_WRITE(data->modulation);
12227 break;
12229 case VKI_V4L2_DBG_G_CHIP_INFO: {
12230 struct vki_v4l2_dbg_chip_info *data =
12231 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12232 POST_FIELD_WRITE(data->name);
12233 POST_FIELD_WRITE(data->flags);
12234 break;
12236 case VKI_V4L2_QUERY_EXT_CTRL: {
12237 struct vki_v4l2_query_ext_ctrl *data =
12238 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12239 POST_MEM_WRITE((Addr)&data->type,
12240 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12241 break;
12244 case VKI_V4L2_SUBDEV_S_FMT:
12245 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12246 case VKI_V4L2_SUBDEV_S_CROP:
12247 case VKI_V4L2_SUBDEV_S_SELECTION:
12248 break;
12250 case VKI_V4L2_SUBDEV_G_FMT: {
12251 struct vki_v4l2_subdev_format *data =
12252 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12253 POST_FIELD_WRITE(data->format);
12254 break;
12256 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12257 struct vki_v4l2_subdev_frame_interval *data =
12258 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12259 POST_FIELD_WRITE(data->interval);
12260 break;
12262 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12263 struct vki_v4l2_subdev_mbus_code_enum *data =
12264 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12265 POST_FIELD_WRITE(data->code);
12266 break;
12268 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12269 struct vki_v4l2_subdev_frame_size_enum *data =
12270 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12271 POST_FIELD_WRITE(data->min_width);
12272 POST_FIELD_WRITE(data->min_height);
12273 POST_FIELD_WRITE(data->max_width);
12274 POST_FIELD_WRITE(data->max_height);
12275 break;
12277 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12278 struct vki_v4l2_subdev_frame_interval_enum *data =
12279 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12280 POST_FIELD_WRITE(data->interval);
12281 break;
12283 case VKI_V4L2_SUBDEV_G_CROP: {
12284 struct vki_v4l2_subdev_crop *data =
12285 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12286 POST_FIELD_WRITE(data->rect);
12287 break;
12289 case VKI_V4L2_SUBDEV_G_SELECTION: {
12290 struct vki_v4l2_subdev_selection *data =
12291 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12292 POST_FIELD_WRITE(data->r);
12293 break;
12295 case VKI_MEDIA_IOC_DEVICE_INFO: {
12296 struct vki_media_device_info *data =
12297 (struct vki_media_device_info *)(Addr)ARG3;
12298 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12299 break;
12301 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12302 struct vki_media_entity_desc *data =
12303 (struct vki_media_entity_desc *)(Addr)ARG3;
12304 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12305 break;
12307 case VKI_MEDIA_IOC_ENUM_LINKS:
12309 * This ioctl does write to the provided pointers, but it's not
12310 * possible to deduce the size of the array those pointers point to.
12312 break;
12313 case VKI_MEDIA_IOC_SETUP_LINK:
12314 break;
12316 /* Serial */
12317 case VKI_TIOCGSERIAL: {
12318 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12319 POST_MEM_WRITE((Addr)data, sizeof(*data));
12320 break;
12322 case VKI_TIOCSSERIAL:
12323 break;
12325 case VKI_PERF_EVENT_IOC_ENABLE:
12326 case VKI_PERF_EVENT_IOC_DISABLE:
12327 case VKI_PERF_EVENT_IOC_REFRESH:
12328 case VKI_PERF_EVENT_IOC_RESET:
12329 case VKI_PERF_EVENT_IOC_PERIOD:
12330 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12331 case VKI_PERF_EVENT_IOC_SET_FILTER:
12332 case VKI_PERF_EVENT_IOC_SET_BPF:
12333 break;
12335 case VKI_PERF_EVENT_IOC_ID:
12336 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12337 break;
12339 /* Pulse Per Second (PPS) */
12340 case VKI_PPS_GETPARAMS: {
12341 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12342 POST_MEM_WRITE((Addr)data, sizeof(*data));
12343 break;
12345 case VKI_PPS_GETCAP:
12346 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12347 break;
12348 case VKI_PPS_FETCH: {
12349 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12350 POST_FIELD_WRITE(data->info);
12351 break;
12353 case VKI_PPS_SETPARAMS:
12354 case VKI_PPS_KC_BIND:
12355 break;
12357 /* PTP Hardware Clock */
12358 case VKI_PTP_CLOCK_GETCAPS: {
12359 struct vki_ptp_clock_caps *data =
12360 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12361 POST_MEM_WRITE((Addr)data, sizeof(*data));
12362 break;
12364 case VKI_PTP_SYS_OFFSET: {
12365 struct vki_ptp_sys_offset *data =
12366 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12367 POST_MEM_WRITE((Addr)data->ts,
12368 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12369 break;
12371 case VKI_PTP_PIN_GETFUNC: {
12372 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12373 POST_MEM_WRITE((Addr)data, sizeof(*data));
12374 break;
12376 case VKI_PTP_SYS_OFFSET_PRECISE: {
12377 struct vki_ptp_sys_offset_precise *data =
12378 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12379 POST_MEM_WRITE((Addr)data, sizeof(*data));
12380 break;
12382 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12383 struct vki_ptp_sys_offset_extended *data =
12384 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12385 POST_MEM_WRITE((Addr)data->ts,
12386 3 * data->n_samples * sizeof(data->ts[0][0]));
12387 break;
12389 case VKI_PTP_EXTTS_REQUEST:
12390 case VKI_PTP_PEROUT_REQUEST:
12391 case VKI_PTP_ENABLE_PPS:
12392 case VKI_PTP_PIN_SETFUNC:
12393 break;
12395 default:
12396 /* EVIOC* are variable length and return size written on success */
12397 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12398 case VKI_EVIOCGNAME(0):
12399 case VKI_EVIOCGPHYS(0):
12400 case VKI_EVIOCGUNIQ(0):
12401 case VKI_EVIOCGKEY(0):
12402 case VKI_EVIOCGLED(0):
12403 case VKI_EVIOCGSND(0):
12404 case VKI_EVIOCGSW(0):
12405 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12406 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12407 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12408 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12409 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12410 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12411 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12412 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12413 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12414 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12415 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12416 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12417 if (RES > 0)
12418 POST_MEM_WRITE(ARG3, RES);
12419 break;
12420 default:
12421 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12422 break;
12424 break;
12427 post_sys_ioctl__out:
12428 {} /* keep C compilers happy */
12431 /* ---------------------------------------------------------------------
12432 socketcall wrapper helpers
12433 ------------------------------------------------------------------ */
12435 void
12436 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12437 UWord arg0, UWord arg1, UWord arg2,
12438 UWord arg3, UWord arg4 )
12440 /* int getsockopt(int s, int level, int optname,
12441 void *optval, socklen_t *optlen); */
12442 Addr optval_p = arg3;
12443 Addr optlen_p = arg4;
12444 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12445 if (optval_p != (Addr)NULL) {
12446 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12447 "socketcall.getsockopt(optval)",
12448 "socketcall.getsockopt(optlen)" );
12449 if (arg1 == VKI_SOL_SCTP &&
12450 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12451 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12453 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12454 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12455 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12456 (Addr)ga->addrs, address_bytes );
12461 void
12462 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12463 SysRes res,
12464 UWord arg0, UWord arg1, UWord arg2,
12465 UWord arg3, UWord arg4 )
12467 Addr optval_p = arg3;
12468 Addr optlen_p = arg4;
12469 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12470 if (optval_p != (Addr)NULL) {
12471 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12472 "socketcall.getsockopt(optlen_out)" );
12473 if (arg1 == VKI_SOL_SCTP &&
12474 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12475 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12477 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12478 struct vki_sockaddr *a = ga->addrs;
12479 int i;
12480 for (i = 0; i < ga->addr_num; i++) {
12481 int sl = 0;
12482 if (a->sa_family == VKI_AF_INET)
12483 sl = sizeof(struct vki_sockaddr_in);
12484 else if (a->sa_family == VKI_AF_INET6)
12485 sl = sizeof(struct vki_sockaddr_in6);
12486 else {
12487 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12488 "address type %d\n", a->sa_family);
12490 a = (struct vki_sockaddr*)((char*)a + sl);
12492 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12497 void
12498 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12499 UWord arg0, UWord arg1, UWord arg2,
12500 UWord arg3, UWord arg4 )
12502 /* int setsockopt(int s, int level, int optname,
12503 const void *optval, socklen_t optlen); */
12504 Addr optval_p = arg3;
12505 if (optval_p != (Addr)NULL) {
12507 * OK, let's handle at least some setsockopt levels and options
12508 * ourselves, so we don't get false claims of references to
12509 * uninitialized memory (such as padding in structures) and *do*
12510 * check what pointers in the argument point to.
12512 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12514 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12517 * struct sock_fprog has a 16-bit count of instructions,
12518 * followed by a pointer to an array of those instructions.
12519 * There's padding between those two elements.
12521 * So that we don't bogusly complain about the padding bytes,
12522 * we just report that we read len and and filter.
12524 * We then make sure that what filter points to is valid.
12526 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12527 (Addr)&fp->len, sizeof(fp->len) );
12528 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12529 (Addr)&fp->filter, sizeof(fp->filter) );
12531 /* len * sizeof (*filter) */
12532 if (fp->filter != NULL)
12534 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12535 (Addr)(fp->filter),
12536 fp->len * sizeof(*fp->filter) );
12539 else
12541 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12542 arg3, /* optval */
12543 arg4 /* optlen */ );
12548 void
12549 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12550 UWord arg1, UWord arg2, UWord arg3,
12551 UWord arg4, UWord arg5 )
12553 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12554 HChar name[40]; // large enough
12555 UInt i;
12556 for (i = 0; i < arg3; i++) {
12557 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12558 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12559 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12560 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12562 if (arg5)
12563 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12566 void
12567 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12568 UWord arg1, UWord arg2, UWord arg3,
12569 UWord arg4, UWord arg5 )
12571 if (res > 0) {
12572 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12573 HChar name[32]; // large enough
12574 UInt i;
12575 for (i = 0; i < res; i++) {
12576 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12577 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12578 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12583 void
12584 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12585 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12587 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12588 HChar name[40]; // large enough
12589 UInt i;
12590 for (i = 0; i < arg3; i++) {
12591 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12592 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12593 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12594 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12598 void
12599 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12600 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12602 if (res > 0) {
12603 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12604 UInt i;
12605 for (i = 0; i < res; i++) {
12606 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12611 /* ---------------------------------------------------------------------
12612 ptrace wrapper helpers
12613 ------------------------------------------------------------------ */
12615 void
12616 ML_(linux_POST_traceme) ( ThreadId tid )
12618 ThreadState *tst = VG_(get_ThreadState)(tid);
12619 tst->ptrace = VKI_PT_PTRACED;
12622 void
12623 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12625 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12627 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12628 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12629 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12630 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12631 (Addr) iov->iov_base, iov->iov_len);
12635 void
12636 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12638 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12640 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12641 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12642 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12643 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12644 (Addr) iov->iov_base, iov->iov_len);
12648 void
12649 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12651 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12653 /* XXX: The actual amount of data written by the kernel might be
12654 less than iov_len, depending on the regset (arg3). */
12655 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12658 PRE(sys_kcmp)
12660 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12661 SARG1, SARG2, SARG3, ARG4, ARG5);
12662 switch (ARG3) {
12663 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12664 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12665 /* Most of the comparison types don't look at |idx1| or
12666 |idx2|. */
12667 PRE_REG_READ3(long, "kcmp",
12668 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12669 break;
12670 case VKI_KCMP_FILE:
12671 default:
12672 PRE_REG_READ5(long, "kcmp",
12673 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12674 unsigned long, idx1, unsigned long, idx2);
12675 break;
12679 /* ---------------------------------------------------------------------
12680 bpf wrappers
12681 ------------------------------------------------------------------ */
12683 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12685 HChar path[32], buf[1024]; /* large enough */
12686 SysRes sres;
12687 HChar *comp;
12688 Int proc_fd;
12690 *key_size = 0;
12691 *value_size = 0;
12693 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12694 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12695 if (sr_isError(sres))
12696 return False;
12697 proc_fd = sr_Res(sres);
12699 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12700 return False;
12701 VG_(close)(proc_fd);
12703 comp = VG_(strstr)(buf, "key_size:");
12704 if (comp)
12705 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12707 comp = VG_(strstr)(buf, "value_size:");
12708 if (comp)
12709 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12711 return (*key_size && *value_size);
12715 * From a file descriptor for an eBPF object, try to determine the size of the
12716 * struct that will be written, i.e. determine if object is a map or a program.
12717 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12718 * search for strings "prog_type" or "map_type".
12720 static UInt bpf_obj_get_info_size(Int fd)
12722 HChar path[32], buf[1024]; /* large enough */
12723 SysRes sres;
12724 Int proc_fd;
12726 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12727 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12728 if (sr_isError(sres))
12729 return 0;
12730 proc_fd = sr_Res(sres);
12732 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12733 return 0;
12734 VG_(close)(proc_fd);
12736 if (VG_(strstr)(buf, "prog_type:"))
12737 return sizeof(struct vki_bpf_prog_info);
12739 if (VG_(strstr)(buf, "map_type:"))
12740 return sizeof(struct vki_bpf_map_info);
12742 return 0;
12745 PRE(sys_bpf)
12747 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12748 UInt res, key_size, value_size;
12750 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12751 (Word)ARG1, ARG2, ARG3);
12752 PRE_REG_READ3(long, "bpf",
12753 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12754 switch (ARG1) {
12755 case VKI_BPF_PROG_GET_NEXT_ID:
12756 case VKI_BPF_MAP_GET_NEXT_ID:
12757 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12758 break;
12759 case VKI_BPF_PROG_GET_FD_BY_ID:
12760 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12761 break;
12762 case VKI_BPF_MAP_GET_FD_BY_ID:
12763 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12764 break;
12765 case VKI_BPF_BTF_GET_FD_BY_ID:
12766 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12767 break;
12768 case VKI_BPF_MAP_CREATE:
12769 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12770 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12771 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12772 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12773 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12774 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12775 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12776 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12777 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12778 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12779 switch (attr->map_type) {
12780 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12781 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12782 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12783 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12784 SET_STATUS_Failure(VKI_EBADF);
12785 break;
12786 case VKI_BPF_MAP_TYPE_ARRAY:
12787 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12788 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12789 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12790 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12791 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12792 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12793 SET_STATUS_Failure(VKI_EBADF);
12794 break;
12798 break;
12799 case VKI_BPF_MAP_TYPE_UNSPEC:
12800 case VKI_BPF_MAP_TYPE_HASH:
12801 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12802 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12803 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12804 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12805 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12806 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12807 case VKI_BPF_MAP_TYPE_LRU_HASH:
12808 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12809 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12810 case VKI_BPF_MAP_TYPE_DEVMAP:
12811 case VKI_BPF_MAP_TYPE_SOCKMAP:
12812 case VKI_BPF_MAP_TYPE_CPUMAP:
12813 case VKI_BPF_MAP_TYPE_XSKMAP:
12814 case VKI_BPF_MAP_TYPE_SOCKHASH:
12815 default:
12816 break;
12818 break;
12819 case VKI_BPF_MAP_LOOKUP_ELEM:
12820 /* Perform a lookup on an eBPF map. Read key, write value. */
12821 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12822 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12823 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12824 if (ML_(safe_to_deref)(attr, ARG3)) {
12825 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12826 SET_STATUS_Failure(VKI_EBADF);
12827 break;
12829 /* Get size of key and value for this map. */
12830 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12831 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12832 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12835 break;
12836 case VKI_BPF_MAP_UPDATE_ELEM:
12837 /* Add or update a map element in kernel. Read key, read value. */
12838 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12839 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12840 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12841 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12842 if (ML_(safe_to_deref)(attr, ARG3)) {
12843 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12844 SET_STATUS_Failure(VKI_EBADF);
12845 break;
12847 /* Get size of key and value for this map. */
12848 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12849 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12850 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12853 break;
12854 case VKI_BPF_MAP_DELETE_ELEM:
12855 /* Delete a map element in kernel. Read key from user space. */
12856 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12857 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12858 if (ML_(safe_to_deref)(attr, ARG3)) {
12859 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12860 SET_STATUS_Failure(VKI_EBADF);
12861 break;
12863 /* Get size of key for this map. */
12864 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12865 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12867 break;
12868 case VKI_BPF_MAP_GET_NEXT_KEY:
12869 /* From a key, get next key for the map. Read key, write next key. */
12870 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12871 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12872 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12873 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12874 if (ML_(safe_to_deref)(attr, ARG3)) {
12875 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12876 SET_STATUS_Failure(VKI_EBADF);
12877 break;
12879 /* Get size of key for this map. */
12880 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12881 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12882 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12885 break;
12886 case VKI_BPF_PROG_LOAD:
12887 /* Load a program into the kernel from an array of instructions. */
12888 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12889 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12890 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12891 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12892 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12893 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12894 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12895 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12896 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12897 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12898 if (ML_(safe_to_deref)(attr, ARG3)) {
12899 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12900 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12901 /* Read instructions, license, program name. */
12902 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12903 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12904 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12905 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12906 /* Possibly write up to log_len into user space log buffer. */
12907 if (attr->log_level || attr->log_size || attr->log_buf)
12908 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12910 break;
12911 case VKI_BPF_OBJ_PIN:
12912 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12913 /* fall through */
12914 case VKI_BPF_OBJ_GET:
12915 /* Get pinned eBPF program or map. Read path name. */
12916 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12917 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12918 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12919 if (ML_(safe_to_deref)(attr, ARG3)) {
12920 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12921 SET_STATUS_Failure(VKI_EBADF);
12922 break;
12924 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12926 break;
12927 case VKI_BPF_PROG_ATTACH:
12928 case VKI_BPF_PROG_DETACH:
12929 /* Detach eBPF program from kernel attach point. */
12930 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12931 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12932 if (ML_(safe_to_deref)(attr, ARG3)) {
12933 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12934 SET_STATUS_Failure(VKI_EBADF);
12935 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12936 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12937 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12938 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12939 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12940 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12941 SET_STATUS_Failure(VKI_EBADF);
12944 break;
12945 case VKI_BPF_PROG_TEST_RUN:
12946 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12947 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12948 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12949 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12950 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12951 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12952 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12953 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12954 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12955 if (ML_(safe_to_deref)(attr, ARG3)) {
12956 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12957 SET_STATUS_Failure(VKI_EBADF);
12958 break;
12960 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12961 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12962 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12964 break;
12965 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12966 /* Get info for eBPF map or program. Write info. */
12967 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12968 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12969 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12970 if (ML_(safe_to_deref)(attr, ARG3)) {
12971 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12972 SET_STATUS_Failure(VKI_EBADF);
12973 break;
12975 /* Get size of struct to write: is object a program or a map? */
12976 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12977 if (res)
12978 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12979 VG_MIN(attr->info.info_len, res));
12980 else
12981 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12982 VG_MIN(attr->info.info_len,
12983 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12984 sizeof(struct vki_bpf_map_info)),
12985 sizeof(struct vki_bpf_btf_info))));
12987 break;
12988 case VKI_BPF_PROG_QUERY:
12990 * Query list of eBPF program attached to cgroup.
12991 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12993 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12994 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12995 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12996 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12997 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12998 if (ML_(safe_to_deref)(attr, ARG3)) {
12999 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
13000 SET_STATUS_Failure(VKI_EBADF);
13001 break;
13003 if (attr->query.prog_cnt > 0) {
13004 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
13005 if (attr->query.prog_ids) {
13006 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
13007 attr->query.prog_cnt * sizeof(__vki_u32));
13011 break;
13012 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13013 /* Open raw tracepoint. Read tracepoint name. */
13014 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
13015 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
13016 if (ML_(safe_to_deref)(attr, ARG3)) {
13017 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
13018 "bpf", tid, False)) {
13019 SET_STATUS_Failure(VKI_EBADF);
13020 break;
13022 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
13023 if (attr->raw_tracepoint.name != 0)
13024 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
13025 "bpf(attr->raw_tracepoint.name)");
13027 break;
13028 case VKI_BPF_BTF_LOAD:
13029 /* Load BTF information about a program into the kernel. */
13030 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
13031 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
13032 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
13033 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
13034 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
13035 if (ML_(safe_to_deref)(attr, ARG3)) {
13036 /* Read BTF data. */
13037 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
13038 /* Possibly write up to btf_log_len into user space log buffer. */
13039 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
13040 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
13041 attr->btf_log_buf, attr->btf_log_size);
13043 break;
13044 case VKI_BPF_TASK_FD_QUERY:
13045 /* Get info about the task. Write collected info. */
13046 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
13047 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
13048 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
13049 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
13050 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
13051 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13052 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13053 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13054 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13055 if (ML_(safe_to_deref)(attr, ARG3)) {
13056 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
13057 SET_STATUS_Failure(VKI_EBADF);
13058 break;
13060 if (attr->task_fd_query.buf_len > 0) {
13061 /* Write task or perf event name. */
13062 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
13063 attr->task_fd_query.buf,
13064 attr->task_fd_query.buf_len);
13067 break;
13068 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13069 /* Perform a lookup on an eBPF map. Read key, write value (delete key) */
13070 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
13071 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
13072 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13073 if (ML_(safe_to_deref)(attr, ARG3)) {
13074 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
13075 SET_STATUS_Failure(VKI_EBADF);
13076 break;
13078 /* Get size of key and value for this map. */
13079 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
13080 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
13081 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
13084 break;
13085 case VKI_BPF_MAP_FREEZE:
13086 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13087 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
13088 break;
13089 default:
13090 VG_(message)(Vg_DebugMsg,
13091 "WARNING: unhandled eBPF command %lu\n", ARG1);
13092 break;
13096 POST(sys_bpf)
13098 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
13099 UInt key_size, value_size;
13101 vg_assert(SUCCESS);
13103 switch (ARG1) {
13104 case VKI_BPF_PROG_GET_NEXT_ID:
13105 case VKI_BPF_MAP_GET_NEXT_ID:
13106 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
13107 break;
13108 case VKI_BPF_MAP_UPDATE_ELEM:
13109 case VKI_BPF_MAP_DELETE_ELEM:
13110 case VKI_BPF_OBJ_PIN:
13111 case VKI_BPF_PROG_ATTACH:
13112 case VKI_BPF_PROG_DETACH:
13113 break;
13114 /* Following commands have bpf() return a file descriptor. */
13115 case VKI_BPF_MAP_CREATE:
13116 case VKI_BPF_OBJ_GET:
13117 case VKI_BPF_PROG_GET_FD_BY_ID:
13118 case VKI_BPF_MAP_GET_FD_BY_ID:
13119 case VKI_BPF_BTF_GET_FD_BY_ID:
13120 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13121 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13122 VG_(close)(RES);
13123 SET_STATUS_Failure(VKI_EMFILE);
13124 } else {
13125 if (VG_(clo_track_fds))
13126 ML_(record_fd_open_nameless)(tid, RES);
13128 break;
13130 * TODO: Is there a way to pass information between PRE and POST hooks?
13131 * To avoid querying again for the size of keys and values.
13133 case VKI_BPF_MAP_LOOKUP_ELEM:
13134 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13135 POST_MEM_WRITE(attr->value, value_size);
13136 break;
13137 case VKI_BPF_MAP_GET_NEXT_KEY:
13138 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13139 POST_MEM_WRITE(attr->next_key, key_size);
13140 break;
13141 case VKI_BPF_PROG_LOAD:
13142 /* Return a file descriptor for loaded program, write into log_buf. */
13143 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13144 VG_(close)(RES);
13145 SET_STATUS_Failure(VKI_EMFILE);
13146 } else {
13147 if (VG_(clo_track_fds))
13148 ML_(record_fd_open_nameless)(tid, RES);
13150 if (attr->log_level || attr->log_size || attr->log_buf)
13151 POST_MEM_WRITE(attr->log_buf, attr->log_size);
13152 break;
13153 case VKI_BPF_PROG_TEST_RUN:
13154 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
13155 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13156 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
13157 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
13158 break;
13159 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13160 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
13161 break;
13162 case VKI_BPF_PROG_QUERY:
13163 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13164 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13165 if (attr->query.prog_ids)
13166 POST_MEM_WRITE(attr->query.prog_ids,
13167 attr->query.prog_cnt * sizeof(__vki_u32));
13168 break;
13169 case VKI_BPF_BTF_LOAD:
13170 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13171 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13172 VG_(close)(RES);
13173 SET_STATUS_Failure(VKI_EMFILE);
13174 } else {
13175 if (VG_(clo_track_fds))
13176 ML_(record_fd_open_nameless)(tid, RES);
13178 if (attr->btf_log_level)
13179 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13180 break;
13181 case VKI_BPF_TASK_FD_QUERY:
13182 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13183 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13184 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13185 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13186 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13187 break;
13188 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13189 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13190 POST_MEM_WRITE(attr->value, value_size);
13191 break;
13192 case VKI_BPF_MAP_FREEZE:
13193 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13194 break;
13195 default:
13196 VG_(message)(Vg_DebugMsg,
13197 "WARNING: unhandled eBPF command %lu\n", ARG1);
13198 break;
13202 PRE(sys_copy_file_range)
13204 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13205 ARG4, ARG5, ARG6);
13207 PRE_REG_READ6(vki_size_t, "copy_file_range",
13208 int, "fd_in",
13209 vki_loff_t *, "off_in",
13210 int, "fd_out",
13211 vki_loff_t *, "off_out",
13212 vki_size_t, "len",
13213 unsigned int, "flags");
13215 /* File descriptors are "specially" tracked by valgrind.
13216 valgrind itself uses some, so make sure someone didn't
13217 put in one of our own... */
13218 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13219 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13220 SET_STATUS_Failure( VKI_EBADF );
13221 } else {
13222 /* Now see if the offsets are defined. PRE_MEM_READ will
13223 double check it can dereference them. */
13224 if (ARG2 != 0)
13225 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13226 if (ARG4 != 0)
13227 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13231 PRE(sys_pkey_alloc)
13233 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13235 PRE_REG_READ2(long, "pkey_alloc",
13236 unsigned long, "flags",
13237 unsigned long, "access_rights");
13239 /* The kernel says: pkey_alloc() is always safe to call regardless of
13240 whether or not the operating system supports protection keys. It can be
13241 used in lieu of any other mechanism for detecting pkey support and will
13242 simply fail with the error ENOSPC if the operating system has no pkey
13243 support.
13245 So we simply always return ENOSPC to signal memory protection keys are
13246 not supported under valgrind, unless there are unknown flags, then we
13247 return EINVAL. */
13248 unsigned long pkey_flags = ARG1;
13249 if (pkey_flags != 0)
13250 SET_STATUS_Failure( VKI_EINVAL );
13251 else
13252 SET_STATUS_Failure( VKI_ENOSPC );
13255 PRE(sys_pkey_free)
13257 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13259 PRE_REG_READ1(long, "pkey_free",
13260 unsigned long, "pkey");
13262 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13263 always an error. */
13264 SET_STATUS_Failure( VKI_EINVAL );
13267 PRE(sys_pkey_mprotect)
13269 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13270 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13271 PRE_REG_READ4(long, "pkey_mprotect",
13272 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13273 unsigned long, pkey);
13275 Addr addr = ARG1;
13276 SizeT len = ARG2;
13277 Int prot = ARG3;
13278 Int pkey = ARG4;
13280 /* Since pkey_alloc () can never succeed, see above, any pkey is
13281 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13282 if (pkey != -1)
13283 SET_STATUS_Failure( VKI_EINVAL );
13284 else
13285 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13287 ARG1 = addr;
13288 ARG2 = len;
13289 ARG3 = prot;
13292 POST(sys_pkey_mprotect)
13294 Addr addr = ARG1;
13295 SizeT len = ARG2;
13296 Int prot = ARG3;
13298 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13301 PRE(sys_io_uring_setup)
13303 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13304 ARG1, ARG2);
13305 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13306 struct vki_io_uring_params *, p);
13307 if (ARG2)
13308 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13309 offsetof(struct vki_io_uring_params, sq_off));
13312 POST(sys_io_uring_setup)
13314 vg_assert(SUCCESS);
13315 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13316 VG_(close)(RES);
13317 SET_STATUS_Failure( VKI_EMFILE );
13318 } else {
13319 if (VG_(clo_track_fds))
13320 ML_(record_fd_open_nameless)(tid, RES);
13321 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13322 sizeof(struct vki_io_sqring_offsets) +
13323 sizeof(struct vki_io_cqring_offsets));
13327 PRE(sys_io_uring_enter)
13329 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13330 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13331 FMT_REGWORD "u )",
13332 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13333 PRE_REG_READ6(long, "io_uring_enter",
13334 unsigned int, fd, unsigned int, to_submit,
13335 unsigned int, min_complete, unsigned int, flags,
13336 const void *, sig, unsigned long, sigsz);
13337 if (ARG5)
13338 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13341 POST(sys_io_uring_enter)
13345 PRE(sys_io_uring_register)
13347 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13348 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13349 PRE_REG_READ4(long, "io_uring_register",
13350 unsigned int, fd, unsigned int, opcode,
13351 void *, arg, unsigned int, nr_args);
13352 switch (ARG2) {
13353 case VKI_IORING_REGISTER_BUFFERS:
13354 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13355 break;
13356 case VKI_IORING_UNREGISTER_BUFFERS:
13357 break;
13358 case VKI_IORING_REGISTER_FILES:
13359 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13360 break;
13361 case VKI_IORING_UNREGISTER_FILES:
13362 break;
13363 case VKI_IORING_REGISTER_EVENTFD:
13364 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13365 break;
13366 case VKI_IORING_UNREGISTER_EVENTFD:
13367 break;
13371 POST(sys_io_uring_register)
13375 PRE(sys_execveat)
13377 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13378 PRE_REG_READ5(vki_off_t, "execveat",
13379 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13380 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13382 #if !defined(__NR_execveat)
13383 SET_STATUS_Failure(VKI_ENOSYS);
13384 return;
13385 #endif
13387 const HChar *path = (const HChar*) ARG2;
13388 Addr arg_2 = ARG3;
13389 Addr arg_3 = ARG4;
13390 const HChar *buf;
13391 HChar *abs_path = NULL;
13392 Bool check_at_symlink = False;
13393 Bool check_pathptr = True;
13395 if (ML_(safe_to_deref) (path, 1)) {
13396 /* If pathname is absolute, we'll ignore dirfd
13397 * and just pass the pathname, try to determine
13398 * the absolute path otherwise. */
13399 if (path[0] != '/') {
13400 /* Check dirfd is a valid fd. */
13401 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13402 SET_STATUS_Failure( VKI_EBADF );
13403 return;
13405 /* If pathname is empty and AT_EMPTY_PATH is
13406 set then dirfd describes the whole path. */
13407 if (path[0] == '\0') {
13408 if (ARG5 & VKI_AT_EMPTY_PATH) {
13409 if (VG_(resolve_filename)(ARG1, &buf)) {
13410 path = buf;
13411 check_pathptr = False;
13415 else if (ARG1 == VKI_AT_FDCWD) {
13416 check_at_symlink = True;
13417 } else
13418 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13419 check_at_symlink = True;
13420 else if (VG_(resolve_filename)(ARG1, &buf)) {
13421 abs_path = VG_(malloc)("execveat",
13422 (VG_(strlen)(buf) + 1
13423 + VG_(strlen)(path) + 1));
13424 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13425 path = abs_path;
13426 check_pathptr = False;
13428 else
13429 path = NULL;
13430 if (check_at_symlink) {
13431 struct vg_stat statbuf;
13432 SysRes statres;
13434 statres = VG_(stat)(path, &statbuf);
13435 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13436 SET_STATUS_Failure( VKI_ELOOP );
13437 return;
13441 } else {
13442 SET_STATUS_Failure(VKI_EFAULT);
13443 return;
13446 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, EXECVEAT,
13447 check_pathptr);
13449 /* The exec failed, we keep running... cleanup. */
13450 VG_(free)(abs_path);
13455 PRE(sys_close_range)
13457 SysRes res = VG_(mk_SysRes_Success)(0);
13458 unsigned int beg, end;
13459 unsigned int last = ARG2;
13461 FUSE_COMPATIBLE_MAY_BLOCK();
13462 PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
13463 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
13464 PRE_REG_READ3(long, "close_range",
13465 unsigned int, first, unsigned int, last,
13466 unsigned int, flags);
13468 if (ARG1 > last) {
13469 SET_STATUS_Failure( VKI_EINVAL );
13470 return;
13473 if (last >= VG_(fd_hard_limit))
13474 last = VG_(fd_hard_limit) - 1;
13476 if (ARG1 > last) {
13477 SET_STATUS_Success ( 0 );
13478 return;
13481 beg = end = ARG1;
13482 do {
13483 if (end > last
13484 || (end == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
13485 || end == VG_(log_output_sink).fd
13486 || end == VG_(xml_output_sink).fd) {
13487 /* Split the range if it contains a file descriptor we're not
13488 * supposed to close. */
13489 if (end - 1 >= beg)
13490 res = VG_(do_syscall3)(__NR_close_range, (UWord)beg, (UWord)end - 1, ARG3 );
13491 beg = end + 1;
13493 } while (end++ <= last);
13495 /* If it failed along the way, it's presumably the flags being wrong. */
13496 SET_STATUS_from_SysRes (res);
13499 POST(sys_close_range)
13501 unsigned int fd;
13502 unsigned int last = ARG2;
13504 if (!VG_(clo_track_fds)
13505 || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
13506 return;
13508 if (last >= VG_(fd_hard_limit))
13509 last = VG_(fd_hard_limit) - 1;
13511 for (fd = ARG1; fd <= last; fd++)
13512 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
13513 && fd != VG_(log_output_sink).fd
13514 && fd != VG_(xml_output_sink).fd)
13515 ML_(record_fd_close)(fd);
13519 #define VKI_O_DIRECTORY 00200000
13520 #define VKI___O_TMPFILE 020000000
13521 #define VKI_O_TMPFILE (VKI___O_TMPFILE | VKI_O_DIRECTORY)
13523 // long syscall(SYS_openat2, int dirfd, const char *pathname,
13524 // struct open_how *how, size_t size);
13525 PRE(sys_openat2)
13527 HChar name[30]; // large enough
13528 SysRes sres;
13529 struct vki_open_how * how;
13531 PRINT("sys_openat2 ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %ld )",
13532 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, SARG4);
13533 PRE_REG_READ4(long, "openat2",
13534 int, dfd, const char *, filename, struct vki_open_how *, how, vki_size_t, size);
13536 PRE_MEM_RASCIIZ( "openat2(filename)", ARG2 );
13537 PRE_MEM_READ( "openat2(how)", ARG3, sizeof(struct vki_open_how));
13539 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
13540 filename is relative to cwd. When comparing dfd against AT_FDCWD,
13541 be sure only to compare the bottom 32 bits. */
13542 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13543 && *(Char *)(Addr)ARG2 != '/'
13544 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
13545 && !ML_(fd_allowed)(ARG1, "openat2", tid, False))
13546 SET_STATUS_Failure( VKI_EBADF );
13548 how = (struct vki_open_how *)ARG3;
13550 if (how && ML_(safe_to_deref) (how, sizeof(struct vki_open_how))) {
13551 if (how->vki_mode) {
13552 if (!(how->vki_flags & ((vki_uint64_t)VKI_O_CREAT | VKI_O_TMPFILE))) {
13553 SET_STATUS_Failure( VKI_EINVAL );
13556 if (how->vki_resolve & ~((vki_uint64_t)VKI_RESOLVE_NO_XDEV |
13557 VKI_RESOLVE_NO_MAGICLINKS |
13558 VKI_RESOLVE_NO_SYMLINKS |
13559 VKI_RESOLVE_BENEATH |
13560 VKI_RESOLVE_IN_ROOT |
13561 VKI_RESOLVE_CACHED)) {
13562 SET_STATUS_Failure( VKI_EINVAL );
13566 /* Handle the case where the open is of /proc/self/cmdline or
13567 /proc/<pid>/cmdline, and just give it a copy of the fd for the
13568 fake file we cooked up at startup (in m_main). Also, seek the
13569 cloned fd back to the start. */
13571 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
13572 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13573 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13574 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
13575 sres = VG_(dup)( VG_(cl_cmdline_fd) );
13576 SET_STATUS_from_SysRes( sres );
13577 if (!sr_isError(sres)) {
13578 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13579 if (off < 0)
13580 SET_STATUS_Failure( VKI_EMFILE );
13582 return;
13585 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
13587 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
13588 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13589 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13590 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
13591 sres = VG_(dup)( VG_(cl_auxv_fd) );
13592 SET_STATUS_from_SysRes( sres );
13593 if (!sr_isError(sres)) {
13594 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13595 if (off < 0)
13596 SET_STATUS_Failure( VKI_EMFILE );
13598 return;
13601 /* And for /proc/self/exe or /proc/<pid>/exe case. */
13603 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
13604 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
13605 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
13606 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
13607 sres = VG_(dup)( VG_(cl_exec_fd) );
13608 SET_STATUS_from_SysRes( sres );
13609 if (!sr_isError(sres)) {
13610 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
13611 if (off < 0)
13612 SET_STATUS_Failure( VKI_EMFILE );
13614 return;
13617 /* Otherwise handle normally */
13618 *flags |= SfMayBlock;
13621 POST(sys_openat2)
13623 vg_assert(SUCCESS);
13624 if (!ML_(fd_allowed)(RES, "openat2", tid, True)) {
13625 VG_(close)(RES);
13626 SET_STATUS_Failure( VKI_EMFILE );
13627 } else {
13628 if (VG_(clo_track_fds))
13629 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
13633 PRE(sys_pidfd_open)
13635 PRINT("sys_pidfd_open ( %ld, %lu )", SARG1, ARG2);
13638 POST(sys_pidfd_open)
13640 if (!ML_(fd_allowed)(RES, "pidfd", tid, True)) {
13641 VG_(close)(RES);
13642 SET_STATUS_Failure( VKI_EMFILE );
13643 } else {
13644 if (VG_(clo_track_fds))
13645 ML_(record_fd_open_nameless) (tid, RES);
13649 PRE(sys_pidfd_getfd)
13651 PRINT("sys_pidfd_getfd ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
13652 PRE_REG_READ3(long, "pidfd_getfd", int, pidfd, int, targetfd, unsigned int, flags);
13655 POST(sys_pidfd_getfd)
13657 vg_assert(SUCCESS);
13658 if (!ML_(fd_allowed)(RES, "pidfd_getfd", tid, True)) {
13659 VG_(close)(RES);
13660 SET_STATUS_Failure( VKI_EMFILE );
13661 } else {
13662 if (VG_(clo_track_fds))
13663 ML_(record_fd_open_nameless) (tid, RES);
13667 #undef PRE
13668 #undef POST
13670 #endif // defined(VGO_linux)
13672 /*--------------------------------------------------------------------*/
13673 /*--- end ---*/
13674 /*--------------------------------------------------------------------*/