bpf attr->raw_tracepoint.name may be NULL for BPF_RAW_TRACEPOINT_OPEN.
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob38edccc9833a2c994d805d2556f87132d4181b36
2 /*--------------------------------------------------------------------*/
3 /*--- Linux-specific syscalls, etc. syswrap-linux.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Nicholas Nethercote
11 njn@valgrind.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_linux)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
37 #include "pub_core_transtab.h" // VG_(discard_translations)
38 #include "pub_core_xarray.h"
39 #include "pub_core_clientstate.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_libcproc.h"
46 #include "pub_core_libcsignal.h"
47 #include "pub_core_machine.h" // VG_(get_SP)
48 #include "pub_core_mallocfree.h"
49 #include "pub_core_tooliface.h"
50 #include "pub_core_options.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_signals.h"
53 #include "pub_core_stacks.h"
54 #include "pub_core_syscall.h"
55 #include "pub_core_syswrap.h"
56 #include "pub_core_inner.h"
57 #if defined(ENABLE_INNER_CLIENT_REQUEST)
58 #include "pub_core_clreq.h"
59 #endif
61 #include "priv_types_n_macros.h"
62 #include "priv_syswrap-generic.h"
63 #include "priv_syswrap-linux.h"
64 #include "priv_syswrap-main.h"
65 #include "priv_syswrap-xen.h"
67 // Run a thread from beginning to end and return the thread's
68 // scheduler-return-code.
69 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
71 VgSchedReturnCode ret;
72 ThreadId tid = (ThreadId)tidW;
73 ThreadState* tst = VG_(get_ThreadState)(tid);
75 VG_(debugLog)(1, "syswrap-linux",
76 "thread_wrapper(tid=%u): entry\n",
77 tid);
79 vg_assert(tst->status == VgTs_Init);
81 /* make sure we get the CPU lock before doing anything significant */
82 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
84 if (0)
85 VG_(printf)("thread tid %u started: stack = %p\n",
86 tid, (void *)&tid);
88 /* Make sure error reporting is enabled in the new thread. */
89 tst->err_disablement_level = 0;
91 VG_TRACK(pre_thread_first_insn, tid);
93 tst->os_state.lwpid = VG_(gettid)();
94 /* Set the threadgroup for real. This overwrites the provisional value set
95 in do_clone(). See comments in do_clone for background, also #226116. */
96 tst->os_state.threadgroup = VG_(getpid)();
98 /* Thread created with all signals blocked; scheduler will set the
99 appropriate mask */
101 ret = VG_(scheduler)(tid);
103 vg_assert(VG_(is_exiting)(tid));
105 vg_assert(tst->status == VgTs_Runnable);
106 vg_assert(VG_(is_running_thread)(tid));
108 VG_(debugLog)(1, "syswrap-linux",
109 "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
110 tid, VG_(name_of_VgSchedReturnCode)(ret));
112 /* Return to caller, still holding the lock. */
113 return ret;
117 /* ---------------------------------------------------------------------
118 clone-related stuff
119 ------------------------------------------------------------------ */
121 /* Run a thread all the way to the end, then do appropriate exit actions
122 (this is the last-one-out-turn-off-the-lights bit). */
123 static void run_a_thread_NORETURN ( Word tidW )
125 ThreadId tid = (ThreadId)tidW;
126 VgSchedReturnCode src;
127 Int c;
128 ThreadState* tst;
129 #ifdef ENABLE_INNER_CLIENT_REQUEST
130 Int registered_vgstack_id;
131 #endif
133 VG_(debugLog)(1, "syswrap-linux",
134 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
135 tid);
137 tst = VG_(get_ThreadState)(tid);
138 vg_assert(tst);
140 /* An thread has two stacks:
141 * the simulated stack (used by the synthetic cpu. Guest process
142 is using this stack).
143 * the valgrind stack (used by the real cpu. Valgrind code is running
144 on this stack).
145 When Valgrind runs as an inner, it must signals that its (real) stack
146 is the stack to use by the outer to e.g. do stacktraces.
148 INNER_REQUEST
149 (registered_vgstack_id
150 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
151 tst->os_state.valgrind_stack_init_SP));
153 /* Run the thread all the way through. */
154 src = thread_wrapper(tid);
156 VG_(debugLog)(1, "syswrap-linux",
157 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
158 tid);
160 c = VG_(count_living_threads)();
161 vg_assert(c >= 1); /* stay sane */
163 /* Deregister thread's stack. */
164 if (tst->os_state.stk_id != NULL_STK_ID)
165 VG_(deregister_stack)(tst->os_state.stk_id);
167 // Tell the tool this thread is exiting
168 VG_TRACK( pre_thread_ll_exit, tid );
170 /* If the thread is exiting with errors disabled, complain loudly;
171 doing so is bad (does the user know this has happened?) Also,
172 in all cases, be paranoid and clear the flag anyway so that the
173 thread slot is safe in this respect if later reallocated. This
174 should be unnecessary since the flag should be cleared when the
175 slot is reallocated, in thread_wrapper(). */
176 if (tst->err_disablement_level > 0) {
177 VG_(umsg)(
178 "WARNING: exiting thread has error reporting disabled.\n"
179 "WARNING: possibly as a result of some mistake in the use\n"
180 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
182 VG_(debugLog)(
183 1, "syswrap-linux",
184 "run_a_thread_NORETURN(tid=%u): "
185 "WARNING: exiting thread has err_disablement_level = %u\n",
186 tid, tst->err_disablement_level
189 tst->err_disablement_level = 0;
191 if (c == 1) {
193 VG_(debugLog)(1, "syswrap-linux",
194 "run_a_thread_NORETURN(tid=%u): "
195 "last one standing\n",
196 tid);
198 /* We are the last one standing. Keep hold of the lock and
199 carry on to show final tool results, then exit the entire system.
200 Use the continuation pointer set at startup in m_main. */
201 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
202 } else {
204 VG_(debugLog)(1, "syswrap-linux",
205 "run_a_thread_NORETURN(tid=%u): "
206 "not last one standing\n",
207 tid);
209 /* OK, thread is dead, but others still exist. Just exit. */
211 /* This releases the run lock */
212 VG_(exit_thread)(tid);
213 vg_assert(tst->status == VgTs_Zombie);
214 vg_assert(sizeof(tst->status) == 4);
215 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
217 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
219 /* We have to use this sequence to terminate the thread to
220 prevent a subtle race. If VG_(exit_thread)() had left the
221 ThreadState as Empty, then it could have been reallocated,
222 reusing the stack while we're doing these last cleanups.
223 Instead, VG_(exit_thread) leaves it as Zombie to prevent
224 reallocation. We need to make sure we don't touch the stack
225 between marking it Empty and exiting. Hence the
226 assembler. */
227 #if defined(VGP_x86_linux)
228 asm volatile (
229 "pushl %%ebx\n"
230 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
231 "movl %2, %%eax\n" /* set %eax = __NR_exit */
232 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
233 "int $0x80\n" /* exit(tst->os_state.exitcode) */
234 "popl %%ebx\n"
235 : "=m" (tst->status)
236 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
237 : "eax"
239 #elif defined(VGP_amd64_linux)
240 asm volatile (
241 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
242 "movq %2, %%rax\n" /* set %rax = __NR_exit */
243 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
244 "syscall\n" /* exit(tst->os_state.exitcode) */
245 : "=m" (tst->status)
246 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
247 : "rax", "rdi"
249 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
250 || defined(VGP_ppc64le_linux)
251 { UInt vgts_empty = (UInt)VgTs_Empty;
252 asm volatile (
253 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
254 "li 0,%2\n\t" /* set r0 = __NR_exit */
255 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
256 "sc\n\t" /* exit(tst->os_state.exitcode) */
257 : "=m" (tst->status)
258 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
259 : "r0", "r3"
262 #elif defined(VGP_arm_linux)
263 asm volatile (
264 "str %1, %0\n" /* set tst->status = VgTs_Empty */
265 "mov r7, %2\n" /* set %r7 = __NR_exit */
266 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
267 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
268 : "=m" (tst->status)
269 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
270 : "r0", "r7"
272 #elif defined(VGP_arm64_linux)
273 asm volatile (
274 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
275 "mov x8, %2\n" /* set %x8 = __NR_exit */
276 "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */
277 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
278 : "=m" (tst->status)
279 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
280 : "x0", "x8"
282 #elif defined(VGP_s390x_linux)
283 asm volatile (
284 "st %1, %0\n" /* set tst->status = VgTs_Empty */
285 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
286 "svc %2\n" /* exit(tst->os_state.exitcode) */
287 : "=m" (tst->status)
288 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
289 : "2"
291 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
292 asm volatile (
293 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
294 "li $2, %2\n\t" /* set v0 = __NR_exit */
295 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
296 "syscall\n\t" /* exit(tst->os_state.exitcode) */
297 "nop"
298 : "=m" (tst->status)
299 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
300 : "cc", "memory" , "v0", "a0"
302 #elif defined(VGP_nanomips_linux)
303 asm volatile (
304 "sw %1, %0 \n\t" /* set tst->status = VgTs_Empty */
305 "li $t4, %2 \n\t" /* set t4 = __NR_exit */
306 "lw $a0, %3 \n\t" /* set a0 = tst->os_state.exitcode */
307 "syscall[32] \n\t" /* exit(tst->os_state.exitcode) */
308 : "=m" (tst->status)
309 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
310 : "memory" , "$t4", "$a0"
312 #else
313 # error Unknown platform
314 #endif
316 VG_(core_panic)("Thread exit failed?\n");
319 /*NOTREACHED*/
320 vg_assert(0);
323 Word ML_(start_thread_NORETURN) ( void* arg )
325 ThreadState* tst = (ThreadState*)arg;
326 ThreadId tid = tst->tid;
328 run_a_thread_NORETURN ( (Word)tid );
329 /*NOTREACHED*/
330 vg_assert(0);
333 /* Allocate a stack for this thread, if it doesn't already have one.
334 They're allocated lazily, and never freed. Returns the initial stack
335 pointer value to use, or 0 if allocation failed. */
336 Addr ML_(allocstack)(ThreadId tid)
338 ThreadState* tst = VG_(get_ThreadState)(tid);
339 VgStack* stack;
340 Addr initial_SP;
342 /* Either the stack_base and stack_init_SP are both zero (in which
343 case a stack hasn't been allocated) or they are both non-zero,
344 in which case it has. */
346 if (tst->os_state.valgrind_stack_base == 0)
347 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
349 if (tst->os_state.valgrind_stack_base != 0)
350 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
352 /* If no stack is present, allocate one. */
354 if (tst->os_state.valgrind_stack_base == 0) {
355 stack = VG_(am_alloc_VgStack)( &initial_SP );
356 if (stack) {
357 tst->os_state.valgrind_stack_base = (Addr)stack;
358 tst->os_state.valgrind_stack_init_SP = initial_SP;
362 if (0)
363 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
364 tid,
365 (void*)tst->os_state.valgrind_stack_base,
366 (void*)tst->os_state.valgrind_stack_init_SP );
368 return tst->os_state.valgrind_stack_init_SP;
371 /* Allocate a stack for the main thread, and run it all the way to the
372 end. Although we already have a working VgStack
373 (VG_(interim_stack)) it's better to allocate a new one, so that
374 overflow detection works uniformly for all threads.
376 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
378 Addr sp;
379 VG_(debugLog)(1, "syswrap-linux",
380 "entering VG_(main_thread_wrapper_NORETURN)\n");
382 sp = ML_(allocstack)(tid);
383 #if defined(ENABLE_INNER_CLIENT_REQUEST)
385 // we must register the main thread stack before the call
386 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
387 // reports 'write error' on the non registered stack.
388 ThreadState* tst = VG_(get_ThreadState)(tid);
389 INNER_REQUEST
390 ((void)
391 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
392 tst->os_state.valgrind_stack_init_SP));
394 #endif
396 #if defined(VGP_ppc32_linux)
397 /* make a stack frame */
398 sp -= 16;
399 sp &= ~0xF;
400 *(UWord *)sp = 0;
401 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
402 /* make a stack frame */
403 sp -= 112;
404 sp &= ~((Addr)0xF);
405 *(UWord *)sp = 0;
406 #elif defined(VGP_s390x_linux)
407 /* make a stack frame */
408 sp -= 160;
409 sp &= ~((Addr)0xF);
410 *(UWord *)sp = 0;
411 #endif
413 /* If we can't even allocate the first thread's stack, we're hosed.
414 Give up. */
415 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
417 /* shouldn't be any other threads around yet */
418 vg_assert( VG_(count_living_threads)() == 1 );
420 ML_(call_on_new_stack_0_1)(
421 (Addr)sp, /* stack */
422 0, /* bogus return address */
423 run_a_thread_NORETURN, /* fn to call */
424 (Word)tid /* arg to give it */
427 /*NOTREACHED*/
428 vg_assert(0);
431 /* Clone a new thread. Note that in the clone syscalls, we hard-code
432 tlsaddr argument as NULL : the guest TLS is emulated via guest
433 registers, and Valgrind itself has no thread local storage. */
434 static SysRes clone_new_thread ( Word (*fn)(void *),
435 void* stack,
436 Word flags,
437 ThreadState* ctst,
438 Int* child_tidptr,
439 Int* parent_tidptr)
441 SysRes res;
442 /* Note that in all the below, we make sys_clone appear to have returned
443 Success(0) in the child, by assigning the relevant child guest
444 register(s) just before the clone syscall. */
445 #if defined(VGP_x86_linux)
446 Int eax;
447 ctst->arch.vex.guest_EAX = 0;
448 eax = do_syscall_clone_x86_linux
449 (ML_(start_thread_NORETURN), stack, flags, ctst,
450 child_tidptr, parent_tidptr, NULL);
451 res = VG_(mk_SysRes_x86_linux)( eax );
452 #elif defined(VGP_amd64_linux)
453 Long rax;
454 ctst->arch.vex.guest_RAX = 0;
455 rax = do_syscall_clone_amd64_linux
456 (ML_(start_thread_NORETURN), stack, flags, ctst,
457 child_tidptr, parent_tidptr, NULL);
458 res = VG_(mk_SysRes_amd64_linux)( rax );
459 #elif defined(VGP_ppc32_linux)
460 ULong word64;
461 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
462 /* %r3 = 0 */
463 ctst->arch.vex.guest_GPR3 = 0;
464 /* %cr0.so = 0 */
465 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
466 word64 = do_syscall_clone_ppc32_linux
467 (ML_(start_thread_NORETURN), stack, flags, ctst,
468 child_tidptr, parent_tidptr, NULL);
469 /* High half word64 is syscall return value. Low half is
470 the entire CR, from which we need to extract CR0.SO. */
471 /* VG_(printf)("word64 = 0x%llx\n", word64); */
472 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
473 /*errflag*/ (((UInt)word64) >> 28) & 1);
474 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
475 ULong word64;
476 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
477 UInt flag = ctst->arch.vex.guest_syscall_flag;
478 /* %r3 = 0 */
479 ctst->arch.vex.guest_GPR3 = 0;
480 /* %cr0.so = 0 */
481 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
482 word64 = do_syscall_clone_ppc64_linux
483 (ML_(start_thread_NORETURN), stack, flags, ctst,
484 child_tidptr, parent_tidptr, NULL);
485 /* Low half word64 is syscall return value. Hi half is
486 the entire CR, from which we need to extract CR0.SO. */
487 /* VG_(printf)("word64 = 0x%llx\n", word64); */
488 res = VG_(mk_SysRes_ppc64_linux)
489 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
490 /*errflag*/ (UInt)((word64 >> (32+28)) & 1), flag);
491 #elif defined(VGP_s390x_linux)
492 ULong r2;
493 ctst->arch.vex.guest_r2 = 0;
494 r2 = do_syscall_clone_s390x_linux
495 (stack, flags, parent_tidptr, child_tidptr, NULL,
496 ML_(start_thread_NORETURN), ctst);
497 res = VG_(mk_SysRes_s390x_linux)( r2 );
498 #elif defined(VGP_arm64_linux)
499 ULong x0;
500 ctst->arch.vex.guest_X0 = 0;
501 x0 = do_syscall_clone_arm64_linux
502 (ML_(start_thread_NORETURN), stack, flags, ctst,
503 child_tidptr, parent_tidptr, NULL);
504 res = VG_(mk_SysRes_arm64_linux)( x0 );
505 #elif defined(VGP_arm_linux)
506 UInt r0;
507 ctst->arch.vex.guest_R0 = 0;
508 r0 = do_syscall_clone_arm_linux
509 (ML_(start_thread_NORETURN), stack, flags, ctst,
510 child_tidptr, parent_tidptr, NULL);
511 res = VG_(mk_SysRes_arm_linux)( r0 );
512 #elif defined(VGP_mips64_linux)
513 UInt ret = 0;
514 ctst->arch.vex.guest_r2 = 0;
515 ctst->arch.vex.guest_r7 = 0;
516 ret = do_syscall_clone_mips64_linux
517 (ML_(start_thread_NORETURN), stack, flags, ctst,
518 parent_tidptr, NULL, child_tidptr);
519 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
520 #elif defined(VGP_mips32_linux)
521 UInt ret = 0;
522 ctst->arch.vex.guest_r2 = 0;
523 ctst->arch.vex.guest_r7 = 0;
524 ret = do_syscall_clone_mips_linux
525 (ML_(start_thread_NORETURN), stack, flags, ctst,
526 child_tidptr, parent_tidptr, NULL);
527 /* High half word64 is syscall return value. Low half is
528 the entire CR, from which we need to extract CR0.SO. */
529 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
530 #elif defined(VGP_nanomips_linux)
531 UInt ret = 0;
532 ctst->arch.vex.guest_r4 = 0;
533 ret = do_syscall_clone_nanomips_linux
534 (ML_(start_thread_NORETURN), stack, flags, ctst,
535 child_tidptr, parent_tidptr, NULL);
536 res = VG_ (mk_SysRes_nanomips_linux) (ret);
537 #else
538 # error Unknown platform
539 #endif
540 return res;
543 static void setup_child ( /*OUT*/ ThreadArchState *child,
544 /*IN*/ ThreadArchState *parent )
546 /* We inherit our parent's guest state. */
547 child->vex = parent->vex;
548 child->vex_shadow1 = parent->vex_shadow1;
549 child->vex_shadow2 = parent->vex_shadow2;
551 #if defined(VGP_x86_linux)
552 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
553 /*IN*/ ThreadArchState *parent );
554 ML_(x86_setup_LDT_GDT)(child, parent);
555 #endif
558 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
560 static const Bool debug = False;
561 ThreadState* ctst = VG_(get_ThreadState)(ctid);
562 // res is succesful by default, overriden if a real syscall is needed/done.
563 SysRes res = VG_(mk_SysRes_Success)(0);
565 if (debug)
566 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
568 #if defined(VGP_x86_linux)
569 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
570 if (debug)
571 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
572 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
573 tlsinfo, tlsinfo->entry_number,
574 tlsinfo->base_addr, tlsinfo->limit,
575 ctst->arch.vex.guest_ESP,
576 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
577 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
578 #elif defined(VGP_amd64_linux)
579 ctst->arch.vex.guest_FS_CONST = tlsaddr;
580 #elif defined(VGP_ppc32_linux)
581 ctst->arch.vex.guest_GPR2 = tlsaddr;
582 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
583 ctst->arch.vex.guest_GPR13 = tlsaddr;
584 #elif defined(VGP_s390x_linux)
585 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
586 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
587 #elif defined(VGP_arm64_linux)
588 /* Just assign the tls pointer in the guest TPIDR_EL0. */
589 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
590 #elif defined(VGP_arm_linux)
591 /* Just assign the tls pointer in the guest TPIDRURO. */
592 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
593 #elif defined(VGP_mips64_linux)
594 ctst->arch.vex.guest_ULR = tlsaddr;
595 ctst->arch.vex.guest_r27 = tlsaddr;
596 #elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
597 ctst->arch.vex.guest_ULR = tlsaddr;
598 ctst->arch.vex.guest_r27 = tlsaddr;
599 #else
600 # error Unknown platform
601 #endif
602 return res;
606 When a client clones, we need to keep track of the new thread. This means:
607 1. allocate a ThreadId+ThreadState+stack for the thread
609 2. initialize the thread's new VCPU state
611 3. create the thread using the same args as the client requested,
612 but using the scheduler entrypoint for EIP, and a separate stack
613 for ESP.
615 static SysRes do_clone ( ThreadId ptid,
616 UWord flags, Addr sp,
617 Int* parent_tidptr,
618 Int* child_tidptr,
619 Addr tlsaddr)
621 ThreadId ctid = VG_(alloc_ThreadState)();
622 ThreadState* ptst = VG_(get_ThreadState)(ptid);
623 ThreadState* ctst = VG_(get_ThreadState)(ctid);
624 UWord* stack;
625 SysRes res;
626 vki_sigset_t blockall, savedmask;
628 VG_(sigfillset)(&blockall);
630 vg_assert(VG_(is_running_thread)(ptid));
631 vg_assert(VG_(is_valid_tid)(ctid));
633 stack = (UWord*)ML_(allocstack)(ctid);
634 if (stack == NULL) {
635 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
636 goto out;
639 /* Copy register state
641 Both parent and child return to the same place, and the code
642 following the clone syscall works out which is which, so we
643 don't need to worry about it.
645 The parent gets the child's new tid returned from clone, but the
646 child gets 0.
648 If the clone call specifies a NULL sp for the new thread, then
649 it actually gets a copy of the parent's sp.
651 setup_child( &ctst->arch, &ptst->arch );
653 if (sp != 0)
654 VG_(set_SP)(ctid, sp);
656 ctst->os_state.parent = ptid;
658 /* inherit signal mask */
659 ctst->sig_mask = ptst->sig_mask;
660 ctst->tmp_sig_mask = ptst->sig_mask;
662 /* Start the child with its threadgroup being the same as the
663 parent's. This is so that any exit_group calls that happen
664 after the child is created but before it sets its
665 os_state.threadgroup field for real (in thread_wrapper in
666 syswrap-linux.c), really kill the new thread. a.k.a this avoids
667 a race condition in which the thread is unkillable (via
668 exit_group) because its threadgroup is not set. The race window
669 is probably only a few hundred or a few thousand cycles long.
670 See #226116. */
671 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
673 ML_(guess_and_register_stack) (sp, ctst);
675 /* Assume the clone will succeed, and tell any tool that wants to
676 know that this thread has come into existence. We cannot defer
677 it beyond this point because setup_tls, just below,
678 causes checks to assert by making references to the new ThreadId
679 if we don't state the new thread exists prior to that point.
680 If the clone fails, we'll send out a ll_exit notification for it
681 at the out: label below, to clean up. */
682 vg_assert(VG_(owns_BigLock_LL)(ptid));
683 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
685 if (flags & VKI_CLONE_SETTLS) {
686 res = setup_child_tls(ctid, tlsaddr);
687 if (sr_isError(res))
688 goto out;
690 flags &= ~VKI_CLONE_SETTLS;
692 /* start the thread with everything blocked */
693 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
695 /* Create the new thread */
696 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
697 child_tidptr, parent_tidptr);
699 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
701 out:
702 if (sr_isError(res)) {
703 /* clone failed */
704 VG_(cleanup_thread)(&ctst->arch);
705 ctst->status = VgTs_Empty;
706 /* oops. Better tell the tool the thread exited in a hurry :-) */
707 VG_TRACK( pre_thread_ll_exit, ctid );
710 return res;
713 /* Do a clone which is really a fork().
714 ML_(do_fork_clone) uses the clone syscall to fork a child process.
715 Note that this should not be called for a thread creation.
716 Also, some flags combinations are not supported, and such combinations
717 are handled either by masking the non supported flags or by asserting.
719 The CLONE_VFORK flag is accepted, as this just tells that the parent is
720 suspended till the child exits or calls execve. We better keep this flag,
721 just in case the guests parent/client code depends on this synchronisation.
723 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
724 instructions in the child process, that will mess up the parent host
725 memory. So, we hope for the best and assumes that the guest application does
726 not (really) depends on sharing the memory between parent and child in the
727 interval between clone and exits/execve.
729 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
730 clone syscall, before child guest instructions are executed. */
731 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
732 Int* parent_tidptr, Int* child_tidptr,
733 Addr child_sp)
735 vki_sigset_t fork_saved_mask;
736 vki_sigset_t mask;
737 SysRes res;
739 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
740 | VKI_CLONE_FILES))
741 return VG_(mk_SysRes_Error)( VKI_EINVAL );
743 /* Block all signals during fork, so that we can fix things up in
744 the child without being interrupted. */
745 VG_(sigfillset)(&mask);
746 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
748 VG_(do_atfork_pre)(tid);
750 /* Since this is the fork() form of clone, we don't need all that
751 VG_(clone) stuff */
752 #if defined(VGP_x86_linux) \
753 || defined(VGP_ppc32_linux) \
754 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
755 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
756 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
757 || defined(VGP_nanomips_linux)
758 res = VG_(do_syscall5)( __NR_clone, flags,
759 (UWord)NULL, (UWord)parent_tidptr,
760 (UWord)NULL, (UWord)child_tidptr );
761 #elif defined(VGP_amd64_linux)
762 /* note that the last two arguments are the opposite way round to x86 and
763 ppc32 as the amd64 kernel expects the arguments in a different order */
764 res = VG_(do_syscall5)( __NR_clone, flags,
765 (UWord)NULL, (UWord)parent_tidptr,
766 (UWord)child_tidptr, (UWord)NULL );
767 #elif defined(VGP_s390x_linux)
768 /* Note that s390 has the stack first and then the flags */
769 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
770 (UWord)parent_tidptr, (UWord)child_tidptr);
771 #else
772 # error Unknown platform
773 #endif
775 if (!sr_isError(res) && sr_Res(res) == 0) {
776 /* child */
777 if (child_sp != 0)
778 VG_(set_SP)(tid, child_sp);
779 VG_(do_atfork_child)(tid);
781 /* restore signal mask */
782 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
784 else
785 if (!sr_isError(res) && sr_Res(res) > 0) {
786 /* parent */
787 VG_(do_atfork_parent)(tid);
789 if (VG_(clo_trace_syscalls))
790 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
791 VG_(getpid)(), (RegWord)sr_Res(res));
793 /* restore signal mask */
794 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
797 return res;
800 /* ---------------------------------------------------------------------
801 PRE/POST wrappers for arch-generic, Linux-specific syscalls
802 ------------------------------------------------------------------ */
804 // Nb: See the comment above the generic PRE/POST wrappers in
805 // m_syswrap/syswrap-generic.c for notes about how they work.
807 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
808 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
810 PRE(sys_clone)
812 UInt cloneflags;
813 Bool badarg = False;
815 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
816 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
817 ARG4, ARG5);
819 // Order of arguments differs between platforms.
820 #if defined(VGP_x86_linux) \
821 || defined(VGP_ppc32_linux) \
822 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
823 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
824 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
825 || defined(VGP_nanomips_linux)
826 #define ARG_CHILD_TIDPTR ARG5
827 #define PRA_CHILD_TIDPTR PRA5
828 #define ARG_TLS ARG4
829 #define PRA_TLS PRA4
830 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
831 #define ARG_CHILD_TIDPTR ARG4
832 #define PRA_CHILD_TIDPTR PRA4
833 #define ARG_TLS ARG5
834 #define PRA_TLS PRA5
835 #else
836 # error Unknown platform
837 #endif
838 // And s390x is even more special, and inverts flags and child stack args
839 #if defined(VGP_s390x_linux)
840 #define ARG_FLAGS ARG2
841 #define PRA_FLAGS PRA2
842 #define ARG_CHILD_STACK ARG1
843 #define PRA_CHILD_STACK PRA1
844 #else
845 #define ARG_FLAGS ARG1
846 #define PRA_FLAGS PRA1
847 #define ARG_CHILD_STACK ARG2
848 #define PRA_CHILD_STACK PRA2
849 #endif
851 if (VG_(tdict).track_pre_reg_read) {
852 PRA_FLAGS("clone", unsigned long, flags);
853 PRA_CHILD_STACK("clone", void *, child_stack);
856 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD)) {
857 if (VG_(tdict).track_pre_reg_read) {
858 PRA3("clone", int *, parent_tidptr);
860 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
861 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
862 VKI_PROT_WRITE)) {
863 badarg = True;
866 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
867 if (VG_(tdict).track_pre_reg_read) {
868 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
870 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
871 dummy type (that we define as a char). We only dereference/check the
872 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
873 if (sizeof(vki_modify_ldt_t) > 1) {
874 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
875 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
876 VKI_PROT_READ)) {
877 badarg = True;
881 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
882 if (VG_(tdict).track_pre_reg_read) {
883 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
885 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
886 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
887 VKI_PROT_WRITE)) {
888 badarg = True;
892 if (badarg) {
893 SET_STATUS_Failure( VKI_EFAULT );
894 return;
897 cloneflags = ARG_FLAGS;
899 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
900 SET_STATUS_Failure( VKI_EINVAL );
901 return;
904 /* Only look at the flags we really care about */
905 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
906 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
907 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
908 /* thread creation */
909 SET_STATUS_from_SysRes(
910 do_clone(tid,
911 ARG_FLAGS, /* flags */
912 (Addr)ARG_CHILD_STACK, /* child ESP */
913 (Int*)(Addr)ARG3, /* parent_tidptr */
914 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
915 (Addr)ARG_TLS)); /* set_tls */
916 break;
918 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
919 case VKI_CLONE_VFORK: /* vfork without memory sharing */
920 cloneflags &= ~VKI_CLONE_VM;
921 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
923 case 0: /* plain fork */
924 SET_STATUS_from_SysRes(
925 ML_(do_fork_clone)(tid,
926 cloneflags, /* flags */
927 (Int*)(Addr)ARG3, /* parent_tidptr */
928 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
929 (Addr)ARG_CHILD_STACK));
930 break;
932 default:
933 /* should we just ENOSYS? */
934 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
935 "x\n", ARG_FLAGS);
936 VG_(message)(Vg_UserMsg, "\n");
937 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
938 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
939 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
940 VG_(unimplemented)
941 ("Valgrind does not support general clone().");
944 if (SUCCESS && RES != 0) {
945 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD))
946 POST_MEM_WRITE(ARG3, sizeof(Int));
947 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
948 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
949 if (ARG_FLAGS & VKI_CLONE_PIDFD) {
950 Int fd = *(Int*)(Addr)ARG3;
951 if (!ML_(fd_allowed)(fd, "clone", tid, True)) {
952 VG_(close)(fd);
953 SET_STATUS_Failure( VKI_EMFILE );
954 } else {
955 if (VG_(clo_track_fds))
956 ML_(record_fd_open_nameless) (tid, fd);
960 /* Thread creation was successful; let the child have the chance
961 to run */
962 *flags |= SfYieldAfter;
965 #undef ARG_CHILD_TIDPTR
966 #undef PRA_CHILD_TIDPTR
967 #undef ARG_TLS
968 #undef PRA_TLS
969 #undef ARG_FLAGS
970 #undef PRA_FLAGS
971 #undef ARG_CHILD_STACK
972 #undef PRA_CHILD_STACK
975 /* ---------------------------------------------------------------------
976 *mount wrappers
977 ------------------------------------------------------------------ */
979 PRE(sys_mount)
981 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
982 // We are conservative and check everything, except the memory pointed to
983 // by 'data'.
984 *flags |= SfMayBlock;
985 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
986 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
987 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
988 (HChar*)(Addr)ARG3, ARG4, ARG5);
989 PRE_REG_READ5(long, "mount",
990 char *, source, char *, target, char *, type,
991 unsigned long, flags, void *, data);
992 if (ARG1)
993 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
994 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
995 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
998 PRE(sys_oldumount)
1000 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
1001 PRE_REG_READ1(long, "umount", char *, path);
1002 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
1005 PRE(sys_umount)
1007 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
1008 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
1009 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1012 /* Not actually wrapped by GLibc but does things with the system
1013 * mounts so it is put here.
1015 PRE(sys_pivot_root)
1017 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1018 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1019 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1020 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1024 /* ---------------------------------------------------------------------
1025 16- and 32-bit uid/gid wrappers
1026 ------------------------------------------------------------------ */
1028 PRE(sys_setfsuid16)
1030 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1031 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1034 PRE(sys_setfsuid)
1036 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1037 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1040 PRE(sys_setfsgid16)
1042 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1043 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1046 PRE(sys_setfsgid)
1048 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1049 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1052 PRE(sys_setresuid16)
1054 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1055 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1056 PRE_REG_READ3(long, "setresuid16",
1057 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1060 PRE(sys_setresuid)
1062 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1063 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1064 PRE_REG_READ3(long, "setresuid",
1065 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1068 PRE(sys_getresuid16)
1070 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1071 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1072 PRE_REG_READ3(long, "getresuid16",
1073 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1074 vki_old_uid_t *, suid);
1075 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1076 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1077 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1079 POST(sys_getresuid16)
1081 vg_assert(SUCCESS);
1082 if (RES == 0) {
1083 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1084 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1085 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1089 PRE(sys_getresuid)
1091 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1092 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1093 PRE_REG_READ3(long, "getresuid",
1094 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1095 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1096 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1097 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1099 POST(sys_getresuid)
1101 vg_assert(SUCCESS);
1102 if (RES == 0) {
1103 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1104 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1105 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1109 PRE(sys_setresgid16)
1111 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1112 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1113 PRE_REG_READ3(long, "setresgid16",
1114 vki_old_gid_t, rgid,
1115 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1118 PRE(sys_setresgid)
1120 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1121 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1122 PRE_REG_READ3(long, "setresgid",
1123 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1126 PRE(sys_getresgid16)
1128 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1129 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1130 PRE_REG_READ3(long, "getresgid16",
1131 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1132 vki_old_gid_t *, sgid);
1133 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1134 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1135 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1137 POST(sys_getresgid16)
1139 vg_assert(SUCCESS);
1140 if (RES == 0) {
1141 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1142 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1143 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1147 PRE(sys_getresgid)
1149 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1150 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1151 PRE_REG_READ3(long, "getresgid",
1152 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1153 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1154 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1155 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1157 POST(sys_getresgid)
1159 vg_assert(SUCCESS);
1160 if (RES == 0) {
1161 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1162 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1163 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1167 /* ---------------------------------------------------------------------
1168 miscellaneous wrappers
1169 ------------------------------------------------------------------ */
1171 PRE(sys_exit_group)
1173 ThreadId t;
1174 ThreadState* tst;
1176 PRINT("exit_group( %ld )", SARG1);
1177 PRE_REG_READ1(void, "exit_group", int, status);
1179 tst = VG_(get_ThreadState)(tid);
1180 /* A little complex; find all the threads with the same threadgroup
1181 as this one (including this one), and mark them to exit */
1182 /* It is unclear how one can get a threadgroup in this process which
1183 is not the threadgroup of the calling thread:
1184 The assignments to threadgroups are:
1185 = 0; /// scheduler.c os_state_clear
1186 = getpid(); /// scheduler.c in child after fork
1187 = getpid(); /// this file, in thread_wrapper
1188 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1189 copying the thread group of the thread doing clone
1190 So, the only case where the threadgroup might be different to the getpid
1191 value is in the child, just after fork. But then the fork syscall is
1192 still going on, the forked thread has had no chance yet to make this
1193 syscall. */
1194 for (t = 1; t < VG_N_THREADS; t++) {
1195 if ( /* not alive */
1196 VG_(threads)[t].status == VgTs_Empty
1198 /* not our group */
1199 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1201 continue;
1202 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1203 the exitreason. */
1204 VG_(threads)[t].os_state.exitcode = ARG1;
1207 /* Indicate in all other threads that the process is exiting.
1208 Then wait using VG_(reap_threads) for these threads to disappear.
1210 Can this give a deadlock if another thread is calling exit in parallel
1211 and would then wait for this thread to disappear ?
1212 The answer is no:
1213 Other threads are either blocked in a syscall or have yielded the CPU.
1215 A thread that has yielded the CPU is trying to get the big lock in
1216 VG_(scheduler). This thread will get the CPU thanks to the call
1217 to VG_(reap_threads). The scheduler will then check for signals,
1218 kill the process if this is a fatal signal, and otherwise prepare
1219 the thread for handling this signal. After this preparation, if
1220 the thread status is VG_(is_exiting), the scheduler exits the thread.
1221 So, a thread that has yielded the CPU does not have a chance to
1222 call exit => no deadlock for this thread.
1224 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1225 to all threads blocked in a syscall.
1226 The syscall will be interrupted, and the control will go to the
1227 scheduler. The scheduler will then return, as the thread is in
1228 exiting state. */
1230 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1231 VG_(reap_threads)(tid);
1232 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1233 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1234 is the thread calling exit_group and so its registers must be considered
1235 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1237 /* We have to claim the syscall already succeeded. */
1238 SET_STATUS_Success(0);
1241 PRE(sys_llseek)
1243 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1244 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1245 ARG1, ARG2, ARG3, ARG4, ARG5);
1246 PRE_REG_READ5(long, "llseek",
1247 unsigned int, fd, unsigned long, offset_high,
1248 unsigned long, offset_low, vki_loff_t *, result,
1249 unsigned int, whence);
1250 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1251 SET_STATUS_Failure( VKI_EBADF );
1252 else
1253 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1255 POST(sys_llseek)
1257 vg_assert(SUCCESS);
1258 if (RES == 0)
1259 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1262 PRE(sys_adjtimex)
1264 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1265 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1266 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1268 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1269 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1271 #define ADJX(bits,field) \
1272 if (tx->modes & (bits)) \
1273 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1274 (Addr)&tx->field, sizeof(tx->field))
1276 if (tx->modes & VKI_ADJ_ADJTIME) {
1277 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1278 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1279 } else {
1280 ADJX(VKI_ADJ_OFFSET, offset);
1281 ADJX(VKI_ADJ_FREQUENCY, freq);
1282 ADJX(VKI_ADJ_MAXERROR, maxerror);
1283 ADJX(VKI_ADJ_ESTERROR, esterror);
1284 ADJX(VKI_ADJ_STATUS, status);
1285 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1286 ADJX(VKI_ADJ_TICK, tick);
1288 #undef ADJX
1291 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1294 POST(sys_adjtimex)
1296 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1299 PRE(sys_clock_adjtime)
1301 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1302 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1303 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1304 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1306 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1307 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1309 #define ADJX(bits,field) \
1310 if (tx->modes & (bits)) \
1311 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1312 (Addr)&tx->field, sizeof(tx->field))
1314 if (tx->modes & VKI_ADJ_ADJTIME) {
1315 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1316 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1317 } else {
1318 ADJX(VKI_ADJ_OFFSET, offset);
1319 ADJX(VKI_ADJ_FREQUENCY, freq);
1320 ADJX(VKI_ADJ_MAXERROR, maxerror);
1321 ADJX(VKI_ADJ_ESTERROR, esterror);
1322 ADJX(VKI_ADJ_STATUS, status);
1323 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1324 ADJX(VKI_ADJ_TICK, tick);
1326 #undef ADJX
1329 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1332 POST(sys_clock_adjtime)
1334 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1337 PRE(sys_ioperm)
1339 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1340 ARG1, ARG2, SARG3 );
1341 PRE_REG_READ3(long, "ioperm",
1342 unsigned long, from, unsigned long, num, int, turn_on);
1345 PRE(sys_syslog)
1347 *flags |= SfMayBlock;
1348 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1349 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1350 switch (ARG1) {
1351 // The kernel uses magic numbers here, rather than named constants,
1352 // therefore so do we.
1353 case 2: case 3: case 4:
1354 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1355 break;
1356 default:
1357 break;
1360 POST(sys_syslog)
1362 switch (ARG1) {
1363 case 2: case 3: case 4:
1364 POST_MEM_WRITE( ARG2, ARG3 );
1365 break;
1366 default:
1367 break;
1371 PRE(sys_vhangup)
1373 PRINT("sys_vhangup ( )");
1374 PRE_REG_READ0(long, "vhangup");
1377 PRE(sys_sysinfo)
1379 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1380 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1381 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1383 POST(sys_sysinfo)
1385 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1388 PRE(sys_personality)
1390 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1391 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1394 PRE(sys_sysctl)
1396 struct __vki_sysctl_args *args;
1397 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1398 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1399 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1400 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1401 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1402 VKI_PROT_READ)) {
1403 SET_STATUS_Failure( VKI_EFAULT );
1404 return;
1407 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1408 if (args->newval != NULL)
1409 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1410 if (args->oldlenp != NULL) {
1411 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1412 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1415 POST(sys_sysctl)
1417 struct __vki_sysctl_args *args;
1418 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1419 if (args->oldlenp != NULL) {
1420 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1421 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1425 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1426 const char *attr_name)
1428 const HChar *step_str = (const HChar *)str;
1429 SizeT len;
1430 UInt i;
1433 * The name can be up to maxlen bytes long, including the terminating null
1434 * byte. So do not check more than maxlen bytes.
1436 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1437 len = VG_(strnlen)((const HChar *)str, maxlen);
1438 if (len < maxlen)
1439 PRE_MEM_RASCIIZ(attr_name, str);
1440 else
1441 PRE_MEM_READ(attr_name, str, maxlen);
1442 } else {
1444 * Do it the slow way, one byte at a time, while checking for terminating
1445 * '\0'.
1447 for (i = 0; i < maxlen; i++) {
1448 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1449 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1450 break;
1455 PRE(sys_prctl)
1457 *flags |= SfMayBlock;
1458 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1459 switch (ARG1) {
1460 case VKI_PR_SET_PDEATHSIG:
1461 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1462 break;
1463 case VKI_PR_GET_PDEATHSIG:
1464 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1465 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1466 break;
1467 case VKI_PR_GET_DUMPABLE:
1468 PRE_REG_READ1(int, "prctl", int, option);
1469 break;
1470 case VKI_PR_SET_DUMPABLE:
1471 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1472 break;
1473 case VKI_PR_GET_UNALIGN:
1474 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1475 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1476 break;
1477 case VKI_PR_SET_UNALIGN:
1478 PRE_REG_READ2(int, "prctl", int, option, int, value);
1479 break;
1480 case VKI_PR_GET_KEEPCAPS:
1481 PRE_REG_READ1(int, "prctl", int, option);
1482 break;
1483 case VKI_PR_SET_KEEPCAPS:
1484 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1485 break;
1486 case VKI_PR_GET_FPEMU:
1487 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1488 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1489 break;
1490 case VKI_PR_SET_FPEMU:
1491 PRE_REG_READ2(int, "prctl", int, option, int, value);
1492 break;
1493 case VKI_PR_GET_FPEXC:
1494 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1495 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1496 break;
1497 case VKI_PR_SET_FPEXC:
1498 PRE_REG_READ2(int, "prctl", int, option, int, value);
1499 break;
1500 case VKI_PR_GET_TIMING:
1501 PRE_REG_READ1(int, "prctl", int, option);
1502 break;
1503 case VKI_PR_SET_TIMING:
1504 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1505 break;
1506 case VKI_PR_SET_NAME:
1507 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1508 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1509 break;
1510 case VKI_PR_GET_NAME:
1511 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1512 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1513 break;
1514 case VKI_PR_GET_ENDIAN:
1515 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1516 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1517 break;
1518 case VKI_PR_SET_ENDIAN:
1519 PRE_REG_READ2(int, "prctl", int, option, int, value);
1520 break;
1521 case VKI_PR_SET_PTRACER:
1522 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1523 break;
1524 case VKI_PR_SET_SECCOMP:
1525 /* This is a bit feeble in that it uses |option| before checking
1526 it, but at least both sides of the conditional check it. */
1527 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1528 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1529 if (ARG3) {
1530 /* Should check that ARG3 points at a valid struct sock_fprog.
1531 Sounds complex; hence be lame. */
1532 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1533 ARG3, 1 );
1535 } else {
1536 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1538 break;
1539 case VKI_PR_CAPBSET_READ:
1540 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1541 break;
1542 case VKI_PR_CAPBSET_DROP:
1543 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1544 break;
1545 default:
1546 PRE_REG_READ5(long, "prctl",
1547 int, option, unsigned long, arg2, unsigned long, arg3,
1548 unsigned long, arg4, unsigned long, arg5);
1549 break;
1552 POST(sys_prctl)
1554 switch (ARG1) {
1555 case VKI_PR_GET_PDEATHSIG:
1556 POST_MEM_WRITE(ARG2, sizeof(Int));
1557 break;
1558 case VKI_PR_GET_UNALIGN:
1559 POST_MEM_WRITE(ARG2, sizeof(Int));
1560 break;
1561 case VKI_PR_GET_FPEMU:
1562 POST_MEM_WRITE(ARG2, sizeof(Int));
1563 break;
1564 case VKI_PR_GET_FPEXC:
1565 POST_MEM_WRITE(ARG2, sizeof(Int));
1566 break;
1567 case VKI_PR_GET_NAME:
1568 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1569 break;
1570 case VKI_PR_GET_ENDIAN:
1571 POST_MEM_WRITE(ARG2, sizeof(Int));
1572 break;
1573 case VKI_PR_SET_NAME:
1575 const HChar* new_name = (const HChar*) (Addr)ARG2;
1576 if (new_name) { // Paranoia
1577 ThreadState* tst = VG_(get_ThreadState)(tid);
1578 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1580 /* Don't bother reusing the memory. This is a rare event. */
1581 tst->thread_name =
1582 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1583 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1586 break;
1590 PRE(sys_sendfile)
1592 *flags |= SfMayBlock;
1593 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1594 SARG1, SARG2, ARG3, ARG4);
1595 PRE_REG_READ4(ssize_t, "sendfile",
1596 int, out_fd, int, in_fd, vki_off_t *, offset,
1597 vki_size_t, count);
1598 if (ARG3 != 0)
1599 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1601 POST(sys_sendfile)
1603 if (ARG3 != 0 ) {
1604 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1608 PRE(sys_sendfile64)
1610 *flags |= SfMayBlock;
1611 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1612 SARG1, SARG2, ARG3, ARG4);
1613 PRE_REG_READ4(ssize_t, "sendfile64",
1614 int, out_fd, int, in_fd, vki_loff_t *, offset,
1615 vki_size_t, count);
1616 if (ARG3 != 0)
1617 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1619 POST(sys_sendfile64)
1621 if (ARG3 != 0 ) {
1622 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1626 static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
1628 struct vki_timespec64 *ts64 = (void *)(Addr)arg;
1629 PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
1630 PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
1633 static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
1635 struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
1636 pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
1637 pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
1640 static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1641 SyscallArgs* arrghs, SyscallStatus* status,
1642 UWord* flags, Bool is_time64 )
1645 arg param used by ops
1647 ARG1 - u32 *futex all
1648 ARG2 - int op
1649 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1650 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1651 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1652 ARG6 - int val3 CMP_REQUEUE
1655 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1656 case VKI_FUTEX_CMP_REQUEUE:
1657 case VKI_FUTEX_WAKE_OP:
1658 case VKI_FUTEX_CMP_REQUEUE_PI:
1659 if (is_time64) {
1660 PRE_REG_READ6(long, "futex_time64",
1661 vki_u32 *, futex, int, op, int, val,
1662 struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
1663 } else {
1664 PRE_REG_READ6(long, "futex",
1665 vki_u32 *, futex, int, op, int, val,
1666 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1668 break;
1669 case VKI_FUTEX_REQUEUE:
1670 case VKI_FUTEX_WAIT_REQUEUE_PI:
1671 if (is_time64) {
1672 PRE_REG_READ5(long, "futex_time64",
1673 vki_u32 *, futex, int, op, int, val,
1674 struct timespec64 *, utime, vki_u32 *, uaddr2);
1675 } else {
1676 PRE_REG_READ5(long, "futex",
1677 vki_u32 *, futex, int, op, int, val,
1678 struct timespec *, utime, vki_u32 *, uaddr2);
1680 break;
1681 case VKI_FUTEX_WAIT_BITSET:
1682 /* Check that the address at least begins in client-accessible area. */
1683 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1684 SET_STATUS_Failure( VKI_EFAULT );
1685 return;
1687 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1688 if (is_time64) {
1689 PRE_REG_READ4(long, "futex_time64",
1690 vki_u32 *, futex, int, op, int, val,
1691 struct timespec64 *, utime);
1692 } else {
1693 PRE_REG_READ4(long, "futex",
1694 vki_u32 *, futex, int, op, int, val,
1695 struct timespec64 *, utime);
1697 } else {
1698 /* Note argument 5 is unused, but argument 6 is used.
1699 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1700 if (is_time64) {
1701 PRE_REG_READ4(long, "futex_time64",
1702 vki_u32 *, futex, int, op, int, val,
1703 struct timespec64 *, utime);
1704 } else {
1705 PRE_REG_READ4(long, "futex",
1706 vki_u32 *, futex, int, op, int, val,
1707 struct timespec *, utime);
1709 if (VG_(tdict).track_pre_reg_read)
1710 PRA6("futex",int,val3);
1712 break;
1713 case VKI_FUTEX_WAKE_BITSET:
1714 PRE_REG_READ3(long, "futex",
1715 vki_u32 *, futex, int, op, int, val);
1716 if (VG_(tdict).track_pre_reg_read) {
1717 PRA6("futex", int, val3);
1719 break;
1720 case VKI_FUTEX_WAIT:
1721 case VKI_FUTEX_LOCK_PI:
1722 if (is_time64) {
1723 PRE_REG_READ4(long, "futex_time64",
1724 vki_u32 *, futex, int, op, int, val,
1725 struct timespec64 *, utime);
1726 } else {
1727 PRE_REG_READ4(long, "futex",
1728 vki_u32 *, futex, int, op, int, val,
1729 struct timespec *, utime);
1731 break;
1732 case VKI_FUTEX_WAKE:
1733 case VKI_FUTEX_FD:
1734 PRE_REG_READ3(long, "futex",
1735 vki_u32 *, futex, int, op, int, val);
1736 break;
1737 case VKI_FUTEX_TRYLOCK_PI:
1738 case VKI_FUTEX_UNLOCK_PI:
1739 default:
1740 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1741 break;
1744 *flags |= SfMayBlock;
1746 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1747 case VKI_FUTEX_WAIT:
1748 case VKI_FUTEX_LOCK_PI:
1749 case VKI_FUTEX_WAIT_BITSET:
1750 case VKI_FUTEX_WAIT_REQUEUE_PI:
1751 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1752 if (ARG4 != 0) {
1753 if (is_time64) {
1754 pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
1755 } else {
1756 PRE_MEM_READ( "futex(timeout)", ARG4,
1757 sizeof(struct vki_timespec) );
1760 break;
1762 case VKI_FUTEX_REQUEUE:
1763 case VKI_FUTEX_CMP_REQUEUE:
1764 case VKI_FUTEX_CMP_REQUEUE_PI:
1765 case VKI_FUTEX_WAKE_OP:
1766 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1767 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1768 break;
1770 case VKI_FUTEX_FD:
1771 case VKI_FUTEX_TRYLOCK_PI:
1772 case VKI_FUTEX_UNLOCK_PI:
1773 case VKI_FUTEX_WAKE:
1774 case VKI_FUTEX_WAKE_BITSET:
1775 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1776 break;
1778 default:
1779 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1780 break;
1784 static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
1785 SyscallStatus* status )
1787 vg_assert(SUCCESS);
1788 POST_MEM_WRITE( ARG1, sizeof(int) );
1789 if (ARG2 == VKI_FUTEX_FD) {
1790 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1791 VG_(close)(RES);
1792 SET_STATUS_Failure( VKI_EMFILE );
1793 } else {
1794 if (VG_(clo_track_fds))
1795 ML_(record_fd_open_nameless)(tid, RES);
1800 PRE(sys_futex)
1802 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1803 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1804 futex_pre_helper (tid, layout, arrghs, status, flags, False);
1807 POST(sys_futex)
1809 futex_post_helper (tid, arrghs, status);
1812 PRE(sys_futex_time64)
1814 PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1815 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1816 futex_pre_helper (tid, layout, arrghs, status, flags, True);
1819 POST(sys_futex_time64)
1821 futex_post_helper (tid, arrghs, status);
1824 PRE(sys_set_robust_list)
1826 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1827 FMT_REGWORD "u )", ARG1, ARG2);
1828 PRE_REG_READ2(long, "set_robust_list",
1829 struct vki_robust_list_head *, head, vki_size_t, len);
1831 /* Just check the robust_list_head structure is readable - don't
1832 try and chase the list as the kernel will only read it when
1833 the thread exits so the current contents is irrelevant. */
1834 if (ARG1 != 0)
1835 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1838 PRE(sys_get_robust_list)
1840 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1841 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1842 PRE_REG_READ3(long, "get_robust_list",
1843 int, pid,
1844 struct vki_robust_list_head **, head_ptr,
1845 vki_size_t *, len_ptr);
1846 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1847 ARG2, sizeof(struct vki_robust_list_head *));
1848 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1849 ARG3, sizeof(struct vki_size_t *));
1851 POST(sys_get_robust_list)
1853 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1854 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1857 struct pselect_sized_sigset {
1858 const vki_sigset_t *ss;
1859 vki_size_t ss_len;
1861 struct pselect_adjusted_sigset {
1862 struct pselect_sized_sigset ss; /* The actual syscall arg */
1863 vki_sigset_t adjusted_ss;
1866 static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1867 SyscallArgs* arrghs, SyscallStatus* status,
1868 UWord* flags, Bool is_time64 )
1870 *flags |= SfMayBlock | SfPostOnFail;
1871 if (is_time64) {
1872 PRE_REG_READ6(long, "pselect6_time64",
1873 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1874 vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
1875 void *, sig);
1876 } else {
1877 PRE_REG_READ6(long, "pselect6",
1878 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1879 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
1880 void *, sig);
1882 // XXX: this possibly understates how much memory is read.
1883 if (ARG2 != 0)
1884 PRE_MEM_READ( "pselect6(readfds)",
1885 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1886 if (ARG3 != 0)
1887 PRE_MEM_READ( "pselect6(writefds)",
1888 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1889 if (ARG4 != 0)
1890 PRE_MEM_READ( "pselect6(exceptfds)",
1891 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1892 if (ARG5 != 0) {
1893 if (is_time64) {
1894 pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
1895 } else {
1896 PRE_MEM_READ( "pselect6(timeout)", ARG5,
1897 sizeof(struct vki_timespec) );
1900 if (ARG6 != 0) {
1901 const struct pselect_sized_sigset *pss =
1902 (struct pselect_sized_sigset *)(Addr)ARG6;
1903 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1904 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1905 ARG6 = 1; /* Something recognisable to POST() hook. */
1906 } else {
1907 struct pselect_adjusted_sigset *pas;
1908 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1909 ARG6 = (Addr)pas;
1910 pas->ss.ss = (void *)1;
1911 pas->ss.ss_len = pss->ss_len;
1912 if (pss->ss_len == sizeof(*pss->ss)) {
1913 if (pss->ss == NULL) {
1914 pas->ss.ss = NULL;
1915 } else {
1916 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1917 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1918 pas->adjusted_ss = *pss->ss;
1919 pas->ss.ss = &pas->adjusted_ss;
1920 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1928 PRE(sys_pselect6)
1930 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1931 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1932 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1933 pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
1936 POST(sys_pselect6)
1938 if (ARG6 != 0 && ARG6 != 1) {
1939 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1943 PRE(sys_pselect6_time64)
1945 PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1946 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1947 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1948 pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
1951 POST(sys_pselect6_time64)
1953 if (ARG6 != 0 && ARG6 != 1) {
1954 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1958 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1959 SyscallArgs* arrghs, SyscallStatus* status,
1960 UWord* flags, Bool is_time64 )
1962 UInt i;
1963 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1964 *flags |= SfMayBlock | SfPostOnFail;
1965 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1966 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1967 ARG1, ARG2, ARG3, ARG4, ARG5);
1968 if (is_time64) {
1969 PRE_REG_READ5(long, "ppoll_time64",
1970 struct vki_pollfd *, ufds, unsigned int, nfds,
1971 struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
1972 vki_size_t, sigsetsize);
1973 } else {
1974 PRE_REG_READ5(long, "ppoll",
1975 struct vki_pollfd *, ufds, unsigned int, nfds,
1976 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1977 vki_size_t, sigsetsize);
1980 for (i = 0; i < ARG2; i++) {
1981 PRE_MEM_READ( "ppoll(ufds.fd)",
1982 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1983 PRE_MEM_READ( "ppoll(ufds.events)",
1984 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1985 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1986 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1989 if (ARG3) {
1990 if (is_time64) {
1991 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
1992 } else {
1993 PRE_MEM_READ( "ppoll(tsp)", ARG3,
1994 sizeof(struct vki_timespec) );
1997 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1998 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1999 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
2000 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
2001 ARG4 = 1; /* Something recognisable to POST() hook. */
2002 } else {
2003 vki_sigset_t *vg_sigmask =
2004 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
2005 ARG4 = (Addr)vg_sigmask;
2006 *vg_sigmask = *guest_sigmask;
2007 VG_(sanitize_client_sigmask)(vg_sigmask);
2012 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2013 SyscallStatus* status )
2015 vg_assert(SUCCESS || FAILURE);
2016 if (SUCCESS && (RES >= 0)) {
2017 UInt i;
2018 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2019 for (i = 0; i < ARG2; i++)
2020 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2022 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
2023 VG_(free)((vki_sigset_t *) (Addr)ARG4);
2027 PRE(sys_ppoll)
2029 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2030 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2031 ARG1, ARG2, ARG3, ARG4, ARG5);
2032 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2035 POST(sys_ppoll)
2037 ppoll_post_helper (tid, arrghs, status);
2040 PRE(sys_ppoll_time64)
2042 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2043 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2044 ARG1, ARG2, ARG3, ARG4, ARG5);
2045 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2048 POST(sys_ppoll_time64)
2050 ppoll_post_helper (tid, arrghs, status);
2054 /* ---------------------------------------------------------------------
2055 epoll_* wrappers
2056 ------------------------------------------------------------------ */
2058 PRE(sys_epoll_create)
2060 PRINT("sys_epoll_create ( %ld )", SARG1);
2061 PRE_REG_READ1(long, "epoll_create", int, size);
2063 POST(sys_epoll_create)
2065 vg_assert(SUCCESS);
2066 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2067 VG_(close)(RES);
2068 SET_STATUS_Failure( VKI_EMFILE );
2069 } else {
2070 if (VG_(clo_track_fds))
2071 ML_(record_fd_open_nameless) (tid, RES);
2075 PRE(sys_epoll_create1)
2077 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2078 PRE_REG_READ1(long, "epoll_create1", int, flags);
2080 POST(sys_epoll_create1)
2082 vg_assert(SUCCESS);
2083 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2084 VG_(close)(RES);
2085 SET_STATUS_Failure( VKI_EMFILE );
2086 } else {
2087 if (VG_(clo_track_fds))
2088 ML_(record_fd_open_nameless) (tid, RES);
2092 PRE(sys_epoll_ctl)
2094 static const HChar* epoll_ctl_s[3] = {
2095 "EPOLL_CTL_ADD",
2096 "EPOLL_CTL_DEL",
2097 "EPOLL_CTL_MOD"
2099 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2100 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2101 PRE_REG_READ4(long, "epoll_ctl",
2102 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2103 if (ARG2 != VKI_EPOLL_CTL_DEL) {
2104 /* Just check the events field, the data field is for user space and
2105 unused by the kernel. */
2106 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2107 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2108 sizeof(__vki_u32) );
2112 /* RES event records have been written (exclude padding). */
2113 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2114 SyscallStatus* status )
2116 vg_assert(SUCCESS);
2117 if (RES > 0) {
2118 Int i;
2119 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2120 for (i = 0; i < RES; i++) {
2121 /* Assume both events and data are set (data is user space only). */
2122 POST_FIELD_WRITE(events[i].events);
2123 POST_FIELD_WRITE(events[i].data);
2128 PRE(sys_epoll_wait)
2130 *flags |= SfMayBlock;
2131 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2132 SARG1, ARG2, SARG3, SARG4);
2133 PRE_REG_READ4(long, "epoll_wait",
2134 int, epfd, struct vki_epoll_event *, events,
2135 int, maxevents, int, timeout);
2136 /* Assume all (maxevents) events records should be (fully) writable. */
2137 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2139 POST(sys_epoll_wait)
2141 epoll_post_helper (tid, arrghs, status);
2144 PRE(sys_epoll_pwait)
2146 *flags |= SfMayBlock;
2147 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2148 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2149 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2150 PRE_REG_READ6(long, "epoll_pwait",
2151 int, epfd, struct vki_epoll_event *, events,
2152 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2153 vki_size_t, sigsetsize);
2154 /* Assume all (maxevents) events records should be (fully) writable. */
2155 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2156 if (ARG5)
2157 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2159 POST(sys_epoll_pwait)
2161 epoll_post_helper (tid, arrghs, status);
2164 PRE(sys_eventfd)
2166 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2167 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2169 POST(sys_eventfd)
2171 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2172 VG_(close)(RES);
2173 SET_STATUS_Failure( VKI_EMFILE );
2174 } else {
2175 if (VG_(clo_track_fds))
2176 ML_(record_fd_open_nameless) (tid, RES);
2180 PRE(sys_eventfd2)
2182 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2183 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2185 POST(sys_eventfd2)
2187 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2188 VG_(close)(RES);
2189 SET_STATUS_Failure( VKI_EMFILE );
2190 } else {
2191 if (VG_(clo_track_fds))
2192 ML_(record_fd_open_nameless) (tid, RES);
2196 PRE(sys_fallocate)
2198 *flags |= SfMayBlock;
2199 #if VG_WORDSIZE == 4
2200 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2201 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2202 PRE_REG_READ6(long, "fallocate",
2203 int, fd, int, mode,
2204 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2205 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2206 #elif VG_WORDSIZE == 8
2207 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2208 SARG1, SARG2, SARG3, SARG4);
2209 PRE_REG_READ4(long, "fallocate",
2210 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2211 #else
2212 # error Unexpected word size
2213 #endif
2214 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2215 SET_STATUS_Failure( VKI_EBADF );
2218 PRE(sys_prlimit64)
2220 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2221 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2222 PRE_REG_READ4(long, "prlimit64",
2223 vki_pid_t, pid, unsigned int, resource,
2224 const struct rlimit64 *, new_rlim,
2225 struct rlimit64 *, old_rlim);
2226 if (ARG3)
2227 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2228 if (ARG4)
2229 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2231 if (ARG3 &&
2232 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2233 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2234 SET_STATUS_Failure( VKI_EINVAL );
2236 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2237 switch (ARG2) {
2238 case VKI_RLIMIT_NOFILE:
2239 SET_STATUS_Success( 0 );
2240 if (ARG4) {
2241 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2242 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2244 if (ARG3) {
2245 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2246 > VG_(fd_hard_limit) ||
2247 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2248 != VG_(fd_hard_limit)) {
2249 SET_STATUS_Failure( VKI_EPERM );
2251 else {
2252 VG_(fd_soft_limit) =
2253 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2256 break;
2258 case VKI_RLIMIT_DATA:
2259 SET_STATUS_Success( 0 );
2260 if (ARG4) {
2261 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2262 VG_(client_rlimit_data).rlim_cur;
2263 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2264 VG_(client_rlimit_data).rlim_max;
2266 if (ARG3) {
2267 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2268 > VG_(client_rlimit_data).rlim_max ||
2269 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2270 > VG_(client_rlimit_data).rlim_max) {
2271 SET_STATUS_Failure( VKI_EPERM );
2273 else {
2274 VG_(client_rlimit_data).rlim_cur =
2275 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2276 VG_(client_rlimit_data).rlim_max =
2277 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2280 break;
2282 case VKI_RLIMIT_STACK:
2283 SET_STATUS_Success( 0 );
2284 if (ARG4) {
2285 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2286 VG_(client_rlimit_stack).rlim_cur;
2287 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2288 VG_(client_rlimit_stack).rlim_max;
2290 if (ARG3) {
2291 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2292 > VG_(client_rlimit_stack).rlim_max ||
2293 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2294 > VG_(client_rlimit_stack).rlim_max) {
2295 SET_STATUS_Failure( VKI_EPERM );
2297 else {
2298 VG_(threads)[tid].client_stack_szB =
2299 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2300 VG_(client_rlimit_stack).rlim_cur =
2301 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2302 VG_(client_rlimit_stack).rlim_max =
2303 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2306 break;
2311 POST(sys_prlimit64)
2313 if (ARG4)
2314 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2317 /* ---------------------------------------------------------------------
2318 tid-related wrappers
2319 ------------------------------------------------------------------ */
2321 PRE(sys_gettid)
2323 PRINT("sys_gettid ()");
2324 PRE_REG_READ0(long, "gettid");
2327 PRE(sys_set_tid_address)
2329 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2330 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2333 PRE(sys_tkill)
2335 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2336 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2337 if (!ML_(client_signal_OK)(ARG2)) {
2338 SET_STATUS_Failure( VKI_EINVAL );
2339 return;
2342 /* Check to see if this kill gave us a pending signal */
2343 *flags |= SfPollAfter;
2345 if (VG_(clo_trace_signals))
2346 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2347 SARG2, SARG1);
2349 /* If we're sending SIGKILL, check to see if the target is one of
2350 our threads and handle it specially. */
2351 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2352 SET_STATUS_Success(0);
2353 return;
2356 /* Ask to handle this syscall via the slow route, since that's the
2357 only one that sets tst->status to VgTs_WaitSys. If the result
2358 of doing the syscall is an immediate run of
2359 async_signalhandler() in m_signals, then we need the thread to
2360 be properly tidied away. I have the impression the previous
2361 version of this wrapper worked on x86/amd64 only because the
2362 kernel did not immediately deliver the async signal to this
2363 thread (on ppc it did, which broke the assertion re tst->status
2364 at the top of async_signalhandler()). */
2365 *flags |= SfMayBlock;
2367 POST(sys_tkill)
2369 if (VG_(clo_trace_signals))
2370 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2371 SARG2, SARG1);
2374 PRE(sys_tgkill)
2376 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2377 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2378 if (!ML_(client_signal_OK)(ARG3)) {
2379 SET_STATUS_Failure( VKI_EINVAL );
2380 return;
2383 /* Check to see if this kill gave us a pending signal */
2384 *flags |= SfPollAfter;
2386 if (VG_(clo_trace_signals))
2387 VG_(message)(Vg_DebugMsg,
2388 "tgkill: sending signal %ld to pid %ld/%ld\n",
2389 SARG3, SARG1, SARG2);
2391 /* If we're sending SIGKILL, check to see if the target is one of
2392 our threads and handle it specially. */
2393 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2394 SET_STATUS_Success(0);
2395 return;
2398 /* Ask to handle this syscall via the slow route, since that's the
2399 only one that sets tst->status to VgTs_WaitSys. If the result
2400 of doing the syscall is an immediate run of
2401 async_signalhandler() in m_signals, then we need the thread to
2402 be properly tidied away. I have the impression the previous
2403 version of this wrapper worked on x86/amd64 only because the
2404 kernel did not immediately deliver the async signal to this
2405 thread (on ppc it did, which broke the assertion re tst->status
2406 at the top of async_signalhandler()). */
2407 *flags |= SfMayBlock;
2409 POST(sys_tgkill)
2411 if (VG_(clo_trace_signals))
2412 VG_(message)(Vg_DebugMsg,
2413 "tgkill: sent signal %ld to pid %ld/%ld\n",
2414 SARG3, SARG1, SARG2);
2417 /* ---------------------------------------------------------------------
2418 fadvise64* wrappers
2419 ------------------------------------------------------------------ */
2421 PRE(sys_fadvise64)
2423 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2424 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2425 PRE_REG_READ5(long, "fadvise64",
2426 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2427 vki_size_t, len, int, advice);
2430 PRE(sys_fadvise64_64)
2432 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2433 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2434 PRE_REG_READ6(long, "fadvise64_64",
2435 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2436 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2439 /* ---------------------------------------------------------------------
2440 io_* wrappers
2441 ------------------------------------------------------------------ */
2443 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2444 // and this allows us to control exactly the code that gets run while
2445 // the padding is in place.
2447 PRE(sys_io_setup)
2449 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2450 PRE_REG_READ2(long, "io_setup",
2451 unsigned, nr_events, vki_aio_context_t *, ctxp);
2452 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2455 POST(sys_io_setup)
2457 SizeT size;
2458 struct vki_aio_ring *r;
2460 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2461 ARG1*sizeof(struct vki_io_event));
2462 r = *(struct vki_aio_ring **)(Addr)ARG2;
2463 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2465 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2466 VKI_PROT_READ | VKI_PROT_WRITE,
2467 VKI_MAP_ANONYMOUS, -1, 0 );
2469 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2472 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2473 // after the syscall. We must get 'size' from the aio_ring structure,
2474 // before the syscall, while the aio_ring structure still exists. (And we
2475 // know that we must look at the aio_ring structure because Tom inspected the
2476 // kernel and glibc sources to see what they do, yuk.)
2478 // XXX This segment can be implicitly unmapped when aio
2479 // file-descriptors are closed...
2480 PRE(sys_io_destroy)
2482 SizeT size = 0;
2484 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2485 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2487 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2488 // possible...
2489 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2490 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2491 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2492 r->nr*sizeof(struct vki_io_event));
2495 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2497 if (SUCCESS && RES == 0) {
2498 Bool d = VG_(am_notify_munmap)( ARG1, size );
2499 VG_TRACK( die_mem_munmap, ARG1, size );
2500 if (d)
2501 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2502 "PRE(sys_io_destroy)" );
2506 PRE(sys_io_getevents)
2508 *flags |= SfMayBlock;
2509 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2510 FMT_REGWORD "x )",
2511 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2512 PRE_REG_READ5(long, "io_getevents",
2513 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2514 struct io_event *, events,
2515 struct timespec *, timeout);
2516 if (ARG3 > 0)
2517 PRE_MEM_WRITE( "io_getevents(events)",
2518 ARG4, sizeof(struct vki_io_event)*ARG3 );
2519 if (ARG5 != 0)
2520 PRE_MEM_READ( "io_getevents(timeout)",
2521 ARG5, sizeof(struct vki_timespec));
2523 POST(sys_io_getevents)
2525 Int i;
2526 vg_assert(SUCCESS);
2527 if (RES > 0) {
2528 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2529 for (i = 0; i < RES; i++) {
2530 const struct vki_io_event *vev =
2531 ((struct vki_io_event *)(Addr)ARG4) + i;
2532 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2534 switch (cb->aio_lio_opcode) {
2535 case VKI_IOCB_CMD_PREAD:
2536 if (vev->result > 0)
2537 POST_MEM_WRITE( cb->aio_buf, vev->result );
2538 break;
2540 case VKI_IOCB_CMD_PWRITE:
2541 break;
2543 case VKI_IOCB_CMD_FSYNC:
2544 break;
2546 case VKI_IOCB_CMD_FDSYNC:
2547 break;
2549 case VKI_IOCB_CMD_PREADV:
2550 if (vev->result > 0) {
2551 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2552 Int remains = vev->result;
2553 Int j;
2555 for (j = 0; j < cb->aio_nbytes; j++) {
2556 Int nReadThisBuf = vec[j].iov_len;
2557 if (nReadThisBuf > remains) nReadThisBuf = remains;
2558 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2559 remains -= nReadThisBuf;
2560 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2563 break;
2565 case VKI_IOCB_CMD_PWRITEV:
2566 break;
2568 default:
2569 VG_(message)(Vg_DebugMsg,
2570 "Warning: unhandled io_getevents opcode: %u\n",
2571 cb->aio_lio_opcode);
2572 break;
2578 PRE(sys_io_submit)
2580 Int i, j;
2582 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2583 ARG1, SARG2, ARG3);
2584 PRE_REG_READ3(long, "io_submit",
2585 vki_aio_context_t, ctx_id, long, nr,
2586 struct iocb **, iocbpp);
2587 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2588 if (ARG3 != 0) {
2589 for (i = 0; i < ARG2; i++) {
2590 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2591 struct vki_iovec *iov;
2593 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2594 switch (cb->aio_lio_opcode) {
2595 case VKI_IOCB_CMD_PREAD:
2596 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2597 break;
2599 case VKI_IOCB_CMD_PWRITE:
2600 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2601 break;
2603 case VKI_IOCB_CMD_FSYNC:
2604 break;
2606 case VKI_IOCB_CMD_FDSYNC:
2607 break;
2609 case VKI_IOCB_CMD_PREADV:
2610 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2611 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2612 for (j = 0; j < cb->aio_nbytes; j++)
2613 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2614 break;
2616 case VKI_IOCB_CMD_PWRITEV:
2617 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2618 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2619 for (j = 0; j < cb->aio_nbytes; j++)
2620 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2621 break;
2623 default:
2624 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2625 cb->aio_lio_opcode);
2626 break;
2632 PRE(sys_io_cancel)
2634 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2635 (ULong)ARG1, ARG2, ARG3);
2636 PRE_REG_READ3(long, "io_cancel",
2637 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2638 struct io_event *, result);
2639 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2640 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2642 POST(sys_io_cancel)
2644 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2647 /* ---------------------------------------------------------------------
2648 *_mempolicy wrappers
2649 ------------------------------------------------------------------ */
2651 PRE(sys_mbind)
2653 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2654 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2655 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2656 PRE_REG_READ6(long, "mbind",
2657 unsigned long, start, unsigned long, len,
2658 unsigned long, policy, unsigned long *, nodemask,
2659 unsigned long, maxnode, unsigned, flags);
2660 if (ARG1 != 0)
2661 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2662 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2665 PRE(sys_set_mempolicy)
2667 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2668 SARG1, ARG2, ARG3);
2669 PRE_REG_READ3(long, "set_mempolicy",
2670 int, policy, unsigned long *, nodemask,
2671 unsigned long, maxnode);
2672 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2673 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2676 PRE(sys_get_mempolicy)
2678 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2679 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2680 ARG1, ARG2, ARG3, ARG4, ARG5);
2681 PRE_REG_READ5(long, "get_mempolicy",
2682 int *, policy, unsigned long *, nodemask,
2683 unsigned long, maxnode, unsigned long, addr,
2684 unsigned long, flags);
2685 if (ARG1 != 0)
2686 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2687 if (ARG2 != 0)
2688 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2689 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2691 POST(sys_get_mempolicy)
2693 if (ARG1 != 0)
2694 POST_MEM_WRITE( ARG1, sizeof(Int) );
2695 if (ARG2 != 0)
2696 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2699 /* ---------------------------------------------------------------------
2700 fanotify_* wrappers
2701 ------------------------------------------------------------------ */
2703 PRE(sys_fanotify_init)
2705 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2706 ARG1, ARG2);
2707 PRE_REG_READ2(long, "fanotify_init",
2708 unsigned int, flags, unsigned int, event_f_flags);
2711 POST(sys_fanotify_init)
2713 vg_assert(SUCCESS);
2714 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2715 VG_(close)(RES);
2716 SET_STATUS_Failure( VKI_EMFILE );
2717 } else {
2718 if (VG_(clo_track_fds))
2719 ML_(record_fd_open_nameless) (tid, RES);
2723 PRE(sys_fanotify_mark)
2725 #if VG_WORDSIZE == 4
2726 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2727 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2728 (HChar *)(Addr)ARG6);
2729 PRE_REG_READ6(long, "sys_fanotify_mark",
2730 int, fanotify_fd, unsigned int, flags,
2731 __vki_u32, mask0, __vki_u32, mask1,
2732 int, dfd, const char *, pathname);
2733 if (ARG6)
2734 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2735 #elif VG_WORDSIZE == 8
2736 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2737 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2738 PRE_REG_READ5(long, "sys_fanotify_mark",
2739 int, fanotify_fd, unsigned int, flags,
2740 __vki_u64, mask,
2741 int, dfd, const char *, pathname);
2742 if (ARG5)
2743 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2744 #else
2745 # error Unexpected word size
2746 #endif
2749 /* ---------------------------------------------------------------------
2750 inotify_* wrappers
2751 ------------------------------------------------------------------ */
2753 PRE(sys_inotify_init)
2755 PRINT("sys_inotify_init ( )");
2756 PRE_REG_READ0(long, "inotify_init");
2758 POST(sys_inotify_init)
2760 vg_assert(SUCCESS);
2761 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2762 VG_(close)(RES);
2763 SET_STATUS_Failure( VKI_EMFILE );
2764 } else {
2765 if (VG_(clo_track_fds))
2766 ML_(record_fd_open_nameless) (tid, RES);
2770 PRE(sys_inotify_init1)
2772 PRINT("sys_inotify_init ( %ld )", SARG1);
2773 PRE_REG_READ1(long, "inotify_init", int, flag);
2776 POST(sys_inotify_init1)
2778 vg_assert(SUCCESS);
2779 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2780 VG_(close)(RES);
2781 SET_STATUS_Failure( VKI_EMFILE );
2782 } else {
2783 if (VG_(clo_track_fds))
2784 ML_(record_fd_open_nameless) (tid, RES);
2788 PRE(sys_inotify_add_watch)
2790 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2791 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2792 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2793 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2796 PRE(sys_inotify_rm_watch)
2798 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2799 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2802 /* ---------------------------------------------------------------------
2803 mq_* wrappers
2804 ------------------------------------------------------------------ */
2806 PRE(sys_mq_open)
2808 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2809 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2810 PRE_REG_READ4(long, "mq_open",
2811 const char *, name, int, oflag, vki_mode_t, mode,
2812 struct mq_attr *, attr);
2813 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2814 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2815 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2816 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2817 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2818 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2819 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2822 POST(sys_mq_open)
2824 vg_assert(SUCCESS);
2825 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2826 VG_(close)(RES);
2827 SET_STATUS_Failure( VKI_EMFILE );
2828 } else {
2829 if (VG_(clo_track_fds))
2830 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2834 PRE(sys_mq_unlink)
2836 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2837 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2838 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2841 PRE(sys_mq_timedsend)
2843 *flags |= SfMayBlock;
2844 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2845 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2846 SARG1,ARG2,ARG3,ARG4,ARG5);
2847 PRE_REG_READ5(long, "mq_timedsend",
2848 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2849 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2850 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2851 SET_STATUS_Failure( VKI_EBADF );
2852 } else {
2853 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2854 if (ARG5 != 0)
2855 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2856 sizeof(struct vki_timespec) );
2860 PRE(sys_mq_timedsend_time64)
2862 *flags |= SfMayBlock;
2863 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2864 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2865 SARG1,ARG2,ARG3,ARG4,ARG5);
2866 PRE_REG_READ5(long, "mq_timedsend_time64",
2867 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2868 unsigned int, msg_prio,
2869 const struct vki_timespec64 *, abs_timeout);
2870 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2871 SET_STATUS_Failure( VKI_EBADF );
2872 } else {
2873 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2874 if (ARG5 != 0)
2875 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2879 PRE(sys_mq_timedreceive)
2881 *flags |= SfMayBlock;
2882 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2883 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2884 SARG1,ARG2,ARG3,ARG4,ARG5);
2885 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2886 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2887 unsigned int *, msg_prio,
2888 const struct timespec *, abs_timeout);
2889 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2890 SET_STATUS_Failure( VKI_EBADF );
2891 } else {
2892 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2893 if (ARG4 != 0)
2894 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2895 ARG4, sizeof(unsigned int) );
2896 if (ARG5 != 0)
2897 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2898 ARG5, sizeof(struct vki_timespec) );
2901 POST(sys_mq_timedreceive)
2903 POST_MEM_WRITE( ARG2, RES );
2904 if (ARG4 != 0)
2905 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2908 PRE(sys_mq_timedreceive_time64)
2910 *flags |= SfMayBlock;
2911 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2912 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2913 SARG1,ARG2,ARG3,ARG4,ARG5);
2914 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2915 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2916 unsigned int *, msg_prio,
2917 const struct vki_timespec64 *, abs_timeout);
2918 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2919 SET_STATUS_Failure( VKI_EBADF );
2920 } else {
2921 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2922 if (ARG4 != 0)
2923 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2924 ARG4, sizeof(unsigned int) );
2925 if (ARG5 != 0)
2926 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2930 POST(sys_mq_timedreceive_time64)
2932 POST_MEM_WRITE( ARG2, RES );
2933 if (ARG4 != 0)
2934 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2937 PRE(sys_mq_notify)
2939 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2940 PRE_REG_READ2(long, "mq_notify",
2941 vki_mqd_t, mqdes, const struct sigevent *, notification);
2942 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2943 SET_STATUS_Failure( VKI_EBADF );
2944 else if (ARG2 != 0)
2945 PRE_MEM_READ( "mq_notify(notification)",
2946 ARG2, sizeof(struct vki_sigevent) );
2949 PRE(sys_mq_getsetattr)
2951 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2952 SARG1, ARG2, ARG3 );
2953 PRE_REG_READ3(long, "mq_getsetattr",
2954 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2955 struct mq_attr *, omqstat);
2956 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2957 SET_STATUS_Failure( VKI_EBADF );
2958 } else {
2959 if (ARG2 != 0) {
2960 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2961 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2962 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2964 if (ARG3 != 0)
2965 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2966 sizeof(struct vki_mq_attr) );
2969 POST(sys_mq_getsetattr)
2971 if (ARG3 != 0)
2972 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2975 /* ---------------------------------------------------------------------
2976 clock_* wrappers
2977 ------------------------------------------------------------------ */
2979 PRE(sys_clock_settime)
2981 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2982 PRE_REG_READ2(long, "clock_settime",
2983 vki_clockid_t, clk_id, const struct timespec *, tp);
2984 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2987 PRE(sys_clock_settime64)
2989 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2990 PRE_REG_READ2(long, "clock_settime64",
2991 vki_clockid_t, clk_id, const struct timespec64 *, tp);
2992 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
2995 PRE(sys_clock_gettime)
2997 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2998 PRE_REG_READ2(long, "clock_gettime",
2999 vki_clockid_t, clk_id, struct timespec *, tp);
3000 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3002 POST(sys_clock_gettime)
3004 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3007 PRE(sys_clock_gettime64)
3009 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3010 PRE_REG_READ2(long, "clock_gettime64",
3011 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3012 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3013 sizeof(struct vki_timespec64) );
3015 POST(sys_clock_gettime64)
3017 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3020 PRE(sys_clock_getres)
3022 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3023 // Nb: we can't use "RES" as the param name because that's a macro
3024 // defined above!
3025 PRE_REG_READ2(long, "clock_getres",
3026 vki_clockid_t, clk_id, struct timespec *, res);
3027 if (ARG2 != 0)
3028 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3030 POST(sys_clock_getres)
3032 if (ARG2 != 0)
3033 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3036 PRE(sys_clock_getres_time64)
3038 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3039 // Nb: we can't use "RES" as the param name because that's a macro
3040 // defined above!
3041 PRE_REG_READ2(long, "clock_getres_time64",
3042 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3043 if (ARG2 != 0)
3044 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3045 sizeof(struct vki_timespec64) );
3047 POST(sys_clock_getres_time64)
3049 if (ARG2 != 0)
3050 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3053 PRE(sys_clock_nanosleep)
3055 *flags |= SfMayBlock|SfPostOnFail;
3056 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3057 FMT_REGWORD "x )",
3058 SARG1, SARG2, ARG3, ARG4);
3059 PRE_REG_READ4(int32_t, "clock_nanosleep",
3060 vki_clockid_t, clkid, int, flags,
3061 const struct timespec *, rqtp, struct timespec *, rmtp);
3062 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3063 if (ARG4 != 0)
3064 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3066 POST(sys_clock_nanosleep)
3068 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3069 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3072 PRE(sys_clock_nanosleep_time64)
3074 *flags |= SfMayBlock|SfPostOnFail;
3075 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3076 FMT_REGWORD "x )",
3077 SARG1, SARG2, ARG3, ARG4);
3078 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3079 vki_clockid_t, clkid, int, flags,
3080 const struct vki_timespec64 *, rqtp,
3081 struct vki_timespec64 *, rmtp);
3082 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3083 if (ARG4 != 0)
3084 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3085 sizeof(struct vki_timespec64) );
3087 POST(sys_clock_nanosleep_time64)
3089 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3090 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3093 /* ---------------------------------------------------------------------
3094 timer_* wrappers
3095 ------------------------------------------------------------------ */
3097 PRE(sys_timer_create)
3099 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3100 SARG1, ARG2, ARG3);
3101 PRE_REG_READ3(long, "timer_create",
3102 vki_clockid_t, clockid, struct sigevent *, evp,
3103 vki_timer_t *, timerid);
3104 if (ARG2 != 0) {
3105 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3106 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3107 sizeof(vki_sigval_t) );
3108 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3109 sizeof(int) );
3110 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3111 sizeof(int) );
3112 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3113 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3114 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3115 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3117 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3119 POST(sys_timer_create)
3121 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3124 PRE(sys_timer_settime)
3126 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3127 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3128 PRE_REG_READ4(long, "timer_settime",
3129 vki_timer_t, timerid, int, flags,
3130 const struct itimerspec *, value,
3131 struct itimerspec *, ovalue);
3132 PRE_MEM_READ( "timer_settime(value)", ARG3,
3133 sizeof(struct vki_itimerspec) );
3134 if (ARG4 != 0)
3135 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3136 sizeof(struct vki_itimerspec) );
3138 POST(sys_timer_settime)
3140 if (ARG4 != 0)
3141 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3144 PRE(sys_timer_settime64)
3146 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3147 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3148 PRE_REG_READ4(long, "timer_settime64",
3149 vki_timer_t, timerid, int, flags,
3150 const struct vki_itimerspec64 *, value,
3151 struct vki_itimerspec64 *, ovalue);
3152 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3153 sizeof(struct vki_itimerspec64) );
3154 if (ARG4 != 0)
3155 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3156 sizeof(struct vki_itimerspec64) );
3158 POST(sys_timer_settime64)
3160 if (ARG4 != 0)
3161 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3164 PRE(sys_timer_gettime)
3166 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3167 PRE_REG_READ2(long, "timer_gettime",
3168 vki_timer_t, timerid, struct itimerspec *, value);
3169 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3170 sizeof(struct vki_itimerspec));
3172 POST(sys_timer_gettime)
3174 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3177 PRE(sys_timer_gettime64)
3179 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3180 PRE_REG_READ2(long, "timer_gettime64",
3181 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3182 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3183 sizeof(struct vki_itimerspec64));
3185 POST(sys_timer_gettime64)
3187 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3190 PRE(sys_timer_getoverrun)
3192 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3193 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3196 PRE(sys_timer_delete)
3198 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3199 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3202 /* ---------------------------------------------------------------------
3203 timerfd* wrappers
3204 See also http://lwn.net/Articles/260172/ for an overview.
3205 See also /usr/src/linux/fs/timerfd.c for the implementation.
3206 ------------------------------------------------------------------ */
3208 /* Returns True if running on 2.6.22, else False (or False if
3209 cannot be determined). */
3210 static Bool linux_kernel_2_6_22(void)
3212 static Int result = -1;
3213 Int fd, read;
3214 HChar release[64]; // large enough
3215 SysRes res;
3217 if (result == -1) {
3218 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3219 if (sr_isError(res))
3220 return False;
3221 fd = sr_Res(res);
3222 read = VG_(read)(fd, release, sizeof(release) - 1);
3223 if (read < 0)
3224 return False;
3225 release[read] = 0;
3226 VG_(close)(fd);
3227 //VG_(printf)("kernel release = %s\n", release);
3228 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3229 && ! VG_(isdigit)(release[6]);
3231 vg_assert(result == 0 || result == 1);
3232 return result == 1;
3235 PRE(sys_timerfd_create)
3237 if (linux_kernel_2_6_22()) {
3238 /* 2.6.22 kernel: timerfd system call. */
3239 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3240 PRE_REG_READ3(long, "sys_timerfd",
3241 int, fd, int, clockid, const struct itimerspec *, tmr);
3242 PRE_MEM_READ("timerfd(tmr)", ARG3,
3243 sizeof(struct vki_itimerspec) );
3244 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3245 SET_STATUS_Failure( VKI_EBADF );
3246 } else {
3247 /* 2.6.24 and later kernels: timerfd_create system call. */
3248 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3249 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3252 POST(sys_timerfd_create)
3254 if (linux_kernel_2_6_22())
3256 /* 2.6.22 kernel: timerfd system call. */
3257 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3258 VG_(close)(RES);
3259 SET_STATUS_Failure( VKI_EMFILE );
3260 } else {
3261 if (VG_(clo_track_fds))
3262 ML_(record_fd_open_nameless) (tid, RES);
3265 else
3267 /* 2.6.24 and later kernels: timerfd_create system call. */
3268 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3269 VG_(close)(RES);
3270 SET_STATUS_Failure( VKI_EMFILE );
3271 } else {
3272 if (VG_(clo_track_fds))
3273 ML_(record_fd_open_nameless) (tid, RES);
3278 PRE(sys_timerfd_gettime)
3280 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3281 PRE_REG_READ2(long, "timerfd_gettime",
3282 int, ufd,
3283 struct vki_itimerspec*, otmr);
3284 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3285 SET_STATUS_Failure(VKI_EBADF);
3286 else
3287 PRE_MEM_WRITE("timerfd_gettime(result)",
3288 ARG2, sizeof(struct vki_itimerspec));
3290 POST(sys_timerfd_gettime)
3292 if (RES == 0)
3293 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3296 PRE(sys_timerfd_gettime64)
3298 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3299 PRE_REG_READ2(long, "timerfd_gettime64",
3300 int, ufd,
3301 struct vki_itimerspec64*, otmr);
3302 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3303 SET_STATUS_Failure(VKI_EBADF);
3304 else
3305 PRE_MEM_WRITE("timerfd_gettime64(result)",
3306 ARG2, sizeof(struct vki_itimerspec64));
3308 POST(sys_timerfd_gettime64)
3310 if (RES == 0)
3311 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3314 PRE(sys_timerfd_settime)
3316 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3317 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3318 PRE_REG_READ4(long, "timerfd_settime",
3319 int, ufd,
3320 int, flags,
3321 const struct vki_itimerspec*, utmr,
3322 struct vki_itimerspec*, otmr);
3323 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3324 SET_STATUS_Failure(VKI_EBADF);
3325 else
3327 PRE_MEM_READ("timerfd_settime(result)",
3328 ARG3, sizeof(struct vki_itimerspec));
3329 if (ARG4)
3331 PRE_MEM_WRITE("timerfd_settime(result)",
3332 ARG4, sizeof(struct vki_itimerspec));
3336 POST(sys_timerfd_settime)
3338 if (RES == 0 && ARG4 != 0)
3339 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3342 PRE(sys_timerfd_settime64)
3344 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3345 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3346 PRE_REG_READ4(long, "timerfd_settime64",
3347 int, ufd,
3348 int, flags,
3349 const struct vki_itimerspec64*, utmr,
3350 struct vki_itimerspec64*, otmr);
3351 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3352 SET_STATUS_Failure(VKI_EBADF);
3353 else
3355 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3356 if (ARG4)
3358 PRE_MEM_WRITE("timerfd_settime64(result)",
3359 ARG4, sizeof(struct vki_itimerspec64));
3363 POST(sys_timerfd_settime64)
3365 if (RES == 0 && ARG4 != 0)
3366 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3369 /* ---------------------------------------------------------------------
3370 capabilities wrappers
3371 ------------------------------------------------------------------ */
3373 PRE(sys_capget)
3375 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3376 PRE_REG_READ2(long, "capget",
3377 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3378 PRE_MEM_READ( "capget(header)", ARG1,
3379 sizeof(struct __vki_user_cap_header_struct) );
3380 if (ARG2 != (Addr)NULL)
3381 PRE_MEM_WRITE( "capget(data)", ARG2,
3382 sizeof(struct __vki_user_cap_data_struct) );
3384 POST(sys_capget)
3386 if (ARG2 != (Addr)NULL)
3387 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3390 PRE(sys_capset)
3392 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3393 PRE_REG_READ2(long, "capset",
3394 vki_cap_user_header_t, header,
3395 const vki_cap_user_data_t, data);
3396 PRE_MEM_READ( "capset(header)",
3397 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3398 PRE_MEM_READ( "capset(data)",
3399 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3402 /* ---------------------------------------------------------------------
3403 16-bit uid/gid/groups wrappers
3404 ------------------------------------------------------------------ */
3406 PRE(sys_getuid16)
3408 PRINT("sys_getuid16 ( )");
3409 PRE_REG_READ0(long, "getuid16");
3412 PRE(sys_setuid16)
3414 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3415 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3418 PRE(sys_getgid16)
3420 PRINT("sys_getgid16 ( )");
3421 PRE_REG_READ0(long, "getgid16");
3424 PRE(sys_setgid16)
3426 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3427 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3430 PRE(sys_geteuid16)
3432 PRINT("sys_geteuid16 ( )");
3433 PRE_REG_READ0(long, "geteuid16");
3436 PRE(sys_getegid16)
3438 PRINT("sys_getegid16 ( )");
3439 PRE_REG_READ0(long, "getegid16");
3442 PRE(sys_setreuid16)
3444 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3445 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3448 PRE(sys_setregid16)
3450 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3451 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3454 PRE(sys_getgroups16)
3456 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3457 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3458 if (ARG1 > 0)
3459 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3461 POST(sys_getgroups16)
3463 vg_assert(SUCCESS);
3464 if (ARG1 > 0 && RES > 0)
3465 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3468 PRE(sys_setgroups16)
3470 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3471 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3472 if (ARG1 > 0)
3473 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3476 /* ---------------------------------------------------------------------
3477 *chown16 wrappers
3478 ------------------------------------------------------------------ */
3480 PRE(sys_chown16)
3482 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3483 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3484 PRE_REG_READ3(long, "chown16",
3485 const char *, path,
3486 vki_old_uid_t, owner, vki_old_gid_t, group);
3487 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3490 PRE(sys_fchown16)
3492 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3493 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3494 PRE_REG_READ3(long, "fchown16",
3495 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3498 /* ---------------------------------------------------------------------
3499 *xattr wrappers
3500 ------------------------------------------------------------------ */
3502 PRE(sys_setxattr)
3504 *flags |= SfMayBlock;
3505 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3506 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3507 ARG4, SARG5);
3508 PRE_REG_READ5(long, "setxattr",
3509 char *, path, char *, name,
3510 void *, value, vki_size_t, size, int, flags);
3511 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3512 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3513 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3516 PRE(sys_lsetxattr)
3518 *flags |= SfMayBlock;
3519 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3520 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3521 ARG1, ARG2, ARG3, ARG4, SARG5);
3522 PRE_REG_READ5(long, "lsetxattr",
3523 char *, path, char *, name,
3524 void *, value, vki_size_t, size, int, flags);
3525 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3526 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3527 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3530 PRE(sys_fsetxattr)
3532 *flags |= SfMayBlock;
3533 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3534 FMT_REGWORD "u, %ld )",
3535 SARG1, ARG2, ARG3, ARG4, SARG5);
3536 PRE_REG_READ5(long, "fsetxattr",
3537 int, fd, char *, name, void *, value,
3538 vki_size_t, size, int, flags);
3539 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3540 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3543 PRE(sys_getxattr)
3545 *flags |= SfMayBlock;
3546 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3547 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3548 PRE_REG_READ4(ssize_t, "getxattr",
3549 char *, path, char *, name, void *, value, vki_size_t, size);
3550 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3551 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3552 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3554 POST(sys_getxattr)
3556 vg_assert(SUCCESS);
3557 if (RES > 0 && ARG3 != (Addr)NULL) {
3558 POST_MEM_WRITE( ARG3, RES );
3562 PRE(sys_lgetxattr)
3564 *flags |= SfMayBlock;
3565 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3566 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3567 PRE_REG_READ4(ssize_t, "lgetxattr",
3568 char *, path, char *, name, void *, value, vki_size_t, size);
3569 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3570 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3571 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3573 POST(sys_lgetxattr)
3575 vg_assert(SUCCESS);
3576 if (RES > 0 && ARG3 != (Addr)NULL) {
3577 POST_MEM_WRITE( ARG3, RES );
3581 PRE(sys_fgetxattr)
3583 *flags |= SfMayBlock;
3584 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3585 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3586 PRE_REG_READ4(ssize_t, "fgetxattr",
3587 int, fd, char *, name, void *, value, vki_size_t, size);
3588 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3589 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3591 POST(sys_fgetxattr)
3593 if (RES > 0 && ARG3 != (Addr)NULL)
3594 POST_MEM_WRITE( ARG3, RES );
3597 PRE(sys_listxattr)
3599 *flags |= SfMayBlock;
3600 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3601 ARG1, ARG2, (ULong)ARG3);
3602 PRE_REG_READ3(ssize_t, "listxattr",
3603 char *, path, char *, list, vki_size_t, size);
3604 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3605 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3607 POST(sys_listxattr)
3609 if (RES > 0 && ARG2 != (Addr)NULL)
3610 POST_MEM_WRITE( ARG2, RES );
3613 PRE(sys_llistxattr)
3615 *flags |= SfMayBlock;
3616 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3617 ARG1, ARG2, (ULong)ARG3);
3618 PRE_REG_READ3(ssize_t, "llistxattr",
3619 char *, path, char *, list, vki_size_t, size);
3620 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3621 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3623 POST(sys_llistxattr)
3625 if (RES > 0 && ARG2 != (Addr)NULL)
3626 POST_MEM_WRITE( ARG2, RES );
3629 PRE(sys_flistxattr)
3631 *flags |= SfMayBlock;
3632 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3633 SARG1, ARG2, ARG3);
3634 PRE_REG_READ3(ssize_t, "flistxattr",
3635 int, fd, char *, list, vki_size_t, size);
3636 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3638 POST(sys_flistxattr)
3640 if (RES > 0 && ARG2 != (Addr)NULL)
3641 POST_MEM_WRITE( ARG2, RES );
3644 PRE(sys_removexattr)
3646 *flags |= SfMayBlock;
3647 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3648 ARG1, ARG2);
3649 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3650 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3651 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3654 PRE(sys_lremovexattr)
3656 *flags |= SfMayBlock;
3657 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3658 ARG1, ARG2);
3659 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3660 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3661 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3664 PRE(sys_fremovexattr)
3666 *flags |= SfMayBlock;
3667 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3668 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3669 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3672 /* ---------------------------------------------------------------------
3673 sched_* wrappers
3674 ------------------------------------------------------------------ */
3676 PRE(sys_sched_setparam)
3678 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3679 PRE_REG_READ2(long, "sched_setparam",
3680 vki_pid_t, pid, struct sched_param *, p);
3681 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3683 POST(sys_sched_setparam)
3685 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3688 PRE(sys_sched_getparam)
3690 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3691 PRE_REG_READ2(long, "sched_getparam",
3692 vki_pid_t, pid, struct sched_param *, p);
3693 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3695 POST(sys_sched_getparam)
3697 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3700 PRE(sys_sched_setattr)
3702 struct vki_sched_attr *attr;
3703 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3704 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3705 PRE_REG_READ3(long, "sched_setattr",
3706 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3707 /* We need to be able to read at least the size field. */
3708 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3709 attr = (struct vki_sched_attr *)(Addr)ARG2;
3710 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3711 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3714 PRE(sys_sched_getattr)
3716 struct vki_sched_attr *attr;
3717 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3718 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3719 PRE_REG_READ4(long, "sched_getattr",
3720 vki_pid_t, pid, struct sched_attr *, p,
3721 unsigned int, size, unsigned int, flags);
3722 /* We need to be able to read at least the size field. */
3723 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3724 /* And the kernel needs to be able to write to the whole struct size. */
3725 attr = (struct vki_sched_attr *)(Addr)ARG2;
3726 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3727 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3729 POST(sys_sched_getattr)
3731 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3732 POST_MEM_WRITE( (Addr)attr, attr->size );
3735 PRE(sys_sched_getscheduler)
3737 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3738 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3741 PRE(sys_sched_setscheduler)
3743 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3744 SARG1, SARG2, ARG3);
3745 PRE_REG_READ3(long, "sched_setscheduler",
3746 vki_pid_t, pid, int, policy, struct sched_param *, p);
3747 if (ARG3 != 0)
3748 PRE_MEM_READ( "sched_setscheduler(p)",
3749 ARG3, sizeof(struct vki_sched_param));
3752 PRE(sys_sched_yield)
3754 *flags |= SfMayBlock;
3755 PRINT("sched_yield()");
3756 PRE_REG_READ0(long, "sys_sched_yield");
3759 PRE(sys_sched_get_priority_max)
3761 PRINT("sched_get_priority_max ( %ld )", SARG1);
3762 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3765 PRE(sys_sched_get_priority_min)
3767 PRINT("sched_get_priority_min ( %ld )", SARG1);
3768 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3771 PRE(sys_sched_rr_get_interval)
3773 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3774 PRE_REG_READ2(int, "sched_rr_get_interval",
3775 vki_pid_t, pid,
3776 struct vki_timespec *, tp);
3777 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3778 ARG2, sizeof(struct vki_timespec));
3781 POST(sys_sched_rr_get_interval)
3783 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3786 PRE(sys_sched_rr_get_interval_time64)
3788 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3789 SARG1, ARG2);
3790 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3791 vki_pid_t, pid,
3792 struct vki_timespec *, tp);
3793 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3794 ARG2, sizeof(struct vki_timespec64));
3797 POST(sys_sched_rr_get_interval_time64)
3799 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3802 PRE(sys_sched_setaffinity)
3804 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3805 SARG1, ARG2, ARG3);
3806 PRE_REG_READ3(long, "sched_setaffinity",
3807 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3808 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3811 PRE(sys_sched_getaffinity)
3813 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3814 SARG1, ARG2, ARG3);
3815 PRE_REG_READ3(long, "sched_getaffinity",
3816 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3817 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3819 POST(sys_sched_getaffinity)
3821 POST_MEM_WRITE(ARG3, ARG2);
3824 PRE(sys_unshare)
3826 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3827 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3830 PRE(sys_setns)
3832 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3833 PRE_REG_READ2(int, "setns",
3834 int, fd,
3835 int, nstype);
3836 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3837 SET_STATUS_Failure( VKI_EBADF );
3841 /* ---------------------------------------------------------------------
3842 miscellaneous wrappers
3843 ------------------------------------------------------------------ */
3845 PRE(sys_munlockall)
3847 *flags |= SfMayBlock;
3848 PRINT("sys_munlockall ( )");
3849 PRE_REG_READ0(long, "munlockall");
3852 // This has different signatures for different platforms.
3854 // x86: int sys_pipe(unsigned long __user *fildes);
3855 // AMD64: long sys_pipe(int *fildes);
3856 // ppc32: int sys_pipe(int __user *fildes);
3857 // ppc64: int sys_pipe(int __user *fildes);
3859 // The type of the argument is most important, and it is an array of 32 bit
3860 // values in all cases. (The return type differs across platforms, but it
3861 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3862 // was caused by using an array of 'unsigned long's, which didn't work on
3863 // AMD64.
3864 PRE(sys_pipe)
3866 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3867 PRE_REG_READ1(int, "pipe", int *, filedes);
3868 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3870 POST(sys_pipe)
3872 Int *p = (Int *)(Addr)ARG1;
3873 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3874 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3875 VG_(close)(p[0]);
3876 VG_(close)(p[1]);
3877 SET_STATUS_Failure( VKI_EMFILE );
3878 } else {
3879 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3880 if (VG_(clo_track_fds)) {
3881 ML_(record_fd_open_nameless)(tid, p[0]);
3882 ML_(record_fd_open_nameless)(tid, p[1]);
3887 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3888 there's a second arg containing flags to be applied to the new file
3889 descriptors. It hardly seems worth the effort to factor out the
3890 duplicated code, hence: */
3891 PRE(sys_pipe2)
3893 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3894 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3895 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3897 POST(sys_pipe2)
3899 Int *p = (Int *)(Addr)ARG1;
3900 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3901 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3902 VG_(close)(p[0]);
3903 VG_(close)(p[1]);
3904 SET_STATUS_Failure( VKI_EMFILE );
3905 } else {
3906 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3907 if (VG_(clo_track_fds)) {
3908 ML_(record_fd_open_nameless)(tid, p[0]);
3909 ML_(record_fd_open_nameless)(tid, p[1]);
3914 PRE(sys_dup3)
3916 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3917 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3918 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3919 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3920 SET_STATUS_Failure( VKI_EBADF );
3923 POST(sys_dup3)
3925 vg_assert(SUCCESS);
3926 if (VG_(clo_track_fds))
3927 ML_(record_fd_open_named)(tid, RES);
3930 PRE(sys_quotactl)
3932 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3933 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3934 PRE_REG_READ4(long, "quotactl",
3935 unsigned int, cmd, const char *, special, vki_qid_t, id,
3936 void *, addr);
3937 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3940 PRE(sys_waitid)
3942 *flags |= SfMayBlock;
3943 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3944 SARG1, SARG2, ARG3, SARG4, ARG5);
3945 PRE_REG_READ5(int32_t, "sys_waitid",
3946 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3947 int, options, struct vki_rusage *, ru);
3948 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3949 if (ARG5 != 0)
3950 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3952 POST(sys_waitid)
3954 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3955 if (ARG5 != 0)
3956 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3959 PRE(sys_sync_file_range)
3961 *flags |= SfMayBlock;
3962 #if VG_WORDSIZE == 4
3963 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3964 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3965 PRE_REG_READ6(long, "sync_file_range",
3966 int, fd,
3967 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3968 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3969 unsigned int, flags);
3970 #elif VG_WORDSIZE == 8
3971 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3972 SARG1, SARG2, SARG3, ARG4);
3973 PRE_REG_READ4(long, "sync_file_range",
3974 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3975 unsigned int, flags);
3976 #else
3977 # error Unexpected word size
3978 #endif
3979 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3980 SET_STATUS_Failure( VKI_EBADF );
3983 PRE(sys_sync_file_range2)
3985 *flags |= SfMayBlock;
3986 #if VG_WORDSIZE == 4
3987 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3988 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3989 PRE_REG_READ6(long, "sync_file_range2",
3990 int, fd, unsigned int, flags,
3991 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3992 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3993 #elif VG_WORDSIZE == 8
3994 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3995 SARG1, ARG2, SARG3, SARG4);
3996 PRE_REG_READ4(long, "sync_file_range2",
3997 int, fd, unsigned int, flags,
3998 vki_loff_t, offset, vki_loff_t, nbytes);
3999 #else
4000 # error Unexpected word size
4001 #endif
4002 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4003 SET_STATUS_Failure( VKI_EBADF );
4006 PRE(sys_stime)
4008 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4009 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4010 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4013 PRE(sys_perf_event_open)
4015 struct vki_perf_event_attr *attr;
4016 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4017 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4018 PRE_REG_READ5(long, "perf_event_open",
4019 struct vki_perf_event_attr *, attr,
4020 vki_pid_t, pid, int, cpu, int, group_fd,
4021 unsigned long, flags);
4022 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4023 PRE_MEM_READ( "perf_event_open(attr->size)",
4024 (Addr)&attr->size, sizeof(attr->size) );
4025 PRE_MEM_READ( "perf_event_open(attr)",
4026 (Addr)attr, attr->size );
4029 POST(sys_perf_event_open)
4031 vg_assert(SUCCESS);
4032 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4033 VG_(close)(RES);
4034 SET_STATUS_Failure( VKI_EMFILE );
4035 } else {
4036 if (VG_(clo_track_fds))
4037 ML_(record_fd_open_nameless)(tid, RES);
4041 PRE(sys_getcpu)
4043 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4044 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4045 PRE_REG_READ3(int, "getcpu",
4046 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4047 if (ARG1 != 0)
4048 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4049 if (ARG2 != 0)
4050 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4051 if (ARG3 != 0)
4052 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4055 POST(sys_getcpu)
4057 if (ARG1 != 0)
4058 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4059 if (ARG2 != 0)
4060 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4061 if (ARG3 != 0)
4062 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4065 PRE(sys_move_pages)
4067 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4068 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4069 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4070 PRE_REG_READ6(int, "move_pages",
4071 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4072 const int *, nodes, int *, status, int, flags);
4073 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4074 if (ARG4)
4075 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4076 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4079 POST(sys_move_pages)
4081 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4084 PRE(sys_getrandom)
4086 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4087 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4088 PRE_REG_READ3(int, "getrandom",
4089 char *, buf, vki_size_t, count, unsigned int, flags);
4090 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4093 POST(sys_getrandom)
4095 POST_MEM_WRITE( ARG1, ARG2 );
4098 PRE(sys_memfd_create)
4100 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4101 ARG1, ARG2);
4102 PRE_REG_READ2(int, "memfd_create",
4103 char *, uname, unsigned int, flags);
4104 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4107 POST(sys_memfd_create)
4109 vg_assert(SUCCESS);
4110 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4111 VG_(close)(RES);
4112 SET_STATUS_Failure( VKI_EMFILE );
4113 } else {
4114 if (VG_(clo_track_fds))
4115 ML_(record_fd_open_nameless)(tid, RES);
4119 PRE(sys_membarrier)
4121 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4122 PRE_REG_READ1(int, "membarrier", int, flags);
4125 PRE(sys_syncfs)
4127 *flags |= SfMayBlock;
4128 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4129 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4132 PRE(sys_statx)
4134 FUSE_COMPATIBLE_MAY_BLOCK();
4135 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4136 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4137 PRE_REG_READ5(long, "statx",
4138 int, dirfd, char *, filename, int, flags,
4139 unsigned int, mask, struct statx *, buf);
4140 // Work around Rust's dubious use of statx, as described here:
4141 // https://github.com/rust-lang/rust/blob/
4142 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4143 // src/libstd/sys/unix/fs.rs#L128-L142
4144 // in which it passes NULL for both filename and buf, and then looks at the
4145 // return value, so as to determine whether or not this syscall is supported.
4146 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4147 if (!both_filename_and_buf_are_null) {
4148 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4149 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4152 POST(sys_statx)
4154 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4157 /* ---------------------------------------------------------------------
4158 utime wrapper
4159 ------------------------------------------------------------------ */
4161 PRE(sys_utime)
4163 *flags |= SfMayBlock;
4164 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4165 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4166 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4167 if (ARG2 != 0)
4168 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4171 /* ---------------------------------------------------------------------
4172 lseek wrapper
4173 ------------------------------------------------------------------ */
4175 PRE(sys_lseek)
4177 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4178 ARG1, SARG2, ARG3);
4179 PRE_REG_READ3(vki_off_t, "lseek",
4180 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4183 /* ---------------------------------------------------------------------
4184 readahead wrapper
4185 ------------------------------------------------------------------ */
4187 PRE(sys_readahead)
4189 *flags |= SfMayBlock;
4190 #if VG_WORDSIZE == 4
4191 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4192 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4193 PRE_REG_READ4(vki_off_t, "readahead",
4194 int, fd, unsigned, MERGE64_FIRST(offset),
4195 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4196 #elif VG_WORDSIZE == 8
4197 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4198 PRE_REG_READ3(vki_off_t, "readahead",
4199 int, fd, vki_loff_t, offset, vki_size_t, count);
4200 #else
4201 # error Unexpected word size
4202 #endif
4203 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4204 SET_STATUS_Failure( VKI_EBADF );
4207 /* ---------------------------------------------------------------------
4208 sig* wrappers
4209 ------------------------------------------------------------------ */
4211 PRE(sys_sigpending)
4213 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4214 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4215 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4217 POST(sys_sigpending)
4219 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4222 // This syscall is not used on amd64/Linux -- it only provides
4223 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4224 // This wrapper is only suitable for 32-bit architectures.
4225 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4226 // conditional compilation like this?)
4227 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4228 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4229 || defined(VGP_nanomips_linux)
4230 PRE(sys_sigprocmask)
4232 vki_old_sigset_t* set;
4233 vki_old_sigset_t* oldset;
4234 vki_sigset_t bigger_set;
4235 vki_sigset_t bigger_oldset;
4237 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4238 PRE_REG_READ3(long, "sigprocmask",
4239 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4240 if (ARG2 != 0)
4241 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4242 if (ARG3 != 0)
4243 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4245 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4246 // vki_sigset_t params.
4247 set = (vki_old_sigset_t*)(Addr)ARG2;
4248 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4250 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4251 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4252 if (set)
4253 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4255 SET_STATUS_from_SysRes(
4256 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4257 set ? &bigger_set : NULL,
4258 oldset ? &bigger_oldset : NULL)
4261 if (oldset)
4262 *oldset = bigger_oldset.sig[0];
4264 if (SUCCESS)
4265 *flags |= SfPollAfter;
4267 POST(sys_sigprocmask)
4269 vg_assert(SUCCESS);
4270 if (RES == 0 && ARG3 != 0)
4271 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4274 /* Convert from non-RT to RT sigset_t's */
4275 static
4276 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4278 VG_(sigemptyset)(set);
4279 set->sig[0] = *oldset;
4281 PRE(sys_sigaction)
4283 vki_sigaction_toK_t new, *newp;
4284 vki_sigaction_fromK_t old, *oldp;
4286 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4287 PRE_REG_READ3(int, "sigaction",
4288 int, signum, const struct old_sigaction *, act,
4289 struct old_sigaction *, oldact);
4291 newp = oldp = NULL;
4293 if (ARG2 != 0) {
4294 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4295 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4296 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4297 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4298 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4299 && (sa->sa_flags & VKI_SA_RESTORER))
4300 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4303 if (ARG3 != 0) {
4304 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4305 oldp = &old;
4308 /* If the new or old sigaction is not NULL, but the structs
4309 aren't accessible then sigaction returns EFAULT and we cannot
4310 use either struct for our own bookkeeping. Just fail early. */
4311 if (ARG2 != 0
4312 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4313 sizeof(struct vki_old_sigaction))) {
4314 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4315 (void *)(Addr)ARG2);
4316 SET_STATUS_Failure ( VKI_EFAULT );
4317 } else if ((ARG3 != 0
4318 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4319 sizeof(struct vki_old_sigaction)))) {
4320 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4321 (void *)(Addr)ARG3);
4322 SET_STATUS_Failure ( VKI_EFAULT );
4323 } else {
4324 if (ARG2 != 0) {
4325 struct vki_old_sigaction *oldnew =
4326 (struct vki_old_sigaction *)(Addr)ARG2;
4328 new.ksa_handler = oldnew->ksa_handler;
4329 new.sa_flags = oldnew->sa_flags;
4330 new.sa_restorer = oldnew->sa_restorer;
4331 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4332 newp = &new;
4335 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4337 if (ARG3 != 0 && SUCCESS && RES == 0) {
4338 struct vki_old_sigaction *oldold =
4339 (struct vki_old_sigaction *)(Addr)ARG3;
4341 oldold->ksa_handler = oldp->ksa_handler;
4342 oldold->sa_flags = oldp->sa_flags;
4343 oldold->sa_restorer = oldp->sa_restorer;
4344 oldold->sa_mask = oldp->sa_mask.sig[0];
4348 POST(sys_sigaction)
4350 vg_assert(SUCCESS);
4351 if (RES == 0 && ARG3 != 0)
4352 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4354 #endif
4356 PRE(sys_signalfd)
4358 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4359 (ULong)ARG3);
4360 PRE_REG_READ3(long, "sys_signalfd",
4361 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4362 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4363 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4364 SET_STATUS_Failure( VKI_EBADF );
4366 POST(sys_signalfd)
4368 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4369 VG_(close)(RES);
4370 SET_STATUS_Failure( VKI_EMFILE );
4371 } else {
4372 if (VG_(clo_track_fds))
4373 ML_(record_fd_open_nameless) (tid, RES);
4377 PRE(sys_signalfd4)
4379 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4380 SARG1, ARG2, ARG3, SARG4);
4381 PRE_REG_READ4(long, "sys_signalfd4",
4382 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4383 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4384 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4385 SET_STATUS_Failure( VKI_EBADF );
4387 POST(sys_signalfd4)
4389 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4390 VG_(close)(RES);
4391 SET_STATUS_Failure( VKI_EMFILE );
4392 } else {
4393 if (VG_(clo_track_fds))
4394 ML_(record_fd_open_nameless) (tid, RES);
4399 /* ---------------------------------------------------------------------
4400 rt_sig* wrappers
4401 ------------------------------------------------------------------ */
4403 PRE(sys_rt_sigaction)
4405 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4406 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4407 PRE_REG_READ4(long, "rt_sigaction",
4408 int, signum, const struct sigaction *, act,
4409 struct sigaction *, oldact, vki_size_t, sigsetsize);
4411 if (ARG2 != 0) {
4412 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4413 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4414 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4415 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4416 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4417 && (sa->sa_flags & VKI_SA_RESTORER))
4418 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4420 if (ARG3 != 0)
4421 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4423 /* If the new or old sigaction is not NULL, but the structs
4424 aren't accessible then sigaction returns EFAULT and we cannot
4425 use either struct for our own bookkeeping. Just fail early. */
4426 if (ARG2 != 0
4427 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4428 sizeof(vki_sigaction_toK_t))) {
4429 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4430 (void *)(Addr)ARG2);
4431 SET_STATUS_Failure ( VKI_EFAULT );
4432 } else if ((ARG3 != 0
4433 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4434 sizeof(vki_sigaction_fromK_t)))) {
4435 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4436 (void *)(Addr)ARG3);
4437 SET_STATUS_Failure ( VKI_EFAULT );
4438 } else {
4440 // XXX: doesn't seem right to be calling do_sys_sigaction for
4441 // sys_rt_sigaction... perhaps this function should be renamed
4442 // VG_(do_sys_rt_sigaction)() --njn
4444 SET_STATUS_from_SysRes(
4445 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4446 (vki_sigaction_fromK_t *)(Addr)ARG3)
4450 POST(sys_rt_sigaction)
4452 vg_assert(SUCCESS);
4453 if (RES == 0 && ARG3 != 0)
4454 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4457 PRE(sys_rt_sigprocmask)
4459 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4460 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4461 PRE_REG_READ4(long, "rt_sigprocmask",
4462 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4463 vki_size_t, sigsetsize);
4464 if (ARG2 != 0)
4465 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4466 if (ARG3 != 0)
4467 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4469 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4470 // Since we want to use the set and oldset for bookkeeping we also want
4471 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4472 if (sizeof(vki_sigset_t) != ARG4)
4473 SET_STATUS_Failure( VKI_EINVAL );
4474 else if (ARG2 != 0
4475 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4476 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4477 (void *)(Addr)ARG2);
4478 SET_STATUS_Failure ( VKI_EFAULT );
4480 else if (ARG3 != 0
4481 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4482 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4483 (void *)(Addr)ARG3);
4484 SET_STATUS_Failure ( VKI_EFAULT );
4487 else {
4488 SET_STATUS_from_SysRes(
4489 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4490 (vki_sigset_t*) (Addr)ARG2,
4491 (vki_sigset_t*) (Addr)ARG3 )
4495 if (SUCCESS)
4496 *flags |= SfPollAfter;
4498 POST(sys_rt_sigprocmask)
4500 vg_assert(SUCCESS);
4501 if (RES == 0 && ARG3 != 0)
4502 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4505 PRE(sys_rt_sigpending)
4507 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4508 PRE_REG_READ2(long, "rt_sigpending",
4509 vki_sigset_t *, set, vki_size_t, sigsetsize);
4510 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4512 POST(sys_rt_sigpending)
4514 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4517 PRE(sys_rt_sigtimedwait)
4519 *flags |= SfMayBlock;
4520 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4521 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4522 ARG1, ARG2, ARG3, ARG4);
4523 PRE_REG_READ4(long, "rt_sigtimedwait",
4524 const vki_sigset_t *, set, vki_siginfo_t *, info,
4525 const struct timespec *, timeout, vki_size_t, sigsetsize);
4526 if (ARG1 != 0)
4527 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4528 if (ARG2 != 0)
4529 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4530 if (ARG3 != 0)
4531 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4532 ARG3, sizeof(struct vki_timespec) );
4534 POST(sys_rt_sigtimedwait)
4536 if (ARG2 != 0)
4537 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4540 PRE(sys_rt_sigtimedwait_time64)
4542 *flags |= SfMayBlock;
4543 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4544 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4545 ARG1, ARG2, ARG3, ARG4);
4546 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4547 const vki_sigset_t *, set, vki_siginfo_t *, info,
4548 const struct vki_timespec64 *, timeout,
4549 vki_size_t, sigsetsize);
4550 if (ARG1 != 0)
4551 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4552 if (ARG2 != 0)
4553 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4554 sizeof(vki_siginfo_t) );
4555 if (ARG3 != 0)
4556 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4558 POST(sys_rt_sigtimedwait_time64)
4560 if (ARG2 != 0)
4561 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4564 PRE(sys_rt_sigqueueinfo)
4566 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4567 SARG1, SARG2, ARG3);
4568 PRE_REG_READ3(long, "rt_sigqueueinfo",
4569 int, pid, int, sig, vki_siginfo_t *, uinfo);
4570 if (ARG2 != 0)
4571 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4573 POST(sys_rt_sigqueueinfo)
4575 if (!ML_(client_signal_OK)(ARG2))
4576 SET_STATUS_Failure( VKI_EINVAL );
4579 PRE(sys_rt_tgsigqueueinfo)
4581 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4582 SARG1, SARG2, SARG3, ARG4);
4583 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4584 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4585 if (ARG3 != 0)
4586 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4589 POST(sys_rt_tgsigqueueinfo)
4591 if (!ML_(client_signal_OK)(ARG3))
4592 SET_STATUS_Failure( VKI_EINVAL );
4595 // XXX: x86-specific? The kernel prototypes for the different archs are
4596 // hard to decipher.
4597 PRE(sys_rt_sigsuspend)
4599 /* The C library interface to sigsuspend just takes a pointer to
4600 a signal mask but this system call has two arguments - a pointer
4601 to the mask and the number of bytes used by it. The kernel insists
4602 on the size being equal to sizeof(sigset_t) however and will just
4603 return EINVAL if it isn't.
4605 *flags |= SfMayBlock;
4606 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4607 ARG1, ARG2 );
4608 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4609 if (ARG1 != (Addr)NULL) {
4610 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4611 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4612 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4613 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4614 be killable by VG_(nuke_all_threads_except).
4615 We thus silently ignore the user request to mask this signal.
4616 Note that this is similar to what is done for e.g.
4617 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4618 } else {
4619 SET_STATUS_Failure(VKI_EFAULT);
4624 /* ---------------------------------------------------------------------
4625 linux msg* wrapper helpers
4626 ------------------------------------------------------------------ */
4628 void
4629 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4630 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4632 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4633 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4634 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4635 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4638 void
4639 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4640 UWord arg0, UWord arg1, UWord arg2,
4641 UWord arg3, UWord arg4 )
4643 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4644 long msgtyp, int msgflg); */
4645 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4646 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4647 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4649 void
4650 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4651 UWord res,
4652 UWord arg0, UWord arg1, UWord arg2,
4653 UWord arg3, UWord arg4 )
4655 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4656 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4657 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4660 void
4661 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4662 UWord arg0, UWord arg1, UWord arg2 )
4664 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4665 switch (arg1 /* cmd */) {
4666 case VKI_IPC_INFO:
4667 case VKI_MSG_INFO:
4668 case VKI_IPC_INFO|VKI_IPC_64:
4669 case VKI_MSG_INFO|VKI_IPC_64:
4670 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4671 arg2, sizeof(struct vki_msginfo) );
4672 break;
4673 case VKI_IPC_STAT:
4674 case VKI_MSG_STAT:
4675 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4676 arg2, sizeof(struct vki_msqid_ds) );
4677 break;
4678 case VKI_IPC_STAT|VKI_IPC_64:
4679 case VKI_MSG_STAT|VKI_IPC_64:
4680 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4681 arg2, sizeof(struct vki_msqid64_ds) );
4682 break;
4683 case VKI_IPC_SET:
4684 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4685 arg2, sizeof(struct vki_msqid_ds) );
4686 break;
4687 case VKI_IPC_SET|VKI_IPC_64:
4688 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4689 arg2, sizeof(struct vki_msqid64_ds) );
4690 break;
4693 void
4694 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4695 UWord res,
4696 UWord arg0, UWord arg1, UWord arg2 )
4698 switch (arg1 /* cmd */) {
4699 case VKI_IPC_INFO:
4700 case VKI_MSG_INFO:
4701 case VKI_IPC_INFO|VKI_IPC_64:
4702 case VKI_MSG_INFO|VKI_IPC_64:
4703 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4704 break;
4705 case VKI_IPC_STAT:
4706 case VKI_MSG_STAT:
4707 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4708 break;
4709 case VKI_IPC_STAT|VKI_IPC_64:
4710 case VKI_MSG_STAT|VKI_IPC_64:
4711 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4712 break;
4716 /* ---------------------------------------------------------------------
4717 Generic handler for sys_ipc
4718 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4719 are either direct system calls, or are all implemented via sys_ipc.
4720 ------------------------------------------------------------------ */
4721 #ifdef __NR_ipc
4722 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4724 Addr* a_p = (Addr*)a;
4725 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4726 return *a_p;
4729 static Bool semctl_cmd_has_4args (UWord cmd)
4731 switch (cmd & ~VKI_IPC_64)
4733 case VKI_IPC_INFO:
4734 case VKI_SEM_INFO:
4735 case VKI_IPC_STAT:
4736 case VKI_SEM_STAT:
4737 case VKI_IPC_SET:
4738 case VKI_GETALL:
4739 case VKI_SETALL:
4740 return True;
4741 default:
4742 return False;
4746 PRE(sys_ipc)
4748 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4749 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4751 switch (ARG1 /* call */) {
4752 case VKI_SEMOP:
4753 PRE_REG_READ5(int, "ipc",
4754 vki_uint, call, int, first, int, second, int, third,
4755 void *, ptr);
4756 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4757 *flags |= SfMayBlock;
4758 break;
4759 case VKI_SEMGET:
4760 PRE_REG_READ4(int, "ipc",
4761 vki_uint, call, int, first, int, second, int, third);
4762 break;
4763 case VKI_SEMCTL:
4765 PRE_REG_READ5(int, "ipc",
4766 vki_uint, call, int, first, int, second, int, third,
4767 void *, ptr);
4768 UWord arg;
4769 if (semctl_cmd_has_4args(ARG4))
4770 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4771 else
4772 arg = 0;
4773 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4774 break;
4776 case VKI_SEMTIMEDOP:
4777 #ifdef VGP_s390x_linux
4778 /* On s390x Linux platforms the sys_ipc semtimedop call has four instead
4779 of five parameters, where the timeout is passed in the third instead of
4780 the fifth. */
4781 PRE_REG_READ5(int, "ipc",
4782 vki_uint, call, int, first, int, second, long, third,
4783 void *, ptr);
4784 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG4 );
4785 #else
4786 PRE_REG_READ6(int, "ipc",
4787 vki_uint, call, int, first, int, second, int, third,
4788 void *, ptr, long, fifth);
4789 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4790 #endif
4791 *flags |= SfMayBlock;
4792 break;
4793 case VKI_MSGSND:
4794 PRE_REG_READ5(int, "ipc",
4795 vki_uint, call, int, first, int, second, int, third,
4796 void *, ptr);
4797 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4798 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4799 *flags |= SfMayBlock;
4800 break;
4801 case VKI_MSGRCV:
4803 PRE_REG_READ5(int, "ipc",
4804 vki_uint, call, int, first, int, second, int, third,
4805 void *, ptr);
4806 Addr msgp;
4807 Word msgtyp;
4809 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4810 "msgrcv(msgp)" );
4811 msgtyp = deref_Addr( tid,
4812 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4813 "msgrcv(msgp)" );
4815 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4817 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4818 *flags |= SfMayBlock;
4819 break;
4821 case VKI_MSGGET:
4822 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4823 break;
4824 case VKI_MSGCTL:
4825 PRE_REG_READ5(int, "ipc",
4826 vki_uint, call, int, first, int, second, int, third,
4827 void *, ptr);
4828 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4829 break;
4830 case VKI_SHMAT:
4832 PRE_REG_READ5(int, "ipc",
4833 vki_uint, call, int, first, int, second, int, third,
4834 void *, ptr);
4835 UWord w;
4836 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4837 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4838 if (w == 0)
4839 SET_STATUS_Failure( VKI_EINVAL );
4840 else
4841 ARG5 = w;
4842 break;
4844 case VKI_SHMDT:
4845 PRE_REG_READ5(int, "ipc",
4846 vki_uint, call, int, first, int, second, int, third,
4847 void *, ptr);
4848 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4849 SET_STATUS_Failure( VKI_EINVAL );
4850 break;
4851 case VKI_SHMGET:
4852 PRE_REG_READ4(int, "ipc",
4853 vki_uint, call, int, first, int, second, int, third);
4854 if (ARG4 & VKI_SHM_HUGETLB) {
4855 static Bool warning_given = False;
4856 ARG4 &= ~VKI_SHM_HUGETLB;
4857 if (!warning_given) {
4858 warning_given = True;
4859 VG_(umsg)(
4860 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4863 break;
4864 case VKI_SHMCTL: /* IPCOP_shmctl */
4865 PRE_REG_READ5(int, "ipc",
4866 vki_uint, call, int, first, int, second, int, third,
4867 void *, ptr);
4868 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4869 break;
4870 default:
4871 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4872 VG_(core_panic)("... bye!\n");
4873 break; /*NOTREACHED*/
4877 POST(sys_ipc)
4879 vg_assert(SUCCESS);
4880 switch (ARG1 /* call */) {
4881 case VKI_SEMOP:
4882 case VKI_SEMGET:
4883 break;
4884 case VKI_SEMCTL:
4886 UWord arg;
4887 if (semctl_cmd_has_4args(ARG4))
4888 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4889 else
4890 arg = 0;
4891 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4892 break;
4894 case VKI_SEMTIMEDOP:
4895 case VKI_MSGSND:
4896 break;
4897 case VKI_MSGRCV:
4899 Addr msgp;
4900 Word msgtyp;
4902 msgp = deref_Addr( tid,
4903 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4904 "msgrcv(msgp)" );
4905 msgtyp = deref_Addr( tid,
4906 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4907 "msgrcv(msgp)" );
4909 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4910 break;
4912 case VKI_MSGGET:
4913 break;
4914 case VKI_MSGCTL:
4915 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4916 break;
4917 case VKI_SHMAT:
4919 Addr addr;
4921 /* force readability. before the syscall it is
4922 * indeed uninitialized, as can be seen in
4923 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4924 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4926 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4927 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4928 break;
4930 case VKI_SHMDT:
4931 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4932 break;
4933 case VKI_SHMGET:
4934 break;
4935 case VKI_SHMCTL:
4936 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4937 break;
4938 default:
4939 VG_(message)(Vg_DebugMsg,
4940 "FATAL: unhandled syscall(ipc) %lu\n",
4941 ARG1 );
4942 VG_(core_panic)("... bye!\n");
4943 break; /*NOTREACHED*/
4946 #endif
4948 PRE(sys_semget)
4950 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4951 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4954 PRE(sys_semop)
4956 *flags |= SfMayBlock;
4957 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4958 SARG1, ARG2, ARG3);
4959 PRE_REG_READ3(long, "semop",
4960 int, semid, struct sembuf *, sops, unsigned, nsoops);
4961 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4964 PRE(sys_semctl)
4966 switch (ARG3 & ~VKI_IPC_64) {
4967 case VKI_IPC_INFO:
4968 case VKI_SEM_INFO:
4969 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4970 SARG3, ARG4);
4971 PRE_REG_READ4(long, "semctl",
4972 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4973 break;
4974 case VKI_IPC_STAT:
4975 case VKI_SEM_STAT:
4976 case VKI_IPC_SET:
4977 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4978 SARG3, ARG4);
4979 PRE_REG_READ4(long, "semctl",
4980 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4981 break;
4982 case VKI_GETALL:
4983 case VKI_SETALL:
4984 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4985 SARG3, ARG4);
4986 PRE_REG_READ4(long, "semctl",
4987 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4988 break;
4989 default:
4990 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4991 PRE_REG_READ3(long, "semctl",
4992 int, semid, int, semnum, int, cmd);
4993 break;
4995 #ifdef VGP_amd64_linux
4996 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4997 #else
4998 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4999 #endif
5002 POST(sys_semctl)
5004 #ifdef VGP_amd64_linux
5005 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
5006 #else
5007 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
5008 #endif
5011 PRE(sys_semtimedop)
5013 *flags |= SfMayBlock;
5014 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5015 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5016 PRE_REG_READ4(long, "semtimedop",
5017 int, semid, struct sembuf *, sops, unsigned, nsoops,
5018 struct timespec *, timeout);
5019 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5022 PRE(sys_semtimedop_time64)
5024 *flags |= SfMayBlock;
5025 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5026 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5027 PRE_REG_READ4(long, "semtimedop_time64",
5028 int, semid, struct sembuf *, sops, unsigned, nsoops,
5029 struct vki_timespec64 *, timeout);
5030 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5031 ARG2 * sizeof(struct vki_sembuf) );
5032 if (ARG3 != 0)
5033 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5036 PRE(sys_msgget)
5038 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5039 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5042 PRE(sys_msgsnd)
5044 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5045 SARG1, ARG2, ARG3, SARG4);
5046 PRE_REG_READ4(long, "msgsnd",
5047 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5048 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5049 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5050 *flags |= SfMayBlock;
5053 PRE(sys_msgrcv)
5055 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5056 SARG1, ARG2, ARG3, SARG4, SARG5);
5057 PRE_REG_READ5(long, "msgrcv",
5058 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5059 long, msgytp, int, msgflg);
5060 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5061 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5062 *flags |= SfMayBlock;
5064 POST(sys_msgrcv)
5066 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5069 PRE(sys_msgctl)
5071 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5072 PRE_REG_READ3(long, "msgctl",
5073 int, msqid, int, cmd, struct msqid_ds *, buf);
5074 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5077 POST(sys_msgctl)
5079 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5082 PRE(sys_shmget)
5084 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5085 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5086 if (ARG3 & VKI_SHM_HUGETLB) {
5087 static Bool warning_given = False;
5088 ARG3 &= ~VKI_SHM_HUGETLB;
5089 if (!warning_given) {
5090 warning_given = True;
5091 VG_(umsg)(
5092 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5097 PRE(sys_shmat)
5099 UWord arg2tmp;
5100 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5101 PRE_REG_READ3(long, "shmat",
5102 int, shmid, const void *, shmaddr, int, shmflg);
5103 #if defined(VGP_arm_linux)
5104 /* Round the attach address down to an VKI_SHMLBA boundary if the
5105 client requested rounding. See #222545. This is necessary only
5106 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5107 other linux targets it is the same as the page size. */
5108 if (ARG3 & VKI_SHM_RND)
5109 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5110 #endif
5111 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5112 if (arg2tmp == 0)
5113 SET_STATUS_Failure( VKI_EINVAL );
5114 else
5115 ARG2 = arg2tmp; // used in POST
5118 POST(sys_shmat)
5120 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5123 PRE(sys_shmdt)
5125 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5126 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5127 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5128 SET_STATUS_Failure( VKI_EINVAL );
5131 POST(sys_shmdt)
5133 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5136 PRE(sys_shmctl)
5138 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5139 PRE_REG_READ3(long, "shmctl",
5140 int, shmid, int, cmd, struct shmid_ds *, buf);
5141 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5142 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5143 #else
5144 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5145 #endif
5148 POST(sys_shmctl)
5150 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5151 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5152 #else
5153 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5154 #endif
5158 /* ---------------------------------------------------------------------
5159 Generic handler for sys_socketcall
5160 Depending on the platform, some socket related syscalls (e.g. socketpair,
5161 socket, bind, ...)
5162 are either direct system calls, or are all implemented via sys_socketcall.
5163 ------------------------------------------------------------------ */
5164 #ifdef __NR_socketcall
5165 PRE(sys_socketcall)
5167 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5168 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5169 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5170 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5171 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5172 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5174 // call PRE_MEM_READ and check for EFAULT result.
5175 #define PRE_MEM_READ_ef(msg, arg, size) \
5177 PRE_MEM_READ( msg, arg, size); \
5178 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5179 SET_STATUS_Failure( VKI_EFAULT ); \
5180 break; \
5184 *flags |= SfMayBlock;
5185 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5186 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5188 switch (ARG1 /* request */) {
5190 case VKI_SYS_SOCKETPAIR:
5191 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5192 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5193 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5194 break;
5196 case VKI_SYS_SOCKET:
5197 /* int socket(int domain, int type, int protocol); */
5198 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5199 break;
5201 case VKI_SYS_BIND:
5202 /* int bind(int sockfd, struct sockaddr *my_addr,
5203 int addrlen); */
5204 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5205 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5206 break;
5208 case VKI_SYS_LISTEN:
5209 /* int listen(int s, int backlog); */
5210 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5211 break;
5213 case VKI_SYS_ACCEPT:
5214 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5215 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5216 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5217 break;
5219 case VKI_SYS_ACCEPT4:
5220 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5221 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5222 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5223 break;
5225 case VKI_SYS_SENDTO:
5226 /* int sendto(int s, const void *msg, int len,
5227 unsigned int flags,
5228 const struct sockaddr *to, int tolen); */
5229 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5230 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5231 ARG2_3, ARG2_4, ARG2_5 );
5232 break;
5234 case VKI_SYS_SEND:
5235 /* int send(int s, const void *msg, size_t len, int flags); */
5236 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5237 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5238 break;
5240 case VKI_SYS_RECVFROM:
5241 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5242 struct sockaddr *from, int *fromlen); */
5243 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5244 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5245 ARG2_3, ARG2_4, ARG2_5 );
5246 break;
5248 case VKI_SYS_RECV:
5249 /* int recv(int s, void *buf, int len, unsigned int flags); */
5250 /* man 2 recv says:
5251 The recv call is normally used only on a connected socket
5252 (see connect(2)) and is identical to recvfrom with a NULL
5253 from parameter.
5255 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5256 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5257 break;
5259 case VKI_SYS_CONNECT:
5260 /* int connect(int sockfd,
5261 struct sockaddr *serv_addr, int addrlen ); */
5262 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5263 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5264 break;
5266 case VKI_SYS_SETSOCKOPT:
5267 /* int setsockopt(int s, int level, int optname,
5268 const void *optval, int optlen); */
5269 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5270 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5271 ARG2_3, ARG2_4 );
5272 break;
5274 case VKI_SYS_GETSOCKOPT:
5275 /* int getsockopt(int s, int level, int optname,
5276 void *optval, socklen_t *optlen); */
5277 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5278 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5279 ARG2_3, ARG2_4 );
5280 break;
5282 case VKI_SYS_GETSOCKNAME:
5283 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5284 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5285 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5286 break;
5288 case VKI_SYS_GETPEERNAME:
5289 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5290 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5291 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5292 break;
5294 case VKI_SYS_SHUTDOWN:
5295 /* int shutdown(int s, int how); */
5296 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5297 break;
5299 case VKI_SYS_SENDMSG:
5300 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5301 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5302 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5303 (struct vki_msghdr *)(Addr)ARG2_1 );
5304 break;
5306 case VKI_SYS_RECVMSG:
5307 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5308 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5309 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5310 (struct vki_msghdr *)(Addr)ARG2_1 );
5311 break;
5313 case VKI_SYS_RECVMMSG:
5314 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5315 struct timespec *timeout); */
5316 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5317 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5318 ARG2_4 );
5319 break;
5321 case VKI_SYS_SENDMMSG:
5322 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5323 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5324 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5325 break;
5327 default:
5328 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5329 SET_STATUS_Failure( VKI_EINVAL );
5330 break;
5332 # undef ARG2_0
5333 # undef ARG2_1
5334 # undef ARG2_2
5335 # undef ARG2_3
5336 # undef ARG2_4
5337 # undef ARG2_5
5340 POST(sys_socketcall)
5342 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5343 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5344 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5345 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5346 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5347 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5349 SysRes r;
5350 vg_assert(SUCCESS);
5351 switch (ARG1 /* request */) {
5353 case VKI_SYS_SOCKETPAIR:
5354 r = ML_(generic_POST_sys_socketpair)(
5355 tid, VG_(mk_SysRes_Success)(RES),
5356 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5358 SET_STATUS_from_SysRes(r);
5359 break;
5361 case VKI_SYS_SOCKET:
5362 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5363 SET_STATUS_from_SysRes(r);
5364 break;
5366 case VKI_SYS_BIND:
5367 /* int bind(int sockfd, struct sockaddr *my_addr,
5368 int addrlen); */
5369 break;
5371 case VKI_SYS_LISTEN:
5372 /* int listen(int s, int backlog); */
5373 break;
5375 case VKI_SYS_ACCEPT:
5376 case VKI_SYS_ACCEPT4:
5377 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5378 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5379 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5380 ARG2_0, ARG2_1, ARG2_2 );
5381 SET_STATUS_from_SysRes(r);
5382 break;
5384 case VKI_SYS_SENDTO:
5385 break;
5387 case VKI_SYS_SEND:
5388 break;
5390 case VKI_SYS_RECVFROM:
5391 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5392 ARG2_0, ARG2_1, ARG2_2,
5393 ARG2_3, ARG2_4, ARG2_5 );
5394 break;
5396 case VKI_SYS_RECV:
5397 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5398 break;
5400 case VKI_SYS_CONNECT:
5401 break;
5403 case VKI_SYS_SETSOCKOPT:
5404 break;
5406 case VKI_SYS_GETSOCKOPT:
5407 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5408 ARG2_0, ARG2_1,
5409 ARG2_2, ARG2_3, ARG2_4 );
5410 break;
5412 case VKI_SYS_GETSOCKNAME:
5413 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5414 ARG2_0, ARG2_1, ARG2_2 );
5415 break;
5417 case VKI_SYS_GETPEERNAME:
5418 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5419 ARG2_0, ARG2_1, ARG2_2 );
5420 break;
5422 case VKI_SYS_SHUTDOWN:
5423 break;
5425 case VKI_SYS_SENDMSG:
5426 break;
5428 case VKI_SYS_RECVMSG:
5429 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5430 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5431 break;
5433 case VKI_SYS_RECVMMSG:
5434 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5435 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5436 break;
5438 case VKI_SYS_SENDMMSG:
5439 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5440 break;
5442 default:
5443 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5444 VG_(core_panic)("... bye!\n");
5445 break; /*NOTREACHED*/
5447 # undef ARG2_0
5448 # undef ARG2_1
5449 # undef ARG2_2
5450 # undef ARG2_3
5451 # undef ARG2_4
5452 # undef ARG2_5
5454 #endif
5456 PRE(sys_socket)
5458 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5459 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5461 POST(sys_socket)
5463 SysRes r;
5464 vg_assert(SUCCESS);
5465 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5466 SET_STATUS_from_SysRes(r);
5469 PRE(sys_setsockopt)
5471 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5472 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5473 PRE_REG_READ5(long, "setsockopt",
5474 int, s, int, level, int, optname,
5475 const void *, optval, unsigned, optlen); // socklen_t
5476 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5479 PRE(sys_getsockopt)
5481 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5482 SARG1, SARG2, SARG3, ARG4, SARG5);
5483 PRE_REG_READ5(long, "getsockopt",
5484 int, s, int, level, int, optname,
5485 void *, optval, int, *optlen);
5486 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5488 POST(sys_getsockopt)
5490 vg_assert(SUCCESS);
5491 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5492 ARG1,ARG2,ARG3,ARG4,ARG5);
5495 PRE(sys_connect)
5497 *flags |= SfMayBlock;
5498 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5499 PRE_REG_READ3(long, "connect",
5500 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5501 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5504 PRE(sys_accept)
5506 *flags |= SfMayBlock;
5507 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5508 SARG1, ARG2, ARG3);
5509 PRE_REG_READ3(long, "accept",
5510 int, s, struct sockaddr *, addr, int *, addrlen);
5511 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5513 POST(sys_accept)
5515 SysRes r;
5516 vg_assert(SUCCESS);
5517 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5518 ARG1,ARG2,ARG3);
5519 SET_STATUS_from_SysRes(r);
5522 PRE(sys_accept4)
5524 *flags |= SfMayBlock;
5525 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5526 SARG1, ARG2, ARG3, SARG4);
5527 PRE_REG_READ4(long, "accept4",
5528 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5529 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5531 POST(sys_accept4)
5533 SysRes r;
5534 vg_assert(SUCCESS);
5535 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5536 ARG1,ARG2,ARG3);
5537 SET_STATUS_from_SysRes(r);
5540 PRE(sys_send)
5542 *flags |= SfMayBlock;
5543 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5544 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5545 PRE_REG_READ4(long, "send",
5546 int, s, const void *, msg, vki_size_t, len,
5547 int, flags);
5549 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5552 PRE(sys_sendto)
5554 *flags |= SfMayBlock;
5555 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5556 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5557 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5558 PRE_REG_READ6(long, "sendto",
5559 int, s, const void *, msg, vki_size_t, len,
5560 unsigned int, flags,
5561 const struct sockaddr *, to, int, tolen);
5562 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5565 PRE (sys_recv)
5567 *flags |= SfMayBlock;
5568 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5569 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5570 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5571 unsigned int, flags);
5572 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5575 POST (sys_recv)
5577 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5580 PRE(sys_recvfrom)
5582 *flags |= SfMayBlock;
5583 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5584 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5585 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5586 PRE_REG_READ6(long, "recvfrom",
5587 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5588 struct sockaddr *, from, int *, fromlen);
5589 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5591 POST(sys_recvfrom)
5593 vg_assert(SUCCESS);
5594 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5595 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5598 PRE(sys_sendmsg)
5600 *flags |= SfMayBlock;
5601 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5602 SARG1, ARG2, ARG3);
5603 PRE_REG_READ3(long, "sendmsg",
5604 int, s, const struct msghdr *, msg, unsigned int, flags);
5605 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5608 PRE(sys_recvmsg)
5610 *flags |= SfMayBlock;
5611 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5612 SARG1, ARG2, ARG3);
5613 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5614 unsigned int, flags);
5615 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5617 POST(sys_recvmsg)
5619 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5620 RES);
5623 PRE(sys_shutdown)
5625 *flags |= SfMayBlock;
5626 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5627 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5630 PRE(sys_bind)
5632 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5633 PRE_REG_READ3(long, "bind",
5634 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5635 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5638 PRE(sys_listen)
5640 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5641 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5644 PRE(sys_getsockname)
5646 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5647 SARG1, ARG2, ARG3);
5648 PRE_REG_READ3(long, "getsockname",
5649 int, s, struct sockaddr *, name, int *, namelen);
5650 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5652 POST(sys_getsockname)
5654 vg_assert(SUCCESS);
5655 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5656 ARG1,ARG2,ARG3);
5659 PRE(sys_getpeername)
5661 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5662 SARG1, ARG2, ARG3);
5663 PRE_REG_READ3(long, "getpeername",
5664 int, s, struct sockaddr *, name, int *, namelen);
5665 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5667 POST(sys_getpeername)
5669 vg_assert(SUCCESS);
5670 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5671 ARG1,ARG2,ARG3);
5674 PRE(sys_socketpair)
5676 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5677 SARG3, ARG4);
5678 PRE_REG_READ4(long, "socketpair",
5679 int, d, int, type, int, protocol, int*, sv);
5680 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5682 POST(sys_socketpair)
5684 vg_assert(SUCCESS);
5685 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5686 ARG1,ARG2,ARG3,ARG4);
5690 /* ---------------------------------------------------------------------
5691 *at wrappers
5692 ------------------------------------------------------------------ */
5694 PRE(sys_openat)
5696 HChar name[30]; // large enough
5697 SysRes sres;
5699 if (ARG3 & VKI_O_CREAT) {
5700 // 4-arg version
5701 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5702 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5703 PRE_REG_READ4(long, "openat",
5704 int, dfd, const char *, filename, int, flags, int, mode);
5705 } else {
5706 // 3-arg version
5707 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5708 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5709 PRE_REG_READ3(long, "openat",
5710 int, dfd, const char *, filename, int, flags);
5713 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5715 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5716 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5717 be sure only to compare the bottom 32 bits. */
5718 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5719 && *(Char *)(Addr)ARG2 != '/'
5720 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5721 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5722 SET_STATUS_Failure( VKI_EBADF );
5724 /* Handle the case where the open is of /proc/self/cmdline or
5725 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5726 fake file we cooked up at startup (in m_main). Also, seek the
5727 cloned fd back to the start. */
5729 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5730 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5731 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5732 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5733 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5734 SET_STATUS_from_SysRes( sres );
5735 if (!sr_isError(sres)) {
5736 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5737 if (off < 0)
5738 SET_STATUS_Failure( VKI_EMFILE );
5740 return;
5743 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5745 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5746 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5747 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5748 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5749 sres = VG_(dup)( VG_(cl_auxv_fd) );
5750 SET_STATUS_from_SysRes( sres );
5751 if (!sr_isError(sres)) {
5752 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5753 if (off < 0)
5754 SET_STATUS_Failure( VKI_EMFILE );
5756 return;
5759 /* And for /proc/self/exe or /proc/<pid>/exe case. */
5761 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5762 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5763 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5764 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5765 sres = VG_(dup)( VG_(cl_exec_fd) );
5766 SET_STATUS_from_SysRes( sres );
5767 if (!sr_isError(sres)) {
5768 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5769 if (off < 0)
5770 SET_STATUS_Failure( VKI_EMFILE );
5772 return;
5775 /* Otherwise handle normally */
5776 *flags |= SfMayBlock;
5779 POST(sys_openat)
5781 vg_assert(SUCCESS);
5782 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5783 VG_(close)(RES);
5784 SET_STATUS_Failure( VKI_EMFILE );
5785 } else {
5786 if (VG_(clo_track_fds))
5787 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5791 PRE(sys_mkdirat)
5793 *flags |= SfMayBlock;
5794 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5795 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5796 PRE_REG_READ3(long, "mkdirat",
5797 int, dfd, const char *, pathname, int, mode);
5798 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5801 PRE(sys_mknodat)
5803 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5804 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5805 PRE_REG_READ4(long, "mknodat",
5806 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5807 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5810 PRE(sys_fchownat)
5812 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5813 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5814 PRE_REG_READ4(long, "fchownat",
5815 int, dfd, const char *, path,
5816 vki_uid_t, owner, vki_gid_t, group);
5817 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5820 PRE(sys_futimesat)
5822 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5823 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5824 PRE_REG_READ3(long, "futimesat",
5825 int, dfd, char *, filename, struct timeval *, tvp);
5826 if (ARG2 != 0)
5827 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5828 if (ARG3 != 0)
5829 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5832 PRE(sys_utimensat)
5834 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5835 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5836 PRE_REG_READ4(long, "utimensat",
5837 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5838 if (ARG2 != 0)
5839 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5840 if (ARG3 != 0) {
5841 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5842 then the tv_sec field is ignored. */
5843 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5844 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5845 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5846 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5847 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5848 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5849 if (times[0].tv_nsec != VKI_UTIME_NOW
5850 && times[0].tv_nsec != VKI_UTIME_OMIT)
5851 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5852 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5853 if (times[1].tv_nsec != VKI_UTIME_NOW
5854 && times[1].tv_nsec != VKI_UTIME_OMIT)
5855 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5856 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5861 PRE(sys_utimensat_time64)
5863 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5864 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5865 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5866 PRE_REG_READ4(long, "utimensat_time64",
5867 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5868 if (ARG2 != 0)
5869 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5870 if (ARG3 != 0) {
5871 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5872 then the tv_sec field is ignored. */
5873 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5874 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5875 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5876 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5877 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5878 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5879 if (times[0].tv_nsec != VKI_UTIME_NOW
5880 && times[0].tv_nsec != VKI_UTIME_OMIT)
5881 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5882 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5883 if (times[1].tv_nsec != VKI_UTIME_NOW
5884 && times[1].tv_nsec != VKI_UTIME_OMIT)
5885 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5886 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5891 #if !defined(VGP_nanomips_linux)
5892 PRE(sys_newfstatat)
5894 FUSE_COMPATIBLE_MAY_BLOCK();
5895 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5896 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5897 PRE_REG_READ3(long, "fstatat",
5898 int, dfd, char *, file_name, struct stat *, buf);
5899 // See the comment about Rust in PRE(sys_statx). When glibc does support
5900 // statx rust uses that instead of the system call, but glibc's statx is
5901 // implemented in terms of fstatat, so the filename being NULL is
5902 // transferred here.
5903 if (ARG2 != 0) {
5904 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5905 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5909 POST(sys_newfstatat)
5911 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5913 #endif
5915 PRE(sys_unlinkat)
5917 *flags |= SfMayBlock;
5918 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5919 (HChar*)(Addr)ARG2);
5920 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5921 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5924 PRE(sys_renameat)
5926 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5927 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5928 ARG4, (HChar*)(Addr)ARG4);
5929 PRE_REG_READ4(long, "renameat",
5930 int, olddfd, const char *, oldpath,
5931 int, newdfd, const char *, newpath);
5932 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5933 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5936 PRE(sys_renameat2)
5938 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5939 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5940 ARG4, (HChar*)(Addr)ARG4, ARG5);
5941 PRE_REG_READ5(long, "renameat2",
5942 int, olddfd, const char *, oldpath,
5943 int, newdfd, const char *, newpath,
5944 unsigned int, flags);
5945 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5946 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5949 PRE(sys_linkat)
5951 *flags |= SfMayBlock;
5952 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5953 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5954 (HChar*)(Addr)ARG4, SARG5);
5955 PRE_REG_READ5(long, "linkat",
5956 int, olddfd, const char *, oldpath,
5957 int, newdfd, const char *, newpath,
5958 int, flags);
5959 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5960 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5963 PRE(sys_symlinkat)
5965 *flags |= SfMayBlock;
5966 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5967 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5968 PRE_REG_READ3(long, "symlinkat",
5969 const char *, oldpath, int, newdfd, const char *, newpath);
5970 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5971 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5974 PRE(sys_readlinkat)
5976 HChar name[30]; // large enough
5977 Word saved = SYSNO;
5979 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5980 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5981 PRE_REG_READ4(long, "readlinkat",
5982 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5983 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5984 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5987 * Handle the case where readlinkat is looking at /proc/self/exe or
5988 * /proc/<pid>/exe.
5990 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5991 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5992 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5993 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5994 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5995 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5996 ARG3, ARG4));
5997 } else {
5998 /* Normal case */
5999 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
6002 if (SUCCESS && RES > 0)
6003 POST_MEM_WRITE( ARG3, RES );
6006 PRE(sys_fchmodat)
6008 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
6009 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6010 PRE_REG_READ3(long, "fchmodat",
6011 int, dfd, const char *, path, vki_mode_t, mode);
6012 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
6015 PRE(sys_faccessat)
6017 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
6018 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
6019 PRE_REG_READ3(long, "faccessat",
6020 int, dfd, const char *, pathname, int, mode);
6021 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
6024 PRE(sys_faccessat2)
6026 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
6027 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
6028 PRE_REG_READ4(long, "faccessat2",
6029 int, dfd, const char *, pathname, int, mode, int, flags);
6030 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6033 PRE(sys_name_to_handle_at)
6035 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6036 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6037 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6038 PRE_REG_READ5(int, "name_to_handle_at",
6039 int, dfd, const char *, name,
6040 struct vki_file_handle *, handle,
6041 int *, mnt_id, int, flag);
6042 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6043 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6044 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6045 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6046 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6048 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6051 POST(sys_name_to_handle_at)
6053 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6054 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6055 POST_MEM_WRITE( ARG4, sizeof(int) );
6058 PRE(sys_open_by_handle_at)
6060 *flags |= SfMayBlock;
6061 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6062 ARG2, SARG3);
6063 PRE_REG_READ3(int, "open_by_handle_at",
6064 int, mountdirfd,
6065 struct vki_file_handle *, handle,
6066 int, flags);
6067 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6068 sizeof(struct vki_file_handle) +
6069 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6072 POST(sys_open_by_handle_at)
6074 vg_assert(SUCCESS);
6075 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6076 VG_(close)(RES);
6077 SET_STATUS_Failure( VKI_EMFILE );
6078 } else {
6079 if (VG_(clo_track_fds))
6080 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6084 /* ---------------------------------------------------------------------
6085 p{read,write}v wrappers
6086 ------------------------------------------------------------------ */
6087 /* This handles the common part of the PRE macro for preadv and preadv2. */
6088 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6089 Int fd, Addr vector, Int count, const char *str)
6091 struct vki_iovec * vec;
6092 Int i;
6093 /* safe size for the "preadv/preadv2(vector[i])" string */
6094 char tmp[30];
6096 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6097 SET_STATUS_Failure( VKI_EBADF );
6098 } else if (count > 0) {
6099 VG_(strcpy) (tmp, str);
6100 VG_(strcat) (tmp, "(vector)");
6101 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6103 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6104 count * sizeof(struct vki_iovec))) {
6105 vec = (struct vki_iovec *)(Addr)vector;
6106 for (i = 0; i < count; i++) {
6107 /* Note: building such a dynamic error string is *not*
6108 a pattern to follow. See bug 417075. */
6109 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6110 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6116 /* This handles the common part of the POST macro for preadv and preadv2. */
6117 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6119 vg_assert(SUCCESS);
6120 if (RES > 0) {
6121 Int i;
6122 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6123 Int remains = RES;
6125 /* RES holds the number of bytes read. */
6126 for (i = 0; i < count; i++) {
6127 Int nReadThisBuf = vec[i].iov_len;
6128 if (nReadThisBuf > remains) nReadThisBuf = remains;
6129 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6130 remains -= nReadThisBuf;
6131 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6136 PRE(sys_preadv)
6138 *flags |= SfMayBlock;
6139 const char *str = "preadv";
6140 #if VG_WORDSIZE == 4
6141 /* Note that the offset argument here is in lo+hi order on both
6142 big and little endian platforms... */
6143 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6144 "u, %lld )",
6145 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6146 PRE_REG_READ5(ssize_t, "preadv",
6147 unsigned long, fd, const struct iovec *, vector,
6148 unsigned long, count, vki_u32, offset_low,
6149 vki_u32, offset_high);
6150 #elif VG_WORDSIZE == 8
6151 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6152 PRE_REG_READ4(ssize_t, "preadv",
6153 unsigned long, fd, const struct iovec *, vector,
6154 unsigned long, count, Word, offset);
6155 #else
6156 # error Unexpected word size
6157 #endif
6158 Int fd = ARG1;
6159 Addr vector = ARG2;
6160 Int count = ARG3;
6162 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6166 POST(sys_preadv)
6168 Addr vector = ARG2;
6169 Int count = ARG3;
6171 handle_post_sys_preadv(tid, status, vector, count);
6174 PRE(sys_preadv2)
6176 *flags |= SfMayBlock;
6177 const char *str = "preadv2";
6178 #if VG_WORDSIZE == 4
6179 /* Note that the offset argument here is in lo+hi order on both
6180 big and little endian platforms... */
6181 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6182 "u, %lld, %" FMT_REGWORD "u )",
6183 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6184 PRE_REG_READ6(ssize_t, "preadv2",
6185 unsigned long, fd, const struct iovec *, vector,
6186 unsigned long, count, vki_u32, offset_low,
6187 vki_u32, offset_high, unsigned long, flags);
6188 #elif VG_WORDSIZE == 8
6189 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6190 PRE_REG_READ5(ssize_t, "preadv2",
6191 unsigned long, fd, const struct iovec *, vector,
6192 unsigned long, count, Word, offset, unsigned long, flags);
6193 #else
6194 # error Unexpected word size
6195 #endif
6196 Int fd = ARG1;
6197 Addr vector = ARG2;
6198 Int count = ARG3;
6200 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6203 POST(sys_preadv2)
6205 Addr vector = ARG2;
6206 Int count = ARG3;
6208 handle_post_sys_preadv(tid, status, vector, count);
6211 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6212 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6213 Int fd, Addr vector, Int count, const char *str)
6215 Int i;
6216 struct vki_iovec * vec;
6217 /* safe size for the "preadv/preadv2(vector[i])" string */
6218 char tmp[30];
6220 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6221 SET_STATUS_Failure( VKI_EBADF );
6222 } else if (count > 0) {
6223 VG_(strcpy) (tmp, str);
6224 VG_(strcat) (tmp, "(vector)");
6225 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6226 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6227 count * sizeof(struct vki_iovec))) {
6228 vec = (struct vki_iovec *)(Addr)vector;
6229 for (i = 0; i < count; i++) {
6230 /* Note: building such a dynamic error string is *not*
6231 a pattern to follow. See bug 417075. */
6232 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6233 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6239 PRE(sys_pwritev)
6241 *flags |= SfMayBlock;
6242 const char *str = "pwritev";
6243 #if VG_WORDSIZE == 4
6244 /* Note that the offset argument here is in lo+hi order on both
6245 big and little endian platforms... */
6246 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6247 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6248 PRE_REG_READ5(ssize_t, "pwritev",
6249 unsigned long, fd, const struct iovec *, vector,
6250 unsigned long, count, vki_u32, offset_low,
6251 vki_u32, offset_high);
6252 #elif VG_WORDSIZE == 8
6253 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6254 PRE_REG_READ4(ssize_t, "pwritev",
6255 unsigned long, fd, const struct iovec *, vector,
6256 unsigned long, count, Word, offset);
6257 #else
6258 # error Unexpected word size
6259 #endif
6260 Int fd = ARG1;
6261 Addr vector = ARG2;
6262 Int count = ARG3;
6264 handle_sys_pwritev(tid, status, fd, vector, count, str);
6267 PRE(sys_pwritev2)
6269 *flags |= SfMayBlock;
6270 const char *str = "pwritev2";
6271 #if VG_WORDSIZE == 4
6272 /* Note that the offset argument here is in lo+hi order on both
6273 big and little endian platforms... */
6274 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6275 "u, %lld, %" FMT_REGWORD "u )",
6276 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6277 PRE_REG_READ6(ssize_t, "pwritev2",
6278 unsigned long, fd, const struct iovec *, vector,
6279 unsigned long, count, vki_u32, offset_low,
6280 vki_u32, offset_high, unsigned long, flags);
6281 #elif VG_WORDSIZE == 8
6282 /* Note offset_high isn't actually used? */
6283 PRE_REG_READ6(ssize_t, "pwritev2",
6284 unsigned long, fd, const struct iovec *, vector,
6285 unsigned long, count, Word, offset,
6286 Word, offset_high, unsigned long, flags);
6287 #else
6288 # error Unexpected word size
6289 #endif
6290 Int fd = ARG1;
6291 Addr vector = ARG2;
6292 Int count = ARG3;
6294 handle_sys_pwritev(tid, status, fd, vector, count, str);
6297 /* ---------------------------------------------------------------------
6298 process_vm_{read,write}v wrappers
6299 ------------------------------------------------------------------ */
6301 PRE(sys_process_vm_readv)
6303 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6304 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6305 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6306 PRE_REG_READ6(ssize_t, "process_vm_readv",
6307 vki_pid_t, pid,
6308 const struct iovec *, lvec,
6309 unsigned long, liovcnt,
6310 const struct iovec *, rvec,
6311 unsigned long, riovcnt,
6312 unsigned long, flags);
6313 PRE_MEM_READ( "process_vm_readv(lvec)",
6314 ARG2, ARG3 * sizeof(struct vki_iovec) );
6315 PRE_MEM_READ( "process_vm_readv(rvec)",
6316 ARG4, ARG5 * sizeof(struct vki_iovec) );
6317 if (ARG2 != 0
6318 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6319 sizeof(struct vki_iovec) * ARG3)) {
6320 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6321 UInt i;
6322 for (i = 0; i < ARG3; i++)
6323 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6324 (Addr)vec[i].iov_base, vec[i].iov_len );
6328 POST(sys_process_vm_readv)
6330 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6331 UInt remains = RES;
6332 UInt i;
6333 for (i = 0; i < ARG3; i++) {
6334 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6335 vec[i].iov_len : remains;
6336 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6337 remains -= nReadThisBuf;
6341 PRE(sys_process_vm_writev)
6343 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6344 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6345 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6346 PRE_REG_READ6(ssize_t, "process_vm_writev",
6347 vki_pid_t, pid,
6348 const struct iovec *, lvec,
6349 unsigned long, liovcnt,
6350 const struct iovec *, rvec,
6351 unsigned long, riovcnt,
6352 unsigned long, flags);
6353 PRE_MEM_READ( "process_vm_writev(lvec)",
6354 ARG2, ARG3 * sizeof(struct vki_iovec) );
6355 PRE_MEM_READ( "process_vm_writev(rvec)",
6356 ARG4, ARG5 * sizeof(struct vki_iovec) );
6357 if (ARG2 != 0
6358 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6359 sizeof(struct vki_iovec) * ARG3)) {
6360 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6361 UInt i;
6362 for (i = 0; i < ARG3; i++)
6363 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6364 (Addr)vec[i].iov_base, vec[i].iov_len );
6368 /* ---------------------------------------------------------------------
6369 {send,recv}mmsg wrappers
6370 ------------------------------------------------------------------ */
6372 PRE(sys_sendmmsg)
6374 *flags |= SfMayBlock;
6375 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6376 SARG3, SARG4);
6377 PRE_REG_READ4(long, "sendmmsg",
6378 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6379 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6382 POST(sys_sendmmsg)
6384 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6387 PRE(sys_recvmmsg)
6389 *flags |= SfMayBlock;
6390 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6391 FMT_REGWORD "x )",
6392 SARG1, ARG2, SARG3, SARG4, ARG5);
6393 PRE_REG_READ5(long, "recvmmsg",
6394 int, s, struct mmsghdr *, mmsg, int, vlen,
6395 int, flags, struct timespec *, timeout);
6396 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6399 POST(sys_recvmmsg)
6401 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6404 PRE(sys_recvmmsg_time64)
6406 *flags |= SfMayBlock;
6407 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6408 FMT_REGWORD "x )",
6409 SARG1, ARG2, SARG3, SARG4, ARG5);
6410 PRE_REG_READ5(long, "recvmmsg_time64",
6411 int, s, struct mmsghdr *, mmsg, int, vlen,
6412 int, flags, struct vki_timespec64 *, timeout);
6413 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6414 HChar name[40]; // large enough
6415 UInt i;
6416 for (i = 0; i < ARG3; i++) {
6417 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6418 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6419 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6420 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6422 if (ARG5)
6423 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6426 POST(sys_recvmmsg_time64)
6428 /* ARG5 isn't actually used, so just use the generic POST. */
6429 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6432 /* ---------------------------------------------------------------------
6433 key retention service wrappers
6434 ------------------------------------------------------------------ */
6436 PRE(sys_request_key)
6438 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6439 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6440 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6441 PRE_REG_READ4(long, "request_key",
6442 const char *, type, const char *, description,
6443 const char *, callout_info, vki_key_serial_t, keyring);
6444 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6445 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6446 if (ARG3 != (UWord)NULL)
6447 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6450 PRE(sys_add_key)
6452 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6453 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6454 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6455 PRE_REG_READ5(long, "add_key",
6456 const char *, type, const char *, description,
6457 const void *, payload, vki_size_t, plen,
6458 vki_key_serial_t, keyring);
6459 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6460 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6461 if (ARG3 != (UWord)NULL)
6462 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6465 PRE(sys_keyctl)
6467 switch (ARG1 /* option */) {
6468 case VKI_KEYCTL_GET_KEYRING_ID:
6469 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6470 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6471 int, option, vki_key_serial_t, id, int, create);
6472 break;
6473 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6474 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6475 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6476 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6477 int, option, const char *, name);
6478 if (ARG2 != (UWord)NULL)
6479 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6480 break;
6481 case VKI_KEYCTL_UPDATE:
6482 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6483 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6484 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6485 int, option, vki_key_serial_t, key,
6486 const void *, payload, vki_size_t, plen);
6487 if (ARG3 != (UWord)NULL)
6488 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6489 break;
6490 case VKI_KEYCTL_REVOKE:
6491 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6492 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6493 int, option, vki_key_serial_t, id);
6494 break;
6495 case VKI_KEYCTL_CHOWN:
6496 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6497 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6498 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6499 int, option, vki_key_serial_t, id,
6500 vki_uid_t, uid, vki_gid_t, gid);
6501 break;
6502 case VKI_KEYCTL_SETPERM:
6503 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6504 SARG2, ARG3);
6505 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6506 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6507 break;
6508 case VKI_KEYCTL_DESCRIBE:
6509 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6510 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6511 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6512 int, option, vki_key_serial_t, id,
6513 char *, buffer, vki_size_t, buflen);
6514 if (ARG3 != (UWord)NULL)
6515 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6516 break;
6517 case VKI_KEYCTL_CLEAR:
6518 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6519 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6520 int, option, vki_key_serial_t, keyring);
6521 break;
6522 case VKI_KEYCTL_LINK:
6523 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6524 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6525 vki_key_serial_t, keyring, vki_key_serial_t, key);
6526 break;
6527 case VKI_KEYCTL_UNLINK:
6528 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6529 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6530 vki_key_serial_t, keyring, vki_key_serial_t, key);
6531 break;
6532 case VKI_KEYCTL_SEARCH:
6533 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6534 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6535 ARG4, (HChar*)(Addr)ARG4, SARG5);
6536 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6537 int, option, vki_key_serial_t, keyring,
6538 const char *, type, const char *, description,
6539 vki_key_serial_t, destring);
6540 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6541 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6542 break;
6543 case VKI_KEYCTL_READ:
6544 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6545 "u )", SARG2, ARG3, ARG4);
6546 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6547 int, option, vki_key_serial_t, keyring,
6548 char *, buffer, vki_size_t, buflen);
6549 if (ARG3 != (UWord)NULL)
6550 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6551 break;
6552 case VKI_KEYCTL_INSTANTIATE:
6553 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6554 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6555 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6556 int, option, vki_key_serial_t, key,
6557 char *, payload, vki_size_t, plen,
6558 vki_key_serial_t, keyring);
6559 if (ARG3 != (UWord)NULL)
6560 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6561 break;
6562 case VKI_KEYCTL_NEGATE:
6563 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6564 SARG2, ARG3, SARG4);
6565 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6566 int, option, vki_key_serial_t, key,
6567 unsigned, timeout, vki_key_serial_t, keyring);
6568 break;
6569 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6570 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6571 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6572 int, option, int, reqkey_defl);
6573 break;
6574 case VKI_KEYCTL_SET_TIMEOUT:
6575 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6576 SARG2, ARG3);
6577 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6578 int, option, vki_key_serial_t, key, unsigned, timeout);
6579 break;
6580 case VKI_KEYCTL_ASSUME_AUTHORITY:
6581 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6582 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6583 int, option, vki_key_serial_t, key);
6584 break;
6585 default:
6586 PRINT("sys_keyctl ( %ld ) ", SARG1);
6587 PRE_REG_READ1(long, "keyctl", int, option);
6588 break;
6592 POST(sys_keyctl)
6594 vg_assert(SUCCESS);
6595 switch (ARG1 /* option */) {
6596 case VKI_KEYCTL_DESCRIBE:
6597 case VKI_KEYCTL_READ:
6598 if (RES > ARG4)
6599 POST_MEM_WRITE(ARG3, ARG4);
6600 else
6601 POST_MEM_WRITE(ARG3, RES);
6602 break;
6603 default:
6604 break;
6608 /* ---------------------------------------------------------------------
6609 ioprio_ wrappers
6610 ------------------------------------------------------------------ */
6612 PRE(sys_ioprio_set)
6614 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6615 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6618 PRE(sys_ioprio_get)
6620 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6621 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6624 /* ---------------------------------------------------------------------
6625 _module wrappers
6626 ------------------------------------------------------------------ */
6628 PRE(sys_init_module)
6630 *flags |= SfMayBlock;
6631 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6632 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6633 PRE_REG_READ3(long, "init_module",
6634 void *, umod, unsigned long, len, const char *, uargs);
6635 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6636 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6639 PRE(sys_finit_module)
6641 *flags |= SfMayBlock;
6643 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6644 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6645 PRE_REG_READ3(long, "finit_module",
6646 int, fd, const char *, params, int, flags);
6647 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6650 PRE(sys_delete_module)
6652 *flags |= SfMayBlock;
6653 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6654 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6655 PRE_REG_READ2(long, "delete_module",
6656 const char *, name_user, unsigned int, flags);
6657 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6660 /* ---------------------------------------------------------------------
6661 splice wrappers
6662 ------------------------------------------------------------------ */
6664 PRE(sys_splice)
6666 *flags |= SfMayBlock;
6667 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6668 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6669 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6670 PRE_REG_READ6(vki_ssize_t, "splice",
6671 int, fd_in, vki_loff_t *, off_in,
6672 int, fd_out, vki_loff_t *, off_out,
6673 vki_size_t, len, unsigned int, flags);
6674 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6675 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6676 SET_STATUS_Failure( VKI_EBADF );
6677 } else {
6678 if (ARG2 != 0)
6679 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6680 if (ARG4 != 0)
6681 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6685 PRE(sys_tee)
6687 *flags |= SfMayBlock;
6688 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6689 SARG1, SARG2, ARG3, ARG4);
6690 PRE_REG_READ4(vki_ssize_t, "tee",
6691 int, fd_in, int, fd_out,
6692 vki_size_t, len, unsigned int, flags);
6693 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6694 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6695 SET_STATUS_Failure( VKI_EBADF );
6699 PRE(sys_vmsplice)
6701 Int fdfl;
6702 *flags |= SfMayBlock;
6703 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6704 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6705 PRE_REG_READ4(vki_ssize_t, "splice",
6706 int, fd, struct vki_iovec *, iov,
6707 unsigned long, nr_segs, unsigned int, flags);
6708 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6709 SET_STATUS_Failure( VKI_EBADF );
6710 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6711 SET_STATUS_Failure( VKI_EBADF );
6712 } else {
6713 const struct vki_iovec *iov;
6714 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6715 for (iov = (struct vki_iovec *)(Addr)ARG2;
6716 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6718 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6719 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6720 PRE_MEM_WRITE( "vmsplice(iov[...])",
6721 (Addr)iov->iov_base, iov->iov_len );
6722 else
6723 PRE_MEM_READ( "vmsplice(iov[...])",
6724 (Addr)iov->iov_base, iov->iov_len );
6730 POST(sys_vmsplice)
6732 vg_assert(SUCCESS);
6733 if (RES > 0) {
6734 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6735 vg_assert(fdfl >= 0);
6736 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6738 const struct vki_iovec *iov;
6739 for (iov = (struct vki_iovec *)(Addr)ARG2;
6740 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6742 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6748 /* ---------------------------------------------------------------------
6749 oprofile-related wrappers
6750 ------------------------------------------------------------------ */
6752 #if defined(VGP_x86_linux)
6753 PRE(sys_lookup_dcookie)
6755 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6756 MERGE64(ARG1,ARG2), ARG3, ARG4);
6757 PRE_REG_READ4(long, "lookup_dcookie",
6758 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6759 char *, buf, vki_size_t, len);
6760 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6762 POST(sys_lookup_dcookie)
6764 vg_assert(SUCCESS);
6765 if (ARG3 != (Addr)NULL)
6766 POST_MEM_WRITE( ARG3, RES);
6768 #endif
6770 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6771 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6772 PRE(sys_lookup_dcookie)
6774 *flags |= SfMayBlock;
6775 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6776 PRE_REG_READ3(int, "lookup_dcookie",
6777 unsigned long long, cookie, char *, buf, vki_size_t, len);
6779 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6782 POST(sys_lookup_dcookie)
6784 vg_assert(SUCCESS);
6785 if (ARG2 != (Addr)NULL)
6786 POST_MEM_WRITE( ARG2, RES );
6788 #endif
6790 /* ---------------------------------------------------------------------
6791 fcntl wrappers
6792 ------------------------------------------------------------------ */
6794 PRE(sys_fcntl)
6796 switch (ARG2) {
6797 // These ones ignore ARG3.
6798 case VKI_F_GETFD:
6799 case VKI_F_GETFL:
6800 case VKI_F_GETOWN:
6801 case VKI_F_GETSIG:
6802 case VKI_F_GETLEASE:
6803 case VKI_F_GETPIPE_SZ:
6804 case VKI_F_GET_SEALS:
6805 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6806 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6807 break;
6809 // These ones use ARG3 as "arg".
6810 case VKI_F_DUPFD:
6811 case VKI_F_DUPFD_CLOEXEC:
6812 case VKI_F_SETFD:
6813 case VKI_F_SETFL:
6814 case VKI_F_SETLEASE:
6815 case VKI_F_NOTIFY:
6816 case VKI_F_SETOWN:
6817 case VKI_F_SETSIG:
6818 case VKI_F_SETPIPE_SZ:
6819 case VKI_F_ADD_SEALS:
6820 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6821 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6822 PRE_REG_READ3(long, "fcntl",
6823 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6824 break;
6826 // These ones use ARG3 as "lock".
6827 case VKI_F_GETLK:
6828 case VKI_F_SETLK:
6829 case VKI_F_SETLKW:
6830 case VKI_F_OFD_GETLK:
6831 case VKI_F_OFD_SETLK:
6832 case VKI_F_OFD_SETLKW:
6833 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6834 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6835 PRE_REG_READ3(long, "fcntl",
6836 unsigned int, fd, unsigned int, cmd,
6837 struct vki_flock *, lock);
6839 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6840 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6841 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6842 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6843 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6844 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6845 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6848 break;
6850 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6851 case VKI_F_GETLK64:
6852 case VKI_F_SETLK64:
6853 case VKI_F_SETLKW64:
6854 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6855 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6856 PRE_REG_READ3(long, "fcntl",
6857 unsigned int, fd, unsigned int, cmd,
6858 struct flock64 *, lock);
6860 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6861 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6862 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6863 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6864 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6865 if (ARG2 == VKI_F_GETLK64) {
6866 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6869 break;
6870 # endif
6872 case VKI_F_SETOWN_EX:
6873 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6874 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6875 PRE_REG_READ3(long, "fcntl",
6876 unsigned int, fd, unsigned int, cmd,
6877 struct vki_f_owner_ex *, arg);
6878 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6879 break;
6881 case VKI_F_GETOWN_EX:
6882 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6883 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6884 PRE_REG_READ3(long, "fcntl",
6885 unsigned int, fd, unsigned int, cmd,
6886 struct vki_f_owner_ex *, arg);
6887 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6888 break;
6890 default:
6891 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6892 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6893 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6894 ARG2);
6895 SET_STATUS_Failure( VKI_EINVAL );
6896 break;
6899 # if defined(VGP_x86_linux)
6900 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6901 # else
6902 if (ARG2 == VKI_F_SETLKW)
6903 # endif
6904 *flags |= SfMayBlock;
6907 POST(sys_fcntl)
6909 vg_assert(SUCCESS);
6910 if (ARG2 == VKI_F_DUPFD) {
6911 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6912 VG_(close)(RES);
6913 SET_STATUS_Failure( VKI_EMFILE );
6914 } else {
6915 if (VG_(clo_track_fds))
6916 ML_(record_fd_open_named)(tid, RES);
6919 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6920 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6921 VG_(close)(RES);
6922 SET_STATUS_Failure( VKI_EMFILE );
6923 } else {
6924 if (VG_(clo_track_fds))
6925 ML_(record_fd_open_named)(tid, RES);
6927 } else if (ARG2 == VKI_F_GETOWN_EX) {
6928 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6929 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6930 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6931 POST_FIELD_WRITE(lock->l_pid);
6932 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6933 } else if (ARG2 == VKI_F_GETLK64) {
6934 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6935 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6936 # endif
6940 // XXX: wrapper only suitable for 32-bit systems
6941 PRE(sys_fcntl64)
6943 switch (ARG2) {
6944 // These ones ignore ARG3.
6945 case VKI_F_GETFD:
6946 case VKI_F_GETFL:
6947 case VKI_F_GETOWN:
6948 case VKI_F_SETOWN:
6949 case VKI_F_GETSIG:
6950 case VKI_F_SETSIG:
6951 case VKI_F_GETLEASE:
6952 case VKI_F_GET_SEALS:
6953 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6954 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6955 break;
6957 // These ones use ARG3 as "arg".
6958 case VKI_F_DUPFD:
6959 case VKI_F_DUPFD_CLOEXEC:
6960 case VKI_F_SETFD:
6961 case VKI_F_SETFL:
6962 case VKI_F_SETLEASE:
6963 case VKI_F_NOTIFY:
6964 case VKI_F_ADD_SEALS:
6965 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6966 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6967 PRE_REG_READ3(long, "fcntl64",
6968 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6969 break;
6971 // These ones use ARG3 as "lock".
6972 case VKI_F_GETLK:
6973 case VKI_F_SETLK:
6974 case VKI_F_SETLKW:
6975 # if defined(VGP_x86_linux)
6976 case VKI_F_GETLK64:
6977 case VKI_F_SETLK64:
6978 case VKI_F_SETLKW64:
6979 # endif
6980 case VKI_F_OFD_GETLK:
6981 case VKI_F_OFD_SETLK:
6982 case VKI_F_OFD_SETLKW:
6983 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6984 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6985 PRE_REG_READ3(long, "fcntl64",
6986 unsigned int, fd, unsigned int, cmd,
6987 struct flock64 *, lock);
6988 break;
6990 case VKI_F_SETOWN_EX:
6991 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6992 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6993 PRE_REG_READ3(long, "fcntl",
6994 unsigned int, fd, unsigned int, cmd,
6995 struct vki_f_owner_ex *, arg);
6996 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6997 break;
6999 case VKI_F_GETOWN_EX:
7000 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
7001 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
7002 PRE_REG_READ3(long, "fcntl",
7003 unsigned int, fd, unsigned int, cmd,
7004 struct vki_f_owner_ex *, arg);
7005 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
7006 break;
7009 # if defined(VGP_x86_linux)
7010 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7011 # else
7012 if (ARG2 == VKI_F_SETLKW)
7013 # endif
7014 *flags |= SfMayBlock;
7017 POST(sys_fcntl64)
7019 vg_assert(SUCCESS);
7020 if (ARG2 == VKI_F_DUPFD) {
7021 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
7022 VG_(close)(RES);
7023 SET_STATUS_Failure( VKI_EMFILE );
7024 } else {
7025 if (VG_(clo_track_fds))
7026 ML_(record_fd_open_named)(tid, RES);
7029 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7030 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
7031 VG_(close)(RES);
7032 SET_STATUS_Failure( VKI_EMFILE );
7033 } else {
7034 if (VG_(clo_track_fds))
7035 ML_(record_fd_open_named)(tid, RES);
7037 } else if (ARG2 == VKI_F_GETOWN_EX) {
7038 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7042 /* ---------------------------------------------------------------------
7043 ioctl wrappers
7044 ------------------------------------------------------------------ */
7046 struct vg_drm_version_info {
7047 struct vki_drm_version data;
7048 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7051 PRE(sys_ioctl)
7053 *flags |= SfMayBlock;
7055 ARG2 = (UInt)ARG2;
7057 // We first handle the ones that don't use ARG3 (even as a
7058 // scalar/non-pointer argument).
7059 switch (ARG2 /* request */) {
7061 /* asm-generic/ioctls.h */
7062 case VKI_FIOCLEX:
7063 case VKI_FIONCLEX:
7064 case VKI_TIOCNOTTY:
7066 /* linux perf_event ioctls */
7067 case VKI_PERF_EVENT_IOC_ENABLE:
7068 case VKI_PERF_EVENT_IOC_DISABLE:
7070 /* linux/soundcard interface (ALSA) */
7071 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7072 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7073 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7074 case VKI_SNDRV_PCM_IOCTL_RESET:
7075 case VKI_SNDRV_PCM_IOCTL_START:
7076 case VKI_SNDRV_PCM_IOCTL_DROP:
7077 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7078 case VKI_SNDRV_PCM_IOCTL_RESUME:
7079 case VKI_SNDRV_PCM_IOCTL_XRUN:
7080 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7081 case VKI_SNDRV_TIMER_IOCTL_START:
7082 case VKI_SNDRV_TIMER_IOCTL_STOP:
7083 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7084 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7086 /* SCSI no operand */
7087 case VKI_SCSI_IOCTL_DOORLOCK:
7088 case VKI_SCSI_IOCTL_DOORUNLOCK:
7090 /* CDROM stuff. */
7091 case VKI_CDROM_DISC_STATUS:
7092 case VKI_CDROMSTOP:
7094 /* DVD stuff */
7095 case VKI_DVD_READ_STRUCT:
7097 /* KVM ioctls that don't check for a numeric value as parameter */
7098 case VKI_KVM_S390_ENABLE_SIE:
7099 case VKI_KVM_CREATE_IRQCHIP:
7100 case VKI_KVM_S390_INITIAL_RESET:
7101 case VKI_KVM_KVMCLOCK_CTRL:
7103 /* vhost without parameter */
7104 case VKI_VHOST_SET_OWNER:
7105 case VKI_VHOST_RESET_OWNER:
7107 /* User input device creation */
7108 case VKI_UI_DEV_CREATE:
7109 case VKI_UI_DEV_DESTROY:
7111 /* InfiniBand */
7112 case VKI_IB_USER_MAD_ENABLE_PKEY:
7114 /* Lustre */
7115 case VKI_LL_IOC_GROUP_LOCK:
7116 case VKI_LL_IOC_GROUP_UNLOCK:
7118 /* V4L2 */
7119 case VKI_V4L2_LOG_STATUS:
7121 /* Mesa */
7122 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7124 /* DVB */
7125 case VKI_DMX_STOP:
7126 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7127 PRE_REG_READ2(long, "ioctl",
7128 unsigned int, fd, unsigned int, request);
7129 return;
7131 default:
7132 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7133 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7134 PRE_REG_READ3(long, "ioctl",
7135 unsigned int, fd, unsigned int, request, unsigned long, arg);
7136 break;
7139 // We now handle those that do look at ARG3 (and unknown ones fall into
7140 // this category). Nb: some of these may well belong in the
7141 // doesn't-use-ARG3 switch above.
7142 switch (ARG2 /* request */) {
7144 case VKI_ION_IOC_ALLOC: {
7145 struct vki_ion_allocation_data* data
7146 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7147 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7148 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7149 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7150 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7151 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7152 break;
7154 case VKI_ION_IOC_MAP: {
7155 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7156 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7157 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7158 break;
7160 case VKI_ION_IOC_IMPORT: {
7161 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7162 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7163 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7164 break;
7167 case VKI_SYNC_IOC_MERGE: {
7168 struct vki_sync_merge_data* data =
7169 (struct vki_sync_merge_data*)(Addr)ARG3;
7170 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7171 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7172 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7173 break;
7176 case VKI_TCSETS:
7177 case VKI_TCSETSW:
7178 case VKI_TCSETSF:
7179 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7180 break;
7181 case VKI_TCGETS:
7182 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7183 break;
7184 case VKI_TCSETA:
7185 case VKI_TCSETAW:
7186 case VKI_TCSETAF:
7187 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7188 break;
7189 case VKI_TCGETA:
7190 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7191 break;
7192 case VKI_TCSBRK:
7193 case VKI_TCXONC:
7194 case VKI_TCSBRKP:
7195 case VKI_TCFLSH:
7196 case VKI_TIOCSIG:
7197 /* These just take an int by value */
7198 break;
7199 case VKI_TIOCGWINSZ:
7200 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7201 break;
7202 case VKI_TIOCSWINSZ:
7203 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7204 break;
7205 case VKI_TIOCMBIS:
7206 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7207 break;
7208 case VKI_TIOCMBIC:
7209 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7210 break;
7211 case VKI_TIOCMSET:
7212 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7213 break;
7214 case VKI_TIOCMGET:
7215 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7216 break;
7217 case VKI_TIOCLINUX:
7218 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7219 if (*(char *)(Addr)ARG3 == 11) {
7220 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7222 break;
7223 case VKI_TIOCGPGRP:
7224 /* Get process group ID for foreground processing group. */
7225 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7226 break;
7227 case VKI_TIOCSPGRP:
7228 /* Set a process group ID? */
7229 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7230 break;
7231 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7232 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7233 break;
7234 case VKI_TIOCSCTTY:
7235 /* Just takes an int value. */
7236 break;
7237 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7238 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7239 break;
7240 case VKI_FIONBIO:
7241 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7242 break;
7243 case VKI_FIOASYNC:
7244 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7245 break;
7246 case VKI_FIONREAD: /* identical to SIOCINQ */
7247 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7248 break;
7249 case VKI_FIOQSIZE:
7250 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7251 break;
7253 case VKI_TIOCSERGETLSR:
7254 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7255 break;
7256 case VKI_TIOCGICOUNT:
7257 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7258 sizeof(struct vki_serial_icounter_struct) );
7259 break;
7261 case VKI_SG_SET_COMMAND_Q:
7262 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7263 break;
7264 case VKI_SG_IO:
7265 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7267 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7268 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7269 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7270 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7271 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7274 break;
7275 case VKI_SG_GET_SCSI_ID:
7276 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7277 break;
7278 case VKI_SG_SET_RESERVED_SIZE:
7279 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7280 break;
7281 case VKI_SG_SET_TIMEOUT:
7282 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7283 break;
7284 case VKI_SG_GET_RESERVED_SIZE:
7285 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7286 break;
7287 case VKI_SG_GET_TIMEOUT:
7288 break;
7289 case VKI_SG_GET_VERSION_NUM:
7290 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7291 break;
7292 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7293 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7294 break;
7295 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7296 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7297 break;
7299 case VKI_IIOCGETCPS:
7300 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7301 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7302 break;
7303 case VKI_IIOCNETGPN:
7304 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7305 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7306 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7307 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7308 sizeof(vki_isdn_net_ioctl_phone) );
7309 break;
7311 /* These all use struct ifreq AFAIK */
7312 case VKI_SIOCGIFINDEX: /* get iface index */
7313 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7314 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7315 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7316 break;
7317 case VKI_SIOCGIFFLAGS: /* get flags */
7318 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7319 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7320 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7321 break;
7322 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7323 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7324 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7325 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7326 break;
7327 case VKI_SIOCGIFMTU: /* get MTU size */
7328 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7329 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7330 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7331 break;
7332 case VKI_SIOCGIFADDR: /* get PA address */
7333 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7334 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7335 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7336 break;
7337 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7338 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7339 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7340 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7341 break;
7342 case VKI_SIOCGIFMETRIC: /* get metric */
7343 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7344 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7345 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7346 break;
7347 case VKI_SIOCGIFMAP: /* Get device parameters */
7348 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7349 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7350 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7351 break;
7352 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7353 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7354 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7355 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7356 break;
7357 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7358 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7359 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7360 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7361 break;
7362 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7363 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7364 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7365 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7366 break;
7367 case VKI_SIOCGIFNAME: /* get iface name */
7368 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7369 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7370 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7371 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7372 break;
7374 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7375 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7376 // The kernel will have to look at ifr_data to determine which operation
7377 // to perform.
7378 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7379 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7381 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7383 // Is this correct? Is ifr_name *always* looked at?
7384 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7385 (Addr)ir->vki_ifr_name );
7387 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7388 // the whole structure is defined. So in this case, just check it's
7389 // accessible.
7390 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7391 case VKI_ETHTOOL_GSET:
7392 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7393 (Addr)ir, sizeof(struct vki_ifreq) );
7394 break;
7395 default:
7396 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7397 (Addr)ir, sizeof(struct vki_ifreq) );
7398 break;
7401 // Now perform the relevant pre-action for the operation.
7402 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7403 case VKI_ETHTOOL_GSET:
7404 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7405 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7406 break;
7407 case VKI_ETHTOOL_SSET:
7408 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7409 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7410 break;
7411 case VKI_ETHTOOL_GDRVINFO:
7412 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7413 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7414 break;
7415 case VKI_ETHTOOL_GREGS:
7416 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7417 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7418 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7419 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7420 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7421 break;
7422 case VKI_ETHTOOL_GWOL:
7423 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7424 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7425 break;
7426 case VKI_ETHTOOL_SWOL:
7427 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7428 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7429 break;
7430 case VKI_ETHTOOL_GMSGLVL:
7431 case VKI_ETHTOOL_GLINK:
7432 case VKI_ETHTOOL_GRXCSUM:
7433 case VKI_ETHTOOL_GSG:
7434 case VKI_ETHTOOL_GTSO:
7435 case VKI_ETHTOOL_GUFO:
7436 case VKI_ETHTOOL_GGSO:
7437 case VKI_ETHTOOL_GFLAGS:
7438 case VKI_ETHTOOL_GGRO:
7439 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7440 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7441 break;
7442 case VKI_ETHTOOL_SMSGLVL:
7443 case VKI_ETHTOOL_SRXCSUM:
7444 case VKI_ETHTOOL_SSG:
7445 case VKI_ETHTOOL_STSO:
7446 case VKI_ETHTOOL_SUFO:
7447 case VKI_ETHTOOL_SGSO:
7448 case VKI_ETHTOOL_SFLAGS:
7449 case VKI_ETHTOOL_SGRO:
7450 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7451 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7452 break;
7453 case VKI_ETHTOOL_NWAY_RST:
7454 break;
7455 case VKI_ETHTOOL_GRINGPARAM:
7456 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7457 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7458 break;
7459 case VKI_ETHTOOL_SRINGPARAM:
7460 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7461 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7462 break;
7463 case VKI_ETHTOOL_TEST:
7464 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7465 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7466 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7467 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7468 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7469 break;
7470 case VKI_ETHTOOL_PHYS_ID:
7471 break;
7472 case VKI_ETHTOOL_GPERMADDR:
7473 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7474 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7475 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7476 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7477 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7478 break;
7479 case VKI_ETHTOOL_RESET:
7480 break;
7481 case VKI_ETHTOOL_GSSET_INFO:
7482 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7483 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7484 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7485 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7486 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7487 break;
7488 case VKI_ETHTOOL_GFEATURES:
7489 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7490 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7491 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7492 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7493 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7494 break;
7495 case VKI_ETHTOOL_SFEATURES:
7496 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7497 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7498 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7499 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7500 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7501 break;
7502 case VKI_ETHTOOL_GCHANNELS:
7503 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7504 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7505 break;
7506 case VKI_ETHTOOL_SCHANNELS:
7507 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7508 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7509 break;
7510 case VKI_ETHTOOL_GET_TS_INFO:
7511 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7512 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7513 break;
7515 break;
7516 } /* case VKI_SIOCETHTOOL */
7518 case VKI_SIOCGMIIPHY: /* get hardware entry */
7519 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7520 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7521 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7522 break;
7523 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7524 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7525 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7526 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7527 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7528 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7529 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7530 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7531 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7532 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7533 sizeof(struct vki_ifreq));
7534 break;
7535 case VKI_SIOCGIFCONF: /* get iface list */
7536 /* WAS:
7537 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7538 KERNEL_DO_SYSCALL(tid,RES);
7539 if (!VG_(is_kerror)(RES) && RES == 0)
7540 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7542 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7543 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7544 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7545 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7546 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7547 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7548 if ( ARG3 ) {
7549 // TODO len must be readable and writable
7550 // buf pointer only needs to be readable
7551 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7552 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7553 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7555 break;
7556 case VKI_SIOCGSTAMP:
7557 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7558 break;
7559 case VKI_SIOCGSTAMPNS:
7560 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7561 break;
7562 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7563 the number of bytes currently in that socket's send buffer.
7564 It writes this value as an int to the memory location
7565 indicated by the third argument of ioctl(2). */
7566 case VKI_SIOCOUTQ:
7567 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7568 break;
7569 case VKI_SIOCGRARP: /* get RARP table entry */
7570 case VKI_SIOCGARP: /* get ARP table entry */
7571 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7572 break;
7574 case VKI_SIOCSIFFLAGS: /* set flags */
7575 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7576 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7577 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7578 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7579 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7580 break;
7581 case VKI_SIOCSIFMAP: /* Set device parameters */
7582 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7583 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7584 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7585 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7586 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7587 break;
7588 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7589 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7590 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7591 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7592 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7593 sizeof(struct vki_hwtstamp_config) );
7594 break;
7595 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7596 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7597 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7598 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7599 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7600 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7601 break;
7602 case VKI_SIOCSIFADDR: /* set PA address */
7603 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7604 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7605 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7606 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7607 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7608 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7609 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7610 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7611 break;
7612 case VKI_SIOCSIFMETRIC: /* set metric */
7613 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7614 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7615 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7616 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7617 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7618 break;
7619 case VKI_SIOCSIFMTU: /* set MTU size */
7620 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7621 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7622 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7623 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7624 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7625 break;
7626 case VKI_SIOCSIFHWADDR: /* set hardware address */
7627 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7628 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7629 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7630 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7631 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7632 break;
7633 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7634 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7635 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7636 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7637 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7638 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7639 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7640 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7641 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7642 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7643 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7644 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7645 break;
7646 /* Routing table calls. */
7647 case VKI_SIOCADDRT: /* add routing table entry */
7648 case VKI_SIOCDELRT: /* delete routing table entry */
7649 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7650 sizeof(struct vki_rtentry));
7651 break;
7653 /* tun/tap related ioctls */
7654 case VKI_TUNSETNOCSUM:
7655 case VKI_TUNSETDEBUG:
7656 break;
7657 case VKI_TUNSETIFF:
7658 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7659 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7660 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7661 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7662 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7663 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7664 break;
7665 case VKI_TUNSETPERSIST:
7666 case VKI_TUNSETOWNER:
7667 case VKI_TUNSETLINK:
7668 case VKI_TUNSETGROUP:
7669 break;
7670 case VKI_TUNGETFEATURES:
7671 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7672 break;
7673 case VKI_TUNSETOFFLOAD:
7674 break;
7675 case VKI_TUNGETIFF:
7676 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7677 break;
7678 case VKI_TUNGETSNDBUF:
7679 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7680 break;
7681 case VKI_TUNSETSNDBUF:
7682 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7683 break;
7684 case VKI_TUNGETVNETHDRSZ:
7685 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7686 break;
7687 case VKI_TUNSETVNETHDRSZ:
7688 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7689 break;
7690 case VKI_TUNSETQUEUE:
7691 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7692 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7693 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7694 break;
7695 case VKI_TUNSETIFINDEX:
7696 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7697 break;
7699 /* RARP cache control calls. */
7700 case VKI_SIOCDRARP: /* delete RARP table entry */
7701 case VKI_SIOCSRARP: /* set RARP table entry */
7702 /* ARP cache control calls. */
7703 case VKI_SIOCSARP: /* set ARP table entry */
7704 case VKI_SIOCDARP: /* delete ARP table entry */
7705 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7706 break;
7708 case VKI_SIOCGPGRP:
7709 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7710 break;
7711 case VKI_SIOCSPGRP:
7712 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7713 //tst->sys_flags &= ~SfMayBlock;
7714 break;
7716 case VKI_SIOCATMARK:
7717 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7718 break;
7720 /* linux/soundcard interface (OSS) */
7721 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7722 case VKI_SNDCTL_SEQ_GETINCOUNT:
7723 case VKI_SNDCTL_SEQ_PERCMODE:
7724 case VKI_SNDCTL_SEQ_TESTMIDI:
7725 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7726 case VKI_SNDCTL_SEQ_NRSYNTHS:
7727 case VKI_SNDCTL_SEQ_NRMIDIS:
7728 case VKI_SNDCTL_SEQ_GETTIME:
7729 case VKI_SNDCTL_DSP_GETBLKSIZE:
7730 case VKI_SNDCTL_DSP_GETFMTS:
7731 case VKI_SNDCTL_DSP_GETTRIGGER:
7732 case VKI_SNDCTL_DSP_GETODELAY:
7733 case VKI_SNDCTL_DSP_GETSPDIF:
7734 case VKI_SNDCTL_DSP_GETCAPS:
7735 case VKI_SOUND_PCM_READ_RATE:
7736 case VKI_SOUND_PCM_READ_CHANNELS:
7737 case VKI_SOUND_PCM_READ_BITS:
7738 case VKI_SOUND_PCM_READ_FILTER:
7739 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7740 ARG3, sizeof(int));
7741 break;
7742 case VKI_SNDCTL_SEQ_CTRLRATE:
7743 case VKI_SNDCTL_DSP_SPEED:
7744 case VKI_SNDCTL_DSP_STEREO:
7745 case VKI_SNDCTL_DSP_CHANNELS:
7746 case VKI_SOUND_PCM_WRITE_FILTER:
7747 case VKI_SNDCTL_DSP_SUBDIVIDE:
7748 case VKI_SNDCTL_DSP_SETFRAGMENT:
7749 case VKI_SNDCTL_DSP_SETFMT:
7750 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7751 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7752 case VKI_SNDCTL_TMR_TIMEBASE:
7753 case VKI_SNDCTL_TMR_TEMPO:
7754 case VKI_SNDCTL_TMR_SOURCE:
7755 case VKI_SNDCTL_MIDI_PRETIME:
7756 case VKI_SNDCTL_MIDI_MPUMODE:
7757 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7758 ARG3, sizeof(int));
7759 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7760 ARG3, sizeof(int));
7761 break;
7762 case VKI_SNDCTL_DSP_GETOSPACE:
7763 case VKI_SNDCTL_DSP_GETISPACE:
7764 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7765 ARG3, sizeof(vki_audio_buf_info));
7766 break;
7767 case VKI_SNDCTL_DSP_NONBLOCK:
7768 break;
7769 case VKI_SNDCTL_DSP_SETTRIGGER:
7770 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7771 ARG3, sizeof(int));
7772 break;
7774 case VKI_SNDCTL_DSP_POST:
7775 case VKI_SNDCTL_DSP_RESET:
7776 case VKI_SNDCTL_DSP_SYNC:
7777 case VKI_SNDCTL_DSP_SETSYNCRO:
7778 case VKI_SNDCTL_DSP_SETDUPLEX:
7779 break;
7781 /* linux/soundcard interface (ALSA) */
7782 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7783 case VKI_SNDRV_PCM_IOCTL_LINK:
7784 /* these just take an int by value */
7785 break;
7786 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7787 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7788 break;
7789 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7790 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7791 break;
7792 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7793 struct vki_snd_ctl_elem_list *data =
7794 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7795 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7796 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7797 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7798 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7799 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7800 if (data->pids) {
7801 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7803 break;
7805 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7806 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7807 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7808 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7809 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7810 break;
7812 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7813 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7814 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7815 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7816 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7817 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7818 break;
7821 /* Real Time Clock (/dev/rtc) ioctls */
7822 case VKI_RTC_UIE_ON:
7823 case VKI_RTC_UIE_OFF:
7824 case VKI_RTC_AIE_ON:
7825 case VKI_RTC_AIE_OFF:
7826 case VKI_RTC_PIE_ON:
7827 case VKI_RTC_PIE_OFF:
7828 case VKI_RTC_IRQP_SET:
7829 break;
7830 case VKI_RTC_RD_TIME:
7831 case VKI_RTC_ALM_READ:
7832 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7833 ARG3, sizeof(struct vki_rtc_time));
7834 break;
7835 case VKI_RTC_ALM_SET:
7836 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7837 break;
7838 case VKI_RTC_IRQP_READ:
7839 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7840 break;
7842 /* Block devices */
7843 case VKI_BLKROSET:
7844 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7845 break;
7846 case VKI_BLKROGET:
7847 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7848 break;
7849 case VKI_BLKGETSIZE:
7850 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7851 break;
7852 case VKI_BLKFLSBUF:
7853 break;
7854 case VKI_BLKRASET:
7855 break;
7856 case VKI_BLKRAGET:
7857 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7858 break;
7859 case VKI_BLKFRASET:
7860 break;
7861 case VKI_BLKFRAGET:
7862 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7863 break;
7864 case VKI_BLKSECTGET:
7865 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7866 break;
7867 case VKI_BLKSSZGET:
7868 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7869 break;
7870 case VKI_BLKBSZGET:
7871 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7872 break;
7873 case VKI_BLKBSZSET:
7874 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7875 break;
7876 case VKI_BLKGETSIZE64:
7877 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7878 break;
7879 case VKI_BLKPBSZGET:
7880 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7881 break;
7882 case VKI_BLKIOMIN:
7883 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7884 break;
7885 case VKI_BLKIOOPT:
7886 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7887 break;
7888 case VKI_BLKALIGNOFF:
7889 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7890 break;
7891 case VKI_BLKDISCARDZEROES:
7892 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7893 break;
7894 case VKI_BLKREPORTZONE:
7895 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7896 sizeof(struct vki_blk_zone_report));
7897 break;
7898 case VKI_BLKRESETZONE:
7899 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7900 sizeof(struct vki_blk_zone_range));
7901 break;
7903 /* Hard disks */
7904 case VKI_HDIO_GETGEO: /* 0x0301 */
7905 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7906 break;
7907 case VKI_HDIO_GET_DMA: /* 0x030b */
7908 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7909 break;
7910 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7911 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7912 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7913 break;
7915 /* SCSI */
7916 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7917 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7918 break;
7919 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7920 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7921 break;
7923 /* CD ROM stuff (??) */
7924 case VKI_CDROM_GET_MCN:
7925 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7926 sizeof(struct vki_cdrom_mcn) );
7927 break;
7928 case VKI_CDROM_SEND_PACKET:
7929 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7930 sizeof(struct vki_cdrom_generic_command));
7931 break;
7932 case VKI_CDROMSUBCHNL:
7933 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7934 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7935 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7936 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7937 sizeof(struct vki_cdrom_subchnl));
7938 break;
7939 case VKI_CDROMREADMODE1: /*0x530d*/
7940 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7941 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7942 break;
7943 case VKI_CDROMREADMODE2: /*0x530c*/
7944 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7945 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7946 break;
7947 case VKI_CDROMREADTOCHDR:
7948 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7949 sizeof(struct vki_cdrom_tochdr));
7950 break;
7951 case VKI_CDROMREADTOCENTRY:
7952 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7953 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7954 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7955 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7956 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7957 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7958 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7959 sizeof(struct vki_cdrom_tocentry));
7960 break;
7961 case VKI_CDROMMULTISESSION: /* 0x5310 */
7962 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7963 sizeof(struct vki_cdrom_multisession));
7964 break;
7965 case VKI_CDROMVOLREAD: /* 0x5313 */
7966 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7967 sizeof(struct vki_cdrom_volctrl));
7968 break;
7969 case VKI_CDROMREADRAW: /* 0x5314 */
7970 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7971 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7972 break;
7973 case VKI_CDROMREADAUDIO: /* 0x530e */
7974 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7975 sizeof (struct vki_cdrom_read_audio));
7976 if ( ARG3 ) {
7977 /* ToDo: don't do any of the following if the structure is invalid */
7978 struct vki_cdrom_read_audio *cra =
7979 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7980 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7981 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7983 break;
7984 case VKI_CDROMPLAYMSF:
7985 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7986 break;
7987 /* The following two are probably bogus (should check args
7988 for readability). JRS 20021117 */
7989 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7990 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7991 break;
7992 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7993 break;
7995 case VKI_FIGETBSZ:
7996 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7997 break;
7998 case VKI_FIBMAP:
7999 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
8000 break;
8001 case VKI_FICLONE:
8002 /* The direction of FICLONE (W) is incorrectly specified
8003 * as it expects a file descriptor and not a pointer to
8004 * user data */
8005 break;
8007 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
8008 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
8009 sizeof(struct vki_fb_var_screeninfo));
8010 break;
8011 case VKI_FBIOPUT_VSCREENINFO:
8012 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
8013 sizeof(struct vki_fb_var_screeninfo));
8014 break;
8015 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
8016 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
8017 sizeof(struct vki_fb_fix_screeninfo));
8018 break;
8019 case VKI_FBIOPAN_DISPLAY:
8020 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
8021 sizeof(struct vki_fb_var_screeninfo));
8023 break;
8024 case VKI_PPCLAIM:
8025 case VKI_PPEXCL:
8026 case VKI_PPYIELD:
8027 case VKI_PPRELEASE:
8028 break;
8029 case VKI_PPSETMODE:
8030 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
8031 break;
8032 case VKI_PPGETMODE:
8033 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
8034 break;
8035 case VKI_PPSETPHASE:
8036 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
8037 break;
8038 case VKI_PPGETPHASE:
8039 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
8040 break;
8041 case VKI_PPGETMODES:
8042 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8043 break;
8044 case VKI_PPSETFLAGS:
8045 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8046 break;
8047 case VKI_PPGETFLAGS:
8048 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8049 break;
8050 case VKI_PPRSTATUS:
8051 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8052 break;
8053 case VKI_PPRDATA:
8054 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8055 break;
8056 case VKI_PPRCONTROL:
8057 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8058 break;
8059 case VKI_PPWDATA:
8060 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8061 break;
8062 case VKI_PPWCONTROL:
8063 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8064 break;
8065 case VKI_PPFCONTROL:
8066 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8067 break;
8068 case VKI_PPDATADIR:
8069 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8070 break;
8071 case VKI_PPNEGOT:
8072 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8073 break;
8074 case VKI_PPWCTLONIRQ:
8075 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8076 break;
8077 case VKI_PPCLRIRQ:
8078 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8079 break;
8080 case VKI_PPSETTIME:
8081 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8082 break;
8083 case VKI_PPGETTIME:
8084 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8085 break;
8087 case VKI_GIO_FONT:
8088 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8089 break;
8090 case VKI_PIO_FONT:
8091 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8092 break;
8094 case VKI_GIO_FONTX:
8095 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8096 if ( ARG3 ) {
8097 /* ToDo: don't do any of the following if the structure is invalid */
8098 struct vki_consolefontdesc *cfd =
8099 (struct vki_consolefontdesc *)(Addr)ARG3;
8100 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8101 32 * cfd->charcount );
8103 break;
8104 case VKI_PIO_FONTX:
8105 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8106 if ( ARG3 ) {
8107 /* ToDo: don't do any of the following if the structure is invalid */
8108 struct vki_consolefontdesc *cfd =
8109 (struct vki_consolefontdesc *)(Addr)ARG3;
8110 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8111 32 * cfd->charcount );
8113 break;
8115 case VKI_PIO_FONTRESET:
8116 break;
8118 case VKI_GIO_CMAP:
8119 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8120 break;
8121 case VKI_PIO_CMAP:
8122 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8123 break;
8125 case VKI_KIOCSOUND:
8126 case VKI_KDMKTONE:
8127 break;
8129 case VKI_KDGETLED:
8130 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8131 break;
8132 case VKI_KDSETLED:
8133 break;
8135 case VKI_KDGKBTYPE:
8136 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8137 break;
8139 case VKI_KDADDIO:
8140 case VKI_KDDELIO:
8141 case VKI_KDENABIO:
8142 case VKI_KDDISABIO:
8143 break;
8145 case VKI_KDSETMODE:
8146 break;
8147 case VKI_KDGETMODE:
8148 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8149 break;
8151 case VKI_KDMAPDISP:
8152 case VKI_KDUNMAPDISP:
8153 break;
8155 case VKI_GIO_SCRNMAP:
8156 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8157 break;
8158 case VKI_PIO_SCRNMAP:
8159 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8160 break;
8161 case VKI_GIO_UNISCRNMAP:
8162 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8163 VKI_E_TABSZ * sizeof(unsigned short) );
8164 break;
8165 case VKI_PIO_UNISCRNMAP:
8166 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8167 VKI_E_TABSZ * sizeof(unsigned short) );
8168 break;
8170 case VKI_GIO_UNIMAP:
8171 if ( ARG3 ) {
8172 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8173 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8174 sizeof(unsigned short));
8175 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8176 sizeof(struct vki_unipair *));
8177 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8178 desc->entry_ct * sizeof(struct vki_unipair));
8180 break;
8181 case VKI_PIO_UNIMAP:
8182 if ( ARG3 ) {
8183 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8184 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8185 sizeof(unsigned short) );
8186 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8187 sizeof(struct vki_unipair *) );
8188 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8189 desc->entry_ct * sizeof(struct vki_unipair) );
8191 break;
8192 case VKI_PIO_UNIMAPCLR:
8193 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8194 break;
8196 case VKI_KDGKBMODE:
8197 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8198 break;
8199 case VKI_KDSKBMODE:
8200 break;
8202 case VKI_KDGKBMETA:
8203 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8204 break;
8205 case VKI_KDSKBMETA:
8206 break;
8208 case VKI_KDGKBLED:
8209 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8210 break;
8211 case VKI_KDSKBLED:
8212 break;
8214 case VKI_KDGKBENT:
8215 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8216 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8217 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8218 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8219 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8220 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8221 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8222 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8223 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8224 break;
8225 case VKI_KDSKBENT:
8226 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
8227 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8228 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8229 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
8230 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8231 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8232 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8233 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8234 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8235 break;
8237 case VKI_KDGKBSENT:
8238 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8239 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8240 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8241 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8242 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8243 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8244 break;
8245 case VKI_KDSKBSENT:
8246 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8247 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8248 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8249 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8250 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8251 break;
8253 case VKI_KDGKBDIACR:
8254 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8255 break;
8256 case VKI_KDSKBDIACR:
8257 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8258 break;
8260 case VKI_KDGETKEYCODE:
8261 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8262 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8263 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8264 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8265 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8266 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8267 break;
8268 case VKI_KDSETKEYCODE:
8269 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8270 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8271 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8272 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8273 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8274 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8275 break;
8277 case VKI_KDSIGACCEPT:
8278 break;
8280 case VKI_KDKBDREP:
8281 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8282 break;
8284 case VKI_KDFONTOP:
8285 if ( ARG3 ) {
8286 struct vki_console_font_op *op =
8287 (struct vki_console_font_op *) (Addr)ARG3;
8288 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8289 sizeof(struct vki_console_font_op) );
8290 switch ( op->op ) {
8291 case VKI_KD_FONT_OP_SET:
8292 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8293 (Addr)op->data,
8294 (op->width + 7) / 8 * 32 * op->charcount );
8295 break;
8296 case VKI_KD_FONT_OP_GET:
8297 if ( op->data )
8298 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8299 (Addr)op->data,
8300 (op->width + 7) / 8 * 32 * op->charcount );
8301 break;
8302 case VKI_KD_FONT_OP_SET_DEFAULT:
8303 if ( op->data )
8304 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8305 (Addr)op->data );
8306 break;
8307 case VKI_KD_FONT_OP_COPY:
8308 break;
8311 break;
8313 case VKI_VT_OPENQRY:
8314 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8315 break;
8316 case VKI_VT_GETMODE:
8317 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8318 break;
8319 case VKI_VT_SETMODE:
8320 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8321 break;
8322 case VKI_VT_GETSTATE:
8323 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8324 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8325 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8326 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8327 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8328 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8329 break;
8330 case VKI_VT_RELDISP:
8331 case VKI_VT_ACTIVATE:
8332 case VKI_VT_WAITACTIVE:
8333 case VKI_VT_DISALLOCATE:
8334 break;
8335 case VKI_VT_RESIZE:
8336 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8337 break;
8338 case VKI_VT_RESIZEX:
8339 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8340 break;
8341 case VKI_VT_LOCKSWITCH:
8342 case VKI_VT_UNLOCKSWITCH:
8343 break;
8345 case VKI_USBDEVFS_CONTROL:
8346 if ( ARG3 ) {
8347 struct vki_usbdevfs_ctrltransfer *vkuc =
8348 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8349 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8350 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8351 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8352 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8353 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8354 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8355 if (vkuc->bRequestType & 0x80)
8356 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8357 else
8358 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8360 break;
8361 case VKI_USBDEVFS_BULK:
8362 if ( ARG3 ) {
8363 struct vki_usbdevfs_bulktransfer *vkub =
8364 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8365 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8366 if (vkub->ep & 0x80)
8367 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8368 else
8369 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8371 break;
8372 case VKI_USBDEVFS_GETDRIVER:
8373 if ( ARG3 ) {
8374 struct vki_usbdevfs_getdriver *vkugd =
8375 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8376 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8378 break;
8379 case VKI_USBDEVFS_SUBMITURB:
8380 if ( ARG3 ) {
8381 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8383 /* Not the whole struct needs to be initialized */
8384 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8385 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8386 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8387 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8388 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8389 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8390 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8391 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8392 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8393 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8394 if (vkusp->bRequestType & 0x80)
8395 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8396 else
8397 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8398 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8399 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8400 int total_length = 0;
8401 int i;
8402 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8403 for(i=0; i<vkuu->number_of_packets; i++) {
8404 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8405 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));
8406 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8407 total_length += vkuu->iso_frame_desc[i].length;
8409 if (vkuu->endpoint & 0x80)
8410 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8411 else
8412 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8413 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8414 } else {
8415 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8416 if (vkuu->endpoint & 0x80)
8417 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8418 else
8419 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8420 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8423 break;
8424 case VKI_USBDEVFS_DISCARDURB:
8425 break;
8426 case VKI_USBDEVFS_REAPURB:
8427 if ( ARG3 ) {
8428 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8430 break;
8431 case VKI_USBDEVFS_REAPURBNDELAY:
8432 if ( ARG3 ) {
8433 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8435 break;
8436 case VKI_USBDEVFS_CONNECTINFO:
8437 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8438 break;
8439 case VKI_USBDEVFS_IOCTL:
8440 if ( ARG3 ) {
8441 struct vki_usbdevfs_ioctl *vkui =
8442 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8443 UInt dir2, size2;
8444 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8445 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8446 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8447 if (size2 > 0) {
8448 if (dir2 & _VKI_IOC_WRITE)
8449 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8450 else if (dir2 & _VKI_IOC_READ)
8451 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8454 break;
8455 case VKI_USBDEVFS_RESET:
8456 break;
8458 /* I2C (/dev/i2c-*) ioctls */
8459 case VKI_I2C_SLAVE:
8460 case VKI_I2C_SLAVE_FORCE:
8461 case VKI_I2C_TENBIT:
8462 case VKI_I2C_PEC:
8463 break;
8464 case VKI_I2C_FUNCS:
8465 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8466 break;
8467 case VKI_I2C_RDWR:
8468 if ( ARG3 ) {
8469 struct vki_i2c_rdwr_ioctl_data *vkui =
8470 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8471 UInt i;
8472 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8473 for (i=0; i < vkui->nmsgs; i++) {
8474 struct vki_i2c_msg *msg = vkui->msgs + i;
8475 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8476 if (msg->flags & VKI_I2C_M_RD)
8477 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8478 else
8479 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8482 break;
8483 case VKI_I2C_SMBUS:
8484 if ( ARG3 ) {
8485 struct vki_i2c_smbus_ioctl_data *vkis
8486 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8487 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8488 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8489 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8490 (Addr)&vkis->size, sizeof(vkis->size));
8491 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8492 (Addr)&vkis->command, sizeof(vkis->command));
8493 /* i2c_smbus_write_quick hides its value in read_write, so
8494 this variable can have a different meaning */
8495 /* to make matters worse i2c_smbus_write_byte stores its
8496 value in command */
8497 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8498 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8499 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8500 /* the rest uses the byte array to store the data,
8501 some the first byte for size */
8502 UInt size;
8503 switch(vkis->size) {
8504 case VKI_I2C_SMBUS_BYTE_DATA:
8505 size = 1;
8506 break;
8507 case VKI_I2C_SMBUS_WORD_DATA:
8508 case VKI_I2C_SMBUS_PROC_CALL:
8509 size = 2;
8510 break;
8511 case VKI_I2C_SMBUS_BLOCK_DATA:
8512 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8513 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8514 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8515 size = 1 + vkis->data->block[0];
8516 break;
8517 default:
8518 size = 0;
8521 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8522 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8523 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8524 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8525 ".i2c_smbus_ioctl_data.data",
8526 (Addr)&vkis->data->block[0], size);
8527 else
8528 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8529 "i2c_smbus_ioctl_data.data",
8530 (Addr)&vkis->data->block[0], size);
8533 break;
8535 /* Wireless extensions ioctls */
8536 case VKI_SIOCSIWCOMMIT:
8537 case VKI_SIOCSIWNWID:
8538 case VKI_SIOCSIWFREQ:
8539 case VKI_SIOCSIWMODE:
8540 case VKI_SIOCSIWSENS:
8541 case VKI_SIOCSIWRANGE:
8542 case VKI_SIOCSIWPRIV:
8543 case VKI_SIOCSIWSTATS:
8544 case VKI_SIOCSIWSPY:
8545 case VKI_SIOCSIWTHRSPY:
8546 case VKI_SIOCSIWAP:
8547 case VKI_SIOCSIWSCAN:
8548 case VKI_SIOCSIWESSID:
8549 case VKI_SIOCSIWRATE:
8550 case VKI_SIOCSIWNICKN:
8551 case VKI_SIOCSIWRTS:
8552 case VKI_SIOCSIWFRAG:
8553 case VKI_SIOCSIWTXPOW:
8554 case VKI_SIOCSIWRETRY:
8555 case VKI_SIOCSIWENCODE:
8556 case VKI_SIOCSIWPOWER:
8557 case VKI_SIOCSIWGENIE:
8558 case VKI_SIOCSIWMLME:
8559 case VKI_SIOCSIWAUTH:
8560 case VKI_SIOCSIWENCODEEXT:
8561 case VKI_SIOCSIWPMKSA:
8562 break;
8563 case VKI_SIOCGIWNAME:
8564 if (ARG3) {
8565 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8566 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8567 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8569 break;
8570 case VKI_SIOCGIWNWID:
8571 case VKI_SIOCGIWSENS:
8572 case VKI_SIOCGIWRATE:
8573 case VKI_SIOCGIWRTS:
8574 case VKI_SIOCGIWFRAG:
8575 case VKI_SIOCGIWTXPOW:
8576 case VKI_SIOCGIWRETRY:
8577 case VKI_SIOCGIWPOWER:
8578 case VKI_SIOCGIWAUTH:
8579 if (ARG3) {
8580 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8581 "RETRY|PARAM|AUTH])",
8582 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8583 sizeof(struct vki_iw_param));
8585 break;
8586 case VKI_SIOCGIWFREQ:
8587 if (ARG3) {
8588 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8589 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8590 sizeof(struct vki_iw_freq));
8592 break;
8593 case VKI_SIOCGIWMODE:
8594 if (ARG3) {
8595 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8596 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8597 sizeof(__vki_u32));
8599 break;
8600 case VKI_SIOCGIWRANGE:
8601 case VKI_SIOCGIWPRIV:
8602 case VKI_SIOCGIWSTATS:
8603 case VKI_SIOCGIWSPY:
8604 case VKI_SIOCGIWTHRSPY:
8605 case VKI_SIOCGIWAPLIST:
8606 case VKI_SIOCGIWSCAN:
8607 case VKI_SIOCGIWESSID:
8608 case VKI_SIOCGIWNICKN:
8609 case VKI_SIOCGIWENCODE:
8610 case VKI_SIOCGIWGENIE:
8611 case VKI_SIOCGIWENCODEEXT:
8612 if (ARG3) {
8613 struct vki_iw_point* point;
8614 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8615 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8616 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8617 (Addr)point->pointer, point->length);
8619 break;
8620 case VKI_SIOCGIWAP:
8621 if (ARG3) {
8622 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8623 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8624 sizeof(struct vki_sockaddr));
8626 break;
8628 /* User input device creation */
8629 case VKI_UI_SET_EVBIT:
8630 case VKI_UI_SET_KEYBIT:
8631 case VKI_UI_SET_RELBIT:
8632 case VKI_UI_SET_ABSBIT:
8633 case VKI_UI_SET_MSCBIT:
8634 case VKI_UI_SET_LEDBIT:
8635 case VKI_UI_SET_SNDBIT:
8636 case VKI_UI_SET_FFBIT:
8637 case VKI_UI_SET_SWBIT:
8638 case VKI_UI_SET_PROPBIT:
8639 /* These just take an int by value */
8640 break;
8642 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8643 || defined(VGPV_mips32_linux_android) \
8644 || defined(VGPV_arm64_linux_android)
8645 /* ashmem */
8646 case VKI_ASHMEM_GET_SIZE:
8647 case VKI_ASHMEM_SET_SIZE:
8648 case VKI_ASHMEM_GET_PROT_MASK:
8649 case VKI_ASHMEM_SET_PROT_MASK:
8650 case VKI_ASHMEM_GET_PIN_STATUS:
8651 case VKI_ASHMEM_PURGE_ALL_CACHES:
8652 break;
8653 case VKI_ASHMEM_GET_NAME:
8654 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8655 break;
8656 case VKI_ASHMEM_SET_NAME:
8657 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8658 break;
8659 case VKI_ASHMEM_PIN:
8660 case VKI_ASHMEM_UNPIN:
8661 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8662 ARG3, sizeof(struct vki_ashmem_pin) );
8663 break;
8665 /* binder */
8666 case VKI_BINDER_WRITE_READ:
8667 if (ARG3) {
8668 struct vki_binder_write_read* bwr
8669 = (struct vki_binder_write_read*)(Addr)ARG3;
8671 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8672 bwr->write_buffer);
8673 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8674 bwr->write_size);
8675 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8676 bwr->write_consumed);
8677 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8678 bwr->read_buffer);
8679 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8680 bwr->read_size);
8681 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8682 bwr->read_consumed);
8684 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8685 bwr->write_consumed);
8686 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8687 bwr->read_consumed);
8689 if (bwr->read_size)
8690 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8691 (Addr)bwr->read_buffer, bwr->read_size);
8692 if (bwr->write_size)
8693 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8694 (Addr)bwr->write_buffer, bwr->write_size);
8696 break;
8698 case VKI_BINDER_SET_IDLE_TIMEOUT:
8699 case VKI_BINDER_SET_MAX_THREADS:
8700 case VKI_BINDER_SET_IDLE_PRIORITY:
8701 case VKI_BINDER_SET_CONTEXT_MGR:
8702 case VKI_BINDER_THREAD_EXIT:
8703 break;
8704 case VKI_BINDER_VERSION:
8705 if (ARG3) {
8706 struct vki_binder_version* bv =
8707 (struct vki_binder_version*)(Addr)ARG3;
8708 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8710 break;
8711 # endif /* defined(VGPV_*_linux_android) */
8713 case VKI_HCIGETDEVLIST:
8714 if (ARG3) {
8715 struct vki_hci_dev_list_req* dlr =
8716 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8717 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8718 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8719 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8720 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8721 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8723 break;
8725 case VKI_HCIINQUIRY:
8726 if (ARG3) {
8727 struct vki_hci_inquiry_req* ir =
8728 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8729 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8730 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8731 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8732 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8733 ir->num_rsp * sizeof(struct vki_inquiry_info));
8735 break;
8737 case VKI_DRM_IOCTL_VERSION:
8738 if (ARG3) {
8739 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8740 struct vg_drm_version_info* info;
8741 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8742 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8743 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8744 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8745 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8746 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8747 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8748 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8749 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8750 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8751 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8752 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8753 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8754 // To ensure we VG_(free) info even when syscall fails:
8755 *flags |= SfPostOnFail;
8756 info->data = *data;
8757 info->orig = data;
8758 ARG3 = (Addr)&info->data;
8760 break;
8761 case VKI_DRM_IOCTL_GET_UNIQUE:
8762 if (ARG3) {
8763 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8764 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8765 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8766 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8768 break;
8769 case VKI_DRM_IOCTL_GET_MAGIC:
8770 if (ARG3) {
8771 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8772 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8774 break;
8775 case VKI_DRM_IOCTL_WAIT_VBLANK:
8776 if (ARG3) {
8777 union vki_drm_wait_vblank *data =
8778 (union vki_drm_wait_vblank *)(Addr)ARG3;
8779 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8780 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8781 /* XXX: It seems request.signal isn't used */
8782 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8784 break;
8785 case VKI_DRM_IOCTL_GEM_CLOSE:
8786 if (ARG3) {
8787 struct vki_drm_gem_close *data =
8788 (struct vki_drm_gem_close *)(Addr)ARG3;
8789 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8791 break;
8792 case VKI_DRM_IOCTL_GEM_FLINK:
8793 if (ARG3) {
8794 struct vki_drm_gem_flink *data =
8795 (struct vki_drm_gem_flink *)(Addr)ARG3;
8796 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8797 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8799 break;
8800 case VKI_DRM_IOCTL_GEM_OPEN:
8801 if (ARG3) {
8802 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8803 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8804 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8805 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8807 break;
8808 case VKI_DRM_IOCTL_I915_GETPARAM:
8809 if (ARG3) {
8810 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8811 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8812 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8814 break;
8815 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8816 if (ARG3) {
8817 struct vki_drm_i915_gem_busy *data =
8818 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8819 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8820 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8822 break;
8823 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8824 if (ARG3) {
8825 struct vki_drm_i915_gem_create *data =
8826 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8827 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8828 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8830 break;
8831 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8832 if (ARG3) {
8833 struct vki_drm_i915_gem_pread *data =
8834 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8835 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8836 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8837 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8838 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8839 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8841 break;
8842 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8843 if (ARG3) {
8844 struct vki_drm_i915_gem_pwrite *data =
8845 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8846 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8847 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8848 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8849 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8850 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8851 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8852 * interleaved vertex attributes may have a wide stride with uninitialized data between
8853 * consecutive vertices) */
8855 break;
8856 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8857 if (ARG3) {
8858 struct vki_drm_i915_gem_mmap_v1 *data =
8859 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8860 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8861 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8862 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8863 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8865 break;
8866 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8867 if (ARG3) {
8868 struct vki_drm_i915_gem_mmap *data =
8869 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8870 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8871 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8872 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8873 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8874 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8876 break;
8877 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8878 if (ARG3) {
8879 struct vki_drm_i915_gem_mmap_gtt *data =
8880 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8881 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8882 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8884 break;
8885 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8886 if (ARG3) {
8887 struct vki_drm_i915_gem_set_domain *data =
8888 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8889 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8890 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8891 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8893 break;
8894 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8895 if (ARG3) {
8896 struct vki_drm_i915_gem_set_tiling *data =
8897 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8898 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8899 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8900 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8901 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8903 break;
8904 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8905 if (ARG3) {
8906 struct vki_drm_i915_gem_get_tiling *data =
8907 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8908 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8909 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8910 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8912 break;
8913 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8914 if (ARG3) {
8915 struct vki_drm_i915_gem_get_aperture *data =
8916 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8917 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8918 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8920 break;
8922 /* KVM ioctls that check for a numeric value as parameter */
8923 case VKI_KVM_GET_API_VERSION:
8924 case VKI_KVM_CREATE_VM:
8925 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8926 case VKI_KVM_CHECK_EXTENSION:
8927 case VKI_KVM_SET_TSS_ADDR:
8928 case VKI_KVM_CREATE_VCPU:
8929 case VKI_KVM_RUN:
8930 break;
8932 case VKI_KVM_S390_MEM_OP: {
8933 struct vki_kvm_s390_mem_op *args =
8934 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8935 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8936 sizeof(struct vki_kvm_s390_mem_op));
8937 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8938 break;
8939 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8940 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8941 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8942 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8944 break;
8947 #ifdef ENABLE_XEN
8948 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8949 SyscallArgs harrghs;
8950 struct vki_xen_privcmd_hypercall *args =
8951 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8953 if (!args)
8954 break;
8956 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8957 harrghs.sysno = args->op;
8958 harrghs.arg1 = args->arg[0];
8959 harrghs.arg2 = args->arg[1];
8960 harrghs.arg3 = args->arg[2];
8961 harrghs.arg4 = args->arg[3];
8962 harrghs.arg5 = args->arg[4];
8963 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8965 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8967 /* HACK. arg8 is used to return the number of hypercall
8968 * arguments actually consumed! */
8969 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8970 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8972 break;
8975 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8976 struct vki_xen_privcmd_mmap *args =
8977 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8978 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8979 (Addr)&args->num, sizeof(args->num));
8980 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8981 (Addr)&args->dom, sizeof(args->dom));
8982 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8983 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8984 break;
8986 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8987 struct vki_xen_privcmd_mmapbatch *args =
8988 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8989 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8990 (Addr)&args->num, sizeof(args->num));
8991 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8992 (Addr)&args->dom, sizeof(args->dom));
8993 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8994 (Addr)&args->addr, sizeof(args->addr));
8995 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8996 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8997 break;
8999 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
9000 struct vki_xen_privcmd_mmapbatch_v2 *args =
9001 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
9002 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
9003 (Addr)&args->num, sizeof(args->num));
9004 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
9005 (Addr)&args->dom, sizeof(args->dom));
9006 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
9007 (Addr)&args->addr, sizeof(args->addr));
9008 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
9009 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
9010 break;
9013 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
9014 struct vki_xen_ioctl_evtchn_bind_virq *args =
9015 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
9016 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
9017 (Addr)&args->virq, sizeof(args->virq));
9019 break;
9020 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
9021 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
9022 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
9023 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
9024 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9025 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
9026 (Addr)&args->remote_port, sizeof(args->remote_port));
9028 break;
9029 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
9030 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
9031 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
9032 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
9033 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9035 break;
9036 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
9037 struct vki_xen_ioctl_evtchn_unbind *args =
9038 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
9039 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
9040 (Addr)&args->port, sizeof(args->port));
9042 break;
9043 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9044 struct vki_xen_ioctl_evtchn_notify *args =
9045 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9046 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9047 (Addr)&args->port, sizeof(args->port));
9049 break;
9050 case VKI_XEN_IOCTL_EVTCHN_RESET:
9051 /* No input*/
9052 break;
9053 #endif
9055 /* Lustre */
9056 case VKI_OBD_IOC_FID2PATH: {
9057 struct vki_getinfo_fid2path *gf =
9058 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9059 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9060 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9061 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9062 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9063 break;
9066 case VKI_LL_IOC_PATH2FID:
9067 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9068 break;
9070 case VKI_LL_IOC_GETPARENT: {
9071 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9072 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9073 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9074 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9075 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9076 break;
9079 /* V4L2 */
9080 case VKI_V4L2_QUERYCAP: {
9081 struct vki_v4l2_capability *data =
9082 (struct vki_v4l2_capability *)(Addr)ARG3;
9083 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9084 break;
9086 case VKI_V4L2_ENUM_FMT: {
9087 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9088 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9089 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9090 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9091 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9092 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9093 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9094 break;
9096 case VKI_V4L2_G_FMT: {
9097 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9098 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9099 switch (data->type) {
9100 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9101 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9102 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9103 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9104 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9105 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9106 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9107 break;
9108 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9109 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9110 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9111 break;
9112 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9113 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9114 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9115 break;
9116 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9117 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9118 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9119 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9120 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9121 if (data->fmt.win.clipcount && data->fmt.win.clips)
9122 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9123 (Addr)data->fmt.win.clips,
9124 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9125 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9126 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9127 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9128 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9129 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9130 break;
9131 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9132 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9133 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9134 break;
9135 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9136 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9137 break;
9139 break;
9141 case VKI_V4L2_S_FMT: {
9142 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9143 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9144 switch (data->type) {
9145 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9146 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9147 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9148 (Addr)&data->type + sizeof(data->type),
9149 sizeof(*data) - sizeof(data->type));
9150 break;
9151 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9152 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9153 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9154 break;
9155 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9156 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9157 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9158 break;
9159 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9160 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9161 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9162 if (data->fmt.win.clipcount && data->fmt.win.clips)
9163 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9164 (Addr)data->fmt.win.clips,
9165 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9166 if (data->fmt.win.bitmap)
9167 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9168 (Addr)data->fmt.win.bitmap,
9169 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9170 break;
9171 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9172 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9173 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9174 break;
9175 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9176 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9177 break;
9179 break;
9181 case VKI_V4L2_TRY_FMT: {
9182 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9183 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9184 switch (data->type) {
9185 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9186 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9187 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9188 (Addr)&data->type + sizeof(data->type),
9189 sizeof(*data) - sizeof(data->type));
9190 break;
9191 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9192 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9193 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9194 break;
9195 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9196 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9197 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9198 break;
9199 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9200 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9201 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9202 if (data->fmt.win.clipcount && data->fmt.win.clips)
9203 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9204 (Addr)data->fmt.win.clips,
9205 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9206 if (data->fmt.win.bitmap)
9207 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9208 (Addr)data->fmt.win.bitmap,
9209 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9210 break;
9211 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9212 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9213 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9214 break;
9215 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9216 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9217 break;
9219 break;
9221 case VKI_V4L2_REQBUFS: {
9222 struct vki_v4l2_requestbuffers *data =
9223 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9224 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9225 break;
9227 case VKI_V4L2_QUERYBUF: {
9228 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9229 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9230 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9231 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9232 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9233 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9234 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9235 unsigned i;
9237 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9238 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9239 for (i = 0; i < data->length; i++) {
9240 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9241 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9242 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9243 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9244 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9246 } else {
9247 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9248 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9250 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9251 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9252 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9253 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9254 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9255 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9256 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9257 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9258 break;
9260 case VKI_V4L2_G_FBUF: {
9261 struct vki_v4l2_framebuffer *data =
9262 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9263 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9264 break;
9266 case VKI_V4L2_S_FBUF: {
9267 struct vki_v4l2_framebuffer *data =
9268 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9269 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9270 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9271 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9272 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9273 break;
9275 case VKI_V4L2_OVERLAY: {
9276 int *data = (int *)(Addr)ARG3;
9277 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9278 break;
9280 case VKI_V4L2_QBUF: {
9281 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9282 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9283 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9284 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9285 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9287 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9288 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9289 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9290 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9291 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9292 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9293 if (is_output) {
9294 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9295 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9297 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9298 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9299 unsigned i;
9301 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9302 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9303 for (i = 0; i < data->length; i++) {
9304 if (is_output) {
9305 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9306 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9308 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9309 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9310 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9311 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9312 else
9313 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9314 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9316 } else {
9317 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9318 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9319 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9320 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9321 else
9322 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9323 if (is_output) {
9324 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9325 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9328 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9329 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9330 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9332 break;
9334 case VKI_V4L2_EXPBUF: {
9335 struct vki_v4l2_exportbuffer *data =
9336 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9337 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9338 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9339 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9340 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9341 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9342 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9343 break;
9345 case VKI_V4L2_DQBUF: {
9346 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9347 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9348 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9349 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9350 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9351 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9352 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9353 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9354 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9355 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9356 unsigned i;
9358 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9359 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9360 for (i = 0; i < data->length; i++) {
9361 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9362 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9363 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9364 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9365 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9367 } else {
9368 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9369 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9370 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9371 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9373 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9374 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9375 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9376 break;
9378 case VKI_V4L2_STREAMON: {
9379 int *data = (int *)(Addr)ARG3;
9380 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9381 break;
9383 case VKI_V4L2_STREAMOFF: {
9384 int *data = (int *)(Addr)ARG3;
9385 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9386 break;
9388 case VKI_V4L2_G_PARM: {
9389 struct vki_v4l2_streamparm *data =
9390 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9391 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9392 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9393 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9394 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9396 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9397 if (is_output) {
9398 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9399 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9400 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9401 } else {
9402 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9403 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9404 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9406 break;
9408 case VKI_V4L2_S_PARM: {
9409 struct vki_v4l2_streamparm *data =
9410 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9411 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9412 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9413 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9414 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9416 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9417 if (is_output)
9418 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9419 else
9420 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9421 break;
9423 case VKI_V4L2_G_STD: {
9424 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9425 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9426 break;
9428 case VKI_V4L2_S_STD: {
9429 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9430 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9431 break;
9433 case VKI_V4L2_ENUMSTD: {
9434 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9435 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9436 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9437 break;
9439 case VKI_V4L2_ENUMINPUT: {
9440 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9441 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9442 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9443 break;
9445 case VKI_V4L2_G_CTRL: {
9446 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9447 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9448 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9449 break;
9451 case VKI_V4L2_S_CTRL: {
9452 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9453 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9454 break;
9456 case VKI_V4L2_G_TUNER: {
9457 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9458 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9459 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9460 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9461 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9462 break;
9464 case VKI_V4L2_S_TUNER: {
9465 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9466 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9467 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9468 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9469 break;
9471 case VKI_V4L2_G_AUDIO: {
9472 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9473 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9474 sizeof(*data) - sizeof(data->reserved));
9475 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9476 break;
9478 case VKI_V4L2_S_AUDIO: {
9479 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9480 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9481 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9482 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9483 break;
9485 case VKI_V4L2_QUERYCTRL: {
9486 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9487 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9488 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9489 sizeof(*data) - sizeof(data->id));
9490 break;
9492 case VKI_V4L2_QUERYMENU: {
9493 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9494 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9495 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9496 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9497 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9498 break;
9500 case VKI_V4L2_G_INPUT: {
9501 int *data = (int *)(Addr)ARG3;
9502 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9503 break;
9505 case VKI_V4L2_S_INPUT: {
9506 int *data = (int *)(Addr)ARG3;
9507 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9508 break;
9510 case VKI_V4L2_G_EDID: {
9511 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9512 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9513 if (data->blocks && data->edid)
9514 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9515 break;
9517 case VKI_V4L2_S_EDID: {
9518 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9519 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9520 if (data->blocks && data->edid)
9521 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9522 break;
9524 case VKI_V4L2_G_OUTPUT: {
9525 int *data = (int *)(Addr)ARG3;
9526 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9527 break;
9529 case VKI_V4L2_S_OUTPUT: {
9530 int *data = (int *)(Addr)ARG3;
9531 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9532 break;
9534 case VKI_V4L2_ENUMOUTPUT: {
9535 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9536 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9537 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9538 break;
9540 case VKI_V4L2_G_AUDOUT: {
9541 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9542 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9543 sizeof(*data) - sizeof(data->reserved));
9544 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9545 break;
9547 case VKI_V4L2_S_AUDOUT: {
9548 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9549 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9550 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9551 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9552 break;
9554 case VKI_V4L2_G_MODULATOR: {
9555 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9556 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9557 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9558 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9559 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9560 break;
9562 case VKI_V4L2_S_MODULATOR: {
9563 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9564 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9565 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9566 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9567 break;
9569 case VKI_V4L2_G_FREQUENCY: {
9570 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9571 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9572 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9573 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9574 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9575 break;
9577 case VKI_V4L2_S_FREQUENCY: {
9578 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9579 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9580 break;
9582 case VKI_V4L2_CROPCAP: {
9583 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9584 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9585 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9586 break;
9588 case VKI_V4L2_G_CROP: {
9589 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9590 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9591 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9592 break;
9594 case VKI_V4L2_S_CROP: {
9595 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9596 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9597 break;
9599 case VKI_V4L2_G_JPEGCOMP: {
9600 struct vki_v4l2_jpegcompression *data =
9601 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9602 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9603 break;
9605 case VKI_V4L2_S_JPEGCOMP: {
9606 struct vki_v4l2_jpegcompression *data =
9607 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9608 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9609 break;
9611 case VKI_V4L2_QUERYSTD: {
9612 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9613 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9614 break;
9616 case VKI_V4L2_ENUMAUDIO: {
9617 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9618 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9619 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9620 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9621 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9622 break;
9624 case VKI_V4L2_ENUMAUDOUT: {
9625 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9626 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9627 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9628 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9629 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9630 break;
9632 case VKI_V4L2_G_PRIORITY: {
9633 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9634 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9635 break;
9637 case VKI_V4L2_S_PRIORITY: {
9638 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9639 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9640 break;
9642 case VKI_V4L2_G_SLICED_VBI_CAP: {
9643 struct vki_v4l2_sliced_vbi_cap *data =
9644 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9645 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9646 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9647 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9648 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9649 break;
9651 case VKI_V4L2_G_EXT_CTRLS: {
9652 struct vki_v4l2_ext_controls *data =
9653 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9654 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9655 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9656 if (data->count) {
9657 unsigned i;
9659 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9660 for (i = 0; i < data->count; i++) {
9661 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9662 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9663 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9664 if (data->controls[i].size) {
9665 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9666 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9667 (Addr)data->controls[i].ptr, data->controls[i].size);
9668 } else {
9669 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9670 data->controls[i].value64);
9674 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9675 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9676 break;
9678 case VKI_V4L2_S_EXT_CTRLS: {
9679 struct vki_v4l2_ext_controls *data =
9680 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9681 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9682 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9683 if (data->count) {
9684 unsigned i;
9686 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9687 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9688 data->count * sizeof(data->controls[0]));
9689 for (i = 0; i < data->count; i++) {
9690 if (data->controls[i].size) {
9691 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9692 (Addr)data->controls[i].ptr, data->controls[i].size);
9696 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9697 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9698 break;
9700 case VKI_V4L2_TRY_EXT_CTRLS: {
9701 struct vki_v4l2_ext_controls *data =
9702 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9703 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9704 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9705 if (data->count) {
9706 unsigned i;
9708 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9709 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9710 data->count * sizeof(data->controls[0]));
9711 for (i = 0; i < data->count; i++) {
9712 if (data->controls[i].size) {
9713 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9714 (Addr)data->controls[i].ptr, data->controls[i].size);
9718 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9719 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9720 break;
9722 case VKI_V4L2_ENUM_FRAMESIZES: {
9723 struct vki_v4l2_frmsizeenum *data =
9724 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9725 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9726 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9727 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9728 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9729 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9730 break;
9732 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9733 struct vki_v4l2_frmivalenum *data =
9734 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9735 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9736 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9737 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9738 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9739 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9740 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9741 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9742 break;
9744 case VKI_V4L2_G_ENC_INDEX: {
9745 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9746 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9747 break;
9749 case VKI_V4L2_ENCODER_CMD: {
9750 struct vki_v4l2_encoder_cmd *data =
9751 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9752 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9753 break;
9755 case VKI_V4L2_TRY_ENCODER_CMD: {
9756 struct vki_v4l2_encoder_cmd *data =
9757 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9758 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9759 break;
9761 case VKI_V4L2_DBG_S_REGISTER: {
9762 struct vki_v4l2_dbg_register *data =
9763 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9764 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9765 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9766 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9767 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9768 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9769 break;
9771 case VKI_V4L2_DBG_G_REGISTER: {
9772 struct vki_v4l2_dbg_register *data =
9773 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9774 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9775 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9776 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9777 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9778 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9779 break;
9781 case VKI_V4L2_S_HW_FREQ_SEEK: {
9782 struct vki_v4l2_hw_freq_seek *data =
9783 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9784 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9785 break;
9787 case VKI_V4L2_S_DV_TIMINGS: {
9788 struct vki_v4l2_dv_timings *data =
9789 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9790 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9791 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9792 break;
9794 case VKI_V4L2_G_DV_TIMINGS: {
9795 struct vki_v4l2_dv_timings *data =
9796 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9797 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9798 break;
9800 case VKI_V4L2_DQEVENT: {
9801 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9802 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9803 break;
9805 case VKI_V4L2_SUBSCRIBE_EVENT: {
9806 struct vki_v4l2_event_subscription *data =
9807 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9808 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9809 break;
9811 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9812 struct vki_v4l2_event_subscription *data =
9813 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9814 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9815 break;
9817 case VKI_V4L2_CREATE_BUFS: {
9818 struct vki_v4l2_create_buffers *data =
9819 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9820 struct vki_v4l2_format *fmt = &data->format;
9821 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9822 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9823 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9824 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9825 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9826 switch (fmt->type) {
9827 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9828 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9829 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9830 break;
9831 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9832 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9833 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9834 break;
9835 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9836 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9837 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9838 break;
9839 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9840 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9841 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9842 break;
9843 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9844 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9845 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9846 break;
9847 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9848 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9849 break;
9851 break;
9853 case VKI_V4L2_PREPARE_BUF: {
9854 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9855 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9856 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9857 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9858 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9859 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9860 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9861 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9862 unsigned i;
9864 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9865 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9866 for (i = 0; i < data->length; i++) {
9867 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9870 break;
9872 case VKI_V4L2_G_SELECTION: {
9873 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9874 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9875 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9876 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9877 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9878 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9879 break;
9881 case VKI_V4L2_S_SELECTION: {
9882 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9883 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9884 break;
9886 case VKI_V4L2_DECODER_CMD: {
9887 struct vki_v4l2_decoder_cmd *data =
9888 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9889 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9890 break;
9892 case VKI_V4L2_TRY_DECODER_CMD: {
9893 struct vki_v4l2_decoder_cmd *data =
9894 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9895 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9896 break;
9898 case VKI_V4L2_ENUM_DV_TIMINGS: {
9899 struct vki_v4l2_enum_dv_timings *data =
9900 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9901 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9902 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9903 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9904 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9905 break;
9907 case VKI_V4L2_QUERY_DV_TIMINGS: {
9908 struct vki_v4l2_dv_timings *data =
9909 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9910 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9911 break;
9913 case VKI_V4L2_DV_TIMINGS_CAP: {
9914 struct vki_v4l2_dv_timings_cap *data =
9915 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9916 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9917 break;
9919 case VKI_V4L2_ENUM_FREQ_BANDS: {
9920 struct vki_v4l2_frequency_band *data =
9921 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9922 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9923 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9924 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9925 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9926 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9927 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9928 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9929 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9930 break;
9932 case VKI_V4L2_DBG_G_CHIP_INFO: {
9933 struct vki_v4l2_dbg_chip_info *data =
9934 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9935 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9936 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9937 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9938 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9939 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9940 break;
9942 case VKI_V4L2_QUERY_EXT_CTRL: {
9943 struct vki_v4l2_query_ext_ctrl *data =
9944 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9945 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9946 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9947 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9948 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9949 break;
9951 case VKI_V4L2_SUBDEV_G_FMT: {
9952 struct vki_v4l2_subdev_format *data =
9953 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9954 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9955 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9956 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9957 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9958 break;
9960 case VKI_V4L2_SUBDEV_S_FMT: {
9961 struct vki_v4l2_subdev_format *data =
9962 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9963 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9964 break;
9966 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9967 struct vki_v4l2_subdev_frame_interval *data =
9968 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9969 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9970 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9971 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9972 break;
9974 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9975 struct vki_v4l2_subdev_frame_interval *data =
9976 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9977 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9978 break;
9980 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9981 struct vki_v4l2_subdev_mbus_code_enum *data =
9982 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9983 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9984 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9985 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9986 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9987 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9988 break;
9990 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9991 struct vki_v4l2_subdev_frame_size_enum *data =
9992 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9993 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9994 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9995 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9996 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9997 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9998 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9999 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
10000 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
10001 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
10002 break;
10004 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
10005 struct vki_v4l2_subdev_frame_interval_enum *data =
10006 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
10007 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
10008 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
10009 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
10010 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
10011 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
10012 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
10013 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
10014 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
10015 break;
10017 case VKI_V4L2_SUBDEV_G_CROP: {
10018 struct vki_v4l2_subdev_crop *data =
10019 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10020 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
10021 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
10022 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
10023 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
10024 break;
10026 case VKI_V4L2_SUBDEV_S_CROP: {
10027 struct vki_v4l2_subdev_crop *data =
10028 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10029 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
10030 break;
10032 case VKI_V4L2_SUBDEV_G_SELECTION: {
10033 struct vki_v4l2_subdev_selection *data =
10034 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10035 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
10036 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
10037 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
10038 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
10039 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
10040 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
10041 break;
10043 case VKI_V4L2_SUBDEV_S_SELECTION: {
10044 struct vki_v4l2_subdev_selection *data =
10045 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10046 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10047 break;
10049 case VKI_MEDIA_IOC_DEVICE_INFO: {
10050 struct vki_media_device_info *data =
10051 (struct vki_media_device_info *)(Addr)ARG3;
10052 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10053 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10054 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10055 break;
10057 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10058 struct vki_media_entity_desc *data =
10059 (struct vki_media_entity_desc *)(Addr)ARG3;
10060 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10061 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10062 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10063 break;
10065 case VKI_MEDIA_IOC_ENUM_LINKS: {
10066 struct vki_media_links_enum *data =
10067 (struct vki_media_links_enum *)(Addr)ARG3;
10068 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10069 break;
10071 case VKI_MEDIA_IOC_SETUP_LINK: {
10072 struct vki_media_link_desc *data =
10073 (struct vki_media_link_desc *)(Addr)ARG3;
10074 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10075 break;
10078 /* Serial */
10079 case VKI_TIOCGSERIAL: {
10080 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10081 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10082 break;
10084 case VKI_TIOCSSERIAL: {
10085 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10086 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10087 break;
10090 case VKI_PERF_EVENT_IOC_RESET:
10091 case VKI_PERF_EVENT_IOC_REFRESH:
10092 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10093 case VKI_PERF_EVENT_IOC_SET_BPF:
10094 /* These take scalar arguments, so already handled above */
10095 break;
10097 case VKI_PERF_EVENT_IOC_PERIOD:
10098 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10099 break;
10101 case VKI_PERF_EVENT_IOC_SET_FILTER:
10102 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10103 break;
10105 case VKI_PERF_EVENT_IOC_ID:
10106 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10107 break;
10109 /* Pulse Per Second (PPS) */
10110 case VKI_PPS_GETPARAMS: {
10111 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10112 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10113 break;
10115 case VKI_PPS_SETPARAMS: {
10116 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10117 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10118 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10119 data->assert_off_tu.sec);
10120 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10121 data->assert_off_tu.nsec);
10122 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10123 data->clear_off_tu.sec);
10124 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10125 data->clear_off_tu.nsec);
10126 break;
10128 case VKI_PPS_GETCAP:
10129 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10130 break;
10131 case VKI_PPS_FETCH: {
10132 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10133 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10134 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10135 break;
10137 case VKI_PPS_KC_BIND: {
10138 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10139 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10140 break;
10143 /* PTP Hardware Clock */
10144 case VKI_PTP_CLOCK_GETCAPS: {
10145 struct vki_ptp_clock_caps *data =
10146 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10147 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10148 break;
10150 case VKI_PTP_EXTTS_REQUEST: {
10151 struct vki_ptp_extts_request *data =
10152 (struct vki_ptp_extts_request *)(Addr)ARG3;
10153 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10154 break;
10156 case VKI_PTP_PEROUT_REQUEST: {
10157 struct vki_ptp_perout_request *data =
10158 (struct vki_ptp_perout_request *)(Addr)ARG3;
10159 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10160 break;
10162 case VKI_PTP_ENABLE_PPS:
10163 break;
10164 case VKI_PTP_SYS_OFFSET: {
10165 struct vki_ptp_sys_offset *data =
10166 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10167 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10168 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10169 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10170 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10171 break;
10173 case VKI_PTP_PIN_GETFUNC: {
10174 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10175 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10176 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10177 break;
10179 case VKI_PTP_PIN_SETFUNC: {
10180 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10181 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10182 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10183 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10184 break;
10186 case VKI_PTP_SYS_OFFSET_PRECISE: {
10187 struct vki_ptp_sys_offset_precise *data =
10188 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10189 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10190 break;
10192 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10193 struct vki_ptp_sys_offset_extended *data =
10194 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10195 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10196 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10197 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10198 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10199 3 * data->n_samples * sizeof(data->ts[0][0]));
10200 break;
10203 default:
10204 /* EVIOC* are variable length and return size written on success */
10205 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10206 case VKI_EVIOCGNAME(0):
10207 case VKI_EVIOCGPHYS(0):
10208 case VKI_EVIOCGUNIQ(0):
10209 case VKI_EVIOCGKEY(0):
10210 case VKI_EVIOCGLED(0):
10211 case VKI_EVIOCGSND(0):
10212 case VKI_EVIOCGSW(0):
10213 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10214 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10215 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10216 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10217 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10218 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10219 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10220 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10221 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10222 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10223 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10224 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10225 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10226 break;
10227 default:
10228 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10229 break;
10231 break;
10235 POST(sys_ioctl)
10237 ARG2 = (UInt)ARG2;
10239 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10241 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10243 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10244 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10245 VG_(clo_kernel_variant))) {
10247 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10248 /* What's going on here: there appear to be a bunch of ioctls
10249 of the form 0xC01C67xx which are undocumented, and if
10250 unhandled give rise to a vast number of false positives in
10251 Memcheck.
10253 The "normal" interpretation of an ioctl of this form would
10254 be that the 3rd arg is a pointer to an area of size 0x1C
10255 (28 bytes) which is filled in by the kernel. Hence you
10256 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10257 But it doesn't.
10259 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10260 One interpretation of this is that ARG3 really does point
10261 to a 28 byte struct, but inside that are pointers to other
10262 areas also filled in by the kernel. If these happen to be
10263 allocated just back up the stack then the 256 byte paint
10264 might cover them too, somewhat indiscriminately.
10266 By printing out ARG3 and also the 28 bytes that it points
10267 at, it's possible to guess that the 7 word structure has
10268 this form
10270 0 1 2 3 4 5 6
10271 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10273 Unfortunately that doesn't seem to work for some reason,
10274 so stay with the blunt-instrument approach for the time
10275 being.
10277 if (1) {
10278 /* blunt-instrument approach */
10279 POST_MEM_WRITE(ARG3, 256);
10280 } else {
10281 /* be a bit more sophisticated */
10282 POST_MEM_WRITE(ARG3, 28);
10283 UInt* word = (UInt*)(Addr)ARG3;
10284 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10285 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10286 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10287 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10289 goto post_sys_ioctl__out;
10292 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10294 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10295 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10296 VG_(clo_kernel_variant))) {
10297 if (ARG2 == 0xC00C0902) {
10298 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10299 goto post_sys_ioctl__out;
10302 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10304 /* --- END special IOCTL handlers for specific Android hardware --- */
10306 /* --- normal handling --- */
10307 switch (ARG2 /* request */) {
10309 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10310 this is pretty poor given that there's no pre-handling to check
10311 that writable areas are addressable. */
10312 case VKI_ION_IOC_ALLOC: {
10313 struct vki_ion_allocation_data* data
10314 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10315 POST_FIELD_WRITE(data->handle);
10316 break;
10318 case VKI_ION_IOC_MAP: {
10319 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10320 POST_FIELD_WRITE(data->fd);
10321 break;
10323 case VKI_ION_IOC_FREE: // is this necessary?
10324 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10325 break;
10326 case VKI_ION_IOC_SHARE:
10327 break;
10328 case VKI_ION_IOC_IMPORT: {
10329 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10330 POST_FIELD_WRITE(data->handle);
10331 break;
10333 case VKI_ION_IOC_SYNC:
10334 break;
10335 case VKI_ION_IOC_CUSTOM: // is this necessary?
10336 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10337 break;
10339 case VKI_SYNC_IOC_MERGE: {
10340 struct vki_sync_merge_data* data =
10341 (struct vki_sync_merge_data*)(Addr)ARG3;
10342 POST_FIELD_WRITE(data->fence);
10343 break;
10346 case VKI_TCSETS:
10347 case VKI_TCSETSW:
10348 case VKI_TCSETSF:
10349 case VKI_IB_USER_MAD_ENABLE_PKEY:
10350 break;
10351 case VKI_TCGETS:
10352 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10353 break;
10354 case VKI_TCSETA:
10355 case VKI_TCSETAW:
10356 case VKI_TCSETAF:
10357 break;
10358 case VKI_TCGETA:
10359 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10360 break;
10361 case VKI_TCSBRK:
10362 case VKI_TCXONC:
10363 case VKI_TCSBRKP:
10364 case VKI_TCFLSH:
10365 case VKI_TIOCSIG:
10366 break;
10367 case VKI_TIOCGWINSZ:
10368 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10369 break;
10370 case VKI_TIOCSWINSZ:
10371 case VKI_TIOCMBIS:
10372 case VKI_TIOCMBIC:
10373 case VKI_TIOCMSET:
10374 break;
10375 case VKI_TIOCMGET:
10376 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10377 break;
10378 case VKI_TIOCLINUX:
10379 POST_MEM_WRITE( ARG3, sizeof(char *) );
10380 break;
10381 case VKI_TIOCGPGRP:
10382 /* Get process group ID for foreground processing group. */
10383 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10384 break;
10385 case VKI_TIOCSPGRP:
10386 /* Set a process group ID? */
10387 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10388 break;
10389 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10390 POST_MEM_WRITE( ARG3, sizeof(int));
10391 break;
10392 case VKI_TIOCSCTTY:
10393 break;
10394 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10395 break;
10396 case VKI_FIONBIO:
10397 break;
10398 case VKI_FIONCLEX:
10399 break;
10400 case VKI_FIOCLEX:
10401 break;
10402 case VKI_TIOCNOTTY:
10403 break;
10404 case VKI_FIOASYNC:
10405 break;
10406 case VKI_FIONREAD: /* identical to SIOCINQ */
10407 POST_MEM_WRITE( ARG3, sizeof(int) );
10408 break;
10409 case VKI_FIOQSIZE:
10410 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10411 break;
10413 case VKI_TIOCSERGETLSR:
10414 POST_MEM_WRITE( ARG3, sizeof(int) );
10415 break;
10416 case VKI_TIOCGICOUNT:
10417 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10418 break;
10420 case VKI_SG_SET_COMMAND_Q:
10421 break;
10422 case VKI_SG_IO:
10424 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10425 if ( sgio->sbp ) {
10426 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10428 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10429 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10430 int transferred = sgio->dxfer_len - sgio->resid;
10431 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10434 break;
10435 case VKI_SG_GET_SCSI_ID:
10436 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10437 break;
10438 case VKI_SG_SET_RESERVED_SIZE:
10439 break;
10440 case VKI_SG_SET_TIMEOUT:
10441 break;
10442 case VKI_SG_GET_RESERVED_SIZE:
10443 POST_MEM_WRITE(ARG3, sizeof(int));
10444 break;
10445 case VKI_SG_GET_TIMEOUT:
10446 break;
10447 case VKI_SG_GET_VERSION_NUM:
10448 POST_MEM_WRITE(ARG3, sizeof(int));
10449 break;
10450 case VKI_SG_EMULATED_HOST:
10451 POST_MEM_WRITE(ARG3, sizeof(int));
10452 break;
10453 case VKI_SG_GET_SG_TABLESIZE:
10454 POST_MEM_WRITE(ARG3, sizeof(int));
10455 break;
10457 case VKI_IIOCGETCPS:
10458 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10459 break;
10460 case VKI_IIOCNETGPN:
10461 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10462 break;
10464 /* These all use struct ifreq AFAIK */
10465 case VKI_SIOCGIFINDEX: /* get iface index */
10466 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10467 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10468 break;
10469 case VKI_SIOCGIFFLAGS: /* get flags */
10470 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10471 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10472 break;
10473 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10474 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10475 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10476 break;
10477 case VKI_SIOCGIFMTU: /* get MTU size */
10478 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10479 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10480 break;
10481 case VKI_SIOCGIFADDR: /* get PA address */
10482 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10483 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10484 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10485 POST_MEM_WRITE(
10486 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10487 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10488 break;
10489 case VKI_SIOCGIFMETRIC: /* get metric */
10490 POST_MEM_WRITE(
10491 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10492 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10493 break;
10494 case VKI_SIOCGIFMAP: /* Get device parameters */
10495 POST_MEM_WRITE(
10496 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10497 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10498 break;
10499 break;
10500 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10501 POST_MEM_WRITE(
10502 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10503 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10504 break;
10505 case VKI_SIOCGIFNAME: /* get iface name */
10506 POST_MEM_WRITE(
10507 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10508 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10509 break;
10510 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10511 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10512 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10513 case VKI_ETHTOOL_GSET:
10514 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10515 break;
10516 case VKI_ETHTOOL_SSET:
10517 break;
10518 case VKI_ETHTOOL_GDRVINFO:
10519 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10520 break;
10521 case VKI_ETHTOOL_GREGS:
10522 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10523 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10524 break;
10525 case VKI_ETHTOOL_GWOL:
10526 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10527 break;
10528 case VKI_ETHTOOL_SWOL:
10529 break;
10530 case VKI_ETHTOOL_GMSGLVL:
10531 case VKI_ETHTOOL_GLINK:
10532 case VKI_ETHTOOL_GRXCSUM:
10533 case VKI_ETHTOOL_GSG:
10534 case VKI_ETHTOOL_GTSO:
10535 case VKI_ETHTOOL_GUFO:
10536 case VKI_ETHTOOL_GGSO:
10537 case VKI_ETHTOOL_GFLAGS:
10538 case VKI_ETHTOOL_GGRO:
10539 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10540 break;
10541 case VKI_ETHTOOL_SMSGLVL:
10542 case VKI_ETHTOOL_SRXCSUM:
10543 case VKI_ETHTOOL_SSG:
10544 case VKI_ETHTOOL_STSO:
10545 case VKI_ETHTOOL_SUFO:
10546 case VKI_ETHTOOL_SGSO:
10547 case VKI_ETHTOOL_SFLAGS:
10548 case VKI_ETHTOOL_SGRO:
10549 break;
10550 case VKI_ETHTOOL_NWAY_RST:
10551 break;
10552 case VKI_ETHTOOL_GRINGPARAM:
10553 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10554 break;
10555 case VKI_ETHTOOL_SRINGPARAM:
10556 break;
10557 case VKI_ETHTOOL_TEST:
10558 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10559 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10560 break;
10561 case VKI_ETHTOOL_PHYS_ID:
10562 break;
10563 case VKI_ETHTOOL_GPERMADDR:
10564 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10565 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10566 break;
10567 case VKI_ETHTOOL_RESET:
10568 break;
10569 case VKI_ETHTOOL_GSSET_INFO:
10570 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10571 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10572 break;
10573 case VKI_ETHTOOL_GFEATURES:
10574 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10575 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10576 break;
10577 case VKI_ETHTOOL_SFEATURES:
10578 break;
10579 case VKI_ETHTOOL_GCHANNELS:
10580 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10581 break;
10582 case VKI_ETHTOOL_SCHANNELS:
10583 break;
10584 case VKI_ETHTOOL_GET_TS_INFO:
10585 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10586 break;
10588 break;
10590 case VKI_SIOCGMIIPHY: /* get hardware entry */
10591 POST_MEM_WRITE(
10592 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10593 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10594 break;
10595 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10596 POST_MEM_WRITE(
10597 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10598 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10599 break;
10601 /* tun/tap related ioctls */
10602 case VKI_TUNSETIFF:
10603 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10604 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10605 break;
10606 case VKI_TUNGETFEATURES:
10607 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10608 break;
10609 case VKI_TUNGETIFF:
10610 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10611 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10612 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10613 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10614 break;
10615 case VKI_TUNGETSNDBUF:
10616 POST_MEM_WRITE( ARG3, sizeof(int) );
10617 break;
10618 case VKI_TUNGETVNETHDRSZ:
10619 POST_MEM_WRITE( ARG3, sizeof(int) );
10620 break;
10622 case VKI_SIOCGIFCONF: /* get iface list */
10623 /* WAS:
10624 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10625 KERNEL_DO_SYSCALL(tid,RES);
10626 if (!VG_(is_kerror)(RES) && RES == 0)
10627 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10629 if (RES == 0 && ARG3 ) {
10630 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10631 if (ifc->vki_ifc_buf != NULL)
10632 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10634 break;
10635 case VKI_SIOCGSTAMP:
10636 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10637 break;
10638 case VKI_SIOCGSTAMPNS:
10639 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10640 break;
10641 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10642 the number of bytes currently in that socket's send buffer.
10643 It writes this value as an int to the memory location
10644 indicated by the third argument of ioctl(2). */
10645 case VKI_SIOCOUTQ:
10646 POST_MEM_WRITE(ARG3, sizeof(int));
10647 break;
10648 case VKI_SIOCGRARP: /* get RARP table entry */
10649 case VKI_SIOCGARP: /* get ARP table entry */
10650 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10651 break;
10653 case VKI_SIOCSIFFLAGS: /* set flags */
10654 case VKI_SIOCSIFMAP: /* Set device parameters */
10655 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10656 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10657 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10658 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10659 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10660 case VKI_SIOCSIFMETRIC: /* set metric */
10661 case VKI_SIOCSIFADDR: /* set PA address */
10662 case VKI_SIOCSIFMTU: /* set MTU size */
10663 case VKI_SIOCSIFHWADDR: /* set hardware address */
10664 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10665 break;
10666 /* Routing table calls. */
10667 case VKI_SIOCADDRT: /* add routing table entry */
10668 case VKI_SIOCDELRT: /* delete routing table entry */
10669 break;
10671 /* RARP cache control calls. */
10672 case VKI_SIOCDRARP: /* delete RARP table entry */
10673 case VKI_SIOCSRARP: /* set RARP table entry */
10674 /* ARP cache control calls. */
10675 case VKI_SIOCSARP: /* set ARP table entry */
10676 case VKI_SIOCDARP: /* delete ARP table entry */
10677 break;
10679 case VKI_SIOCGPGRP:
10680 POST_MEM_WRITE(ARG3, sizeof(int));
10681 break;
10682 case VKI_SIOCSPGRP:
10683 break;
10685 case VKI_SIOCATMARK:
10686 POST_MEM_WRITE(ARG3, sizeof(int));
10687 break;
10689 /* linux/soundcard interface (OSS) */
10690 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10691 case VKI_SNDCTL_SEQ_GETINCOUNT:
10692 case VKI_SNDCTL_SEQ_PERCMODE:
10693 case VKI_SNDCTL_SEQ_TESTMIDI:
10694 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10695 case VKI_SNDCTL_SEQ_NRSYNTHS:
10696 case VKI_SNDCTL_SEQ_NRMIDIS:
10697 case VKI_SNDCTL_SEQ_GETTIME:
10698 case VKI_SNDCTL_DSP_GETBLKSIZE:
10699 case VKI_SNDCTL_DSP_GETFMTS:
10700 case VKI_SNDCTL_DSP_SETFMT:
10701 case VKI_SNDCTL_DSP_GETTRIGGER:
10702 case VKI_SNDCTL_DSP_GETODELAY:
10703 case VKI_SNDCTL_DSP_GETSPDIF:
10704 case VKI_SNDCTL_DSP_GETCAPS:
10705 case VKI_SOUND_PCM_READ_RATE:
10706 case VKI_SOUND_PCM_READ_CHANNELS:
10707 case VKI_SOUND_PCM_READ_BITS:
10708 case VKI_SOUND_PCM_READ_FILTER:
10709 POST_MEM_WRITE(ARG3, sizeof(int));
10710 break;
10711 case VKI_SNDCTL_SEQ_CTRLRATE:
10712 case VKI_SNDCTL_DSP_SPEED:
10713 case VKI_SNDCTL_DSP_STEREO:
10714 case VKI_SNDCTL_DSP_CHANNELS:
10715 case VKI_SOUND_PCM_WRITE_FILTER:
10716 case VKI_SNDCTL_DSP_SUBDIVIDE:
10717 case VKI_SNDCTL_DSP_SETFRAGMENT:
10718 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10719 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10720 case VKI_SNDCTL_TMR_TIMEBASE:
10721 case VKI_SNDCTL_TMR_TEMPO:
10722 case VKI_SNDCTL_TMR_SOURCE:
10723 case VKI_SNDCTL_MIDI_PRETIME:
10724 case VKI_SNDCTL_MIDI_MPUMODE:
10725 break;
10726 case VKI_SNDCTL_DSP_GETOSPACE:
10727 case VKI_SNDCTL_DSP_GETISPACE:
10728 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10729 break;
10730 case VKI_SNDCTL_DSP_NONBLOCK:
10731 break;
10732 case VKI_SNDCTL_DSP_SETTRIGGER:
10733 break;
10735 case VKI_SNDCTL_DSP_POST:
10736 case VKI_SNDCTL_DSP_RESET:
10737 case VKI_SNDCTL_DSP_SYNC:
10738 case VKI_SNDCTL_DSP_SETSYNCRO:
10739 case VKI_SNDCTL_DSP_SETDUPLEX:
10740 break;
10742 /* linux/soundcard interface (ALSA) */
10743 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10744 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10745 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10746 case VKI_SNDRV_PCM_IOCTL_RESET:
10747 case VKI_SNDRV_PCM_IOCTL_START:
10748 case VKI_SNDRV_PCM_IOCTL_DROP:
10749 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10750 case VKI_SNDRV_PCM_IOCTL_RESUME:
10751 case VKI_SNDRV_PCM_IOCTL_XRUN:
10752 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10753 case VKI_SNDRV_TIMER_IOCTL_START:
10754 case VKI_SNDRV_TIMER_IOCTL_STOP:
10755 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10756 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10757 break;
10759 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10760 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10761 break;
10763 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10764 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10765 break;
10766 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10767 struct vki_snd_ctl_elem_list *data =
10768 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10769 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10770 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10771 if (data->pids) {
10772 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10774 break;
10776 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10777 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10778 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10779 break;
10781 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10782 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10783 break;
10785 /* SCSI no operand */
10786 case VKI_SCSI_IOCTL_DOORLOCK:
10787 case VKI_SCSI_IOCTL_DOORUNLOCK:
10788 break;
10790 /* Real Time Clock (/dev/rtc) ioctls */
10791 case VKI_RTC_UIE_ON:
10792 case VKI_RTC_UIE_OFF:
10793 case VKI_RTC_AIE_ON:
10794 case VKI_RTC_AIE_OFF:
10795 case VKI_RTC_PIE_ON:
10796 case VKI_RTC_PIE_OFF:
10797 case VKI_RTC_IRQP_SET:
10798 break;
10799 case VKI_RTC_RD_TIME:
10800 case VKI_RTC_ALM_READ:
10801 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10802 break;
10803 case VKI_RTC_ALM_SET:
10804 break;
10805 case VKI_RTC_IRQP_READ:
10806 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10807 break;
10809 /* Block devices */
10810 case VKI_BLKROSET:
10811 break;
10812 case VKI_BLKROGET:
10813 POST_MEM_WRITE(ARG3, sizeof(int));
10814 break;
10815 case VKI_BLKGETSIZE:
10816 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10817 break;
10818 case VKI_BLKFLSBUF:
10819 break;
10820 case VKI_BLKRASET:
10821 break;
10822 case VKI_BLKRAGET:
10823 POST_MEM_WRITE(ARG3, sizeof(long));
10824 break;
10825 case VKI_BLKFRASET:
10826 break;
10827 case VKI_BLKFRAGET:
10828 POST_MEM_WRITE(ARG3, sizeof(long));
10829 break;
10830 case VKI_BLKSECTGET:
10831 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10832 break;
10833 case VKI_BLKSSZGET:
10834 POST_MEM_WRITE(ARG3, sizeof(int));
10835 break;
10836 case VKI_BLKBSZGET:
10837 POST_MEM_WRITE(ARG3, sizeof(int));
10838 break;
10839 case VKI_BLKBSZSET:
10840 break;
10841 case VKI_BLKGETSIZE64:
10842 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10843 break;
10844 case VKI_BLKPBSZGET:
10845 POST_MEM_WRITE(ARG3, sizeof(int));
10846 break;
10847 case VKI_BLKIOMIN:
10848 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10849 break;
10850 case VKI_BLKIOOPT:
10851 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10852 break;
10853 case VKI_BLKALIGNOFF:
10854 POST_MEM_WRITE(ARG3, sizeof(int));
10855 break;
10856 case VKI_BLKDISCARDZEROES:
10857 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10858 break;
10859 case VKI_BLKREPORTZONE: {
10860 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10862 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10863 break;
10865 case VKI_BLKRESETZONE:
10866 break;
10868 /* Hard disks */
10869 case VKI_HDIO_GETGEO: /* 0x0301 */
10870 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10871 break;
10872 case VKI_HDIO_GET_DMA: /* 0x030b */
10873 POST_MEM_WRITE(ARG3, sizeof(long));
10874 break;
10875 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10876 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10877 break;
10879 /* SCSI */
10880 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10881 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10882 break;
10883 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10884 POST_MEM_WRITE(ARG3, sizeof(int));
10885 break;
10887 /* CD ROM stuff (??) */
10888 case VKI_CDROM_DISC_STATUS:
10889 case VKI_CDROMSTOP:
10890 break;
10891 case VKI_CDROMSUBCHNL:
10892 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10893 break;
10894 case VKI_CDROMREADTOCHDR:
10895 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10896 break;
10897 case VKI_CDROMREADTOCENTRY:
10898 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10899 break;
10900 case VKI_CDROMMULTISESSION:
10901 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10902 break;
10903 case VKI_CDROMVOLREAD:
10904 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10905 break;
10906 case VKI_CDROMREADMODE1:
10907 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10908 break;
10909 case VKI_CDROMREADMODE2:
10910 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10911 break;
10912 case VKI_CDROMREADRAW:
10913 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10914 break;
10915 case VKI_CDROMREADAUDIO:
10917 struct vki_cdrom_read_audio *cra =
10918 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10919 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10920 break;
10923 case VKI_CDROMPLAYMSF:
10924 break;
10925 /* The following two are probably bogus (should check args
10926 for readability). JRS 20021117 */
10927 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10928 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10929 break;
10930 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10931 break;
10933 /* DVD stuff */
10934 case VKI_DVD_READ_STRUCT:
10935 break;
10937 case VKI_FIGETBSZ:
10938 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10939 break;
10940 case VKI_FIBMAP:
10941 POST_MEM_WRITE(ARG3, sizeof(int));
10942 break;
10943 case VKI_FICLONE:
10944 break;
10946 case VKI_FBIOGET_VSCREENINFO: //0x4600
10947 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10948 break;
10949 case VKI_FBIOGET_FSCREENINFO: //0x4602
10950 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10951 break;
10953 case VKI_PPCLAIM:
10954 case VKI_PPEXCL:
10955 case VKI_PPYIELD:
10956 case VKI_PPRELEASE:
10957 case VKI_PPSETMODE:
10958 case VKI_PPSETPHASE:
10959 case VKI_PPSETFLAGS:
10960 case VKI_PPWDATA:
10961 case VKI_PPWCONTROL:
10962 case VKI_PPFCONTROL:
10963 case VKI_PPDATADIR:
10964 case VKI_PPNEGOT:
10965 case VKI_PPWCTLONIRQ:
10966 case VKI_PPSETTIME:
10967 break;
10968 case VKI_PPGETMODE:
10969 POST_MEM_WRITE( ARG3, sizeof(int) );
10970 break;
10971 case VKI_PPGETPHASE:
10972 POST_MEM_WRITE( ARG3, sizeof(int) );
10973 break;
10974 case VKI_PPGETMODES:
10975 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10976 break;
10977 case VKI_PPGETFLAGS:
10978 POST_MEM_WRITE( ARG3, sizeof(int) );
10979 break;
10980 case VKI_PPRSTATUS:
10981 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10982 break;
10983 case VKI_PPRDATA:
10984 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10985 break;
10986 case VKI_PPRCONTROL:
10987 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10988 break;
10989 case VKI_PPCLRIRQ:
10990 POST_MEM_WRITE( ARG3, sizeof(int) );
10991 break;
10992 case VKI_PPGETTIME:
10993 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10994 break;
10996 case VKI_GIO_FONT:
10997 POST_MEM_WRITE( ARG3, 32 * 256 );
10998 break;
10999 case VKI_PIO_FONT:
11000 break;
11002 case VKI_GIO_FONTX:
11003 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
11004 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
11005 break;
11006 case VKI_PIO_FONTX:
11007 break;
11009 case VKI_PIO_FONTRESET:
11010 break;
11012 case VKI_GIO_CMAP:
11013 POST_MEM_WRITE( ARG3, 16 * 3 );
11014 break;
11015 case VKI_PIO_CMAP:
11016 break;
11018 case VKI_KIOCSOUND:
11019 case VKI_KDMKTONE:
11020 break;
11022 case VKI_KDGETLED:
11023 POST_MEM_WRITE( ARG3, sizeof(char) );
11024 break;
11025 case VKI_KDSETLED:
11026 break;
11028 case VKI_KDGKBTYPE:
11029 POST_MEM_WRITE( ARG3, sizeof(char) );
11030 break;
11032 case VKI_KDADDIO:
11033 case VKI_KDDELIO:
11034 case VKI_KDENABIO:
11035 case VKI_KDDISABIO:
11036 break;
11038 case VKI_KDSETMODE:
11039 break;
11040 case VKI_KDGETMODE:
11041 POST_MEM_WRITE( ARG3, sizeof(int) );
11042 break;
11044 case VKI_KDMAPDISP:
11045 case VKI_KDUNMAPDISP:
11046 break;
11048 case VKI_GIO_SCRNMAP:
11049 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11050 break;
11051 case VKI_PIO_SCRNMAP:
11052 break;
11053 case VKI_GIO_UNISCRNMAP:
11054 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11055 break;
11056 case VKI_PIO_UNISCRNMAP:
11057 break;
11059 case VKI_GIO_UNIMAP:
11060 if ( ARG3 ) {
11061 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11062 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11063 POST_MEM_WRITE( (Addr)desc->entries,
11064 desc->entry_ct * sizeof(struct vki_unipair) );
11066 break;
11067 case VKI_PIO_UNIMAP:
11068 break;
11069 case VKI_PIO_UNIMAPCLR:
11070 break;
11072 case VKI_KDGKBMODE:
11073 POST_MEM_WRITE( ARG3, sizeof(int) );
11074 break;
11075 case VKI_KDSKBMODE:
11076 break;
11078 case VKI_KDGKBMETA:
11079 POST_MEM_WRITE( ARG3, sizeof(int) );
11080 break;
11081 case VKI_KDSKBMETA:
11082 break;
11084 case VKI_KDGKBLED:
11085 POST_MEM_WRITE( ARG3, sizeof(char) );
11086 break;
11087 case VKI_KDSKBLED:
11088 break;
11090 case VKI_KDGKBENT:
11091 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11092 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11093 break;
11094 case VKI_KDSKBENT:
11095 break;
11097 case VKI_KDGKBSENT:
11098 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11099 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11100 break;
11101 case VKI_KDSKBSENT:
11102 break;
11104 case VKI_KDGKBDIACR:
11105 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11106 break;
11107 case VKI_KDSKBDIACR:
11108 break;
11110 case VKI_KDGETKEYCODE:
11111 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11112 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11113 break;
11114 case VKI_KDSETKEYCODE:
11115 break;
11117 case VKI_KDSIGACCEPT:
11118 break;
11120 case VKI_KDKBDREP:
11121 break;
11123 case VKI_KDFONTOP:
11124 if ( ARG3 ) {
11125 struct vki_console_font_op *op =
11126 (struct vki_console_font_op *) (Addr)ARG3;
11127 switch ( op->op ) {
11128 case VKI_KD_FONT_OP_SET:
11129 break;
11130 case VKI_KD_FONT_OP_GET:
11131 if ( op->data )
11132 POST_MEM_WRITE( (Addr) op->data,
11133 (op->width + 7) / 8 * 32 * op->charcount );
11134 break;
11135 case VKI_KD_FONT_OP_SET_DEFAULT:
11136 break;
11137 case VKI_KD_FONT_OP_COPY:
11138 break;
11140 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11142 break;
11144 case VKI_VT_OPENQRY:
11145 POST_MEM_WRITE( ARG3, sizeof(int) );
11146 break;
11147 case VKI_VT_GETMODE:
11148 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11149 break;
11150 case VKI_VT_SETMODE:
11151 break;
11152 case VKI_VT_GETSTATE:
11153 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11154 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11155 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11156 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11157 break;
11158 case VKI_VT_RELDISP:
11159 case VKI_VT_ACTIVATE:
11160 case VKI_VT_WAITACTIVE:
11161 case VKI_VT_DISALLOCATE:
11162 break;
11163 case VKI_VT_RESIZE:
11164 break;
11165 case VKI_VT_RESIZEX:
11166 break;
11167 case VKI_VT_LOCKSWITCH:
11168 case VKI_VT_UNLOCKSWITCH:
11169 break;
11171 case VKI_USBDEVFS_CONTROL:
11172 if ( ARG3 ) {
11173 struct vki_usbdevfs_ctrltransfer *vkuc =
11174 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11175 if (vkuc->bRequestType & 0x80)
11176 POST_MEM_WRITE((Addr)vkuc->data, RES);
11178 break;
11179 case VKI_USBDEVFS_BULK:
11180 if ( ARG3 ) {
11181 struct vki_usbdevfs_bulktransfer *vkub =
11182 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11183 if (vkub->ep & 0x80)
11184 POST_MEM_WRITE((Addr)vkub->data, RES);
11186 break;
11187 case VKI_USBDEVFS_GETDRIVER:
11188 if ( ARG3 ) {
11189 struct vki_usbdevfs_getdriver *vkugd =
11190 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11191 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11193 break;
11194 case VKI_USBDEVFS_REAPURB:
11195 case VKI_USBDEVFS_REAPURBNDELAY:
11196 if ( ARG3 ) {
11197 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11198 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11199 if (!*vkuu)
11200 break;
11201 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11202 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11203 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11204 if (vkusp->bRequestType & 0x80)
11205 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11206 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11207 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11208 char *bp = (*vkuu)->buffer;
11209 int i;
11210 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11211 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11212 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11213 if ((*vkuu)->endpoint & 0x80)
11214 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11215 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11217 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11218 } else {
11219 if ((*vkuu)->endpoint & 0x80)
11220 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11221 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11224 break;
11225 case VKI_USBDEVFS_CONNECTINFO:
11226 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11227 break;
11228 case VKI_USBDEVFS_IOCTL:
11229 if ( ARG3 ) {
11230 struct vki_usbdevfs_ioctl *vkui =
11231 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11232 UInt dir2, size2;
11233 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11234 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11235 if (size2 > 0) {
11236 if (dir2 & _VKI_IOC_READ)
11237 POST_MEM_WRITE((Addr)vkui->data, size2);
11240 break;
11242 /* I2C (/dev/i2c-*) ioctls */
11243 case VKI_I2C_SLAVE:
11244 case VKI_I2C_SLAVE_FORCE:
11245 case VKI_I2C_TENBIT:
11246 case VKI_I2C_PEC:
11247 break;
11248 case VKI_I2C_FUNCS:
11249 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11250 break;
11251 case VKI_I2C_RDWR:
11252 if ( ARG3 ) {
11253 struct vki_i2c_rdwr_ioctl_data *vkui =
11254 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11255 UInt i;
11256 for (i=0; i < vkui->nmsgs; i++) {
11257 struct vki_i2c_msg *msg = vkui->msgs + i;
11258 if (msg->flags & VKI_I2C_M_RD)
11259 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11262 break;
11263 case VKI_I2C_SMBUS:
11264 if ( ARG3 ) {
11265 struct vki_i2c_smbus_ioctl_data *vkis
11266 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11267 /* i2c_smbus_write_quick hides its value in read_write, so
11268 this variable can have a different meaning */
11269 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11270 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11271 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11272 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11273 UInt size;
11274 switch(vkis->size) {
11275 case VKI_I2C_SMBUS_BYTE:
11276 case VKI_I2C_SMBUS_BYTE_DATA:
11277 size = 1;
11278 break;
11279 case VKI_I2C_SMBUS_WORD_DATA:
11280 case VKI_I2C_SMBUS_PROC_CALL:
11281 size = 2;
11282 break;
11283 case VKI_I2C_SMBUS_BLOCK_DATA:
11284 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11285 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11286 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11287 size = 1 + vkis->data->block[0];
11288 break;
11289 default:
11290 size = 0;
11292 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11296 break;
11298 /* Wireless extensions ioctls */
11299 case VKI_SIOCSIWCOMMIT:
11300 case VKI_SIOCSIWNWID:
11301 case VKI_SIOCSIWFREQ:
11302 case VKI_SIOCSIWMODE:
11303 case VKI_SIOCSIWSENS:
11304 case VKI_SIOCSIWRANGE:
11305 case VKI_SIOCSIWPRIV:
11306 case VKI_SIOCSIWSTATS:
11307 case VKI_SIOCSIWSPY:
11308 case VKI_SIOCSIWTHRSPY:
11309 case VKI_SIOCSIWAP:
11310 case VKI_SIOCSIWSCAN:
11311 case VKI_SIOCSIWESSID:
11312 case VKI_SIOCSIWRATE:
11313 case VKI_SIOCSIWNICKN:
11314 case VKI_SIOCSIWRTS:
11315 case VKI_SIOCSIWFRAG:
11316 case VKI_SIOCSIWTXPOW:
11317 case VKI_SIOCSIWRETRY:
11318 case VKI_SIOCSIWENCODE:
11319 case VKI_SIOCSIWPOWER:
11320 case VKI_SIOCSIWGENIE:
11321 case VKI_SIOCSIWMLME:
11322 case VKI_SIOCSIWAUTH:
11323 case VKI_SIOCSIWENCODEEXT:
11324 case VKI_SIOCSIWPMKSA:
11325 break;
11326 case VKI_SIOCGIWNAME:
11327 if (ARG3) {
11328 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11329 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11331 break;
11332 case VKI_SIOCGIWNWID:
11333 case VKI_SIOCGIWSENS:
11334 case VKI_SIOCGIWRATE:
11335 case VKI_SIOCGIWRTS:
11336 case VKI_SIOCGIWFRAG:
11337 case VKI_SIOCGIWTXPOW:
11338 case VKI_SIOCGIWRETRY:
11339 case VKI_SIOCGIWPOWER:
11340 case VKI_SIOCGIWAUTH:
11341 if (ARG3) {
11342 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11343 sizeof(struct vki_iw_param));
11345 break;
11346 case VKI_SIOCGIWFREQ:
11347 if (ARG3) {
11348 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11349 sizeof(struct vki_iw_freq));
11351 break;
11352 case VKI_SIOCGIWMODE:
11353 if (ARG3) {
11354 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11355 sizeof(__vki_u32));
11357 break;
11358 case VKI_SIOCGIWRANGE:
11359 case VKI_SIOCGIWPRIV:
11360 case VKI_SIOCGIWSTATS:
11361 case VKI_SIOCGIWSPY:
11362 case VKI_SIOCGIWTHRSPY:
11363 case VKI_SIOCGIWAPLIST:
11364 case VKI_SIOCGIWSCAN:
11365 case VKI_SIOCGIWESSID:
11366 case VKI_SIOCGIWNICKN:
11367 case VKI_SIOCGIWENCODE:
11368 case VKI_SIOCGIWGENIE:
11369 case VKI_SIOCGIWENCODEEXT:
11370 if (ARG3) {
11371 struct vki_iw_point* point;
11372 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11373 POST_MEM_WRITE((Addr)point->pointer, point->length);
11375 break;
11376 case VKI_SIOCGIWAP:
11377 if (ARG3) {
11378 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11379 sizeof(struct vki_sockaddr));
11381 break;
11383 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11384 || defined(VGPV_mips32_linux_android) \
11385 || defined(VGPV_arm64_linux_android)
11386 /* ashmem */
11387 case VKI_ASHMEM_GET_SIZE:
11388 case VKI_ASHMEM_SET_SIZE:
11389 case VKI_ASHMEM_GET_PROT_MASK:
11390 case VKI_ASHMEM_SET_PROT_MASK:
11391 case VKI_ASHMEM_GET_PIN_STATUS:
11392 case VKI_ASHMEM_PURGE_ALL_CACHES:
11393 case VKI_ASHMEM_SET_NAME:
11394 case VKI_ASHMEM_PIN:
11395 case VKI_ASHMEM_UNPIN:
11396 break;
11397 case VKI_ASHMEM_GET_NAME:
11398 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11399 break;
11401 /* binder */
11402 case VKI_BINDER_WRITE_READ:
11403 if (ARG3) {
11404 struct vki_binder_write_read* bwr
11405 = (struct vki_binder_write_read*)(Addr)ARG3;
11406 POST_FIELD_WRITE(bwr->write_consumed);
11407 POST_FIELD_WRITE(bwr->read_consumed);
11409 if (bwr->read_size)
11410 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11412 break;
11414 case VKI_BINDER_SET_IDLE_TIMEOUT:
11415 case VKI_BINDER_SET_MAX_THREADS:
11416 case VKI_BINDER_SET_IDLE_PRIORITY:
11417 case VKI_BINDER_SET_CONTEXT_MGR:
11418 case VKI_BINDER_THREAD_EXIT:
11419 break;
11420 case VKI_BINDER_VERSION:
11421 if (ARG3) {
11422 struct vki_binder_version* bv =
11423 (struct vki_binder_version*)(Addr)ARG3;
11424 POST_FIELD_WRITE(bv->protocol_version);
11426 break;
11427 # endif /* defined(VGPV_*_linux_android) */
11429 case VKI_HCIGETDEVLIST:
11430 if (ARG3) {
11431 struct vki_hci_dev_list_req* dlr =
11432 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11433 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11434 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11436 break;
11438 case VKI_HCIINQUIRY:
11439 if (ARG3) {
11440 struct vki_hci_inquiry_req* ir =
11441 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11442 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11443 ir->num_rsp * sizeof(struct vki_inquiry_info));
11445 break;
11447 case VKI_DRM_IOCTL_VERSION:
11448 if (ARG3) {
11449 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11450 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11451 const vki_size_t orig_name_len = info->orig->name_len;
11452 const vki_size_t orig_date_len = info->orig->date_len;
11453 const vki_size_t orig_desc_len = info->orig->desc_len;
11454 *info->orig = info->data;
11455 ARG3 = (Addr)info->orig;
11456 data = info->orig;
11457 VG_(free)(info);
11458 if (SUCCESS) {
11459 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11460 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11461 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11462 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11463 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11464 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11465 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11466 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11467 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11470 break;
11471 case VKI_DRM_IOCTL_GET_UNIQUE:
11472 if (ARG3) {
11473 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11474 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11476 break;
11477 case VKI_DRM_IOCTL_GET_MAGIC:
11478 if (ARG3) {
11479 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11480 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11482 break;
11483 case VKI_DRM_IOCTL_WAIT_VBLANK:
11484 if (ARG3) {
11485 union vki_drm_wait_vblank *data =
11486 (union vki_drm_wait_vblank *)(Addr)ARG3;
11487 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11489 break;
11490 case VKI_DRM_IOCTL_GEM_FLINK:
11491 if (ARG3) {
11492 struct vki_drm_gem_flink *data =
11493 (struct vki_drm_gem_flink *)(Addr)ARG3;
11494 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11496 break;
11497 case VKI_DRM_IOCTL_GEM_OPEN:
11498 if (ARG3) {
11499 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11500 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11501 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11503 break;
11504 case VKI_DRM_IOCTL_I915_GETPARAM:
11505 if (ARG3) {
11506 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11507 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11509 break;
11510 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11511 if (ARG3) {
11512 struct vki_drm_i915_gem_busy *data =
11513 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11514 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11516 break;
11517 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11518 if (ARG3) {
11519 struct vki_drm_i915_gem_create *data =
11520 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11521 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11523 break;
11524 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11525 if (ARG3) {
11526 struct vki_drm_i915_gem_pread *data =
11527 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11528 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11530 break;
11531 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11532 if (ARG3) {
11533 struct vki_drm_i915_gem_mmap_v1 *data =
11534 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11535 Addr addr = data->addr_ptr;
11536 SizeT size = data->size;
11537 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11538 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11539 ML_(notify_core_and_tool_of_mmap)(addr, size,
11540 VKI_PROT_READ | VKI_PROT_WRITE,
11541 VKI_MAP_ANONYMOUS, -1, 0 );
11542 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11544 break;
11545 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11546 if (ARG3) {
11547 struct vki_drm_i915_gem_mmap *data =
11548 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11549 Addr addr = data->addr_ptr;
11550 SizeT size = data->size;
11551 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11552 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11553 ML_(notify_core_and_tool_of_mmap)(addr, size,
11554 VKI_PROT_READ | VKI_PROT_WRITE,
11555 VKI_MAP_ANONYMOUS, -1, 0 );
11556 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11558 break;
11559 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11560 if (ARG3) {
11561 struct vki_drm_i915_gem_mmap_gtt *data =
11562 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11563 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11565 break;
11566 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11567 if (ARG3) {
11568 struct vki_drm_i915_gem_set_tiling *data =
11569 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11570 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11571 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11572 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11574 break;
11575 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11576 if (ARG3) {
11577 struct vki_drm_i915_gem_get_tiling *data =
11578 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11579 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11580 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11582 break;
11583 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11584 if (ARG3) {
11585 struct vki_drm_i915_gem_get_aperture *data =
11586 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11587 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11588 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11590 break;
11592 /* KVM ioctls that only write the system call return value */
11593 case VKI_KVM_GET_API_VERSION:
11594 case VKI_KVM_CREATE_VM:
11595 case VKI_KVM_CHECK_EXTENSION:
11596 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11597 case VKI_KVM_S390_ENABLE_SIE:
11598 case VKI_KVM_CREATE_VCPU:
11599 case VKI_KVM_SET_TSS_ADDR:
11600 case VKI_KVM_CREATE_IRQCHIP:
11601 case VKI_KVM_RUN:
11602 case VKI_KVM_S390_INITIAL_RESET:
11603 case VKI_KVM_KVMCLOCK_CTRL:
11604 break;
11606 case VKI_KVM_S390_MEM_OP: {
11607 struct vki_kvm_s390_mem_op *args =
11608 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11609 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11610 break;
11611 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11612 POST_MEM_WRITE((Addr)args->buf, args->size);
11614 break;
11616 #ifdef ENABLE_XEN
11617 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11618 SyscallArgs harrghs;
11619 struct vki_xen_privcmd_hypercall *args =
11620 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11622 if (!args)
11623 break;
11625 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11626 harrghs.sysno = args->op;
11627 harrghs.arg1 = args->arg[0];
11628 harrghs.arg2 = args->arg[1];
11629 harrghs.arg3 = args->arg[2];
11630 harrghs.arg4 = args->arg[3];
11631 harrghs.arg5 = args->arg[4];
11632 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11634 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11636 break;
11638 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11639 break;
11640 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11641 struct vki_xen_privcmd_mmapbatch *args =
11642 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11643 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11645 break;
11646 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11647 struct vki_xen_privcmd_mmapbatch_v2 *args =
11648 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11649 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11651 break;
11653 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11654 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11655 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11656 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11657 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11658 case VKI_XEN_IOCTL_EVTCHN_RESET:
11659 /* No output */
11660 break;
11661 #endif
11663 /* Lustre */
11664 case VKI_OBD_IOC_FID2PATH: {
11665 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11666 POST_FIELD_WRITE(args->gf_recno);
11667 POST_FIELD_WRITE(args->gf_linkno);
11668 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11669 break;
11672 case VKI_LL_IOC_PATH2FID:
11673 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11674 break;
11676 case VKI_LL_IOC_GETPARENT: {
11677 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11678 POST_FIELD_WRITE(gp->gp_fid);
11679 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11680 break;
11683 /* V4L2 */
11684 case VKI_V4L2_S_FMT:
11685 case VKI_V4L2_TRY_FMT:
11686 case VKI_V4L2_REQBUFS:
11687 case VKI_V4L2_OVERLAY:
11688 case VKI_V4L2_STREAMON:
11689 case VKI_V4L2_STREAMOFF:
11690 case VKI_V4L2_S_PARM:
11691 case VKI_V4L2_S_STD:
11692 case VKI_V4L2_S_FREQUENCY:
11693 case VKI_V4L2_S_CTRL:
11694 case VKI_V4L2_S_TUNER:
11695 case VKI_V4L2_S_AUDIO:
11696 case VKI_V4L2_S_INPUT:
11697 case VKI_V4L2_S_EDID:
11698 case VKI_V4L2_S_OUTPUT:
11699 case VKI_V4L2_S_AUDOUT:
11700 case VKI_V4L2_S_MODULATOR:
11701 case VKI_V4L2_S_JPEGCOMP:
11702 case VKI_V4L2_S_CROP:
11703 case VKI_V4L2_S_PRIORITY:
11704 case VKI_V4L2_S_HW_FREQ_SEEK:
11705 case VKI_V4L2_S_DV_TIMINGS:
11706 case VKI_V4L2_SUBSCRIBE_EVENT:
11707 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11708 case VKI_V4L2_PREPARE_BUF:
11709 break;
11710 case VKI_V4L2_QUERYCAP: {
11711 struct vki_v4l2_capability *data =
11712 (struct vki_v4l2_capability *)(Addr)ARG3;
11713 POST_MEM_WRITE((Addr)data, sizeof(*data));
11714 break;
11716 case VKI_V4L2_ENUM_FMT: {
11717 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11718 POST_FIELD_WRITE(data->flags);
11719 POST_FIELD_WRITE(data->description);
11720 POST_FIELD_WRITE(data->pixelformat);
11721 POST_FIELD_WRITE(data->reserved);
11722 break;
11724 case VKI_V4L2_G_FMT: {
11725 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11726 switch (data->type) {
11727 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11728 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11729 POST_FIELD_WRITE(data->fmt.pix);
11730 break;
11731 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11732 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11733 POST_FIELD_WRITE(data->fmt.vbi);
11734 break;
11735 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11736 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11737 POST_FIELD_WRITE(data->fmt.sliced);
11738 break;
11739 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11740 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11741 POST_FIELD_WRITE(data->fmt.win);
11742 break;
11743 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11744 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11745 POST_FIELD_WRITE(data->fmt.pix_mp);
11746 break;
11747 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11748 POST_FIELD_WRITE(data->fmt.sdr);
11749 break;
11751 break;
11753 case VKI_V4L2_QUERYBUF: {
11754 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11755 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11756 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11757 unsigned i;
11759 for (i = 0; i < data->length; i++) {
11760 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11761 POST_FIELD_WRITE(data->m.planes[i].length);
11762 POST_FIELD_WRITE(data->m.planes[i].m);
11763 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11764 POST_FIELD_WRITE(data->m.planes[i].reserved);
11766 } else {
11767 POST_FIELD_WRITE(data->m);
11768 POST_FIELD_WRITE(data->length);
11770 POST_FIELD_WRITE(data->bytesused);
11771 POST_FIELD_WRITE(data->flags);
11772 POST_FIELD_WRITE(data->field);
11773 POST_FIELD_WRITE(data->timestamp);
11774 POST_FIELD_WRITE(data->timecode);
11775 POST_FIELD_WRITE(data->sequence);
11776 POST_FIELD_WRITE(data->memory);
11777 POST_FIELD_WRITE(data->sequence);
11778 break;
11780 case VKI_V4L2_G_FBUF: {
11781 struct vki_v4l2_framebuffer *data =
11782 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11783 POST_MEM_WRITE((Addr)data, sizeof(*data));
11784 break;
11786 case VKI_V4L2_S_FBUF: {
11787 struct vki_v4l2_framebuffer *data =
11788 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11789 POST_FIELD_WRITE(data->capability);
11790 POST_FIELD_WRITE(data->flags);
11791 POST_FIELD_WRITE(data->fmt);
11792 break;
11794 case VKI_V4L2_QBUF: {
11795 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11797 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11798 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11799 unsigned i;
11801 for (i = 0; i < data->length; i++) {
11802 POST_FIELD_WRITE(data->m.planes[i].length);
11803 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11804 POST_FIELD_WRITE(data->m.planes[i].m);
11806 } else {
11807 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11808 POST_FIELD_WRITE(data->m);
11809 POST_FIELD_WRITE(data->length);
11811 break;
11813 case VKI_V4L2_EXPBUF: {
11814 struct vki_v4l2_exportbuffer *data =
11815 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11816 POST_FIELD_WRITE(data->fd);
11817 break;
11819 case VKI_V4L2_DQBUF: {
11820 struct vki_v4l2_buffer *data =
11821 (struct vki_v4l2_buffer *)(Addr)ARG3;
11822 POST_FIELD_WRITE(data->index);
11823 POST_FIELD_WRITE(data->bytesused);
11824 POST_FIELD_WRITE(data->field);
11825 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11826 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11827 unsigned i;
11829 for (i = 0; i < data->length; i++) {
11830 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11831 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11832 POST_FIELD_WRITE(data->m.planes[i].length);
11833 POST_FIELD_WRITE(data->m.planes[i].m);
11835 } else {
11836 POST_FIELD_WRITE(data->m);
11837 POST_FIELD_WRITE(data->length);
11838 POST_FIELD_WRITE(data->bytesused);
11839 POST_FIELD_WRITE(data->field);
11841 POST_FIELD_WRITE(data->timestamp);
11842 POST_FIELD_WRITE(data->timecode);
11843 POST_FIELD_WRITE(data->sequence);
11844 break;
11846 case VKI_V4L2_G_PARM: {
11847 struct vki_v4l2_streamparm *data =
11848 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11849 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11850 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11851 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11852 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11854 if (is_output)
11855 POST_MEM_WRITE((Addr)&data->parm.output,
11856 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11857 else
11858 POST_MEM_WRITE((Addr)&data->parm.capture,
11859 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11860 break;
11862 case VKI_V4L2_G_STD: {
11863 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11864 POST_MEM_WRITE((Addr)data, sizeof(*data));
11865 break;
11867 case VKI_V4L2_ENUMSTD: {
11868 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11869 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11870 break;
11872 case VKI_V4L2_ENUMINPUT: {
11873 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11874 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11875 break;
11877 case VKI_V4L2_G_CTRL: {
11878 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11879 POST_FIELD_WRITE(data->value);
11880 break;
11882 case VKI_V4L2_G_TUNER: {
11883 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11884 POST_MEM_WRITE((Addr)data->name,
11885 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11886 break;
11888 case VKI_V4L2_G_AUDIO: {
11889 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11890 POST_MEM_WRITE((Addr)data,
11891 sizeof(*data) - sizeof(data->reserved));
11892 break;
11894 case VKI_V4L2_QUERYCTRL: {
11895 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11896 POST_MEM_WRITE((Addr)&data->type,
11897 sizeof(*data) - sizeof(data->id));
11898 break;
11900 case VKI_V4L2_QUERYMENU: {
11901 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11902 POST_MEM_WRITE((Addr)data->name,
11903 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11904 break;
11906 case VKI_V4L2_G_INPUT: {
11907 int *data = (int *)(Addr)ARG3;
11908 POST_MEM_WRITE((Addr)data, sizeof(*data));
11909 break;
11911 case VKI_V4L2_G_EDID: {
11912 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11913 if (data->blocks && data->edid)
11914 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11915 break;
11917 case VKI_V4L2_G_OUTPUT: {
11918 int *data = (int *)(Addr)ARG3;
11919 POST_MEM_WRITE((Addr)data, sizeof(*data));
11920 break;
11922 case VKI_V4L2_ENUMOUTPUT: {
11923 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11924 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11925 break;
11927 case VKI_V4L2_G_AUDOUT: {
11928 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11929 POST_MEM_WRITE((Addr)data,
11930 sizeof(*data) - sizeof(data->reserved));
11931 break;
11933 case VKI_V4L2_G_MODULATOR: {
11934 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11935 POST_MEM_WRITE((Addr)data->name,
11936 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11937 break;
11939 case VKI_V4L2_G_FREQUENCY: {
11940 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11941 POST_FIELD_WRITE(data->type);
11942 POST_FIELD_WRITE(data->frequency);
11943 break;
11945 case VKI_V4L2_CROPCAP: {
11946 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11947 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11948 break;
11950 case VKI_V4L2_G_CROP: {
11951 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11952 POST_FIELD_WRITE(data->c);
11953 break;
11955 case VKI_V4L2_G_JPEGCOMP: {
11956 struct vki_v4l2_jpegcompression *data =
11957 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11958 POST_MEM_WRITE((Addr)data, sizeof(*data));
11959 break;
11961 case VKI_V4L2_QUERYSTD: {
11962 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11963 POST_MEM_WRITE((Addr)data, sizeof(*data));
11964 break;
11966 case VKI_V4L2_ENUMAUDIO: {
11967 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11968 POST_MEM_WRITE((Addr)data->name,
11969 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11970 break;
11972 case VKI_V4L2_ENUMAUDOUT: {
11973 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11974 POST_MEM_WRITE((Addr)data->name,
11975 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11976 break;
11978 case VKI_V4L2_G_PRIORITY: {
11979 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11980 POST_MEM_WRITE((Addr)data, sizeof(*data));
11981 break;
11983 case VKI_V4L2_G_SLICED_VBI_CAP: {
11984 struct vki_v4l2_sliced_vbi_cap *data =
11985 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11986 POST_MEM_WRITE((Addr)data,
11987 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11988 break;
11990 case VKI_V4L2_G_EXT_CTRLS: {
11991 struct vki_v4l2_ext_controls *data =
11992 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11993 if (data->count) {
11994 unsigned i;
11996 for (i = 0; i < data->count; i++) {
11997 if (data->controls[i].size)
11998 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11999 else
12000 POST_FIELD_WRITE(data->controls[i].value64);
12003 POST_FIELD_WRITE(data->error_idx);
12004 break;
12006 case VKI_V4L2_S_EXT_CTRLS: {
12007 struct vki_v4l2_ext_controls *data =
12008 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12009 POST_FIELD_WRITE(data->error_idx);
12010 break;
12012 case VKI_V4L2_TRY_EXT_CTRLS: {
12013 struct vki_v4l2_ext_controls *data =
12014 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12015 POST_FIELD_WRITE(data->error_idx);
12016 break;
12018 case VKI_V4L2_ENUM_FRAMESIZES: {
12019 struct vki_v4l2_frmsizeenum *data =
12020 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
12021 POST_FIELD_WRITE(data->type);
12022 POST_FIELD_WRITE(data->stepwise);
12023 break;
12025 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
12026 struct vki_v4l2_frmivalenum *data =
12027 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
12028 POST_FIELD_WRITE(data->type);
12029 POST_FIELD_WRITE(data->stepwise);
12030 break;
12032 case VKI_V4L2_G_ENC_INDEX: {
12033 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
12034 POST_MEM_WRITE((Addr)data, sizeof(*data));
12035 break;
12037 case VKI_V4L2_ENCODER_CMD: {
12038 struct vki_v4l2_encoder_cmd *data =
12039 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12040 POST_FIELD_WRITE(data->flags);
12041 break;
12043 case VKI_V4L2_TRY_ENCODER_CMD: {
12044 struct vki_v4l2_encoder_cmd *data =
12045 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12046 POST_FIELD_WRITE(data->flags);
12047 break;
12049 case VKI_V4L2_DBG_S_REGISTER: {
12050 struct vki_v4l2_dbg_register *data =
12051 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12052 POST_FIELD_WRITE(data->size);
12053 break;
12055 case VKI_V4L2_DBG_G_REGISTER: {
12056 struct vki_v4l2_dbg_register *data =
12057 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12058 POST_FIELD_WRITE(data->val);
12059 POST_FIELD_WRITE(data->size);
12060 break;
12062 case VKI_V4L2_G_DV_TIMINGS: {
12063 struct vki_v4l2_dv_timings *data =
12064 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12065 POST_MEM_WRITE((Addr)data, sizeof(*data));
12066 break;
12068 case VKI_V4L2_DQEVENT: {
12069 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12070 POST_MEM_WRITE((Addr)data, sizeof(*data));
12071 break;
12073 case VKI_V4L2_CREATE_BUFS: {
12074 struct vki_v4l2_create_buffers *data =
12075 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12076 POST_FIELD_WRITE(data->index);
12077 break;
12079 case VKI_V4L2_G_SELECTION: {
12080 struct vki_v4l2_selection *data =
12081 (struct vki_v4l2_selection *)(Addr)ARG3;
12082 POST_FIELD_WRITE(data->r);
12083 break;
12085 case VKI_V4L2_S_SELECTION: {
12086 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12087 POST_FIELD_WRITE(data->r);
12088 break;
12090 case VKI_V4L2_DECODER_CMD: {
12091 struct vki_v4l2_decoder_cmd *data =
12092 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12093 POST_FIELD_WRITE(data->flags);
12094 break;
12096 case VKI_V4L2_TRY_DECODER_CMD: {
12097 struct vki_v4l2_decoder_cmd *data =
12098 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12099 POST_FIELD_WRITE(data->flags);
12100 break;
12102 case VKI_V4L2_ENUM_DV_TIMINGS: {
12103 struct vki_v4l2_enum_dv_timings *data =
12104 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12105 POST_FIELD_WRITE(data->timings);
12106 break;
12108 case VKI_V4L2_QUERY_DV_TIMINGS: {
12109 struct vki_v4l2_dv_timings *data =
12110 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12111 POST_MEM_WRITE((Addr)data, sizeof(*data));
12112 break;
12114 case VKI_V4L2_DV_TIMINGS_CAP: {
12115 struct vki_v4l2_dv_timings_cap *data =
12116 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12117 POST_MEM_WRITE((Addr)data, sizeof(*data));
12118 break;
12120 case VKI_V4L2_ENUM_FREQ_BANDS: {
12121 struct vki_v4l2_frequency_band *data =
12122 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12123 POST_FIELD_WRITE(data->capability);
12124 POST_FIELD_WRITE(data->rangelow);
12125 POST_FIELD_WRITE(data->rangehigh);
12126 POST_FIELD_WRITE(data->modulation);
12127 break;
12129 case VKI_V4L2_DBG_G_CHIP_INFO: {
12130 struct vki_v4l2_dbg_chip_info *data =
12131 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12132 POST_FIELD_WRITE(data->name);
12133 POST_FIELD_WRITE(data->flags);
12134 break;
12136 case VKI_V4L2_QUERY_EXT_CTRL: {
12137 struct vki_v4l2_query_ext_ctrl *data =
12138 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12139 POST_MEM_WRITE((Addr)&data->type,
12140 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12141 break;
12144 case VKI_V4L2_SUBDEV_S_FMT:
12145 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12146 case VKI_V4L2_SUBDEV_S_CROP:
12147 case VKI_V4L2_SUBDEV_S_SELECTION:
12148 break;
12150 case VKI_V4L2_SUBDEV_G_FMT: {
12151 struct vki_v4l2_subdev_format *data =
12152 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12153 POST_FIELD_WRITE(data->format);
12154 break;
12156 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12157 struct vki_v4l2_subdev_frame_interval *data =
12158 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12159 POST_FIELD_WRITE(data->interval);
12160 break;
12162 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12163 struct vki_v4l2_subdev_mbus_code_enum *data =
12164 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12165 POST_FIELD_WRITE(data->code);
12166 break;
12168 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12169 struct vki_v4l2_subdev_frame_size_enum *data =
12170 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12171 POST_FIELD_WRITE(data->min_width);
12172 POST_FIELD_WRITE(data->min_height);
12173 POST_FIELD_WRITE(data->max_width);
12174 POST_FIELD_WRITE(data->max_height);
12175 break;
12177 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12178 struct vki_v4l2_subdev_frame_interval_enum *data =
12179 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12180 POST_FIELD_WRITE(data->interval);
12181 break;
12183 case VKI_V4L2_SUBDEV_G_CROP: {
12184 struct vki_v4l2_subdev_crop *data =
12185 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12186 POST_FIELD_WRITE(data->rect);
12187 break;
12189 case VKI_V4L2_SUBDEV_G_SELECTION: {
12190 struct vki_v4l2_subdev_selection *data =
12191 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12192 POST_FIELD_WRITE(data->r);
12193 break;
12195 case VKI_MEDIA_IOC_DEVICE_INFO: {
12196 struct vki_media_device_info *data =
12197 (struct vki_media_device_info *)(Addr)ARG3;
12198 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12199 break;
12201 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12202 struct vki_media_entity_desc *data =
12203 (struct vki_media_entity_desc *)(Addr)ARG3;
12204 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12205 break;
12207 case VKI_MEDIA_IOC_ENUM_LINKS:
12209 * This ioctl does write to the provided pointers, but it's not
12210 * possible to deduce the size of the array those pointers point to.
12212 break;
12213 case VKI_MEDIA_IOC_SETUP_LINK:
12214 break;
12216 /* Serial */
12217 case VKI_TIOCGSERIAL: {
12218 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12219 POST_MEM_WRITE((Addr)data, sizeof(*data));
12220 break;
12222 case VKI_TIOCSSERIAL:
12223 break;
12225 case VKI_PERF_EVENT_IOC_ENABLE:
12226 case VKI_PERF_EVENT_IOC_DISABLE:
12227 case VKI_PERF_EVENT_IOC_REFRESH:
12228 case VKI_PERF_EVENT_IOC_RESET:
12229 case VKI_PERF_EVENT_IOC_PERIOD:
12230 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12231 case VKI_PERF_EVENT_IOC_SET_FILTER:
12232 case VKI_PERF_EVENT_IOC_SET_BPF:
12233 break;
12235 case VKI_PERF_EVENT_IOC_ID:
12236 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12237 break;
12239 /* Pulse Per Second (PPS) */
12240 case VKI_PPS_GETPARAMS: {
12241 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12242 POST_MEM_WRITE((Addr)data, sizeof(*data));
12243 break;
12245 case VKI_PPS_GETCAP:
12246 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12247 break;
12248 case VKI_PPS_FETCH: {
12249 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12250 POST_FIELD_WRITE(data->info);
12251 break;
12253 case VKI_PPS_SETPARAMS:
12254 case VKI_PPS_KC_BIND:
12255 break;
12257 /* PTP Hardware Clock */
12258 case VKI_PTP_CLOCK_GETCAPS: {
12259 struct vki_ptp_clock_caps *data =
12260 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12261 POST_MEM_WRITE((Addr)data, sizeof(*data));
12262 break;
12264 case VKI_PTP_SYS_OFFSET: {
12265 struct vki_ptp_sys_offset *data =
12266 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12267 POST_MEM_WRITE((Addr)data->ts,
12268 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12269 break;
12271 case VKI_PTP_PIN_GETFUNC: {
12272 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12273 POST_MEM_WRITE((Addr)data, sizeof(*data));
12274 break;
12276 case VKI_PTP_SYS_OFFSET_PRECISE: {
12277 struct vki_ptp_sys_offset_precise *data =
12278 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12279 POST_MEM_WRITE((Addr)data, sizeof(*data));
12280 break;
12282 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12283 struct vki_ptp_sys_offset_extended *data =
12284 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12285 POST_MEM_WRITE((Addr)data->ts,
12286 3 * data->n_samples * sizeof(data->ts[0][0]));
12287 break;
12289 case VKI_PTP_EXTTS_REQUEST:
12290 case VKI_PTP_PEROUT_REQUEST:
12291 case VKI_PTP_ENABLE_PPS:
12292 case VKI_PTP_PIN_SETFUNC:
12293 break;
12295 default:
12296 /* EVIOC* are variable length and return size written on success */
12297 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12298 case VKI_EVIOCGNAME(0):
12299 case VKI_EVIOCGPHYS(0):
12300 case VKI_EVIOCGUNIQ(0):
12301 case VKI_EVIOCGKEY(0):
12302 case VKI_EVIOCGLED(0):
12303 case VKI_EVIOCGSND(0):
12304 case VKI_EVIOCGSW(0):
12305 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12306 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12307 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12308 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12309 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12310 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12311 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12312 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12313 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12314 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12315 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12316 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12317 if (RES > 0)
12318 POST_MEM_WRITE(ARG3, RES);
12319 break;
12320 default:
12321 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12322 break;
12324 break;
12327 post_sys_ioctl__out:
12328 {} /* keep C compilers happy */
12331 /* ---------------------------------------------------------------------
12332 socketcall wrapper helpers
12333 ------------------------------------------------------------------ */
12335 void
12336 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12337 UWord arg0, UWord arg1, UWord arg2,
12338 UWord arg3, UWord arg4 )
12340 /* int getsockopt(int s, int level, int optname,
12341 void *optval, socklen_t *optlen); */
12342 Addr optval_p = arg3;
12343 Addr optlen_p = arg4;
12344 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12345 if (optval_p != (Addr)NULL) {
12346 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12347 "socketcall.getsockopt(optval)",
12348 "socketcall.getsockopt(optlen)" );
12349 if (arg1 == VKI_SOL_SCTP &&
12350 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12351 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12353 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12354 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12355 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12356 (Addr)ga->addrs, address_bytes );
12361 void
12362 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12363 SysRes res,
12364 UWord arg0, UWord arg1, UWord arg2,
12365 UWord arg3, UWord arg4 )
12367 Addr optval_p = arg3;
12368 Addr optlen_p = arg4;
12369 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12370 if (optval_p != (Addr)NULL) {
12371 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12372 "socketcall.getsockopt(optlen_out)" );
12373 if (arg1 == VKI_SOL_SCTP &&
12374 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12375 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12377 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12378 struct vki_sockaddr *a = ga->addrs;
12379 int i;
12380 for (i = 0; i < ga->addr_num; i++) {
12381 int sl = 0;
12382 if (a->sa_family == VKI_AF_INET)
12383 sl = sizeof(struct vki_sockaddr_in);
12384 else if (a->sa_family == VKI_AF_INET6)
12385 sl = sizeof(struct vki_sockaddr_in6);
12386 else {
12387 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12388 "address type %d\n", a->sa_family);
12390 a = (struct vki_sockaddr*)((char*)a + sl);
12392 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12397 void
12398 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12399 UWord arg0, UWord arg1, UWord arg2,
12400 UWord arg3, UWord arg4 )
12402 /* int setsockopt(int s, int level, int optname,
12403 const void *optval, socklen_t optlen); */
12404 Addr optval_p = arg3;
12405 if (optval_p != (Addr)NULL) {
12407 * OK, let's handle at least some setsockopt levels and options
12408 * ourselves, so we don't get false claims of references to
12409 * uninitialized memory (such as padding in structures) and *do*
12410 * check what pointers in the argument point to.
12412 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12414 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12417 * struct sock_fprog has a 16-bit count of instructions,
12418 * followed by a pointer to an array of those instructions.
12419 * There's padding between those two elements.
12421 * So that we don't bogusly complain about the padding bytes,
12422 * we just report that we read len and and filter.
12424 * We then make sure that what filter points to is valid.
12426 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12427 (Addr)&fp->len, sizeof(fp->len) );
12428 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12429 (Addr)&fp->filter, sizeof(fp->filter) );
12431 /* len * sizeof (*filter) */
12432 if (fp->filter != NULL)
12434 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12435 (Addr)(fp->filter),
12436 fp->len * sizeof(*fp->filter) );
12439 else
12441 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12442 arg3, /* optval */
12443 arg4 /* optlen */ );
12448 void
12449 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12450 UWord arg1, UWord arg2, UWord arg3,
12451 UWord arg4, UWord arg5 )
12453 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12454 HChar name[40]; // large enough
12455 UInt i;
12456 for (i = 0; i < arg3; i++) {
12457 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12458 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12459 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12460 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12462 if (arg5)
12463 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12466 void
12467 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12468 UWord arg1, UWord arg2, UWord arg3,
12469 UWord arg4, UWord arg5 )
12471 if (res > 0) {
12472 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12473 HChar name[32]; // large enough
12474 UInt i;
12475 for (i = 0; i < res; i++) {
12476 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12477 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12478 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12483 void
12484 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12485 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12487 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12488 HChar name[40]; // large enough
12489 UInt i;
12490 for (i = 0; i < arg3; i++) {
12491 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12492 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12493 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12494 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12498 void
12499 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12500 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12502 if (res > 0) {
12503 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12504 UInt i;
12505 for (i = 0; i < res; i++) {
12506 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12511 /* ---------------------------------------------------------------------
12512 ptrace wrapper helpers
12513 ------------------------------------------------------------------ */
12515 void
12516 ML_(linux_POST_traceme) ( ThreadId tid )
12518 ThreadState *tst = VG_(get_ThreadState)(tid);
12519 tst->ptrace = VKI_PT_PTRACED;
12522 void
12523 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12525 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12527 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12528 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12529 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12530 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12531 (Addr) iov->iov_base, iov->iov_len);
12535 void
12536 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12538 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12540 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12541 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12542 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12543 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12544 (Addr) iov->iov_base, iov->iov_len);
12548 void
12549 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12551 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12553 /* XXX: The actual amount of data written by the kernel might be
12554 less than iov_len, depending on the regset (arg3). */
12555 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12558 PRE(sys_kcmp)
12560 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12561 SARG1, SARG2, SARG3, ARG4, ARG5);
12562 switch (ARG3) {
12563 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12564 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12565 /* Most of the comparison types don't look at |idx1| or
12566 |idx2|. */
12567 PRE_REG_READ3(long, "kcmp",
12568 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12569 break;
12570 case VKI_KCMP_FILE:
12571 default:
12572 PRE_REG_READ5(long, "kcmp",
12573 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12574 unsigned long, idx1, unsigned long, idx2);
12575 break;
12579 /* ---------------------------------------------------------------------
12580 bpf wrappers
12581 ------------------------------------------------------------------ */
12583 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12585 HChar path[32], buf[1024]; /* large enough */
12586 SysRes sres;
12587 HChar *comp;
12588 Int proc_fd;
12590 *key_size = 0;
12591 *value_size = 0;
12593 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12594 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12595 if (sr_isError(sres))
12596 return False;
12597 proc_fd = sr_Res(sres);
12599 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12600 return False;
12601 VG_(close)(proc_fd);
12603 comp = VG_(strstr)(buf, "key_size:");
12604 if (comp)
12605 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12607 comp = VG_(strstr)(buf, "value_size:");
12608 if (comp)
12609 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12611 return (*key_size && *value_size);
12615 * From a file descriptor for an eBPF object, try to determine the size of the
12616 * struct that will be written, i.e. determine if object is a map or a program.
12617 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12618 * search for strings "prog_type" or "map_type".
12620 static UInt bpf_obj_get_info_size(Int fd)
12622 HChar path[32], buf[1024]; /* large enough */
12623 SysRes sres;
12624 Int proc_fd;
12626 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12627 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12628 if (sr_isError(sres))
12629 return 0;
12630 proc_fd = sr_Res(sres);
12632 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12633 return 0;
12634 VG_(close)(proc_fd);
12636 if (VG_(strstr)(buf, "prog_type:"))
12637 return sizeof(struct vki_bpf_prog_info);
12639 if (VG_(strstr)(buf, "map_type:"))
12640 return sizeof(struct vki_bpf_map_info);
12642 return 0;
12645 PRE(sys_bpf)
12647 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12648 UInt res, key_size, value_size;
12650 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12651 (Word)ARG1, ARG2, ARG3);
12652 PRE_REG_READ3(long, "bpf",
12653 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12654 switch (ARG1) {
12655 case VKI_BPF_PROG_GET_NEXT_ID:
12656 case VKI_BPF_MAP_GET_NEXT_ID:
12657 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12658 break;
12659 case VKI_BPF_PROG_GET_FD_BY_ID:
12660 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12661 break;
12662 case VKI_BPF_MAP_GET_FD_BY_ID:
12663 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12664 break;
12665 case VKI_BPF_BTF_GET_FD_BY_ID:
12666 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12667 break;
12668 case VKI_BPF_MAP_CREATE:
12669 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12670 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12671 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12672 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12673 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12674 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12675 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12676 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12677 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12678 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12679 switch (attr->map_type) {
12680 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12681 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12682 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12683 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12684 SET_STATUS_Failure(VKI_EBADF);
12685 break;
12686 case VKI_BPF_MAP_TYPE_ARRAY:
12687 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12688 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12689 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12690 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12691 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12692 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12693 SET_STATUS_Failure(VKI_EBADF);
12694 break;
12698 break;
12699 case VKI_BPF_MAP_TYPE_UNSPEC:
12700 case VKI_BPF_MAP_TYPE_HASH:
12701 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12702 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12703 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12704 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12705 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12706 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12707 case VKI_BPF_MAP_TYPE_LRU_HASH:
12708 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12709 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12710 case VKI_BPF_MAP_TYPE_DEVMAP:
12711 case VKI_BPF_MAP_TYPE_SOCKMAP:
12712 case VKI_BPF_MAP_TYPE_CPUMAP:
12713 case VKI_BPF_MAP_TYPE_XSKMAP:
12714 case VKI_BPF_MAP_TYPE_SOCKHASH:
12715 default:
12716 break;
12718 break;
12719 case VKI_BPF_MAP_LOOKUP_ELEM:
12720 /* Perform a lookup on an eBPF map. Read key, write value. */
12721 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12722 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12723 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12724 if (ML_(safe_to_deref)(attr, ARG3)) {
12725 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12726 SET_STATUS_Failure(VKI_EBADF);
12727 break;
12729 /* Get size of key and value for this map. */
12730 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12731 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12732 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12735 break;
12736 case VKI_BPF_MAP_UPDATE_ELEM:
12737 /* Add or update a map element in kernel. Read key, read value. */
12738 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12739 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12740 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12741 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12742 if (ML_(safe_to_deref)(attr, ARG3)) {
12743 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12744 SET_STATUS_Failure(VKI_EBADF);
12745 break;
12747 /* Get size of key and value for this map. */
12748 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12749 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12750 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12753 break;
12754 case VKI_BPF_MAP_DELETE_ELEM:
12755 /* Delete a map element in kernel. Read key from user space. */
12756 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12757 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12758 if (ML_(safe_to_deref)(attr, ARG3)) {
12759 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12760 SET_STATUS_Failure(VKI_EBADF);
12761 break;
12763 /* Get size of key for this map. */
12764 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12765 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12767 break;
12768 case VKI_BPF_MAP_GET_NEXT_KEY:
12769 /* From a key, get next key for the map. Read key, write next key. */
12770 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12771 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12772 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12773 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12774 if (ML_(safe_to_deref)(attr, ARG3)) {
12775 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12776 SET_STATUS_Failure(VKI_EBADF);
12777 break;
12779 /* Get size of key for this map. */
12780 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12781 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12782 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12785 break;
12786 case VKI_BPF_PROG_LOAD:
12787 /* Load a program into the kernel from an array of instructions. */
12788 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12789 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12790 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12791 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12792 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12793 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12794 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12795 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12796 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12797 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12798 if (ML_(safe_to_deref)(attr, ARG3)) {
12799 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12800 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12801 /* Read instructions, license, program name. */
12802 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12803 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12804 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12805 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12806 /* Possibly write up to log_len into user space log buffer. */
12807 if (attr->log_level || attr->log_size || attr->log_buf)
12808 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12810 break;
12811 case VKI_BPF_OBJ_PIN:
12812 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12813 /* fall through */
12814 case VKI_BPF_OBJ_GET:
12815 /* Get pinned eBPF program or map. Read path name. */
12816 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12817 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12818 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12819 if (ML_(safe_to_deref)(attr, ARG3)) {
12820 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12821 SET_STATUS_Failure(VKI_EBADF);
12822 break;
12824 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12826 break;
12827 case VKI_BPF_PROG_ATTACH:
12828 case VKI_BPF_PROG_DETACH:
12829 /* Detach eBPF program from kernel attach point. */
12830 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12831 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12832 if (ML_(safe_to_deref)(attr, ARG3)) {
12833 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12834 SET_STATUS_Failure(VKI_EBADF);
12835 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12836 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12837 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12838 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12839 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12840 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12841 SET_STATUS_Failure(VKI_EBADF);
12844 break;
12845 case VKI_BPF_PROG_TEST_RUN:
12846 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12847 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12848 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12849 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12850 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12851 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12852 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12853 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12854 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12855 if (ML_(safe_to_deref)(attr, ARG3)) {
12856 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12857 SET_STATUS_Failure(VKI_EBADF);
12858 break;
12860 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12861 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12862 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12864 break;
12865 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12866 /* Get info for eBPF map or program. Write info. */
12867 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12868 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12869 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12870 if (ML_(safe_to_deref)(attr, ARG3)) {
12871 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12872 SET_STATUS_Failure(VKI_EBADF);
12873 break;
12875 /* Get size of struct to write: is object a program or a map? */
12876 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12877 if (res)
12878 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12879 VG_MIN(attr->info.info_len, res));
12880 else
12881 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12882 VG_MIN(attr->info.info_len,
12883 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12884 sizeof(struct vki_bpf_map_info)),
12885 sizeof(struct vki_bpf_btf_info))));
12887 break;
12888 case VKI_BPF_PROG_QUERY:
12890 * Query list of eBPF program attached to cgroup.
12891 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12893 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12894 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12895 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12896 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12897 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12898 if (ML_(safe_to_deref)(attr, ARG3)) {
12899 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12900 SET_STATUS_Failure(VKI_EBADF);
12901 break;
12903 if (attr->query.prog_cnt > 0) {
12904 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12905 if (attr->query.prog_ids) {
12906 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12907 attr->query.prog_cnt * sizeof(__vki_u32));
12911 break;
12912 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12913 /* Open raw tracepoint. Read tracepoint name. */
12914 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12915 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12916 if (ML_(safe_to_deref)(attr, ARG3)) {
12917 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12918 "bpf", tid, False)) {
12919 SET_STATUS_Failure(VKI_EBADF);
12920 break;
12922 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12923 if (attr->raw_tracepoint.name != NULL)
12924 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
12925 "bpf(attr->raw_tracepoint.name)");
12927 break;
12928 case VKI_BPF_BTF_LOAD:
12929 /* Load BTF information about a program into the kernel. */
12930 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
12931 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
12932 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
12933 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
12934 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
12935 if (ML_(safe_to_deref)(attr, ARG3)) {
12936 /* Read BTF data. */
12937 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
12938 /* Possibly write up to btf_log_len into user space log buffer. */
12939 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
12940 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
12941 attr->btf_log_buf, attr->btf_log_size);
12943 break;
12944 case VKI_BPF_TASK_FD_QUERY:
12945 /* Get info about the task. Write collected info. */
12946 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
12947 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
12948 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
12949 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
12950 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
12951 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12952 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12953 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12954 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12955 if (ML_(safe_to_deref)(attr, ARG3)) {
12956 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
12957 SET_STATUS_Failure(VKI_EBADF);
12958 break;
12960 if (attr->task_fd_query.buf_len > 0) {
12961 /* Write task or perf event name. */
12962 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
12963 attr->task_fd_query.buf,
12964 attr->task_fd_query.buf_len);
12967 break;
12968 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
12969 /* Perform a lookup on an eBPF map. Read key, write value (delete key) */
12970 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12971 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12972 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12973 if (ML_(safe_to_deref)(attr, ARG3)) {
12974 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12975 SET_STATUS_Failure(VKI_EBADF);
12976 break;
12978 /* Get size of key and value for this map. */
12979 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12980 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12981 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12984 break;
12985 case VKI_BPF_MAP_FREEZE:
12986 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
12987 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12988 break;
12989 default:
12990 VG_(message)(Vg_DebugMsg,
12991 "WARNING: unhandled eBPF command %lu\n", ARG1);
12992 break;
12996 POST(sys_bpf)
12998 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12999 UInt key_size, value_size;
13001 vg_assert(SUCCESS);
13003 switch (ARG1) {
13004 case VKI_BPF_PROG_GET_NEXT_ID:
13005 case VKI_BPF_MAP_GET_NEXT_ID:
13006 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
13007 break;
13008 case VKI_BPF_MAP_UPDATE_ELEM:
13009 case VKI_BPF_MAP_DELETE_ELEM:
13010 case VKI_BPF_OBJ_PIN:
13011 case VKI_BPF_PROG_ATTACH:
13012 case VKI_BPF_PROG_DETACH:
13013 break;
13014 /* Following commands have bpf() return a file descriptor. */
13015 case VKI_BPF_MAP_CREATE:
13016 case VKI_BPF_OBJ_GET:
13017 case VKI_BPF_PROG_GET_FD_BY_ID:
13018 case VKI_BPF_MAP_GET_FD_BY_ID:
13019 case VKI_BPF_BTF_GET_FD_BY_ID:
13020 case VKI_BPF_RAW_TRACEPOINT_OPEN:
13021 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13022 VG_(close)(RES);
13023 SET_STATUS_Failure(VKI_EMFILE);
13024 } else {
13025 if (VG_(clo_track_fds))
13026 ML_(record_fd_open_nameless)(tid, RES);
13028 break;
13030 * TODO: Is there a way to pass information between PRE and POST hooks?
13031 * To avoid querying again for the size of keys and values.
13033 case VKI_BPF_MAP_LOOKUP_ELEM:
13034 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13035 POST_MEM_WRITE(attr->value, value_size);
13036 break;
13037 case VKI_BPF_MAP_GET_NEXT_KEY:
13038 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13039 POST_MEM_WRITE(attr->next_key, key_size);
13040 break;
13041 case VKI_BPF_PROG_LOAD:
13042 /* Return a file descriptor for loaded program, write into log_buf. */
13043 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13044 VG_(close)(RES);
13045 SET_STATUS_Failure(VKI_EMFILE);
13046 } else {
13047 if (VG_(clo_track_fds))
13048 ML_(record_fd_open_nameless)(tid, RES);
13050 if (attr->log_level || attr->log_size || attr->log_buf)
13051 POST_MEM_WRITE(attr->log_buf, attr->log_size);
13052 break;
13053 case VKI_BPF_PROG_TEST_RUN:
13054 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
13055 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13056 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
13057 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
13058 break;
13059 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13060 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
13061 break;
13062 case VKI_BPF_PROG_QUERY:
13063 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13064 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13065 if (attr->query.prog_ids)
13066 POST_MEM_WRITE(attr->query.prog_ids,
13067 attr->query.prog_cnt * sizeof(__vki_u32));
13068 break;
13069 case VKI_BPF_BTF_LOAD:
13070 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13071 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13072 VG_(close)(RES);
13073 SET_STATUS_Failure(VKI_EMFILE);
13074 } else {
13075 if (VG_(clo_track_fds))
13076 ML_(record_fd_open_nameless)(tid, RES);
13078 if (attr->btf_log_level)
13079 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13080 break;
13081 case VKI_BPF_TASK_FD_QUERY:
13082 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13083 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13084 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13085 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13086 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13087 break;
13088 case VKI_BPF_MAP_LOOKUP_AND_DELETE_ELEM:
13089 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13090 POST_MEM_WRITE(attr->value, value_size);
13091 break;
13092 case VKI_BPF_MAP_FREEZE:
13093 /* Freeze map, read map_fd (write frozen flag, not visible to user space). */
13094 break;
13095 default:
13096 VG_(message)(Vg_DebugMsg,
13097 "WARNING: unhandled eBPF command %lu\n", ARG1);
13098 break;
13102 PRE(sys_copy_file_range)
13104 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13105 ARG4, ARG5, ARG6);
13107 PRE_REG_READ6(vki_size_t, "copy_file_range",
13108 int, "fd_in",
13109 vki_loff_t *, "off_in",
13110 int, "fd_out",
13111 vki_loff_t *, "off_out",
13112 vki_size_t, "len",
13113 unsigned int, "flags");
13115 /* File descriptors are "specially" tracked by valgrind.
13116 valgrind itself uses some, so make sure someone didn't
13117 put in one of our own... */
13118 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13119 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13120 SET_STATUS_Failure( VKI_EBADF );
13121 } else {
13122 /* Now see if the offsets are defined. PRE_MEM_READ will
13123 double check it can dereference them. */
13124 if (ARG2 != 0)
13125 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13126 if (ARG4 != 0)
13127 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13131 PRE(sys_pkey_alloc)
13133 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13135 PRE_REG_READ2(long, "pkey_alloc",
13136 unsigned long, "flags",
13137 unsigned long, "access_rights");
13139 /* The kernel says: pkey_alloc() is always safe to call regardless of
13140 whether or not the operating system supports protection keys. It can be
13141 used in lieu of any other mechanism for detecting pkey support and will
13142 simply fail with the error ENOSPC if the operating system has no pkey
13143 support.
13145 So we simply always return ENOSPC to signal memory protection keys are
13146 not supported under valgrind, unless there are unknown flags, then we
13147 return EINVAL. */
13148 unsigned long pkey_flags = ARG1;
13149 if (pkey_flags != 0)
13150 SET_STATUS_Failure( VKI_EINVAL );
13151 else
13152 SET_STATUS_Failure( VKI_ENOSPC );
13155 PRE(sys_pkey_free)
13157 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13159 PRE_REG_READ1(long, "pkey_free",
13160 unsigned long, "pkey");
13162 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13163 always an error. */
13164 SET_STATUS_Failure( VKI_EINVAL );
13167 PRE(sys_pkey_mprotect)
13169 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13170 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13171 PRE_REG_READ4(long, "pkey_mprotect",
13172 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13173 unsigned long, pkey);
13175 Addr addr = ARG1;
13176 SizeT len = ARG2;
13177 Int prot = ARG3;
13178 Int pkey = ARG4;
13180 /* Since pkey_alloc () can never succeed, see above, any pkey is
13181 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13182 if (pkey != -1)
13183 SET_STATUS_Failure( VKI_EINVAL );
13184 else
13185 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13187 ARG1 = addr;
13188 ARG2 = len;
13189 ARG3 = prot;
13192 POST(sys_pkey_mprotect)
13194 Addr addr = ARG1;
13195 SizeT len = ARG2;
13196 Int prot = ARG3;
13198 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13201 PRE(sys_io_uring_setup)
13203 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13204 ARG1, ARG2);
13205 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13206 struct vki_io_uring_params *, p);
13207 if (ARG2)
13208 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13209 offsetof(struct vki_io_uring_params, sq_off));
13212 POST(sys_io_uring_setup)
13214 vg_assert(SUCCESS);
13215 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13216 VG_(close)(RES);
13217 SET_STATUS_Failure( VKI_EMFILE );
13218 } else {
13219 if (VG_(clo_track_fds))
13220 ML_(record_fd_open_nameless)(tid, RES);
13221 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13222 sizeof(struct vki_io_sqring_offsets) +
13223 sizeof(struct vki_io_cqring_offsets));
13227 PRE(sys_io_uring_enter)
13229 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13230 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13231 FMT_REGWORD "u )",
13232 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13233 PRE_REG_READ6(long, "io_uring_enter",
13234 unsigned int, fd, unsigned int, to_submit,
13235 unsigned int, min_complete, unsigned int, flags,
13236 const void *, sig, unsigned long, sigsz);
13237 if (ARG5)
13238 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13241 POST(sys_io_uring_enter)
13245 PRE(sys_io_uring_register)
13247 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13248 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13249 PRE_REG_READ4(long, "io_uring_register",
13250 unsigned int, fd, unsigned int, opcode,
13251 void *, arg, unsigned int, nr_args);
13252 switch (ARG2) {
13253 case VKI_IORING_REGISTER_BUFFERS:
13254 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13255 break;
13256 case VKI_IORING_UNREGISTER_BUFFERS:
13257 break;
13258 case VKI_IORING_REGISTER_FILES:
13259 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13260 break;
13261 case VKI_IORING_UNREGISTER_FILES:
13262 break;
13263 case VKI_IORING_REGISTER_EVENTFD:
13264 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13265 break;
13266 case VKI_IORING_UNREGISTER_EVENTFD:
13267 break;
13271 POST(sys_io_uring_register)
13275 PRE(sys_execveat)
13277 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13278 PRE_REG_READ5(vki_off_t, "execveat",
13279 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13280 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13282 #if !defined(__NR_execveat)
13283 SET_STATUS_Failure(VKI_ENOSYS);
13284 return;
13285 #endif
13287 char *path = (char*) ARG2;
13288 Addr arg_2 = ARG3;
13289 Addr arg_3 = ARG4;
13290 const HChar *buf;
13291 HChar *abs_path = NULL;
13292 Bool check_at_symlink = False;
13293 Bool check_pathptr = True;
13295 if (ML_(safe_to_deref) (path, 1)) {
13296 /* If pathname is absolute, we'll ignore dirfd
13297 * and just pass the pathname, try to determine
13298 * the absolute path otherwise. */
13299 if (path[0] != '/') {
13300 /* Check dirfd is a valid fd. */
13301 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13302 SET_STATUS_Failure( VKI_EBADF );
13303 return;
13305 /* If pathname is empty and AT_EMPTY_PATH is
13306 set then dirfd describes the whole path. */
13307 if (path[0] == '\0') {
13308 if (ARG5 & VKI_AT_EMPTY_PATH) {
13309 if (VG_(resolve_filename)(ARG1, &buf)) {
13310 VG_(strcpy)(path, buf);
13311 check_pathptr = False;
13315 else if (ARG1 == VKI_AT_FDCWD) {
13316 check_at_symlink = True;
13317 } else
13318 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13319 check_at_symlink = True;
13320 else if (VG_(resolve_filename)(ARG1, &buf)) {
13321 abs_path = VG_(malloc)("execveat",
13322 (VG_(strlen)(buf) + 1
13323 + VG_(strlen)(path) + 1));
13324 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13325 path = abs_path;
13326 check_pathptr = False;
13328 else
13329 path = NULL;
13330 if (check_at_symlink) {
13331 struct vg_stat statbuf;
13332 SysRes statres;
13334 statres = VG_(stat)(path, &statbuf);
13335 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13336 SET_STATUS_Failure( VKI_ELOOP );
13337 return;
13341 } else {
13342 SET_STATUS_Failure(VKI_EFAULT);
13343 return;
13346 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, EXECVEAT,
13347 check_pathptr);
13349 /* The exec failed, we keep running... cleanup. */
13350 VG_(free)(abs_path);
13355 PRE(sys_close_range)
13357 SysRes res = VG_(mk_SysRes_Success)(0);
13358 unsigned int beg, end;
13359 unsigned int last = ARG2;
13361 FUSE_COMPATIBLE_MAY_BLOCK();
13362 PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
13363 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
13364 PRE_REG_READ3(long, "close_range",
13365 unsigned int, first, unsigned int, last,
13366 unsigned int, flags);
13368 if (ARG1 > last) {
13369 SET_STATUS_Failure( VKI_EINVAL );
13370 return;
13373 if (last >= VG_(fd_hard_limit))
13374 last = VG_(fd_hard_limit) - 1;
13376 if (ARG1 > last) {
13377 SET_STATUS_Success ( 0 );
13378 return;
13381 beg = end = ARG1;
13382 do {
13383 if (end > last
13384 || (end == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
13385 || end == VG_(log_output_sink).fd
13386 || end == VG_(xml_output_sink).fd) {
13387 /* Split the range if it contains a file descriptor we're not
13388 * supposed to close. */
13389 if (end - 1 >= beg)
13390 res = VG_(do_syscall3)(__NR_close_range, (UWord)beg, (UWord)end - 1, ARG3 );
13391 beg = end + 1;
13393 } while (end++ <= last);
13395 /* If it failed along the way, it's presumably the flags being wrong. */
13396 SET_STATUS_from_SysRes (res);
13399 POST(sys_close_range)
13401 unsigned int fd;
13402 unsigned int last = ARG2;
13404 if (!VG_(clo_track_fds)
13405 || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
13406 return;
13408 if (last >= VG_(fd_hard_limit))
13409 last = VG_(fd_hard_limit) - 1;
13411 for (fd = ARG1; fd <= last; fd++)
13412 if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
13413 && fd != VG_(log_output_sink).fd
13414 && fd != VG_(xml_output_sink).fd)
13415 ML_(record_fd_close)(fd);
13418 #undef PRE
13419 #undef POST
13421 #endif // defined(VGO_linux)
13423 /*--------------------------------------------------------------------*/
13424 /*--- end ---*/
13425 /*--------------------------------------------------------------------*/