configure.ac: Sort AC_CHECK_FUNCS() arguments alphabetically
[valgrind.git] / coregrind / m_syswrap / syswrap-linux.c
blob5ae4e66132d513f6f14e4e85e66ef06b1e8e93e5
2 /*--------------------------------------------------------------------*/
3 /*--- Linux-specific syscalls, etc. syswrap-linux.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Nicholas Nethercote
11 njn@valgrind.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_linux)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
37 #include "pub_core_transtab.h" // VG_(discard_translations)
38 #include "pub_core_xarray.h"
39 #include "pub_core_clientstate.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_libcproc.h"
46 #include "pub_core_libcsignal.h"
47 #include "pub_core_machine.h" // VG_(get_SP)
48 #include "pub_core_mallocfree.h"
49 #include "pub_core_tooliface.h"
50 #include "pub_core_options.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_signals.h"
53 #include "pub_core_stacks.h"
54 #include "pub_core_syscall.h"
55 #include "pub_core_syswrap.h"
56 #include "pub_core_inner.h"
57 #if defined(ENABLE_INNER_CLIENT_REQUEST)
58 #include "pub_core_clreq.h"
59 #endif
61 #include "priv_types_n_macros.h"
62 #include "priv_syswrap-generic.h"
63 #include "priv_syswrap-linux.h"
64 #include "priv_syswrap-main.h"
65 #include "priv_syswrap-xen.h"
67 // Run a thread from beginning to end and return the thread's
68 // scheduler-return-code.
69 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
71 VgSchedReturnCode ret;
72 ThreadId tid = (ThreadId)tidW;
73 ThreadState* tst = VG_(get_ThreadState)(tid);
75 VG_(debugLog)(1, "syswrap-linux",
76 "thread_wrapper(tid=%u): entry\n",
77 tid);
79 vg_assert(tst->status == VgTs_Init);
81 /* make sure we get the CPU lock before doing anything significant */
82 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
84 if (0)
85 VG_(printf)("thread tid %u started: stack = %p\n",
86 tid, (void *)&tid);
88 /* Make sure error reporting is enabled in the new thread. */
89 tst->err_disablement_level = 0;
91 VG_TRACK(pre_thread_first_insn, tid);
93 tst->os_state.lwpid = VG_(gettid)();
94 /* Set the threadgroup for real. This overwrites the provisional value set
95 in do_clone(). See comments in do_clone for background, also #226116. */
96 tst->os_state.threadgroup = VG_(getpid)();
98 /* Thread created with all signals blocked; scheduler will set the
99 appropriate mask */
101 ret = VG_(scheduler)(tid);
103 vg_assert(VG_(is_exiting)(tid));
105 vg_assert(tst->status == VgTs_Runnable);
106 vg_assert(VG_(is_running_thread)(tid));
108 VG_(debugLog)(1, "syswrap-linux",
109 "thread_wrapper(tid=%u): exit, schedreturncode %s\n",
110 tid, VG_(name_of_VgSchedReturnCode)(ret));
112 /* Return to caller, still holding the lock. */
113 return ret;
117 /* ---------------------------------------------------------------------
118 clone-related stuff
119 ------------------------------------------------------------------ */
121 /* Run a thread all the way to the end, then do appropriate exit actions
122 (this is the last-one-out-turn-off-the-lights bit). */
123 static void run_a_thread_NORETURN ( Word tidW )
125 ThreadId tid = (ThreadId)tidW;
126 VgSchedReturnCode src;
127 Int c;
128 ThreadState* tst;
129 #ifdef ENABLE_INNER_CLIENT_REQUEST
130 Int registered_vgstack_id;
131 #endif
133 VG_(debugLog)(1, "syswrap-linux",
134 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
135 tid);
137 tst = VG_(get_ThreadState)(tid);
138 vg_assert(tst);
140 /* An thread has two stacks:
141 * the simulated stack (used by the synthetic cpu. Guest process
142 is using this stack).
143 * the valgrind stack (used by the real cpu. Valgrind code is running
144 on this stack).
145 When Valgrind runs as an inner, it must signals that its (real) stack
146 is the stack to use by the outer to e.g. do stacktraces.
148 INNER_REQUEST
149 (registered_vgstack_id
150 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
151 tst->os_state.valgrind_stack_init_SP));
153 /* Run the thread all the way through. */
154 src = thread_wrapper(tid);
156 VG_(debugLog)(1, "syswrap-linux",
157 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
158 tid);
160 c = VG_(count_living_threads)();
161 vg_assert(c >= 1); /* stay sane */
163 /* Deregister thread's stack. */
164 if (tst->os_state.stk_id != NULL_STK_ID)
165 VG_(deregister_stack)(tst->os_state.stk_id);
167 // Tell the tool this thread is exiting
168 VG_TRACK( pre_thread_ll_exit, tid );
170 /* If the thread is exiting with errors disabled, complain loudly;
171 doing so is bad (does the user know this has happened?) Also,
172 in all cases, be paranoid and clear the flag anyway so that the
173 thread slot is safe in this respect if later reallocated. This
174 should be unnecessary since the flag should be cleared when the
175 slot is reallocated, in thread_wrapper(). */
176 if (tst->err_disablement_level > 0) {
177 VG_(umsg)(
178 "WARNING: exiting thread has error reporting disabled.\n"
179 "WARNING: possibly as a result of some mistake in the use\n"
180 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
182 VG_(debugLog)(
183 1, "syswrap-linux",
184 "run_a_thread_NORETURN(tid=%u): "
185 "WARNING: exiting thread has err_disablement_level = %u\n",
186 tid, tst->err_disablement_level
189 tst->err_disablement_level = 0;
191 if (c == 1) {
193 VG_(debugLog)(1, "syswrap-linux",
194 "run_a_thread_NORETURN(tid=%u): "
195 "last one standing\n",
196 tid);
198 /* We are the last one standing. Keep hold of the lock and
199 carry on to show final tool results, then exit the entire system.
200 Use the continuation pointer set at startup in m_main. */
201 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
202 } else {
204 VG_(debugLog)(1, "syswrap-linux",
205 "run_a_thread_NORETURN(tid=%u): "
206 "not last one standing\n",
207 tid);
209 /* OK, thread is dead, but others still exist. Just exit. */
211 /* This releases the run lock */
212 VG_(exit_thread)(tid);
213 vg_assert(tst->status == VgTs_Zombie);
214 vg_assert(sizeof(tst->status) == 4);
215 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
217 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
219 /* We have to use this sequence to terminate the thread to
220 prevent a subtle race. If VG_(exit_thread)() had left the
221 ThreadState as Empty, then it could have been reallocated,
222 reusing the stack while we're doing these last cleanups.
223 Instead, VG_(exit_thread) leaves it as Zombie to prevent
224 reallocation. We need to make sure we don't touch the stack
225 between marking it Empty and exiting. Hence the
226 assembler. */
227 #if defined(VGP_x86_linux)
228 asm volatile (
229 "pushl %%ebx\n"
230 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
231 "movl %2, %%eax\n" /* set %eax = __NR_exit */
232 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
233 "int $0x80\n" /* exit(tst->os_state.exitcode) */
234 "popl %%ebx\n"
235 : "=m" (tst->status)
236 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
237 : "eax"
239 #elif defined(VGP_amd64_linux)
240 asm volatile (
241 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
242 "movq %2, %%rax\n" /* set %rax = __NR_exit */
243 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
244 "syscall\n" /* exit(tst->os_state.exitcode) */
245 : "=m" (tst->status)
246 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
247 : "rax", "rdi"
249 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
250 || defined(VGP_ppc64le_linux)
251 { UInt vgts_empty = (UInt)VgTs_Empty;
252 asm volatile (
253 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
254 "li 0,%2\n\t" /* set r0 = __NR_exit */
255 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
256 "sc\n\t" /* exit(tst->os_state.exitcode) */
257 : "=m" (tst->status)
258 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
259 : "r0", "r3"
262 #elif defined(VGP_arm_linux)
263 asm volatile (
264 "str %1, %0\n" /* set tst->status = VgTs_Empty */
265 "mov r7, %2\n" /* set %r7 = __NR_exit */
266 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
267 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
268 : "=m" (tst->status)
269 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
270 : "r0", "r7"
272 #elif defined(VGP_arm64_linux)
273 asm volatile (
274 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
275 "mov x8, %2\n" /* set %x8 = __NR_exit */
276 "ldr x0, %3\n" /* set %x0 = tst->os_state.exitcode */
277 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
278 : "=m" (tst->status)
279 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
280 : "x0", "x8"
282 #elif defined(VGP_s390x_linux)
283 asm volatile (
284 "st %1, %0\n" /* set tst->status = VgTs_Empty */
285 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
286 "svc %2\n" /* exit(tst->os_state.exitcode) */
287 : "=m" (tst->status)
288 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
289 : "2"
291 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
292 asm volatile (
293 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
294 "li $2, %2\n\t" /* set v0 = __NR_exit */
295 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
296 "syscall\n\t" /* exit(tst->os_state.exitcode) */
297 "nop"
298 : "=m" (tst->status)
299 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
300 : "cc", "memory" , "v0", "a0"
302 #elif defined(VGP_nanomips_linux)
303 asm volatile (
304 "sw %1, %0 \n\t" /* set tst->status = VgTs_Empty */
305 "li $t4, %2 \n\t" /* set t4 = __NR_exit */
306 "lw $a0, %3 \n\t" /* set a0 = tst->os_state.exitcode */
307 "syscall[32] \n\t" /* exit(tst->os_state.exitcode) */
308 : "=m" (tst->status)
309 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
310 : "memory" , "$t4", "$a0"
312 #else
313 # error Unknown platform
314 #endif
316 VG_(core_panic)("Thread exit failed?\n");
319 /*NOTREACHED*/
320 vg_assert(0);
323 Word ML_(start_thread_NORETURN) ( void* arg )
325 ThreadState* tst = (ThreadState*)arg;
326 ThreadId tid = tst->tid;
328 run_a_thread_NORETURN ( (Word)tid );
329 /*NOTREACHED*/
330 vg_assert(0);
333 /* Allocate a stack for this thread, if it doesn't already have one.
334 They're allocated lazily, and never freed. Returns the initial stack
335 pointer value to use, or 0 if allocation failed. */
336 Addr ML_(allocstack)(ThreadId tid)
338 ThreadState* tst = VG_(get_ThreadState)(tid);
339 VgStack* stack;
340 Addr initial_SP;
342 /* Either the stack_base and stack_init_SP are both zero (in which
343 case a stack hasn't been allocated) or they are both non-zero,
344 in which case it has. */
346 if (tst->os_state.valgrind_stack_base == 0)
347 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
349 if (tst->os_state.valgrind_stack_base != 0)
350 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
352 /* If no stack is present, allocate one. */
354 if (tst->os_state.valgrind_stack_base == 0) {
355 stack = VG_(am_alloc_VgStack)( &initial_SP );
356 if (stack) {
357 tst->os_state.valgrind_stack_base = (Addr)stack;
358 tst->os_state.valgrind_stack_init_SP = initial_SP;
362 if (0)
363 VG_(printf)( "stack for tid %u at %p; init_SP=%p\n",
364 tid,
365 (void*)tst->os_state.valgrind_stack_base,
366 (void*)tst->os_state.valgrind_stack_init_SP );
368 return tst->os_state.valgrind_stack_init_SP;
371 /* Allocate a stack for the main thread, and run it all the way to the
372 end. Although we already have a working VgStack
373 (VG_(interim_stack)) it's better to allocate a new one, so that
374 overflow detection works uniformly for all threads.
376 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
378 Addr sp;
379 VG_(debugLog)(1, "syswrap-linux",
380 "entering VG_(main_thread_wrapper_NORETURN)\n");
382 sp = ML_(allocstack)(tid);
383 #if defined(ENABLE_INNER_CLIENT_REQUEST)
385 // we must register the main thread stack before the call
386 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
387 // reports 'write error' on the non registered stack.
388 ThreadState* tst = VG_(get_ThreadState)(tid);
389 INNER_REQUEST
390 ((void)
391 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
392 tst->os_state.valgrind_stack_init_SP));
394 #endif
396 #if defined(VGP_ppc32_linux)
397 /* make a stack frame */
398 sp -= 16;
399 sp &= ~0xF;
400 *(UWord *)sp = 0;
401 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
402 /* make a stack frame */
403 sp -= 112;
404 sp &= ~((Addr)0xF);
405 *(UWord *)sp = 0;
406 #elif defined(VGP_s390x_linux)
407 /* make a stack frame */
408 sp -= 160;
409 sp &= ~((Addr)0xF);
410 *(UWord *)sp = 0;
411 #endif
413 /* If we can't even allocate the first thread's stack, we're hosed.
414 Give up. */
415 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
417 /* shouldn't be any other threads around yet */
418 vg_assert( VG_(count_living_threads)() == 1 );
420 ML_(call_on_new_stack_0_1)(
421 (Addr)sp, /* stack */
422 0, /* bogus return address */
423 run_a_thread_NORETURN, /* fn to call */
424 (Word)tid /* arg to give it */
427 /*NOTREACHED*/
428 vg_assert(0);
431 /* Clone a new thread. Note that in the clone syscalls, we hard-code
432 tlsaddr argument as NULL : the guest TLS is emulated via guest
433 registers, and Valgrind itself has no thread local storage. */
434 static SysRes clone_new_thread ( Word (*fn)(void *),
435 void* stack,
436 Word flags,
437 ThreadState* ctst,
438 Int* child_tidptr,
439 Int* parent_tidptr)
441 SysRes res;
442 /* Note that in all the below, we make sys_clone appear to have returned
443 Success(0) in the child, by assigning the relevant child guest
444 register(s) just before the clone syscall. */
445 #if defined(VGP_x86_linux)
446 Int eax;
447 ctst->arch.vex.guest_EAX = 0;
448 eax = do_syscall_clone_x86_linux
449 (ML_(start_thread_NORETURN), stack, flags, ctst,
450 child_tidptr, parent_tidptr, NULL);
451 res = VG_(mk_SysRes_x86_linux)( eax );
452 #elif defined(VGP_amd64_linux)
453 Long rax;
454 ctst->arch.vex.guest_RAX = 0;
455 rax = do_syscall_clone_amd64_linux
456 (ML_(start_thread_NORETURN), stack, flags, ctst,
457 child_tidptr, parent_tidptr, NULL);
458 res = VG_(mk_SysRes_amd64_linux)( rax );
459 #elif defined(VGP_ppc32_linux)
460 ULong word64;
461 UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
462 /* %r3 = 0 */
463 ctst->arch.vex.guest_GPR3 = 0;
464 /* %cr0.so = 0 */
465 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
466 word64 = do_syscall_clone_ppc32_linux
467 (ML_(start_thread_NORETURN), stack, flags, ctst,
468 child_tidptr, parent_tidptr, NULL);
469 /* High half word64 is syscall return value. Low half is
470 the entire CR, from which we need to extract CR0.SO. */
471 /* VG_(printf)("word64 = 0x%llx\n", word64); */
472 res = VG_(mk_SysRes_ppc32_linux)(/*val*/(UInt)(word64 >> 32),
473 /*errflag*/ (((UInt)word64) >> 28) & 1);
474 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
475 ULong word64;
476 UInt old_cr = LibVEX_GuestPPC64_get_CR( &ctst->arch.vex );
477 /* %r3 = 0 */
478 ctst->arch.vex.guest_GPR3 = 0;
479 /* %cr0.so = 0 */
480 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
481 word64 = do_syscall_clone_ppc64_linux
482 (ML_(start_thread_NORETURN), stack, flags, ctst,
483 child_tidptr, parent_tidptr, NULL);
484 /* Low half word64 is syscall return value. Hi half is
485 the entire CR, from which we need to extract CR0.SO. */
486 /* VG_(printf)("word64 = 0x%llx\n", word64); */
487 res = VG_(mk_SysRes_ppc64_linux)
488 (/*val*/(UInt)(word64 & 0xFFFFFFFFULL),
489 /*errflag*/ (UInt)((word64 >> (32+28)) & 1));
490 #elif defined(VGP_s390x_linux)
491 ULong r2;
492 ctst->arch.vex.guest_r2 = 0;
493 r2 = do_syscall_clone_s390x_linux
494 (stack, flags, parent_tidptr, child_tidptr, NULL,
495 ML_(start_thread_NORETURN), ctst);
496 res = VG_(mk_SysRes_s390x_linux)( r2 );
497 #elif defined(VGP_arm64_linux)
498 ULong x0;
499 ctst->arch.vex.guest_X0 = 0;
500 x0 = do_syscall_clone_arm64_linux
501 (ML_(start_thread_NORETURN), stack, flags, ctst,
502 child_tidptr, parent_tidptr, NULL);
503 res = VG_(mk_SysRes_arm64_linux)( x0 );
504 #elif defined(VGP_arm_linux)
505 UInt r0;
506 ctst->arch.vex.guest_R0 = 0;
507 r0 = do_syscall_clone_arm_linux
508 (ML_(start_thread_NORETURN), stack, flags, ctst,
509 child_tidptr, parent_tidptr, NULL);
510 res = VG_(mk_SysRes_arm_linux)( r0 );
511 #elif defined(VGP_mips64_linux)
512 UInt ret = 0;
513 ctst->arch.vex.guest_r2 = 0;
514 ctst->arch.vex.guest_r7 = 0;
515 ret = do_syscall_clone_mips64_linux
516 (ML_(start_thread_NORETURN), stack, flags, ctst,
517 parent_tidptr, NULL, child_tidptr);
518 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
519 #elif defined(VGP_mips32_linux)
520 UInt ret = 0;
521 ctst->arch.vex.guest_r2 = 0;
522 ctst->arch.vex.guest_r7 = 0;
523 ret = do_syscall_clone_mips_linux
524 (ML_(start_thread_NORETURN), stack, flags, ctst,
525 child_tidptr, parent_tidptr, NULL);
526 /* High half word64 is syscall return value. Low half is
527 the entire CR, from which we need to extract CR0.SO. */
528 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
529 #elif defined(VGP_nanomips_linux)
530 UInt ret = 0;
531 ctst->arch.vex.guest_r4 = 0;
532 ret = do_syscall_clone_nanomips_linux
533 (ML_(start_thread_NORETURN), stack, flags, ctst,
534 child_tidptr, parent_tidptr, NULL);
535 res = VG_ (mk_SysRes_nanomips_linux) (ret);
536 #else
537 # error Unknown platform
538 #endif
539 return res;
542 static void setup_child ( /*OUT*/ ThreadArchState *child,
543 /*IN*/ ThreadArchState *parent )
545 /* We inherit our parent's guest state. */
546 child->vex = parent->vex;
547 child->vex_shadow1 = parent->vex_shadow1;
548 child->vex_shadow2 = parent->vex_shadow2;
550 #if defined(VGP_x86_linux)
551 extern void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
552 /*IN*/ ThreadArchState *parent );
553 ML_(x86_setup_LDT_GDT)(child, parent);
554 #endif
557 static SysRes setup_child_tls (ThreadId ctid, Addr tlsaddr)
559 static const Bool debug = False;
560 ThreadState* ctst = VG_(get_ThreadState)(ctid);
561 // res is succesful by default, overriden if a real syscall is needed/done.
562 SysRes res = VG_(mk_SysRes_Success)(0);
564 if (debug)
565 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
567 #if defined(VGP_x86_linux)
568 vki_modify_ldt_t* tlsinfo = (vki_modify_ldt_t*)tlsaddr;
569 if (debug)
570 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%u "
571 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
572 tlsinfo, tlsinfo->entry_number,
573 tlsinfo->base_addr, tlsinfo->limit,
574 ctst->arch.vex.guest_ESP,
575 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
576 res = ML_(x86_sys_set_thread_area)(ctid, tlsinfo);
577 #elif defined(VGP_amd64_linux)
578 ctst->arch.vex.guest_FS_CONST = tlsaddr;
579 #elif defined(VGP_ppc32_linux)
580 ctst->arch.vex.guest_GPR2 = tlsaddr;
581 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
582 ctst->arch.vex.guest_GPR13 = tlsaddr;
583 #elif defined(VGP_s390x_linux)
584 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
585 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
586 #elif defined(VGP_arm64_linux)
587 /* Just assign the tls pointer in the guest TPIDR_EL0. */
588 ctst->arch.vex.guest_TPIDR_EL0 = tlsaddr;
589 #elif defined(VGP_arm_linux)
590 /* Just assign the tls pointer in the guest TPIDRURO. */
591 ctst->arch.vex.guest_TPIDRURO = tlsaddr;
592 #elif defined(VGP_mips64_linux)
593 ctst->arch.vex.guest_ULR = tlsaddr;
594 ctst->arch.vex.guest_r27 = tlsaddr;
595 #elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
596 ctst->arch.vex.guest_ULR = tlsaddr;
597 ctst->arch.vex.guest_r27 = tlsaddr;
598 #else
599 # error Unknown platform
600 #endif
601 return res;
605 When a client clones, we need to keep track of the new thread. This means:
606 1. allocate a ThreadId+ThreadState+stack for the thread
608 2. initialize the thread's new VCPU state
610 3. create the thread using the same args as the client requested,
611 but using the scheduler entrypoint for EIP, and a separate stack
612 for ESP.
614 static SysRes do_clone ( ThreadId ptid,
615 UWord flags, Addr sp,
616 Int* parent_tidptr,
617 Int* child_tidptr,
618 Addr tlsaddr)
620 ThreadId ctid = VG_(alloc_ThreadState)();
621 ThreadState* ptst = VG_(get_ThreadState)(ptid);
622 ThreadState* ctst = VG_(get_ThreadState)(ctid);
623 UWord* stack;
624 SysRes res;
625 vki_sigset_t blockall, savedmask;
627 VG_(sigfillset)(&blockall);
629 vg_assert(VG_(is_running_thread)(ptid));
630 vg_assert(VG_(is_valid_tid)(ctid));
632 stack = (UWord*)ML_(allocstack)(ctid);
633 if (stack == NULL) {
634 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
635 goto out;
638 /* Copy register state
640 Both parent and child return to the same place, and the code
641 following the clone syscall works out which is which, so we
642 don't need to worry about it.
644 The parent gets the child's new tid returned from clone, but the
645 child gets 0.
647 If the clone call specifies a NULL sp for the new thread, then
648 it actually gets a copy of the parent's sp.
650 setup_child( &ctst->arch, &ptst->arch );
652 if (sp != 0)
653 VG_(set_SP)(ctid, sp);
655 ctst->os_state.parent = ptid;
657 /* inherit signal mask */
658 ctst->sig_mask = ptst->sig_mask;
659 ctst->tmp_sig_mask = ptst->sig_mask;
661 /* Start the child with its threadgroup being the same as the
662 parent's. This is so that any exit_group calls that happen
663 after the child is created but before it sets its
664 os_state.threadgroup field for real (in thread_wrapper in
665 syswrap-linux.c), really kill the new thread. a.k.a this avoids
666 a race condition in which the thread is unkillable (via
667 exit_group) because its threadgroup is not set. The race window
668 is probably only a few hundred or a few thousand cycles long.
669 See #226116. */
670 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
672 ML_(guess_and_register_stack) (sp, ctst);
674 /* Assume the clone will succeed, and tell any tool that wants to
675 know that this thread has come into existence. We cannot defer
676 it beyond this point because setup_tls, just below,
677 causes checks to assert by making references to the new ThreadId
678 if we don't state the new thread exists prior to that point.
679 If the clone fails, we'll send out a ll_exit notification for it
680 at the out: label below, to clean up. */
681 vg_assert(VG_(owns_BigLock_LL)(ptid));
682 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
684 if (flags & VKI_CLONE_SETTLS) {
685 res = setup_child_tls(ctid, tlsaddr);
686 if (sr_isError(res))
687 goto out;
689 flags &= ~VKI_CLONE_SETTLS;
691 /* start the thread with everything blocked */
692 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
694 /* Create the new thread */
695 res = clone_new_thread ( ML_(start_thread_NORETURN), stack, flags, ctst,
696 child_tidptr, parent_tidptr);
698 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
700 out:
701 if (sr_isError(res)) {
702 /* clone failed */
703 VG_(cleanup_thread)(&ctst->arch);
704 ctst->status = VgTs_Empty;
705 /* oops. Better tell the tool the thread exited in a hurry :-) */
706 VG_TRACK( pre_thread_ll_exit, ctid );
709 return res;
712 /* Do a clone which is really a fork().
713 ML_(do_fork_clone) uses the clone syscall to fork a child process.
714 Note that this should not be called for a thread creation.
715 Also, some flags combinations are not supported, and such combinations
716 are handled either by masking the non supported flags or by asserting.
718 The CLONE_VFORK flag is accepted, as this just tells that the parent is
719 suspended till the child exits or calls execve. We better keep this flag,
720 just in case the guests parent/client code depends on this synchronisation.
722 We cannot keep the flag CLONE_VM, as Valgrind will do whatever host
723 instructions in the child process, that will mess up the parent host
724 memory. So, we hope for the best and assumes that the guest application does
725 not (really) depends on sharing the memory between parent and child in the
726 interval between clone and exits/execve.
728 If child_sp != 0, the child (guest) sp will be set to child_sp just after the
729 clone syscall, before child guest instructions are executed. */
730 static SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
731 Int* parent_tidptr, Int* child_tidptr,
732 Addr child_sp)
734 vki_sigset_t fork_saved_mask;
735 vki_sigset_t mask;
736 SysRes res;
738 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
739 | VKI_CLONE_FILES))
740 return VG_(mk_SysRes_Error)( VKI_EINVAL );
742 /* Block all signals during fork, so that we can fix things up in
743 the child without being interrupted. */
744 VG_(sigfillset)(&mask);
745 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
747 VG_(do_atfork_pre)(tid);
749 /* Since this is the fork() form of clone, we don't need all that
750 VG_(clone) stuff */
751 #if defined(VGP_x86_linux) \
752 || defined(VGP_ppc32_linux) \
753 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
754 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
755 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
756 || defined(VGP_nanomips_linux)
757 res = VG_(do_syscall5)( __NR_clone, flags,
758 (UWord)NULL, (UWord)parent_tidptr,
759 (UWord)NULL, (UWord)child_tidptr );
760 #elif defined(VGP_amd64_linux)
761 /* note that the last two arguments are the opposite way round to x86 and
762 ppc32 as the amd64 kernel expects the arguments in a different order */
763 res = VG_(do_syscall5)( __NR_clone, flags,
764 (UWord)NULL, (UWord)parent_tidptr,
765 (UWord)child_tidptr, (UWord)NULL );
766 #elif defined(VGP_s390x_linux)
767 /* Note that s390 has the stack first and then the flags */
768 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
769 (UWord)parent_tidptr, (UWord)child_tidptr);
770 #else
771 # error Unknown platform
772 #endif
774 if (!sr_isError(res) && sr_Res(res) == 0) {
775 /* child */
776 if (child_sp != 0)
777 VG_(set_SP)(tid, child_sp);
778 VG_(do_atfork_child)(tid);
780 /* restore signal mask */
781 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
783 else
784 if (!sr_isError(res) && sr_Res(res) > 0) {
785 /* parent */
786 VG_(do_atfork_parent)(tid);
788 if (VG_(clo_trace_syscalls))
789 VG_(printf)(" clone(fork): process %d created child %" FMT_REGWORD "u\n",
790 VG_(getpid)(), (RegWord)sr_Res(res));
792 /* restore signal mask */
793 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
796 return res;
799 /* ---------------------------------------------------------------------
800 PRE/POST wrappers for arch-generic, Linux-specific syscalls
801 ------------------------------------------------------------------ */
803 // Nb: See the comment above the generic PRE/POST wrappers in
804 // m_syswrap/syswrap-generic.c for notes about how they work.
806 #define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
807 #define POST(name) DEFN_POST_TEMPLATE(linux, name)
809 PRE(sys_clone)
811 UInt cloneflags;
812 Bool badarg = False;
814 PRINT("sys_clone ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD
815 "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3,
816 ARG4, ARG5);
818 // Order of arguments differs between platforms.
819 #if defined(VGP_x86_linux) \
820 || defined(VGP_ppc32_linux) \
821 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
822 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
823 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux) \
824 || defined(VGP_nanomips_linux)
825 #define ARG_CHILD_TIDPTR ARG5
826 #define PRA_CHILD_TIDPTR PRA5
827 #define ARG_TLS ARG4
828 #define PRA_TLS PRA4
829 #elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
830 #define ARG_CHILD_TIDPTR ARG4
831 #define PRA_CHILD_TIDPTR PRA4
832 #define ARG_TLS ARG5
833 #define PRA_TLS PRA5
834 #else
835 # error Unknown platform
836 #endif
837 // And s390x is even more special, and inverts flags and child stack args
838 #if defined(VGP_s390x_linux)
839 #define ARG_FLAGS ARG2
840 #define PRA_FLAGS PRA2
841 #define ARG_CHILD_STACK ARG1
842 #define PRA_CHILD_STACK PRA1
843 #else
844 #define ARG_FLAGS ARG1
845 #define PRA_FLAGS PRA1
846 #define ARG_CHILD_STACK ARG2
847 #define PRA_CHILD_STACK PRA2
848 #endif
850 if (VG_(tdict).track_pre_reg_read) {
851 PRA_FLAGS("clone", unsigned long, flags);
852 PRA_CHILD_STACK("clone", void *, child_stack);
855 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD)) {
856 if (VG_(tdict).track_pre_reg_read) {
857 PRA3("clone", int *, parent_tidptr);
859 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
860 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
861 VKI_PROT_WRITE)) {
862 badarg = True;
865 if (ARG_FLAGS & VKI_CLONE_SETTLS) {
866 if (VG_(tdict).track_pre_reg_read) {
867 PRA_TLS("clone", vki_modify_ldt_t *, tlsinfo);
869 /* Not very clear what is vki_modify_ldt_t: for many platforms, it is a
870 dummy type (that we define as a char). We only dereference/check the
871 ARG_TLS pointer if the type looks like a real type, i.e. sizeof > 1. */
872 if (sizeof(vki_modify_ldt_t) > 1) {
873 PRE_MEM_READ("clone(tlsinfo)", ARG_TLS, sizeof(vki_modify_ldt_t));
874 if (!VG_(am_is_valid_for_client)(ARG_TLS, sizeof(vki_modify_ldt_t),
875 VKI_PROT_READ)) {
876 badarg = True;
880 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
881 if (VG_(tdict).track_pre_reg_read) {
882 PRA_CHILD_TIDPTR("clone", int *, child_tidptr);
884 PRE_MEM_WRITE("clone(child_tidptr)", ARG_CHILD_TIDPTR, sizeof(Int));
885 if (!VG_(am_is_valid_for_client)(ARG_CHILD_TIDPTR, sizeof(Int),
886 VKI_PROT_WRITE)) {
887 badarg = True;
891 if (badarg) {
892 SET_STATUS_Failure( VKI_EFAULT );
893 return;
896 cloneflags = ARG_FLAGS;
898 if (!ML_(client_signal_OK)(ARG_FLAGS & VKI_CSIGNAL)) {
899 SET_STATUS_Failure( VKI_EINVAL );
900 return;
903 /* Only look at the flags we really care about */
904 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
905 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
906 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
907 /* thread creation */
908 SET_STATUS_from_SysRes(
909 do_clone(tid,
910 ARG_FLAGS, /* flags */
911 (Addr)ARG_CHILD_STACK, /* child ESP */
912 (Int*)(Addr)ARG3, /* parent_tidptr */
913 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
914 (Addr)ARG_TLS)); /* set_tls */
915 break;
917 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
918 case VKI_CLONE_VFORK: /* vfork without memory sharing */
919 cloneflags &= ~VKI_CLONE_VM;
920 // FALLTHROUGH - assume vfork (somewhat) == fork, see ML_(do_fork_clone).
922 case 0: /* plain fork */
923 SET_STATUS_from_SysRes(
924 ML_(do_fork_clone)(tid,
925 cloneflags, /* flags */
926 (Int*)(Addr)ARG3, /* parent_tidptr */
927 (Int*)(Addr)ARG_CHILD_TIDPTR, /* child_tidptr */
928 (Addr)ARG_CHILD_STACK));
929 break;
931 default:
932 /* should we just ENOSYS? */
933 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%" FMT_REGWORD
934 "x\n", ARG_FLAGS);
935 VG_(message)(Vg_UserMsg, "\n");
936 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
937 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
938 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
939 VG_(unimplemented)
940 ("Valgrind does not support general clone().");
943 if (SUCCESS) {
944 if (ARG_FLAGS & (VKI_CLONE_PARENT_SETTID | VKI_CLONE_PIDFD))
945 POST_MEM_WRITE(ARG3, sizeof(Int));
946 if (ARG_FLAGS & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
947 POST_MEM_WRITE(ARG_CHILD_TIDPTR, sizeof(Int));
948 if (ARG_FLAGS & VKI_CLONE_PIDFD) {
949 Int fd = *(Int*)(Addr)ARG3;
950 if (!ML_(fd_allowed)(fd, "clone", tid, True)) {
951 VG_(close)(fd);
952 SET_STATUS_Failure( VKI_EMFILE );
953 } else {
954 if (VG_(clo_track_fds))
955 ML_(record_fd_open_nameless) (tid, fd);
959 /* Thread creation was successful; let the child have the chance
960 to run */
961 *flags |= SfYieldAfter;
964 #undef ARG_CHILD_TIDPTR
965 #undef PRA_CHILD_TIDPTR
966 #undef ARG_TLS
967 #undef PRA_TLS
968 #undef ARG_FLAGS
969 #undef PRA_FLAGS
970 #undef ARG_CHILD_STACK
971 #undef PRA_CHILD_STACK
974 /* ---------------------------------------------------------------------
975 *mount wrappers
976 ------------------------------------------------------------------ */
978 PRE(sys_mount)
980 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
981 // We are conservative and check everything, except the memory pointed to
982 // by 'data'.
983 *flags |= SfMayBlock;
984 PRINT("sys_mount( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
985 FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
986 ARG1, (HChar*)(Addr)ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3,
987 (HChar*)(Addr)ARG3, ARG4, ARG5);
988 PRE_REG_READ5(long, "mount",
989 char *, source, char *, target, char *, type,
990 unsigned long, flags, void *, data);
991 if (ARG1)
992 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
993 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
994 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
997 PRE(sys_oldumount)
999 PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1);
1000 PRE_REG_READ1(long, "umount", char *, path);
1001 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
1004 PRE(sys_umount)
1006 PRINT("sys_umount( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
1007 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
1008 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
1011 /* Not actually wrapped by GLibc but does things with the system
1012 * mounts so it is put here.
1014 PRE(sys_pivot_root)
1016 PRINT("sys_pivot_root ( %s %s )", (HChar*)(Addr)ARG1, (HChar*)(Addr)ARG2);
1017 PRE_REG_READ2(int, "pivot_root", char *, new_root, char *, old_root);
1018 PRE_MEM_RASCIIZ( "pivot_root(new_root)", ARG1);
1019 PRE_MEM_RASCIIZ( "pivot_root(old_root)", ARG2);
1023 /* ---------------------------------------------------------------------
1024 16- and 32-bit uid/gid wrappers
1025 ------------------------------------------------------------------ */
1027 PRE(sys_setfsuid16)
1029 PRINT("sys_setfsuid16 ( %" FMT_REGWORD "u )", ARG1);
1030 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
1033 PRE(sys_setfsuid)
1035 PRINT("sys_setfsuid ( %" FMT_REGWORD "u )", ARG1);
1036 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
1039 PRE(sys_setfsgid16)
1041 PRINT("sys_setfsgid16 ( %" FMT_REGWORD "u )", ARG1);
1042 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
1045 PRE(sys_setfsgid)
1047 PRINT("sys_setfsgid ( %" FMT_REGWORD "u )", ARG1);
1048 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
1051 PRE(sys_setresuid16)
1053 PRINT("sys_setresuid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1054 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1055 PRE_REG_READ3(long, "setresuid16",
1056 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
1059 PRE(sys_setresuid)
1061 PRINT("sys_setresuid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1062 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1063 PRE_REG_READ3(long, "setresuid",
1064 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
1067 PRE(sys_getresuid16)
1069 PRINT("sys_getresuid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1070 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1071 PRE_REG_READ3(long, "getresuid16",
1072 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
1073 vki_old_uid_t *, suid);
1074 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
1075 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
1076 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
1078 POST(sys_getresuid16)
1080 vg_assert(SUCCESS);
1081 if (RES == 0) {
1082 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
1083 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
1084 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
1088 PRE(sys_getresuid)
1090 PRINT("sys_getresuid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1091 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1092 PRE_REG_READ3(long, "getresuid",
1093 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
1094 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
1095 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
1096 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
1098 POST(sys_getresuid)
1100 vg_assert(SUCCESS);
1101 if (RES == 0) {
1102 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
1103 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
1104 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
1108 PRE(sys_setresgid16)
1110 PRINT("sys_setresgid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1111 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1112 PRE_REG_READ3(long, "setresgid16",
1113 vki_old_gid_t, rgid,
1114 vki_old_gid_t, egid, vki_old_gid_t, sgid);
1117 PRE(sys_setresgid)
1119 PRINT("sys_setresgid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
1120 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
1121 PRE_REG_READ3(long, "setresgid",
1122 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
1125 PRE(sys_getresgid16)
1127 PRINT("sys_getresgid16 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1128 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1129 PRE_REG_READ3(long, "getresgid16",
1130 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
1131 vki_old_gid_t *, sgid);
1132 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
1133 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
1134 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
1136 POST(sys_getresgid16)
1138 vg_assert(SUCCESS);
1139 if (RES == 0) {
1140 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
1141 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
1142 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
1146 PRE(sys_getresgid)
1148 PRINT("sys_getresgid ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1149 FMT_REGWORD "x )", ARG1,ARG2,ARG3);
1150 PRE_REG_READ3(long, "getresgid",
1151 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
1152 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
1153 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
1154 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
1156 POST(sys_getresgid)
1158 vg_assert(SUCCESS);
1159 if (RES == 0) {
1160 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
1161 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
1162 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
1166 /* ---------------------------------------------------------------------
1167 miscellaneous wrappers
1168 ------------------------------------------------------------------ */
1170 PRE(sys_exit_group)
1172 ThreadId t;
1173 ThreadState* tst;
1175 PRINT("exit_group( %ld )", SARG1);
1176 PRE_REG_READ1(void, "exit_group", int, status);
1178 tst = VG_(get_ThreadState)(tid);
1179 /* A little complex; find all the threads with the same threadgroup
1180 as this one (including this one), and mark them to exit */
1181 /* It is unclear how one can get a threadgroup in this process which
1182 is not the threadgroup of the calling thread:
1183 The assignments to threadgroups are:
1184 = 0; /// scheduler.c os_state_clear
1185 = getpid(); /// scheduler.c in child after fork
1186 = getpid(); /// this file, in thread_wrapper
1187 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
1188 copying the thread group of the thread doing clone
1189 So, the only case where the threadgroup might be different to the getpid
1190 value is in the child, just after fork. But then the fork syscall is
1191 still going on, the forked thread has had no chance yet to make this
1192 syscall. */
1193 for (t = 1; t < VG_N_THREADS; t++) {
1194 if ( /* not alive */
1195 VG_(threads)[t].status == VgTs_Empty
1197 /* not our group */
1198 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
1200 continue;
1201 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1202 the exitreason. */
1203 VG_(threads)[t].os_state.exitcode = ARG1;
1206 /* Indicate in all other threads that the process is exiting.
1207 Then wait using VG_(reap_threads) for these threads to disappear.
1209 Can this give a deadlock if another thread is calling exit in parallel
1210 and would then wait for this thread to disappear ?
1211 The answer is no:
1212 Other threads are either blocked in a syscall or have yielded the CPU.
1214 A thread that has yielded the CPU is trying to get the big lock in
1215 VG_(scheduler). This thread will get the CPU thanks to the call
1216 to VG_(reap_threads). The scheduler will then check for signals,
1217 kill the process if this is a fatal signal, and otherwise prepare
1218 the thread for handling this signal. After this preparation, if
1219 the thread status is VG_(is_exiting), the scheduler exits the thread.
1220 So, a thread that has yielded the CPU does not have a chance to
1221 call exit => no deadlock for this thread.
1223 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
1224 to all threads blocked in a syscall.
1225 The syscall will be interrupted, and the control will go to the
1226 scheduler. The scheduler will then return, as the thread is in
1227 exiting state. */
1229 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
1230 VG_(reap_threads)(tid);
1231 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1232 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1233 is the thread calling exit_group and so its registers must be considered
1234 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1236 /* We have to claim the syscall already succeeded. */
1237 SET_STATUS_Success(0);
1240 PRE(sys_llseek)
1242 PRINT("sys_llseek ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
1243 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1244 ARG1, ARG2, ARG3, ARG4, ARG5);
1245 PRE_REG_READ5(long, "llseek",
1246 unsigned int, fd, unsigned long, offset_high,
1247 unsigned long, offset_low, vki_loff_t *, result,
1248 unsigned int, whence);
1249 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
1250 SET_STATUS_Failure( VKI_EBADF );
1251 else
1252 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
1254 POST(sys_llseek)
1256 vg_assert(SUCCESS);
1257 if (RES == 0)
1258 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
1261 PRE(sys_adjtimex)
1263 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG1;
1264 PRINT("sys_adjtimex ( %#" FMT_REGWORD "x )", ARG1);
1265 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
1267 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1268 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
1270 #define ADJX(bits,field) \
1271 if (tx->modes & (bits)) \
1272 PRE_MEM_READ( "adjtimex(timex->"#field")", \
1273 (Addr)&tx->field, sizeof(tx->field))
1275 if (tx->modes & VKI_ADJ_ADJTIME) {
1276 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1277 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1278 } else {
1279 ADJX(VKI_ADJ_OFFSET, offset);
1280 ADJX(VKI_ADJ_FREQUENCY, freq);
1281 ADJX(VKI_ADJ_MAXERROR, maxerror);
1282 ADJX(VKI_ADJ_ESTERROR, esterror);
1283 ADJX(VKI_ADJ_STATUS, status);
1284 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1285 ADJX(VKI_ADJ_TICK, tick);
1287 #undef ADJX
1290 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
1293 POST(sys_adjtimex)
1295 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
1298 PRE(sys_clock_adjtime)
1300 struct vki_timex *tx = (struct vki_timex *)(Addr)ARG2;
1301 PRINT("sys_clock_adjtime ( %ld, %#" FMT_REGWORD "x )", SARG1,ARG2);
1302 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
1303 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1305 if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
1306 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
1308 #define ADJX(bits,field) \
1309 if (tx->modes & (bits)) \
1310 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
1311 (Addr)&tx->field, sizeof(tx->field))
1313 if (tx->modes & VKI_ADJ_ADJTIME) {
1314 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
1315 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
1316 } else {
1317 ADJX(VKI_ADJ_OFFSET, offset);
1318 ADJX(VKI_ADJ_FREQUENCY, freq);
1319 ADJX(VKI_ADJ_MAXERROR, maxerror);
1320 ADJX(VKI_ADJ_ESTERROR, esterror);
1321 ADJX(VKI_ADJ_STATUS, status);
1322 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
1323 ADJX(VKI_ADJ_TICK, tick);
1325 #undef ADJX
1328 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
1331 POST(sys_clock_adjtime)
1333 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
1336 PRE(sys_ioperm)
1338 PRINT("sys_ioperm ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %ld )",
1339 ARG1, ARG2, SARG3 );
1340 PRE_REG_READ3(long, "ioperm",
1341 unsigned long, from, unsigned long, num, int, turn_on);
1344 PRE(sys_syslog)
1346 *flags |= SfMayBlock;
1347 PRINT("sys_syslog (%ld, %#" FMT_REGWORD "x, %ld)", SARG1, ARG2, SARG3);
1348 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
1349 switch (ARG1) {
1350 // The kernel uses magic numbers here, rather than named constants,
1351 // therefore so do we.
1352 case 2: case 3: case 4:
1353 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
1354 break;
1355 default:
1356 break;
1359 POST(sys_syslog)
1361 switch (ARG1) {
1362 case 2: case 3: case 4:
1363 POST_MEM_WRITE( ARG2, ARG3 );
1364 break;
1365 default:
1366 break;
1370 PRE(sys_vhangup)
1372 PRINT("sys_vhangup ( )");
1373 PRE_REG_READ0(long, "vhangup");
1376 PRE(sys_sysinfo)
1378 PRINT("sys_sysinfo ( %#" FMT_REGWORD "x )",ARG1);
1379 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
1380 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
1382 POST(sys_sysinfo)
1384 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
1387 PRE(sys_personality)
1389 PRINT("sys_personality ( %llu )", (ULong)ARG1);
1390 PRE_REG_READ1(long, "personality", vki_u_long, persona);
1393 PRE(sys_sysctl)
1395 struct __vki_sysctl_args *args;
1396 PRINT("sys_sysctl ( %#" FMT_REGWORD "x )", ARG1 );
1397 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1398 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
1399 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
1400 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
1401 VKI_PROT_READ)) {
1402 SET_STATUS_Failure( VKI_EFAULT );
1403 return;
1406 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
1407 if (args->newval != NULL)
1408 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
1409 if (args->oldlenp != NULL) {
1410 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
1411 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
1414 POST(sys_sysctl)
1416 struct __vki_sysctl_args *args;
1417 args = (struct __vki_sysctl_args *)(Addr)ARG1;
1418 if (args->oldlenp != NULL) {
1419 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
1420 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
1424 static void pre_asciiz_str(ThreadId tid, Addr str, SizeT maxlen,
1425 const char *attr_name)
1427 const HChar *step_str = (const HChar *)str;
1428 SizeT len;
1429 UInt i;
1432 * The name can be up to maxlen bytes long, including the terminating null
1433 * byte. So do not check more than maxlen bytes.
1435 if (ML_(safe_to_deref)((const HChar *)str, maxlen)) {
1436 len = VG_(strnlen)((const HChar *)str, maxlen);
1437 if (len < maxlen)
1438 PRE_MEM_RASCIIZ(attr_name, str);
1439 else
1440 PRE_MEM_READ(attr_name, str, maxlen);
1441 } else {
1443 * Do it the slow way, one byte at a time, while checking for terminating
1444 * '\0'.
1446 for (i = 0; i < maxlen; i++) {
1447 PRE_MEM_READ(attr_name, (Addr)&step_str[i], 1);
1448 if (!ML_(safe_to_deref)(&step_str[i], 1) || step_str[i] == '\0')
1449 break;
1454 PRE(sys_prctl)
1456 *flags |= SfMayBlock;
1457 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", SARG1, SARG2, SARG3, SARG4, SARG5 );
1458 switch (ARG1) {
1459 case VKI_PR_SET_PDEATHSIG:
1460 PRE_REG_READ2(int, "prctl", int, option, int, signal);
1461 break;
1462 case VKI_PR_GET_PDEATHSIG:
1463 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
1464 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
1465 break;
1466 case VKI_PR_GET_DUMPABLE:
1467 PRE_REG_READ1(int, "prctl", int, option);
1468 break;
1469 case VKI_PR_SET_DUMPABLE:
1470 PRE_REG_READ2(int, "prctl", int, option, int, dump);
1471 break;
1472 case VKI_PR_GET_UNALIGN:
1473 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1474 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
1475 break;
1476 case VKI_PR_SET_UNALIGN:
1477 PRE_REG_READ2(int, "prctl", int, option, int, value);
1478 break;
1479 case VKI_PR_GET_KEEPCAPS:
1480 PRE_REG_READ1(int, "prctl", int, option);
1481 break;
1482 case VKI_PR_SET_KEEPCAPS:
1483 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
1484 break;
1485 case VKI_PR_GET_FPEMU:
1486 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1487 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
1488 break;
1489 case VKI_PR_SET_FPEMU:
1490 PRE_REG_READ2(int, "prctl", int, option, int, value);
1491 break;
1492 case VKI_PR_GET_FPEXC:
1493 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1494 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
1495 break;
1496 case VKI_PR_SET_FPEXC:
1497 PRE_REG_READ2(int, "prctl", int, option, int, value);
1498 break;
1499 case VKI_PR_GET_TIMING:
1500 PRE_REG_READ1(int, "prctl", int, option);
1501 break;
1502 case VKI_PR_SET_TIMING:
1503 PRE_REG_READ2(int, "prctl", int, option, int, timing);
1504 break;
1505 case VKI_PR_SET_NAME:
1506 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1507 pre_asciiz_str(tid, ARG2, VKI_TASK_COMM_LEN, "prctl(set-name)");
1508 break;
1509 case VKI_PR_GET_NAME:
1510 PRE_REG_READ2(int, "prctl", int, option, char *, name);
1511 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
1512 break;
1513 case VKI_PR_GET_ENDIAN:
1514 PRE_REG_READ2(int, "prctl", int, option, int *, value);
1515 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1516 break;
1517 case VKI_PR_SET_ENDIAN:
1518 PRE_REG_READ2(int, "prctl", int, option, int, value);
1519 break;
1520 case VKI_PR_SET_PTRACER:
1521 PRE_REG_READ2(int, "prctl", int, option, int, ptracer_process_ID);
1522 break;
1523 case VKI_PR_SET_SECCOMP:
1524 /* This is a bit feeble in that it uses |option| before checking
1525 it, but at least both sides of the conditional check it. */
1526 if (ARG2 == VKI_SECCOMP_MODE_FILTER) {
1527 PRE_REG_READ3(int, "prctl", int, option, int, mode, char*, filter);
1528 if (ARG3) {
1529 /* Should check that ARG3 points at a valid struct sock_fprog.
1530 Sounds complex; hence be lame. */
1531 PRE_MEM_READ( "prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter)",
1532 ARG3, 1 );
1534 } else {
1535 PRE_REG_READ2(int, "prctl", int, option, int, mode);
1537 break;
1538 case VKI_PR_CAPBSET_READ:
1539 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1540 break;
1541 case VKI_PR_CAPBSET_DROP:
1542 PRE_REG_READ2(int, "prctl", int, option, int, capability);
1543 break;
1544 default:
1545 PRE_REG_READ5(long, "prctl",
1546 int, option, unsigned long, arg2, unsigned long, arg3,
1547 unsigned long, arg4, unsigned long, arg5);
1548 break;
1551 POST(sys_prctl)
1553 switch (ARG1) {
1554 case VKI_PR_GET_PDEATHSIG:
1555 POST_MEM_WRITE(ARG2, sizeof(Int));
1556 break;
1557 case VKI_PR_GET_UNALIGN:
1558 POST_MEM_WRITE(ARG2, sizeof(Int));
1559 break;
1560 case VKI_PR_GET_FPEMU:
1561 POST_MEM_WRITE(ARG2, sizeof(Int));
1562 break;
1563 case VKI_PR_GET_FPEXC:
1564 POST_MEM_WRITE(ARG2, sizeof(Int));
1565 break;
1566 case VKI_PR_GET_NAME:
1567 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1568 break;
1569 case VKI_PR_GET_ENDIAN:
1570 POST_MEM_WRITE(ARG2, sizeof(Int));
1571 break;
1572 case VKI_PR_SET_NAME:
1574 const HChar* new_name = (const HChar*) (Addr)ARG2;
1575 if (new_name) { // Paranoia
1576 ThreadState* tst = VG_(get_ThreadState)(tid);
1577 SizeT new_len = VG_(strnlen)(new_name, VKI_TASK_COMM_LEN);
1579 /* Don't bother reusing the memory. This is a rare event. */
1580 tst->thread_name =
1581 VG_(realloc)("syswrap.prctl", tst->thread_name, new_len + 1);
1582 VG_(strlcpy)(tst->thread_name, new_name, new_len + 1);
1585 break;
1589 PRE(sys_sendfile)
1591 *flags |= SfMayBlock;
1592 PRINT("sys_sendfile ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1593 SARG1, SARG2, ARG3, ARG4);
1594 PRE_REG_READ4(ssize_t, "sendfile",
1595 int, out_fd, int, in_fd, vki_off_t *, offset,
1596 vki_size_t, count);
1597 if (ARG3 != 0)
1598 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1600 POST(sys_sendfile)
1602 if (ARG3 != 0 ) {
1603 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1607 PRE(sys_sendfile64)
1609 *flags |= SfMayBlock;
1610 PRINT("sendfile64 ( %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
1611 SARG1, SARG2, ARG3, ARG4);
1612 PRE_REG_READ4(ssize_t, "sendfile64",
1613 int, out_fd, int, in_fd, vki_loff_t *, offset,
1614 vki_size_t, count);
1615 if (ARG3 != 0)
1616 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1618 POST(sys_sendfile64)
1620 if (ARG3 != 0 ) {
1621 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1625 static void pre_read_timespec64 (ThreadId tid, const char *msg, UWord arg)
1627 struct vki_timespec64 *ts64 = (void *)(Addr)arg;
1628 PRE_MEM_READ (msg, (Addr) &ts64->tv_sec, sizeof(vki_time64_t));
1629 PRE_MEM_READ (msg, (Addr) &ts64->tv_nsec, sizeof(vki_int32_t));
1632 static void pre_read_itimerspec64 (ThreadId tid, const char *msg, UWord arg)
1634 struct vki_itimerspec64 *its64 = (void *)(Addr)arg;
1635 pre_read_timespec64 (tid, msg, (UWord) &its64->it_interval);
1636 pre_read_timespec64 (tid, msg, (UWord) &its64->it_value);
1639 static void futex_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1640 SyscallArgs* arrghs, SyscallStatus* status,
1641 UWord* flags, Bool is_time64 )
1644 arg param used by ops
1646 ARG1 - u32 *futex all
1647 ARG2 - int op
1648 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1649 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1650 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1651 ARG6 - int val3 CMP_REQUEUE
1654 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1655 case VKI_FUTEX_CMP_REQUEUE:
1656 case VKI_FUTEX_WAKE_OP:
1657 case VKI_FUTEX_CMP_REQUEUE_PI:
1658 if (is_time64) {
1659 PRE_REG_READ6(long, "futex_time64",
1660 vki_u32 *, futex, int, op, int, val,
1661 struct timespec64 *, utime, vki_u32 *, uaddr2, int, val3);
1662 } else {
1663 PRE_REG_READ6(long, "futex",
1664 vki_u32 *, futex, int, op, int, val,
1665 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1667 break;
1668 case VKI_FUTEX_REQUEUE:
1669 case VKI_FUTEX_WAIT_REQUEUE_PI:
1670 if (is_time64) {
1671 PRE_REG_READ5(long, "futex_time64",
1672 vki_u32 *, futex, int, op, int, val,
1673 struct timespec64 *, utime, vki_u32 *, uaddr2);
1674 } else {
1675 PRE_REG_READ5(long, "futex",
1676 vki_u32 *, futex, int, op, int, val,
1677 struct timespec *, utime, vki_u32 *, uaddr2);
1679 break;
1680 case VKI_FUTEX_WAIT_BITSET:
1681 /* Check that the address at least begins in client-accessible area. */
1682 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1683 SET_STATUS_Failure( VKI_EFAULT );
1684 return;
1686 if (*(vki_u32 *)(Addr)ARG1 != ARG3) {
1687 if (is_time64) {
1688 PRE_REG_READ4(long, "futex_time64",
1689 vki_u32 *, futex, int, op, int, val,
1690 struct timespec64 *, utime);
1691 } else {
1692 PRE_REG_READ4(long, "futex",
1693 vki_u32 *, futex, int, op, int, val,
1694 struct timespec64 *, utime);
1696 } else {
1697 /* Note argument 5 is unused, but argument 6 is used.
1698 So we cannot just PRE_REG_READ6. Read argument 6 separately. */
1699 if (is_time64) {
1700 PRE_REG_READ4(long, "futex_time64",
1701 vki_u32 *, futex, int, op, int, val,
1702 struct timespec64 *, utime);
1703 } else {
1704 PRE_REG_READ4(long, "futex",
1705 vki_u32 *, futex, int, op, int, val,
1706 struct timespec *, utime);
1708 if (VG_(tdict).track_pre_reg_read)
1709 PRA6("futex",int,val3);
1711 break;
1712 case VKI_FUTEX_WAKE_BITSET:
1713 PRE_REG_READ3(long, "futex",
1714 vki_u32 *, futex, int, op, int, val);
1715 if (VG_(tdict).track_pre_reg_read) {
1716 PRA6("futex", int, val3);
1718 break;
1719 case VKI_FUTEX_WAIT:
1720 case VKI_FUTEX_LOCK_PI:
1721 if (is_time64) {
1722 PRE_REG_READ4(long, "futex_time64",
1723 vki_u32 *, futex, int, op, int, val,
1724 struct timespec64 *, utime);
1725 } else {
1726 PRE_REG_READ4(long, "futex",
1727 vki_u32 *, futex, int, op, int, val,
1728 struct timespec *, utime);
1730 break;
1731 case VKI_FUTEX_WAKE:
1732 case VKI_FUTEX_FD:
1733 PRE_REG_READ3(long, "futex",
1734 vki_u32 *, futex, int, op, int, val);
1735 break;
1736 case VKI_FUTEX_TRYLOCK_PI:
1737 case VKI_FUTEX_UNLOCK_PI:
1738 default:
1739 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1740 break;
1743 *flags |= SfMayBlock;
1745 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
1746 case VKI_FUTEX_WAIT:
1747 case VKI_FUTEX_LOCK_PI:
1748 case VKI_FUTEX_WAIT_BITSET:
1749 case VKI_FUTEX_WAIT_REQUEUE_PI:
1750 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1751 if (ARG4 != 0) {
1752 if (is_time64) {
1753 pre_read_timespec64 (tid, "futex_time64(timeout)", ARG4);
1754 } else {
1755 PRE_MEM_READ( "futex(timeout)", ARG4,
1756 sizeof(struct vki_timespec) );
1759 break;
1761 case VKI_FUTEX_REQUEUE:
1762 case VKI_FUTEX_CMP_REQUEUE:
1763 case VKI_FUTEX_CMP_REQUEUE_PI:
1764 case VKI_FUTEX_WAKE_OP:
1765 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1766 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1767 break;
1769 case VKI_FUTEX_FD:
1770 case VKI_FUTEX_TRYLOCK_PI:
1771 case VKI_FUTEX_UNLOCK_PI:
1772 case VKI_FUTEX_WAKE:
1773 case VKI_FUTEX_WAKE_BITSET:
1774 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1775 break;
1777 default:
1778 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1779 break;
1783 static void futex_post_helper ( ThreadId tid, SyscallArgs* arrghs,
1784 SyscallStatus* status )
1786 vg_assert(SUCCESS);
1787 POST_MEM_WRITE( ARG1, sizeof(int) );
1788 if (ARG2 == VKI_FUTEX_FD) {
1789 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
1790 VG_(close)(RES);
1791 SET_STATUS_Failure( VKI_EMFILE );
1792 } else {
1793 if (VG_(clo_track_fds))
1794 ML_(record_fd_open_nameless)(tid, RES);
1799 PRE(sys_futex)
1801 PRINT("sys_futex ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1802 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1803 futex_pre_helper (tid, layout, arrghs, status, flags, False);
1806 POST(sys_futex)
1808 futex_post_helper (tid, arrghs, status);
1811 PRE(sys_futex_time64)
1813 PRINT("sys_futex_time64 ( %#" FMT_REGWORD "x, %ld, %ld, %#" FMT_REGWORD
1814 "x, %#" FMT_REGWORD "x )", ARG1, SARG2, SARG3, ARG4, ARG5);
1815 futex_pre_helper (tid, layout, arrghs, status, flags, True);
1818 POST(sys_futex_time64)
1820 futex_post_helper (tid, arrghs, status);
1823 PRE(sys_set_robust_list)
1825 PRINT("sys_set_robust_list ( %#" FMT_REGWORD "x, %"
1826 FMT_REGWORD "u )", ARG1, ARG2);
1827 PRE_REG_READ2(long, "set_robust_list",
1828 struct vki_robust_list_head *, head, vki_size_t, len);
1830 /* Just check the robust_list_head structure is readable - don't
1831 try and chase the list as the kernel will only read it when
1832 the thread exits so the current contents is irrelevant. */
1833 if (ARG1 != 0)
1834 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1837 PRE(sys_get_robust_list)
1839 PRINT("sys_get_robust_list ( %ld, %#" FMT_REGWORD "x, %#"
1840 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
1841 PRE_REG_READ3(long, "get_robust_list",
1842 int, pid,
1843 struct vki_robust_list_head **, head_ptr,
1844 vki_size_t *, len_ptr);
1845 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1846 ARG2, sizeof(struct vki_robust_list_head *));
1847 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1848 ARG3, sizeof(struct vki_size_t *));
1850 POST(sys_get_robust_list)
1852 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1853 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1856 struct pselect_sized_sigset {
1857 const vki_sigset_t *ss;
1858 vki_size_t ss_len;
1860 struct pselect_adjusted_sigset {
1861 struct pselect_sized_sigset ss; /* The actual syscall arg */
1862 vki_sigset_t adjusted_ss;
1865 static void pselect6_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1866 SyscallArgs* arrghs, SyscallStatus* status,
1867 UWord* flags, Bool is_time64 )
1869 *flags |= SfMayBlock | SfPostOnFail;
1870 if (is_time64) {
1871 PRE_REG_READ6(long, "pselect6_time64",
1872 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1873 vki_fd_set *, exceptfds, struct vki_timespec64 *, timeout,
1874 void *, sig);
1875 } else {
1876 PRE_REG_READ6(long, "pselect6",
1877 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1878 vki_fd_set *, exceptfds, struct vki_timespec *, timeout,
1879 void *, sig);
1881 // XXX: this possibly understates how much memory is read.
1882 if (ARG2 != 0)
1883 PRE_MEM_READ( "pselect6(readfds)",
1884 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1885 if (ARG3 != 0)
1886 PRE_MEM_READ( "pselect6(writefds)",
1887 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1888 if (ARG4 != 0)
1889 PRE_MEM_READ( "pselect6(exceptfds)",
1890 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1891 if (ARG5 != 0) {
1892 if (is_time64) {
1893 pre_read_timespec64(tid, "pselect6_time64(timeout)", ARG5);
1894 } else {
1895 PRE_MEM_READ( "pselect6(timeout)", ARG5,
1896 sizeof(struct vki_timespec) );
1899 if (ARG6 != 0) {
1900 const struct pselect_sized_sigset *pss =
1901 (struct pselect_sized_sigset *)(Addr)ARG6;
1902 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
1903 if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
1904 ARG6 = 1; /* Something recognisable to POST() hook. */
1905 } else {
1906 struct pselect_adjusted_sigset *pas;
1907 pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
1908 ARG6 = (Addr)pas;
1909 pas->ss.ss = (void *)1;
1910 pas->ss.ss_len = pss->ss_len;
1911 if (pss->ss_len == sizeof(*pss->ss)) {
1912 if (pss->ss == NULL) {
1913 pas->ss.ss = NULL;
1914 } else {
1915 PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
1916 if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
1917 pas->adjusted_ss = *pss->ss;
1918 pas->ss.ss = &pas->adjusted_ss;
1919 VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
1927 PRE(sys_pselect6)
1929 PRINT("sys_pselect6 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1930 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1931 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1932 pselect6_pre_helper (tid, layout, arrghs, status, flags, False);
1935 POST(sys_pselect6)
1937 if (ARG6 != 0 && ARG6 != 1) {
1938 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1942 PRE(sys_pselect6_time64)
1944 PRINT("sys_pselect6_time64 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
1945 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
1946 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1947 pselect6_pre_helper (tid, layout, arrghs, status, flags, True);
1950 POST(sys_pselect6_time64)
1952 if (ARG6 != 0 && ARG6 != 1) {
1953 VG_(free)((struct pselect_adjusted_sigset *)(Addr)ARG6);
1957 static void ppoll_pre_helper ( ThreadId tid, SyscallArgLayout* layout,
1958 SyscallArgs* arrghs, SyscallStatus* status,
1959 UWord* flags, Bool is_time64 )
1961 UInt i;
1962 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
1963 *flags |= SfMayBlock | SfPostOnFail;
1964 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
1965 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
1966 ARG1, ARG2, ARG3, ARG4, ARG5);
1967 if (is_time64) {
1968 PRE_REG_READ5(long, "ppoll_time64",
1969 struct vki_pollfd *, ufds, unsigned int, nfds,
1970 struct vki_timespec64 *, tsp, vki_sigset_t *, sigmask,
1971 vki_size_t, sigsetsize);
1972 } else {
1973 PRE_REG_READ5(long, "ppoll",
1974 struct vki_pollfd *, ufds, unsigned int, nfds,
1975 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1976 vki_size_t, sigsetsize);
1979 for (i = 0; i < ARG2; i++) {
1980 PRE_MEM_READ( "ppoll(ufds.fd)",
1981 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1982 PRE_MEM_READ( "ppoll(ufds.events)",
1983 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
1984 PRE_MEM_WRITE( "ppoll(ufds.revents)",
1985 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1988 if (ARG3) {
1989 if (is_time64) {
1990 pre_read_timespec64(tid, "ppoll_time64(tsp)", ARG3);
1991 } else {
1992 PRE_MEM_READ( "ppoll(tsp)", ARG3,
1993 sizeof(struct vki_timespec) );
1996 if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
1997 const vki_sigset_t *guest_sigmask = (vki_sigset_t *)(Addr)ARG4;
1998 PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
1999 if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
2000 ARG4 = 1; /* Something recognisable to POST() hook. */
2001 } else {
2002 vki_sigset_t *vg_sigmask =
2003 VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
2004 ARG4 = (Addr)vg_sigmask;
2005 *vg_sigmask = *guest_sigmask;
2006 VG_(sanitize_client_sigmask)(vg_sigmask);
2011 static void ppoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2012 SyscallStatus* status )
2014 vg_assert(SUCCESS || FAILURE);
2015 if (SUCCESS && (RES >= 0)) {
2016 UInt i;
2017 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
2018 for (i = 0; i < ARG2; i++)
2019 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
2021 if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
2022 VG_(free)((vki_sigset_t *) (Addr)ARG4);
2026 PRE(sys_ppoll)
2028 PRINT("sys_ppoll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD
2029 "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2030 ARG1, ARG2, ARG3, ARG4, ARG5);
2031 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2034 POST(sys_ppoll)
2036 ppoll_post_helper (tid, arrghs, status);
2039 PRE(sys_ppoll_time64)
2041 PRINT("sys_ppoll_time64 ( %#" FMT_REGWORD "x, %" FMT_REGWORD
2042 "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )\n",
2043 ARG1, ARG2, ARG3, ARG4, ARG5);
2044 ppoll_pre_helper (tid, layout, arrghs, status, flags, False);
2047 POST(sys_ppoll_time64)
2049 ppoll_post_helper (tid, arrghs, status);
2053 /* ---------------------------------------------------------------------
2054 epoll_* wrappers
2055 ------------------------------------------------------------------ */
2057 PRE(sys_epoll_create)
2059 PRINT("sys_epoll_create ( %ld )", SARG1);
2060 PRE_REG_READ1(long, "epoll_create", int, size);
2062 POST(sys_epoll_create)
2064 vg_assert(SUCCESS);
2065 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
2066 VG_(close)(RES);
2067 SET_STATUS_Failure( VKI_EMFILE );
2068 } else {
2069 if (VG_(clo_track_fds))
2070 ML_(record_fd_open_nameless) (tid, RES);
2074 PRE(sys_epoll_create1)
2076 PRINT("sys_epoll_create1 ( %ld )", SARG1);
2077 PRE_REG_READ1(long, "epoll_create1", int, flags);
2079 POST(sys_epoll_create1)
2081 vg_assert(SUCCESS);
2082 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
2083 VG_(close)(RES);
2084 SET_STATUS_Failure( VKI_EMFILE );
2085 } else {
2086 if (VG_(clo_track_fds))
2087 ML_(record_fd_open_nameless) (tid, RES);
2091 PRE(sys_epoll_ctl)
2093 static const HChar* epoll_ctl_s[3] = {
2094 "EPOLL_CTL_ADD",
2095 "EPOLL_CTL_DEL",
2096 "EPOLL_CTL_MOD"
2098 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#" FMT_REGWORD "x )",
2099 SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4);
2100 PRE_REG_READ4(long, "epoll_ctl",
2101 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
2102 if (ARG2 != VKI_EPOLL_CTL_DEL) {
2103 /* Just check the events field, the data field is for user space and
2104 unused by the kernel. */
2105 struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4;
2106 PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events,
2107 sizeof(__vki_u32) );
2111 /* RES event records have been written (exclude padding). */
2112 static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs,
2113 SyscallStatus* status )
2115 vg_assert(SUCCESS);
2116 if (RES > 0) {
2117 Int i;
2118 struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2;
2119 for (i = 0; i < RES; i++) {
2120 /* Assume both events and data are set (data is user space only). */
2121 POST_FIELD_WRITE(events[i].events);
2122 POST_FIELD_WRITE(events[i].data);
2127 PRE(sys_epoll_wait)
2129 *flags |= SfMayBlock;
2130 PRINT("sys_epoll_wait ( %ld, %#" FMT_REGWORD "x, %ld, %ld )",
2131 SARG1, ARG2, SARG3, SARG4);
2132 PRE_REG_READ4(long, "epoll_wait",
2133 int, epfd, struct vki_epoll_event *, events,
2134 int, maxevents, int, timeout);
2135 /* Assume all (maxevents) events records should be (fully) writable. */
2136 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2138 POST(sys_epoll_wait)
2140 epoll_post_helper (tid, arrghs, status);
2143 PRE(sys_epoll_pwait)
2145 *flags |= SfMayBlock;
2146 PRINT("sys_epoll_pwait ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
2147 FMT_REGWORD "x, %" FMT_REGWORD "u )",
2148 SARG1, ARG2, SARG3, SARG4, ARG5, ARG6);
2149 PRE_REG_READ6(long, "epoll_pwait",
2150 int, epfd, struct vki_epoll_event *, events,
2151 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
2152 vki_size_t, sigsetsize);
2153 /* Assume all (maxevents) events records should be (fully) writable. */
2154 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
2155 if (ARG5)
2156 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
2158 POST(sys_epoll_pwait)
2160 epoll_post_helper (tid, arrghs, status);
2163 PRE(sys_eventfd)
2165 PRINT("sys_eventfd ( %" FMT_REGWORD "u )", ARG1);
2166 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
2168 POST(sys_eventfd)
2170 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
2171 VG_(close)(RES);
2172 SET_STATUS_Failure( VKI_EMFILE );
2173 } else {
2174 if (VG_(clo_track_fds))
2175 ML_(record_fd_open_nameless) (tid, RES);
2179 PRE(sys_eventfd2)
2181 PRINT("sys_eventfd2 ( %" FMT_REGWORD "u, %ld )", ARG1, SARG2);
2182 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
2184 POST(sys_eventfd2)
2186 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
2187 VG_(close)(RES);
2188 SET_STATUS_Failure( VKI_EMFILE );
2189 } else {
2190 if (VG_(clo_track_fds))
2191 ML_(record_fd_open_nameless) (tid, RES);
2195 PRE(sys_fallocate)
2197 *flags |= SfMayBlock;
2198 #if VG_WORDSIZE == 4
2199 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
2200 SARG1, SARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
2201 PRE_REG_READ6(long, "fallocate",
2202 int, fd, int, mode,
2203 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2204 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
2205 #elif VG_WORDSIZE == 8
2206 PRINT("sys_fallocate ( %ld, %ld, %ld, %ld )",
2207 SARG1, SARG2, SARG3, SARG4);
2208 PRE_REG_READ4(long, "fallocate",
2209 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
2210 #else
2211 # error Unexpected word size
2212 #endif
2213 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
2214 SET_STATUS_Failure( VKI_EBADF );
2217 PRE(sys_prlimit64)
2219 PRINT("sys_prlimit64 ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
2220 FMT_REGWORD "x )", SARG1,ARG2,ARG3,ARG4);
2221 PRE_REG_READ4(long, "prlimit64",
2222 vki_pid_t, pid, unsigned int, resource,
2223 const struct rlimit64 *, new_rlim,
2224 struct rlimit64 *, old_rlim);
2225 if (ARG3)
2226 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
2227 if (ARG4)
2228 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
2230 if (ARG3 &&
2231 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2232 > ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max) {
2233 SET_STATUS_Failure( VKI_EINVAL );
2235 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
2236 switch (ARG2) {
2237 case VKI_RLIMIT_NOFILE:
2238 SET_STATUS_Success( 0 );
2239 if (ARG4) {
2240 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur = VG_(fd_soft_limit);
2241 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max = VG_(fd_hard_limit);
2243 if (ARG3) {
2244 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2245 > VG_(fd_hard_limit) ||
2246 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2247 != VG_(fd_hard_limit)) {
2248 SET_STATUS_Failure( VKI_EPERM );
2250 else {
2251 VG_(fd_soft_limit) =
2252 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2255 break;
2257 case VKI_RLIMIT_DATA:
2258 SET_STATUS_Success( 0 );
2259 if (ARG4) {
2260 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2261 VG_(client_rlimit_data).rlim_cur;
2262 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2263 VG_(client_rlimit_data).rlim_max;
2265 if (ARG3) {
2266 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2267 > VG_(client_rlimit_data).rlim_max ||
2268 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2269 > VG_(client_rlimit_data).rlim_max) {
2270 SET_STATUS_Failure( VKI_EPERM );
2272 else {
2273 VG_(client_rlimit_data).rlim_cur =
2274 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2275 VG_(client_rlimit_data).rlim_max =
2276 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2279 break;
2281 case VKI_RLIMIT_STACK:
2282 SET_STATUS_Success( 0 );
2283 if (ARG4) {
2284 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_cur =
2285 VG_(client_rlimit_stack).rlim_cur;
2286 ((struct vki_rlimit64 *)(Addr)ARG4)->rlim_max =
2287 VG_(client_rlimit_stack).rlim_max;
2289 if (ARG3) {
2290 if (((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur
2291 > VG_(client_rlimit_stack).rlim_max ||
2292 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max
2293 > VG_(client_rlimit_stack).rlim_max) {
2294 SET_STATUS_Failure( VKI_EPERM );
2296 else {
2297 VG_(threads)[tid].client_stack_szB =
2298 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2299 VG_(client_rlimit_stack).rlim_cur =
2300 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_cur;
2301 VG_(client_rlimit_stack).rlim_max =
2302 ((struct vki_rlimit64 *)(Addr)ARG3)->rlim_max;
2305 break;
2310 POST(sys_prlimit64)
2312 if (ARG4)
2313 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
2316 /* ---------------------------------------------------------------------
2317 tid-related wrappers
2318 ------------------------------------------------------------------ */
2320 PRE(sys_gettid)
2322 PRINT("sys_gettid ()");
2323 PRE_REG_READ0(long, "gettid");
2326 PRE(sys_set_tid_address)
2328 PRINT("sys_set_tid_address ( %#" FMT_REGWORD "x )", ARG1);
2329 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
2332 PRE(sys_tkill)
2334 PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
2335 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
2336 if (!ML_(client_signal_OK)(ARG2)) {
2337 SET_STATUS_Failure( VKI_EINVAL );
2338 return;
2341 /* Check to see if this kill gave us a pending signal */
2342 *flags |= SfPollAfter;
2344 if (VG_(clo_trace_signals))
2345 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
2346 SARG2, SARG1);
2348 /* If we're sending SIGKILL, check to see if the target is one of
2349 our threads and handle it specially. */
2350 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
2351 SET_STATUS_Success(0);
2352 return;
2355 /* Ask to handle this syscall via the slow route, since that's the
2356 only one that sets tst->status to VgTs_WaitSys. If the result
2357 of doing the syscall is an immediate run of
2358 async_signalhandler() in m_signals, then we need the thread to
2359 be properly tidied away. I have the impression the previous
2360 version of this wrapper worked on x86/amd64 only because the
2361 kernel did not immediately deliver the async signal to this
2362 thread (on ppc it did, which broke the assertion re tst->status
2363 at the top of async_signalhandler()). */
2364 *flags |= SfMayBlock;
2366 POST(sys_tkill)
2368 if (VG_(clo_trace_signals))
2369 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
2370 SARG2, SARG1);
2373 PRE(sys_tgkill)
2375 PRINT("sys_tgkill ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2376 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
2377 if (!ML_(client_signal_OK)(ARG3)) {
2378 SET_STATUS_Failure( VKI_EINVAL );
2379 return;
2382 /* Check to see if this kill gave us a pending signal */
2383 *flags |= SfPollAfter;
2385 if (VG_(clo_trace_signals))
2386 VG_(message)(Vg_DebugMsg,
2387 "tgkill: sending signal %ld to pid %ld/%ld\n",
2388 SARG3, SARG1, SARG2);
2390 /* If we're sending SIGKILL, check to see if the target is one of
2391 our threads and handle it specially. */
2392 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
2393 SET_STATUS_Success(0);
2394 return;
2397 /* Ask to handle this syscall via the slow route, since that's the
2398 only one that sets tst->status to VgTs_WaitSys. If the result
2399 of doing the syscall is an immediate run of
2400 async_signalhandler() in m_signals, then we need the thread to
2401 be properly tidied away. I have the impression the previous
2402 version of this wrapper worked on x86/amd64 only because the
2403 kernel did not immediately deliver the async signal to this
2404 thread (on ppc it did, which broke the assertion re tst->status
2405 at the top of async_signalhandler()). */
2406 *flags |= SfMayBlock;
2408 POST(sys_tgkill)
2410 if (VG_(clo_trace_signals))
2411 VG_(message)(Vg_DebugMsg,
2412 "tgkill: sent signal %ld to pid %ld/%ld\n",
2413 SARG3, SARG1, SARG2);
2416 /* ---------------------------------------------------------------------
2417 fadvise64* wrappers
2418 ------------------------------------------------------------------ */
2420 PRE(sys_fadvise64)
2422 PRINT("sys_fadvise64 ( %ld, %llu, %" FMT_REGWORD "u, %ld )",
2423 SARG1, MERGE64(ARG2,ARG3), ARG4, SARG5);
2424 PRE_REG_READ5(long, "fadvise64",
2425 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2426 vki_size_t, len, int, advice);
2429 PRE(sys_fadvise64_64)
2431 PRINT("sys_fadvise64_64 ( %ld, %llu, %llu, %ld )",
2432 SARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), SARG6);
2433 PRE_REG_READ6(long, "fadvise64_64",
2434 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
2435 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
2438 /* ---------------------------------------------------------------------
2439 io_* wrappers
2440 ------------------------------------------------------------------ */
2442 // Nb: this wrapper has to pad/unpad memory around the syscall itself,
2443 // and this allows us to control exactly the code that gets run while
2444 // the padding is in place.
2446 PRE(sys_io_setup)
2448 PRINT("sys_io_setup ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2);
2449 PRE_REG_READ2(long, "io_setup",
2450 unsigned, nr_events, vki_aio_context_t *, ctxp);
2451 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
2454 POST(sys_io_setup)
2456 SizeT size;
2457 struct vki_aio_ring *r;
2459 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2460 ARG1*sizeof(struct vki_io_event));
2461 r = *(struct vki_aio_ring **)(Addr)ARG2;
2462 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
2464 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
2465 VKI_PROT_READ | VKI_PROT_WRITE,
2466 VKI_MAP_ANONYMOUS, -1, 0 );
2468 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
2471 // Nb: This wrapper is "Special" because we need 'size' to do the unmap
2472 // after the syscall. We must get 'size' from the aio_ring structure,
2473 // before the syscall, while the aio_ring structure still exists. (And we
2474 // know that we must look at the aio_ring structure because Tom inspected the
2475 // kernel and glibc sources to see what they do, yuk.)
2477 // XXX This segment can be implicitly unmapped when aio
2478 // file-descriptors are closed...
2479 PRE(sys_io_destroy)
2481 SizeT size = 0;
2483 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
2484 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
2486 // If we are going to seg fault (due to a bogus ARG1) do it as late as
2487 // possible...
2488 if (ML_(safe_to_deref)( (void*)(Addr)ARG1, sizeof(struct vki_aio_ring))) {
2489 struct vki_aio_ring *r = (struct vki_aio_ring *)(Addr)ARG1;
2490 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
2491 r->nr*sizeof(struct vki_io_event));
2494 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
2496 if (SUCCESS && RES == 0) {
2497 Bool d = VG_(am_notify_munmap)( ARG1, size );
2498 VG_TRACK( die_mem_munmap, ARG1, size );
2499 if (d)
2500 VG_(discard_translations)( (Addr)ARG1, (ULong)size,
2501 "PRE(sys_io_destroy)" );
2505 PRE(sys_io_getevents)
2507 *flags |= SfMayBlock;
2508 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#" FMT_REGWORD "x, %#"
2509 FMT_REGWORD "x )",
2510 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
2511 PRE_REG_READ5(long, "io_getevents",
2512 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
2513 struct io_event *, events,
2514 struct timespec *, timeout);
2515 if (ARG3 > 0)
2516 PRE_MEM_WRITE( "io_getevents(events)",
2517 ARG4, sizeof(struct vki_io_event)*ARG3 );
2518 if (ARG5 != 0)
2519 PRE_MEM_READ( "io_getevents(timeout)",
2520 ARG5, sizeof(struct vki_timespec));
2522 POST(sys_io_getevents)
2524 Int i;
2525 vg_assert(SUCCESS);
2526 if (RES > 0) {
2527 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
2528 for (i = 0; i < RES; i++) {
2529 const struct vki_io_event *vev =
2530 ((struct vki_io_event *)(Addr)ARG4) + i;
2531 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
2533 switch (cb->aio_lio_opcode) {
2534 case VKI_IOCB_CMD_PREAD:
2535 if (vev->result > 0)
2536 POST_MEM_WRITE( cb->aio_buf, vev->result );
2537 break;
2539 case VKI_IOCB_CMD_PWRITE:
2540 break;
2542 case VKI_IOCB_CMD_FSYNC:
2543 break;
2545 case VKI_IOCB_CMD_FDSYNC:
2546 break;
2548 case VKI_IOCB_CMD_PREADV:
2549 if (vev->result > 0) {
2550 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
2551 Int remains = vev->result;
2552 Int j;
2554 for (j = 0; j < cb->aio_nbytes; j++) {
2555 Int nReadThisBuf = vec[j].iov_len;
2556 if (nReadThisBuf > remains) nReadThisBuf = remains;
2557 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
2558 remains -= nReadThisBuf;
2559 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
2562 break;
2564 case VKI_IOCB_CMD_PWRITEV:
2565 break;
2567 default:
2568 VG_(message)(Vg_DebugMsg,
2569 "Warning: unhandled io_getevents opcode: %u\n",
2570 cb->aio_lio_opcode);
2571 break;
2577 PRE(sys_io_submit)
2579 Int i, j;
2581 PRINT("sys_io_submit ( %" FMT_REGWORD "u, %ld, %#" FMT_REGWORD "x )",
2582 ARG1, SARG2, ARG3);
2583 PRE_REG_READ3(long, "io_submit",
2584 vki_aio_context_t, ctx_id, long, nr,
2585 struct iocb **, iocbpp);
2586 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
2587 if (ARG3 != 0) {
2588 for (i = 0; i < ARG2; i++) {
2589 struct vki_iocb *cb = ((struct vki_iocb **)(Addr)ARG3)[i];
2590 struct vki_iovec *iov;
2592 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
2593 switch (cb->aio_lio_opcode) {
2594 case VKI_IOCB_CMD_PREAD:
2595 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
2596 break;
2598 case VKI_IOCB_CMD_PWRITE:
2599 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
2600 break;
2602 case VKI_IOCB_CMD_FSYNC:
2603 break;
2605 case VKI_IOCB_CMD_FDSYNC:
2606 break;
2608 case VKI_IOCB_CMD_PREADV:
2609 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2610 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2611 for (j = 0; j < cb->aio_nbytes; j++)
2612 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2613 break;
2615 case VKI_IOCB_CMD_PWRITEV:
2616 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
2617 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
2618 for (j = 0; j < cb->aio_nbytes; j++)
2619 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
2620 break;
2622 default:
2623 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
2624 cb->aio_lio_opcode);
2625 break;
2631 PRE(sys_io_cancel)
2633 PRINT("sys_io_cancel ( %llu, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2634 (ULong)ARG1, ARG2, ARG3);
2635 PRE_REG_READ3(long, "io_cancel",
2636 vki_aio_context_t, ctx_id, struct iocb *, iocb,
2637 struct io_event *, result);
2638 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
2639 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
2641 POST(sys_io_cancel)
2643 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
2646 /* ---------------------------------------------------------------------
2647 *_mempolicy wrappers
2648 ------------------------------------------------------------------ */
2650 PRE(sys_mbind)
2652 PRINT("sys_mbind ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD
2653 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2654 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
2655 PRE_REG_READ6(long, "mbind",
2656 unsigned long, start, unsigned long, len,
2657 unsigned long, policy, unsigned long *, nodemask,
2658 unsigned long, maxnode, unsigned, flags);
2659 if (ARG1 != 0)
2660 PRE_MEM_READ( "mbind(nodemask)", ARG4,
2661 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
2664 PRE(sys_set_mempolicy)
2666 PRINT("sys_set_mempolicy ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
2667 SARG1, ARG2, ARG3);
2668 PRE_REG_READ3(long, "set_mempolicy",
2669 int, policy, unsigned long *, nodemask,
2670 unsigned long, maxnode);
2671 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
2672 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2675 PRE(sys_get_mempolicy)
2677 PRINT("sys_get_mempolicy ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
2678 FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "x )",
2679 ARG1, ARG2, ARG3, ARG4, ARG5);
2680 PRE_REG_READ5(long, "get_mempolicy",
2681 int *, policy, unsigned long *, nodemask,
2682 unsigned long, maxnode, unsigned long, addr,
2683 unsigned long, flags);
2684 if (ARG1 != 0)
2685 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
2686 if (ARG2 != 0)
2687 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
2688 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2690 POST(sys_get_mempolicy)
2692 if (ARG1 != 0)
2693 POST_MEM_WRITE( ARG1, sizeof(Int) );
2694 if (ARG2 != 0)
2695 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
2698 /* ---------------------------------------------------------------------
2699 fanotify_* wrappers
2700 ------------------------------------------------------------------ */
2702 PRE(sys_fanotify_init)
2704 PRINT("sys_fanotify_init ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
2705 ARG1, ARG2);
2706 PRE_REG_READ2(long, "fanotify_init",
2707 unsigned int, flags, unsigned int, event_f_flags);
2710 POST(sys_fanotify_init)
2712 vg_assert(SUCCESS);
2713 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
2714 VG_(close)(RES);
2715 SET_STATUS_Failure( VKI_EMFILE );
2716 } else {
2717 if (VG_(clo_track_fds))
2718 ML_(record_fd_open_nameless) (tid, RES);
2722 PRE(sys_fanotify_mark)
2724 #if VG_WORDSIZE == 4
2725 PRINT( "sys_fanotify_mark ( %ld, %" FMT_REGWORD "u, %llu, %ld, %#"
2726 FMT_REGWORD "x(%s))", SARG1, ARG2, MERGE64(ARG3,ARG4), SARG5, ARG6,
2727 (HChar *)(Addr)ARG6);
2728 PRE_REG_READ6(long, "sys_fanotify_mark",
2729 int, fanotify_fd, unsigned int, flags,
2730 __vki_u32, mask0, __vki_u32, mask1,
2731 int, dfd, const char *, pathname);
2732 if (ARG6)
2733 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
2734 #elif VG_WORDSIZE == 8
2735 PRINT( "sys_fanotify_mark ( %ld, %lu, %lu, %ld, %#lx(%s))",
2736 SARG1, ARG2, ARG3, SARG4, ARG5, (HChar *)(Addr)ARG5);
2737 PRE_REG_READ5(long, "sys_fanotify_mark",
2738 int, fanotify_fd, unsigned int, flags,
2739 __vki_u64, mask,
2740 int, dfd, const char *, pathname);
2741 if (ARG5)
2742 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
2743 #else
2744 # error Unexpected word size
2745 #endif
2748 /* ---------------------------------------------------------------------
2749 inotify_* wrappers
2750 ------------------------------------------------------------------ */
2752 PRE(sys_inotify_init)
2754 PRINT("sys_inotify_init ( )");
2755 PRE_REG_READ0(long, "inotify_init");
2757 POST(sys_inotify_init)
2759 vg_assert(SUCCESS);
2760 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2761 VG_(close)(RES);
2762 SET_STATUS_Failure( VKI_EMFILE );
2763 } else {
2764 if (VG_(clo_track_fds))
2765 ML_(record_fd_open_nameless) (tid, RES);
2769 PRE(sys_inotify_init1)
2771 PRINT("sys_inotify_init ( %ld )", SARG1);
2772 PRE_REG_READ1(long, "inotify_init", int, flag);
2775 POST(sys_inotify_init1)
2777 vg_assert(SUCCESS);
2778 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
2779 VG_(close)(RES);
2780 SET_STATUS_Failure( VKI_EMFILE );
2781 } else {
2782 if (VG_(clo_track_fds))
2783 ML_(record_fd_open_nameless) (tid, RES);
2787 PRE(sys_inotify_add_watch)
2789 PRINT( "sys_inotify_add_watch ( %ld, %#" FMT_REGWORD "x, %"
2790 FMT_REGWORD "x )", SARG1, ARG2, ARG3);
2791 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
2792 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
2795 PRE(sys_inotify_rm_watch)
2797 PRINT( "sys_inotify_rm_watch ( %ld, %" FMT_REGWORD "x )", SARG1, ARG2);
2798 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
2801 /* ---------------------------------------------------------------------
2802 mq_* wrappers
2803 ------------------------------------------------------------------ */
2805 PRE(sys_mq_open)
2807 PRINT("sys_mq_open( %#" FMT_REGWORD "x(%s), %ld, %" FMT_REGWORD "u, %#"
2808 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, ARG4);
2809 PRE_REG_READ4(long, "mq_open",
2810 const char *, name, int, oflag, vki_mode_t, mode,
2811 struct mq_attr *, attr);
2812 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2813 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2814 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG4;
2815 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2816 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2817 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2818 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2821 POST(sys_mq_open)
2823 vg_assert(SUCCESS);
2824 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2825 VG_(close)(RES);
2826 SET_STATUS_Failure( VKI_EMFILE );
2827 } else {
2828 if (VG_(clo_track_fds))
2829 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
2833 PRE(sys_mq_unlink)
2835 PRINT("sys_mq_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
2836 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2837 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2840 PRE(sys_mq_timedsend)
2842 *flags |= SfMayBlock;
2843 PRINT("sys_mq_timedsend ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2844 FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2845 SARG1,ARG2,ARG3,ARG4,ARG5);
2846 PRE_REG_READ5(long, "mq_timedsend",
2847 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2848 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2849 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2850 SET_STATUS_Failure( VKI_EBADF );
2851 } else {
2852 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2853 if (ARG5 != 0)
2854 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2855 sizeof(struct vki_timespec) );
2859 PRE(sys_mq_timedsend_time64)
2861 *flags |= SfMayBlock;
2862 PRINT("sys_mq_timedsend_time64 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
2863 "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
2864 SARG1,ARG2,ARG3,ARG4,ARG5);
2865 PRE_REG_READ5(long, "mq_timedsend_time64",
2866 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2867 unsigned int, msg_prio,
2868 const struct vki_timespec64 *, abs_timeout);
2869 if (!ML_(fd_allowed)(ARG1, "mq_timedsend_time64", tid, False)) {
2870 SET_STATUS_Failure( VKI_EBADF );
2871 } else {
2872 PRE_MEM_READ( "mq_timedsend_time64(msg_ptr)", ARG2, ARG3 );
2873 if (ARG5 != 0)
2874 pre_read_timespec64(tid, "mq_timedsend_time64(abs_timeout)", ARG5);
2878 PRE(sys_mq_timedreceive)
2880 *flags |= SfMayBlock;
2881 PRINT("sys_mq_timedreceive( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2882 FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2883 SARG1,ARG2,ARG3,ARG4,ARG5);
2884 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2885 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2886 unsigned int *, msg_prio,
2887 const struct timespec *, abs_timeout);
2888 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2889 SET_STATUS_Failure( VKI_EBADF );
2890 } else {
2891 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2892 if (ARG4 != 0)
2893 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2894 ARG4, sizeof(unsigned int) );
2895 if (ARG5 != 0)
2896 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2897 ARG5, sizeof(struct vki_timespec) );
2900 POST(sys_mq_timedreceive)
2902 POST_MEM_WRITE( ARG2, RES );
2903 if (ARG4 != 0)
2904 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2907 PRE(sys_mq_timedreceive_time64)
2909 *flags |= SfMayBlock;
2910 PRINT("sys_mq_timedreceive_time64( %ld, %#" FMT_REGWORD "x, %"
2911 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2912 SARG1,ARG2,ARG3,ARG4,ARG5);
2913 PRE_REG_READ5(ssize_t, "mq_timedreceive_time64",
2914 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2915 unsigned int *, msg_prio,
2916 const struct vki_timespec64 *, abs_timeout);
2917 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive_time64", tid, False)) {
2918 SET_STATUS_Failure( VKI_EBADF );
2919 } else {
2920 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_ptr)", ARG2, ARG3 );
2921 if (ARG4 != 0)
2922 PRE_MEM_WRITE( "mq_timedreceive_time64(msg_prio)",
2923 ARG4, sizeof(unsigned int) );
2924 if (ARG5 != 0)
2925 pre_read_timespec64(tid, "mq_timedreceive_time64(abs_timeout)", ARG5);
2929 POST(sys_mq_timedreceive_time64)
2931 POST_MEM_WRITE( ARG2, RES );
2932 if (ARG4 != 0)
2933 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2936 PRE(sys_mq_notify)
2938 PRINT("sys_mq_notify( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
2939 PRE_REG_READ2(long, "mq_notify",
2940 vki_mqd_t, mqdes, const struct sigevent *, notification);
2941 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2942 SET_STATUS_Failure( VKI_EBADF );
2943 else if (ARG2 != 0)
2944 PRE_MEM_READ( "mq_notify(notification)",
2945 ARG2, sizeof(struct vki_sigevent) );
2948 PRE(sys_mq_getsetattr)
2950 PRINT("sys_mq_getsetattr( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2951 SARG1, ARG2, ARG3 );
2952 PRE_REG_READ3(long, "mq_getsetattr",
2953 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2954 struct mq_attr *, omqstat);
2955 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2956 SET_STATUS_Failure( VKI_EBADF );
2957 } else {
2958 if (ARG2 != 0) {
2959 const struct vki_mq_attr *attr = (struct vki_mq_attr *)(Addr)ARG2;
2960 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2961 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2963 if (ARG3 != 0)
2964 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2965 sizeof(struct vki_mq_attr) );
2968 POST(sys_mq_getsetattr)
2970 if (ARG3 != 0)
2971 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2974 /* ---------------------------------------------------------------------
2975 clock_* wrappers
2976 ------------------------------------------------------------------ */
2978 PRE(sys_clock_settime)
2980 PRINT("sys_clock_settime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2981 PRE_REG_READ2(long, "clock_settime",
2982 vki_clockid_t, clk_id, const struct timespec *, tp);
2983 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2986 PRE(sys_clock_settime64)
2988 PRINT("sys_clock_settime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2989 PRE_REG_READ2(long, "clock_settime64",
2990 vki_clockid_t, clk_id, const struct timespec64 *, tp);
2991 pre_read_timespec64(tid, "clock_settime64(tp)", ARG2);
2994 PRE(sys_clock_gettime)
2996 PRINT("sys_clock_gettime( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
2997 PRE_REG_READ2(long, "clock_gettime",
2998 vki_clockid_t, clk_id, struct timespec *, tp);
2999 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
3001 POST(sys_clock_gettime)
3003 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3006 PRE(sys_clock_gettime64)
3008 PRINT("sys_clock_gettime64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3009 PRE_REG_READ2(long, "clock_gettime64",
3010 vki_clockid_t, clk_id, struct vki_timespec64 *, tp);
3011 PRE_MEM_WRITE ( "clock_gettime64(tp)", ARG2,
3012 sizeof(struct vki_timespec64) );
3014 POST(sys_clock_gettime64)
3016 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3019 PRE(sys_clock_getres)
3021 PRINT("sys_clock_getres( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3022 // Nb: we can't use "RES" as the param name because that's a macro
3023 // defined above!
3024 PRE_REG_READ2(long, "clock_getres",
3025 vki_clockid_t, clk_id, struct timespec *, res);
3026 if (ARG2 != 0)
3027 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
3029 POST(sys_clock_getres)
3031 if (ARG2 != 0)
3032 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
3035 PRE(sys_clock_getres_time64)
3037 PRINT("sys_clock_getres_time64( %ld, %#" FMT_REGWORD "x )" , SARG1, ARG2);
3038 // Nb: we can't use "RES" as the param name because that's a macro
3039 // defined above!
3040 PRE_REG_READ2(long, "clock_getres_time64",
3041 vki_clockid_t, clk_id, struct vki_timespec64 *, res);
3042 if (ARG2 != 0)
3043 PRE_MEM_WRITE( "clock_getres_time64(res)", ARG2,
3044 sizeof(struct vki_timespec64) );
3046 POST(sys_clock_getres_time64)
3048 if (ARG2 != 0)
3049 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec64) );
3052 PRE(sys_clock_nanosleep)
3054 *flags |= SfMayBlock|SfPostOnFail;
3055 PRINT("sys_clock_nanosleep( %ld, %ld, %#" FMT_REGWORD "x, %#"
3056 FMT_REGWORD "x )",
3057 SARG1, SARG2, ARG3, ARG4);
3058 PRE_REG_READ4(int32_t, "clock_nanosleep",
3059 vki_clockid_t, clkid, int, flags,
3060 const struct timespec *, rqtp, struct timespec *, rmtp);
3061 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
3062 if (ARG4 != 0)
3063 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
3065 POST(sys_clock_nanosleep)
3067 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3068 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
3071 PRE(sys_clock_nanosleep_time64)
3073 *flags |= SfMayBlock|SfPostOnFail;
3074 PRINT("sys_clock_nanosleep_time64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3075 FMT_REGWORD "x )",
3076 SARG1, SARG2, ARG3, ARG4);
3077 PRE_REG_READ4(int32_t, "clock_nanosleep_time64",
3078 vki_clockid_t, clkid, int, flags,
3079 const struct vki_timespec64 *, rqtp,
3080 struct vki_timespec64 *, rmtp);
3081 pre_read_timespec64(tid, "clock_nanosleep_time64(rqtp)", ARG3);
3082 if (ARG4 != 0)
3083 PRE_MEM_WRITE( "clock_nanosleep_time64(rmtp)", ARG4,
3084 sizeof(struct vki_timespec64) );
3086 POST(sys_clock_nanosleep_time64)
3088 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
3089 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec64) );
3092 /* ---------------------------------------------------------------------
3093 timer_* wrappers
3094 ------------------------------------------------------------------ */
3096 PRE(sys_timer_create)
3098 PRINT("sys_timer_create( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3099 SARG1, ARG2, ARG3);
3100 PRE_REG_READ3(long, "timer_create",
3101 vki_clockid_t, clockid, struct sigevent *, evp,
3102 vki_timer_t *, timerid);
3103 if (ARG2 != 0) {
3104 struct vki_sigevent *evp = (struct vki_sigevent *) (Addr)ARG2;
3105 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
3106 sizeof(vki_sigval_t) );
3107 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
3108 sizeof(int) );
3109 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
3110 sizeof(int) );
3111 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
3112 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
3113 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
3114 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
3116 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
3118 POST(sys_timer_create)
3120 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
3123 PRE(sys_timer_settime)
3125 PRINT("sys_timer_settime( %ld, %ld, %#" FMT_REGWORD "x, %#"
3126 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3127 PRE_REG_READ4(long, "timer_settime",
3128 vki_timer_t, timerid, int, flags,
3129 const struct itimerspec *, value,
3130 struct itimerspec *, ovalue);
3131 PRE_MEM_READ( "timer_settime(value)", ARG3,
3132 sizeof(struct vki_itimerspec) );
3133 if (ARG4 != 0)
3134 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
3135 sizeof(struct vki_itimerspec) );
3137 POST(sys_timer_settime)
3139 if (ARG4 != 0)
3140 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
3143 PRE(sys_timer_settime64)
3145 PRINT("sys_timer_settime64( %ld, %ld, %#" FMT_REGWORD "x, %#"
3146 FMT_REGWORD "x )", SARG1,SARG2,ARG3,ARG4);
3147 PRE_REG_READ4(long, "timer_settime64",
3148 vki_timer_t, timerid, int, flags,
3149 const struct vki_itimerspec64 *, value,
3150 struct vki_itimerspec64 *, ovalue);
3151 PRE_MEM_READ( "timer_settime64(value)", ARG3,
3152 sizeof(struct vki_itimerspec64) );
3153 if (ARG4 != 0)
3154 PRE_MEM_WRITE( "timer_settime64(ovalue)", ARG4,
3155 sizeof(struct vki_itimerspec64) );
3157 POST(sys_timer_settime64)
3159 if (ARG4 != 0)
3160 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec64) );
3163 PRE(sys_timer_gettime)
3165 PRINT("sys_timer_gettime( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3166 PRE_REG_READ2(long, "timer_gettime",
3167 vki_timer_t, timerid, struct itimerspec *, value);
3168 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
3169 sizeof(struct vki_itimerspec));
3171 POST(sys_timer_gettime)
3173 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
3176 PRE(sys_timer_gettime64)
3178 PRINT("sys_timer_gettime64( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3179 PRE_REG_READ2(long, "timer_gettime64",
3180 vki_timer_t, timerid, struct vki_itimerspec64 *, value);
3181 PRE_MEM_WRITE( "timer_gettime64(value)", ARG2,
3182 sizeof(struct vki_itimerspec64));
3184 POST(sys_timer_gettime64)
3186 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec64) );
3189 PRE(sys_timer_getoverrun)
3191 PRINT("sys_timer_getoverrun( %#" FMT_REGWORD "x )", ARG1);
3192 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
3195 PRE(sys_timer_delete)
3197 PRINT("sys_timer_delete( %#" FMT_REGWORD "x )", ARG1);
3198 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
3201 /* ---------------------------------------------------------------------
3202 timerfd* wrappers
3203 See also http://lwn.net/Articles/260172/ for an overview.
3204 See also /usr/src/linux/fs/timerfd.c for the implementation.
3205 ------------------------------------------------------------------ */
3207 /* Returns True if running on 2.6.22, else False (or False if
3208 cannot be determined). */
3209 static Bool linux_kernel_2_6_22(void)
3211 static Int result = -1;
3212 Int fd, read;
3213 HChar release[64]; // large enough
3214 SysRes res;
3216 if (result == -1) {
3217 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
3218 if (sr_isError(res))
3219 return False;
3220 fd = sr_Res(res);
3221 read = VG_(read)(fd, release, sizeof(release) - 1);
3222 if (read < 0)
3223 return False;
3224 release[read] = 0;
3225 VG_(close)(fd);
3226 //VG_(printf)("kernel release = %s\n", release);
3227 result = VG_(strncmp)(release, "2.6.22", 6) == 0
3228 && ! VG_(isdigit)(release[6]);
3230 vg_assert(result == 0 || result == 1);
3231 return result == 1;
3234 PRE(sys_timerfd_create)
3236 if (linux_kernel_2_6_22()) {
3237 /* 2.6.22 kernel: timerfd system call. */
3238 PRINT("sys_timerfd ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
3239 PRE_REG_READ3(long, "sys_timerfd",
3240 int, fd, int, clockid, const struct itimerspec *, tmr);
3241 PRE_MEM_READ("timerfd(tmr)", ARG3,
3242 sizeof(struct vki_itimerspec) );
3243 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
3244 SET_STATUS_Failure( VKI_EBADF );
3245 } else {
3246 /* 2.6.24 and later kernels: timerfd_create system call. */
3247 PRINT("sys_timerfd_create (%ld, %ld )", SARG1, SARG2);
3248 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
3251 POST(sys_timerfd_create)
3253 if (linux_kernel_2_6_22())
3255 /* 2.6.22 kernel: timerfd system call. */
3256 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
3257 VG_(close)(RES);
3258 SET_STATUS_Failure( VKI_EMFILE );
3259 } else {
3260 if (VG_(clo_track_fds))
3261 ML_(record_fd_open_nameless) (tid, RES);
3264 else
3266 /* 2.6.24 and later kernels: timerfd_create system call. */
3267 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
3268 VG_(close)(RES);
3269 SET_STATUS_Failure( VKI_EMFILE );
3270 } else {
3271 if (VG_(clo_track_fds))
3272 ML_(record_fd_open_nameless) (tid, RES);
3277 PRE(sys_timerfd_gettime)
3279 PRINT("sys_timerfd_gettime ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3280 PRE_REG_READ2(long, "timerfd_gettime",
3281 int, ufd,
3282 struct vki_itimerspec*, otmr);
3283 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
3284 SET_STATUS_Failure(VKI_EBADF);
3285 else
3286 PRE_MEM_WRITE("timerfd_gettime(result)",
3287 ARG2, sizeof(struct vki_itimerspec));
3289 POST(sys_timerfd_gettime)
3291 if (RES == 0)
3292 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
3295 PRE(sys_timerfd_gettime64)
3297 PRINT("sys_timerfd_gettime64 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3298 PRE_REG_READ2(long, "timerfd_gettime64",
3299 int, ufd,
3300 struct vki_itimerspec64*, otmr);
3301 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime64", tid, False))
3302 SET_STATUS_Failure(VKI_EBADF);
3303 else
3304 PRE_MEM_WRITE("timerfd_gettime64(result)",
3305 ARG2, sizeof(struct vki_itimerspec64));
3307 POST(sys_timerfd_gettime64)
3309 if (RES == 0)
3310 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec64));
3313 PRE(sys_timerfd_settime)
3315 PRINT("sys_timerfd_settime ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3316 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3317 PRE_REG_READ4(long, "timerfd_settime",
3318 int, ufd,
3319 int, flags,
3320 const struct vki_itimerspec*, utmr,
3321 struct vki_itimerspec*, otmr);
3322 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
3323 SET_STATUS_Failure(VKI_EBADF);
3324 else
3326 PRE_MEM_READ("timerfd_settime(result)",
3327 ARG3, sizeof(struct vki_itimerspec));
3328 if (ARG4)
3330 PRE_MEM_WRITE("timerfd_settime(result)",
3331 ARG4, sizeof(struct vki_itimerspec));
3335 POST(sys_timerfd_settime)
3337 if (RES == 0 && ARG4 != 0)
3338 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
3341 PRE(sys_timerfd_settime64)
3343 PRINT("sys_timerfd_settime64 ( %ld, %ld, %#" FMT_REGWORD "x, %#"
3344 FMT_REGWORD "x )", SARG1, SARG2, ARG3, ARG4);
3345 PRE_REG_READ4(long, "timerfd_settime64",
3346 int, ufd,
3347 int, flags,
3348 const struct vki_itimerspec64*, utmr,
3349 struct vki_itimerspec64*, otmr);
3350 if (!ML_(fd_allowed)(ARG1, "timerfd_settime64", tid, False))
3351 SET_STATUS_Failure(VKI_EBADF);
3352 else
3354 pre_read_itimerspec64 (tid, "timerfd_settime64(result)", ARG3);
3355 if (ARG4)
3357 PRE_MEM_WRITE("timerfd_settime64(result)",
3358 ARG4, sizeof(struct vki_itimerspec64));
3362 POST(sys_timerfd_settime64)
3364 if (RES == 0 && ARG4 != 0)
3365 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec64));
3368 /* ---------------------------------------------------------------------
3369 capabilities wrappers
3370 ------------------------------------------------------------------ */
3372 PRE(sys_capget)
3374 PRINT("sys_capget ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3375 PRE_REG_READ2(long, "capget",
3376 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
3377 PRE_MEM_READ( "capget(header)", ARG1,
3378 sizeof(struct __vki_user_cap_header_struct) );
3379 if (ARG2 != (Addr)NULL)
3380 PRE_MEM_WRITE( "capget(data)", ARG2,
3381 sizeof(struct __vki_user_cap_data_struct) );
3383 POST(sys_capget)
3385 if (ARG2 != (Addr)NULL)
3386 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
3389 PRE(sys_capset)
3391 PRINT("sys_capset ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2 );
3392 PRE_REG_READ2(long, "capset",
3393 vki_cap_user_header_t, header,
3394 const vki_cap_user_data_t, data);
3395 PRE_MEM_READ( "capset(header)",
3396 ARG1, sizeof(struct __vki_user_cap_header_struct) );
3397 PRE_MEM_READ( "capset(data)",
3398 ARG2, sizeof(struct __vki_user_cap_data_struct) );
3401 /* ---------------------------------------------------------------------
3402 16-bit uid/gid/groups wrappers
3403 ------------------------------------------------------------------ */
3405 PRE(sys_getuid16)
3407 PRINT("sys_getuid16 ( )");
3408 PRE_REG_READ0(long, "getuid16");
3411 PRE(sys_setuid16)
3413 PRINT("sys_setuid16 ( %" FMT_REGWORD "u )", ARG1);
3414 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
3417 PRE(sys_getgid16)
3419 PRINT("sys_getgid16 ( )");
3420 PRE_REG_READ0(long, "getgid16");
3423 PRE(sys_setgid16)
3425 PRINT("sys_setgid16 ( %" FMT_REGWORD "u )", ARG1);
3426 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
3429 PRE(sys_geteuid16)
3431 PRINT("sys_geteuid16 ( )");
3432 PRE_REG_READ0(long, "geteuid16");
3435 PRE(sys_getegid16)
3437 PRINT("sys_getegid16 ( )");
3438 PRE_REG_READ0(long, "getegid16");
3441 PRE(sys_setreuid16)
3443 PRINT("setreuid16 ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
3444 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
3447 PRE(sys_setregid16)
3449 PRINT("sys_setregid16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3450 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
3453 PRE(sys_getgroups16)
3455 PRINT("sys_getgroups16 ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3456 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
3457 if (ARG1 > 0)
3458 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3460 POST(sys_getgroups16)
3462 vg_assert(SUCCESS);
3463 if (ARG1 > 0 && RES > 0)
3464 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
3467 PRE(sys_setgroups16)
3469 PRINT("sys_setgroups16 ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
3470 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
3471 if (ARG1 > 0)
3472 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
3475 /* ---------------------------------------------------------------------
3476 *chown16 wrappers
3477 ------------------------------------------------------------------ */
3479 PRE(sys_chown16)
3481 PRINT("sys_chown16 ( %#" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, 0x%"
3482 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3483 PRE_REG_READ3(long, "chown16",
3484 const char *, path,
3485 vki_old_uid_t, owner, vki_old_gid_t, group);
3486 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
3489 PRE(sys_fchown16)
3491 PRINT("sys_fchown16 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3492 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3493 PRE_REG_READ3(long, "fchown16",
3494 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
3497 /* ---------------------------------------------------------------------
3498 *xattr wrappers
3499 ------------------------------------------------------------------ */
3501 PRE(sys_setxattr)
3503 *flags |= SfMayBlock;
3504 PRINT("sys_setxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3505 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, ARG2, ARG3,
3506 ARG4, SARG5);
3507 PRE_REG_READ5(long, "setxattr",
3508 char *, path, char *, name,
3509 void *, value, vki_size_t, size, int, flags);
3510 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
3511 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
3512 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
3515 PRE(sys_lsetxattr)
3517 *flags |= SfMayBlock;
3518 PRINT("sys_lsetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3519 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
3520 ARG1, ARG2, ARG3, ARG4, SARG5);
3521 PRE_REG_READ5(long, "lsetxattr",
3522 char *, path, char *, name,
3523 void *, value, vki_size_t, size, int, flags);
3524 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
3525 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
3526 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
3529 PRE(sys_fsetxattr)
3531 *flags |= SfMayBlock;
3532 PRINT("sys_fsetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3533 FMT_REGWORD "u, %ld )",
3534 SARG1, ARG2, ARG3, ARG4, SARG5);
3535 PRE_REG_READ5(long, "fsetxattr",
3536 int, fd, char *, name, void *, value,
3537 vki_size_t, size, int, flags);
3538 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
3539 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
3542 PRE(sys_getxattr)
3544 *flags |= SfMayBlock;
3545 PRINT("sys_getxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3546 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3547 PRE_REG_READ4(ssize_t, "getxattr",
3548 char *, path, char *, name, void *, value, vki_size_t, size);
3549 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
3550 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
3551 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
3553 POST(sys_getxattr)
3555 vg_assert(SUCCESS);
3556 if (RES > 0 && ARG3 != (Addr)NULL) {
3557 POST_MEM_WRITE( ARG3, RES );
3561 PRE(sys_lgetxattr)
3563 *flags |= SfMayBlock;
3564 PRINT("sys_lgetxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3565 FMT_REGWORD "x, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
3566 PRE_REG_READ4(ssize_t, "lgetxattr",
3567 char *, path, char *, name, void *, value, vki_size_t, size);
3568 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
3569 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
3570 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
3572 POST(sys_lgetxattr)
3574 vg_assert(SUCCESS);
3575 if (RES > 0 && ARG3 != (Addr)NULL) {
3576 POST_MEM_WRITE( ARG3, RES );
3580 PRE(sys_fgetxattr)
3582 *flags |= SfMayBlock;
3583 PRINT("sys_fgetxattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
3584 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
3585 PRE_REG_READ4(ssize_t, "fgetxattr",
3586 int, fd, char *, name, void *, value, vki_size_t, size);
3587 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
3588 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
3590 POST(sys_fgetxattr)
3592 if (RES > 0 && ARG3 != (Addr)NULL)
3593 POST_MEM_WRITE( ARG3, RES );
3596 PRE(sys_listxattr)
3598 *flags |= SfMayBlock;
3599 PRINT("sys_listxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3600 ARG1, ARG2, (ULong)ARG3);
3601 PRE_REG_READ3(ssize_t, "listxattr",
3602 char *, path, char *, list, vki_size_t, size);
3603 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
3604 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
3606 POST(sys_listxattr)
3608 if (RES > 0 && ARG2 != (Addr)NULL)
3609 POST_MEM_WRITE( ARG2, RES );
3612 PRE(sys_llistxattr)
3614 *flags |= SfMayBlock;
3615 PRINT("sys_llistxattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %llu )",
3616 ARG1, ARG2, (ULong)ARG3);
3617 PRE_REG_READ3(ssize_t, "llistxattr",
3618 char *, path, char *, list, vki_size_t, size);
3619 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
3620 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
3622 POST(sys_llistxattr)
3624 if (RES > 0 && ARG2 != (Addr)NULL)
3625 POST_MEM_WRITE( ARG2, RES );
3628 PRE(sys_flistxattr)
3630 *flags |= SfMayBlock;
3631 PRINT("sys_flistxattr ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
3632 SARG1, ARG2, ARG3);
3633 PRE_REG_READ3(ssize_t, "flistxattr",
3634 int, fd, char *, list, vki_size_t, size);
3635 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
3637 POST(sys_flistxattr)
3639 if (RES > 0 && ARG2 != (Addr)NULL)
3640 POST_MEM_WRITE( ARG2, RES );
3643 PRE(sys_removexattr)
3645 *flags |= SfMayBlock;
3646 PRINT("sys_removexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3647 ARG1, ARG2);
3648 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
3649 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
3650 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
3653 PRE(sys_lremovexattr)
3655 *flags |= SfMayBlock;
3656 PRINT("sys_lremovexattr ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3657 ARG1, ARG2);
3658 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
3659 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
3660 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
3663 PRE(sys_fremovexattr)
3665 *flags |= SfMayBlock;
3666 PRINT("sys_fremovexattr ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3667 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
3668 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
3671 /* ---------------------------------------------------------------------
3672 sched_* wrappers
3673 ------------------------------------------------------------------ */
3675 PRE(sys_sched_setparam)
3677 PRINT("sched_setparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3678 PRE_REG_READ2(long, "sched_setparam",
3679 vki_pid_t, pid, struct sched_param *, p);
3680 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
3682 POST(sys_sched_setparam)
3684 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3687 PRE(sys_sched_getparam)
3689 PRINT("sched_getparam ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2 );
3690 PRE_REG_READ2(long, "sched_getparam",
3691 vki_pid_t, pid, struct sched_param *, p);
3692 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
3694 POST(sys_sched_getparam)
3696 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
3699 PRE(sys_sched_setattr)
3701 struct vki_sched_attr *attr;
3702 PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#"
3703 FMT_REGWORD "x )", SARG1, ARG2, ARG3 );
3704 PRE_REG_READ3(long, "sched_setattr",
3705 vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags);
3706 /* We need to be able to read at least the size field. */
3707 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3708 attr = (struct vki_sched_attr *)(Addr)ARG2;
3709 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3710 PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size);
3713 PRE(sys_sched_getattr)
3715 struct vki_sched_attr *attr;
3716 PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
3717 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 );
3718 PRE_REG_READ4(long, "sched_getattr",
3719 vki_pid_t, pid, struct sched_attr *, p,
3720 unsigned int, size, unsigned int, flags);
3721 /* We need to be able to read at least the size field. */
3722 PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) );
3723 /* And the kernel needs to be able to write to the whole struct size. */
3724 attr = (struct vki_sched_attr *)(Addr)ARG2;
3725 if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t)))
3726 PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size);
3728 POST(sys_sched_getattr)
3730 struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2;
3731 POST_MEM_WRITE( (Addr)attr, attr->size );
3734 PRE(sys_sched_getscheduler)
3736 PRINT("sys_sched_getscheduler ( %ld )", SARG1);
3737 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
3740 PRE(sys_sched_setscheduler)
3742 PRINT("sys_sched_setscheduler ( %ld, %ld, %#" FMT_REGWORD "x )",
3743 SARG1, SARG2, ARG3);
3744 PRE_REG_READ3(long, "sched_setscheduler",
3745 vki_pid_t, pid, int, policy, struct sched_param *, p);
3746 if (ARG3 != 0)
3747 PRE_MEM_READ( "sched_setscheduler(p)",
3748 ARG3, sizeof(struct vki_sched_param));
3751 PRE(sys_sched_yield)
3753 *flags |= SfMayBlock;
3754 PRINT("sched_yield()");
3755 PRE_REG_READ0(long, "sys_sched_yield");
3758 PRE(sys_sched_get_priority_max)
3760 PRINT("sched_get_priority_max ( %ld )", SARG1);
3761 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
3764 PRE(sys_sched_get_priority_min)
3766 PRINT("sched_get_priority_min ( %ld )", SARG1);
3767 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
3770 PRE(sys_sched_rr_get_interval)
3772 PRINT("sys_sched_rr_get_interval ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3773 PRE_REG_READ2(int, "sched_rr_get_interval",
3774 vki_pid_t, pid,
3775 struct vki_timespec *, tp);
3776 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
3777 ARG2, sizeof(struct vki_timespec));
3780 POST(sys_sched_rr_get_interval)
3782 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
3785 PRE(sys_sched_rr_get_interval_time64)
3787 PRINT("sys_sched_rr_get_interval_time64 ( %ld, %#" FMT_REGWORD "x )",
3788 SARG1, ARG2);
3789 PRE_REG_READ2(int, "sched_rr_get_interval_time64",
3790 vki_pid_t, pid,
3791 struct vki_timespec *, tp);
3792 PRE_MEM_WRITE("sched_rr_get_interval_time64(timespec)",
3793 ARG2, sizeof(struct vki_timespec64));
3796 POST(sys_sched_rr_get_interval_time64)
3798 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec64));
3801 PRE(sys_sched_setaffinity)
3803 PRINT("sched_setaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3804 SARG1, ARG2, ARG3);
3805 PRE_REG_READ3(long, "sched_setaffinity",
3806 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3807 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
3810 PRE(sys_sched_getaffinity)
3812 PRINT("sched_getaffinity ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3813 SARG1, ARG2, ARG3);
3814 PRE_REG_READ3(long, "sched_getaffinity",
3815 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
3816 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
3818 POST(sys_sched_getaffinity)
3820 POST_MEM_WRITE(ARG3, ARG2);
3823 PRE(sys_unshare)
3825 PRINT("sys_unshare ( %#" FMT_REGWORD "x )", ARG1);
3826 PRE_REG_READ1(int, "unshare", unsigned long, flags);
3829 PRE(sys_setns)
3831 PRINT("sys_setns ( %ld, %ld )", SARG1, SARG2);
3832 PRE_REG_READ2(int, "setns",
3833 int, fd,
3834 int, nstype);
3835 if (!ML_(fd_allowed)(ARG1, "setns", tid, False))
3836 SET_STATUS_Failure( VKI_EBADF );
3840 /* ---------------------------------------------------------------------
3841 miscellaneous wrappers
3842 ------------------------------------------------------------------ */
3844 PRE(sys_munlockall)
3846 *flags |= SfMayBlock;
3847 PRINT("sys_munlockall ( )");
3848 PRE_REG_READ0(long, "munlockall");
3851 // This has different signatures for different platforms.
3853 // x86: int sys_pipe(unsigned long __user *fildes);
3854 // AMD64: long sys_pipe(int *fildes);
3855 // ppc32: int sys_pipe(int __user *fildes);
3856 // ppc64: int sys_pipe(int __user *fildes);
3858 // The type of the argument is most important, and it is an array of 32 bit
3859 // values in all cases. (The return type differs across platforms, but it
3860 // is not used.) So we use 'int' as its type. This fixed bug #113230 which
3861 // was caused by using an array of 'unsigned long's, which didn't work on
3862 // AMD64.
3863 PRE(sys_pipe)
3865 PRINT("sys_pipe ( %#" FMT_REGWORD "x )", ARG1);
3866 PRE_REG_READ1(int, "pipe", int *, filedes);
3867 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
3869 POST(sys_pipe)
3871 Int *p = (Int *)(Addr)ARG1;
3872 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
3873 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
3874 VG_(close)(p[0]);
3875 VG_(close)(p[1]);
3876 SET_STATUS_Failure( VKI_EMFILE );
3877 } else {
3878 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3879 if (VG_(clo_track_fds)) {
3880 ML_(record_fd_open_nameless)(tid, p[0]);
3881 ML_(record_fd_open_nameless)(tid, p[1]);
3886 /* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
3887 there's a second arg containing flags to be applied to the new file
3888 descriptors. It hardly seems worth the effort to factor out the
3889 duplicated code, hence: */
3890 PRE(sys_pipe2)
3892 PRINT("sys_pipe2 ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2);
3893 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
3894 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
3896 POST(sys_pipe2)
3898 Int *p = (Int *)(Addr)ARG1;
3899 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
3900 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
3901 VG_(close)(p[0]);
3902 VG_(close)(p[1]);
3903 SET_STATUS_Failure( VKI_EMFILE );
3904 } else {
3905 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
3906 if (VG_(clo_track_fds)) {
3907 ML_(record_fd_open_nameless)(tid, p[0]);
3908 ML_(record_fd_open_nameless)(tid, p[1]);
3913 PRE(sys_dup3)
3915 PRINT("sys_dup3 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3916 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3917 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
3918 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
3919 SET_STATUS_Failure( VKI_EBADF );
3922 POST(sys_dup3)
3924 vg_assert(SUCCESS);
3925 if (VG_(clo_track_fds))
3926 ML_(record_fd_open_named)(tid, RES);
3929 PRE(sys_quotactl)
3931 PRINT("sys_quotactl (0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x, 0x%"
3932 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4);
3933 PRE_REG_READ4(long, "quotactl",
3934 unsigned int, cmd, const char *, special, vki_qid_t, id,
3935 void *, addr);
3936 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
3939 PRE(sys_waitid)
3941 *flags |= SfMayBlock;
3942 PRINT("sys_waitid( %ld, %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
3943 SARG1, SARG2, ARG3, SARG4, ARG5);
3944 PRE_REG_READ5(int32_t, "sys_waitid",
3945 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
3946 int, options, struct vki_rusage *, ru);
3947 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
3948 if (ARG5 != 0)
3949 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
3951 POST(sys_waitid)
3953 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
3954 if (ARG5 != 0)
3955 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
3958 PRE(sys_sync_file_range)
3960 *flags |= SfMayBlock;
3961 #if VG_WORDSIZE == 4
3962 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %#" FMT_REGWORD "x )",
3963 SARG1, (Long)MERGE64(ARG2,ARG3), (Long)MERGE64(ARG4,ARG5),ARG6);
3964 PRE_REG_READ6(long, "sync_file_range",
3965 int, fd,
3966 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3967 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
3968 unsigned int, flags);
3969 #elif VG_WORDSIZE == 8
3970 PRINT("sys_sync_file_range ( %ld, %ld, %ld, %#lx )",
3971 SARG1, SARG2, SARG3, ARG4);
3972 PRE_REG_READ4(long, "sync_file_range",
3973 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
3974 unsigned int, flags);
3975 #else
3976 # error Unexpected word size
3977 #endif
3978 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
3979 SET_STATUS_Failure( VKI_EBADF );
3982 PRE(sys_sync_file_range2)
3984 *flags |= SfMayBlock;
3985 #if VG_WORDSIZE == 4
3986 PRINT("sys_sync_file_range2 ( %ld, %" FMT_REGWORD "u, %lld, %lld )",
3987 SARG1, ARG2, (Long)MERGE64(ARG3,ARG4), (Long)MERGE64(ARG5,ARG6));
3988 PRE_REG_READ6(long, "sync_file_range2",
3989 int, fd, unsigned int, flags,
3990 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
3991 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
3992 #elif VG_WORDSIZE == 8
3993 PRINT("sys_sync_file_range2 ( %ld, %lu, %ld, %ld )",
3994 SARG1, ARG2, SARG3, SARG4);
3995 PRE_REG_READ4(long, "sync_file_range2",
3996 int, fd, unsigned int, flags,
3997 vki_loff_t, offset, vki_loff_t, nbytes);
3998 #else
3999 # error Unexpected word size
4000 #endif
4001 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
4002 SET_STATUS_Failure( VKI_EBADF );
4005 PRE(sys_stime)
4007 PRINT("sys_stime ( %#" FMT_REGWORD "x )", ARG1);
4008 PRE_REG_READ1(int, "stime", vki_time_t*, t);
4009 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
4012 PRE(sys_perf_event_open)
4014 struct vki_perf_event_attr *attr;
4015 PRINT("sys_perf_event_open ( %#" FMT_REGWORD "x, %ld, %ld, %ld, %#"
4016 FMT_REGWORD "x )", ARG1, SARG2, SARG3, SARG4, ARG5);
4017 PRE_REG_READ5(long, "perf_event_open",
4018 struct vki_perf_event_attr *, attr,
4019 vki_pid_t, pid, int, cpu, int, group_fd,
4020 unsigned long, flags);
4021 attr = (struct vki_perf_event_attr *)(Addr)ARG1;
4022 PRE_MEM_READ( "perf_event_open(attr->size)",
4023 (Addr)&attr->size, sizeof(attr->size) );
4024 PRE_MEM_READ( "perf_event_open(attr)",
4025 (Addr)attr, attr->size );
4028 POST(sys_perf_event_open)
4030 vg_assert(SUCCESS);
4031 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
4032 VG_(close)(RES);
4033 SET_STATUS_Failure( VKI_EMFILE );
4034 } else {
4035 if (VG_(clo_track_fds))
4036 ML_(record_fd_open_nameless)(tid, RES);
4040 PRE(sys_getcpu)
4042 PRINT("sys_getcpu ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4043 FMT_REGWORD "x )" , ARG1, ARG2, ARG3);
4044 PRE_REG_READ3(int, "getcpu",
4045 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
4046 if (ARG1 != 0)
4047 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
4048 if (ARG2 != 0)
4049 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
4050 if (ARG3 != 0)
4051 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
4054 POST(sys_getcpu)
4056 if (ARG1 != 0)
4057 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
4058 if (ARG2 != 0)
4059 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
4060 if (ARG3 != 0)
4061 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
4064 PRE(sys_move_pages)
4066 PRINT("sys_move_pages ( %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#"
4067 FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4068 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4069 PRE_REG_READ6(int, "move_pages",
4070 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
4071 const int *, nodes, int *, status, int, flags);
4072 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
4073 if (ARG4)
4074 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
4075 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
4078 POST(sys_move_pages)
4080 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
4083 PRE(sys_getrandom)
4085 PRINT("sys_getrandom ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4086 FMT_REGWORD "u )" , ARG1, ARG2, ARG3);
4087 PRE_REG_READ3(int, "getrandom",
4088 char *, buf, vki_size_t, count, unsigned int, flags);
4089 PRE_MEM_WRITE( "getrandom(cpu)", ARG1, ARG2 );
4092 POST(sys_getrandom)
4094 POST_MEM_WRITE( ARG1, ARG2 );
4097 PRE(sys_memfd_create)
4099 PRINT("sys_memfd_create ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )" ,
4100 ARG1, ARG2);
4101 PRE_REG_READ2(int, "memfd_create",
4102 char *, uname, unsigned int, flags);
4103 PRE_MEM_RASCIIZ( "memfd_create(uname)", ARG1 );
4106 POST(sys_memfd_create)
4108 vg_assert(SUCCESS);
4109 if (!ML_(fd_allowed)(RES, "memfd_create", tid, True)) {
4110 VG_(close)(RES);
4111 SET_STATUS_Failure( VKI_EMFILE );
4112 } else {
4113 if (VG_(clo_track_fds))
4114 ML_(record_fd_open_nameless)(tid, RES);
4118 PRE(sys_membarrier)
4120 PRINT("sys_membarrier ( %#" FMT_REGWORD "x )", ARG1);
4121 PRE_REG_READ1(int, "membarrier", int, flags);
4124 PRE(sys_syncfs)
4126 *flags |= SfMayBlock;
4127 PRINT("sys_syncfs ( %" FMT_REGWORD "u )", ARG1);
4128 PRE_REG_READ1(long, "syncfs", unsigned int, fd);
4131 PRE(sys_statx)
4133 FUSE_COMPATIBLE_MAY_BLOCK();
4134 PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
4135 (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5);
4136 PRE_REG_READ5(long, "statx",
4137 int, dirfd, char *, filename, int, flags,
4138 unsigned int, mask, struct statx *, buf);
4139 // Work around Rust's dubious use of statx, as described here:
4140 // https://github.com/rust-lang/rust/blob/
4141 // ccd238309f9dce92a05a23c2959e2819668c69a4/
4142 // src/libstd/sys/unix/fs.rs#L128-L142
4143 // in which it passes NULL for both filename and buf, and then looks at the
4144 // return value, so as to determine whether or not this syscall is supported.
4145 Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0;
4146 if (!both_filename_and_buf_are_null) {
4147 PRE_MEM_RASCIIZ( "statx(filename)", ARG2 );
4148 PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
4151 POST(sys_statx)
4153 POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
4156 /* ---------------------------------------------------------------------
4157 utime wrapper
4158 ------------------------------------------------------------------ */
4160 PRE(sys_utime)
4162 *flags |= SfMayBlock;
4163 PRINT("sys_utime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4164 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
4165 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4166 if (ARG2 != 0)
4167 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
4170 /* ---------------------------------------------------------------------
4171 lseek wrapper
4172 ------------------------------------------------------------------ */
4174 PRE(sys_lseek)
4176 PRINT("sys_lseek ( %" FMT_REGWORD "u, %ld, %" FMT_REGWORD "u )",
4177 ARG1, SARG2, ARG3);
4178 PRE_REG_READ3(vki_off_t, "lseek",
4179 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
4182 /* ---------------------------------------------------------------------
4183 readahead wrapper
4184 ------------------------------------------------------------------ */
4186 PRE(sys_readahead)
4188 *flags |= SfMayBlock;
4189 #if VG_WORDSIZE == 4
4190 PRINT("sys_readahead ( %ld, %lld, %" FMT_REGWORD "u )",
4191 SARG1, (Long)MERGE64(ARG2,ARG3), ARG4);
4192 PRE_REG_READ4(vki_off_t, "readahead",
4193 int, fd, unsigned, MERGE64_FIRST(offset),
4194 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
4195 #elif VG_WORDSIZE == 8
4196 PRINT("sys_readahead ( %ld, %ld, %lu )", SARG1, SARG2, ARG3);
4197 PRE_REG_READ3(vki_off_t, "readahead",
4198 int, fd, vki_loff_t, offset, vki_size_t, count);
4199 #else
4200 # error Unexpected word size
4201 #endif
4202 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
4203 SET_STATUS_Failure( VKI_EBADF );
4206 /* ---------------------------------------------------------------------
4207 sig* wrappers
4208 ------------------------------------------------------------------ */
4210 PRE(sys_sigpending)
4212 PRINT( "sys_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4213 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
4214 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
4216 POST(sys_sigpending)
4218 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
4221 // This syscall is not used on amd64/Linux -- it only provides
4222 // sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
4223 // This wrapper is only suitable for 32-bit architectures.
4224 // (XXX: so how is it that PRE(sys_sigpending) above doesn't need
4225 // conditional compilation like this?)
4226 #if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
4227 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
4228 || defined(VGP_nanomips_linux)
4229 PRE(sys_sigprocmask)
4231 vki_old_sigset_t* set;
4232 vki_old_sigset_t* oldset;
4233 vki_sigset_t bigger_set;
4234 vki_sigset_t bigger_oldset;
4236 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4237 PRE_REG_READ3(long, "sigprocmask",
4238 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
4239 if (ARG2 != 0)
4240 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
4241 if (ARG3 != 0)
4242 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
4244 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
4245 // vki_sigset_t params.
4246 set = (vki_old_sigset_t*)(Addr)ARG2;
4247 oldset = (vki_old_sigset_t*)(Addr)ARG3;
4249 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
4250 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
4251 if (set)
4252 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
4254 SET_STATUS_from_SysRes(
4255 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4256 set ? &bigger_set : NULL,
4257 oldset ? &bigger_oldset : NULL)
4260 if (oldset)
4261 *oldset = bigger_oldset.sig[0];
4263 if (SUCCESS)
4264 *flags |= SfPollAfter;
4266 POST(sys_sigprocmask)
4268 vg_assert(SUCCESS);
4269 if (RES == 0 && ARG3 != 0)
4270 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
4273 /* Convert from non-RT to RT sigset_t's */
4274 static
4275 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
4277 VG_(sigemptyset)(set);
4278 set->sig[0] = *oldset;
4280 PRE(sys_sigaction)
4282 vki_sigaction_toK_t new, *newp;
4283 vki_sigaction_fromK_t old, *oldp;
4285 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
4286 PRE_REG_READ3(int, "sigaction",
4287 int, signum, const struct old_sigaction *, act,
4288 struct old_sigaction *, oldact);
4290 newp = oldp = NULL;
4292 if (ARG2 != 0) {
4293 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)(Addr)ARG2;
4294 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4295 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4296 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4297 if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
4298 && (sa->sa_flags & VKI_SA_RESTORER))
4299 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4302 if (ARG3 != 0) {
4303 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
4304 oldp = &old;
4307 /* If the new or old sigaction is not NULL, but the structs
4308 aren't accessible then sigaction returns EFAULT and we cannot
4309 use either struct for our own bookkeeping. Just fail early. */
4310 if (ARG2 != 0
4311 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4312 sizeof(struct vki_old_sigaction))) {
4313 VG_(umsg)("Warning: bad act handler address %p in sigaction()\n",
4314 (void *)(Addr)ARG2);
4315 SET_STATUS_Failure ( VKI_EFAULT );
4316 } else if ((ARG3 != 0
4317 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4318 sizeof(struct vki_old_sigaction)))) {
4319 VG_(umsg)("Warning: bad oldact handler address %p in sigaction()\n",
4320 (void *)(Addr)ARG3);
4321 SET_STATUS_Failure ( VKI_EFAULT );
4322 } else {
4323 if (ARG2 != 0) {
4324 struct vki_old_sigaction *oldnew =
4325 (struct vki_old_sigaction *)(Addr)ARG2;
4327 new.ksa_handler = oldnew->ksa_handler;
4328 new.sa_flags = oldnew->sa_flags;
4329 new.sa_restorer = oldnew->sa_restorer;
4330 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
4331 newp = &new;
4334 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
4336 if (ARG3 != 0 && SUCCESS && RES == 0) {
4337 struct vki_old_sigaction *oldold =
4338 (struct vki_old_sigaction *)(Addr)ARG3;
4340 oldold->ksa_handler = oldp->ksa_handler;
4341 oldold->sa_flags = oldp->sa_flags;
4342 oldold->sa_restorer = oldp->sa_restorer;
4343 oldold->sa_mask = oldp->sa_mask.sig[0];
4347 POST(sys_sigaction)
4349 vg_assert(SUCCESS);
4350 if (RES == 0 && ARG3 != 0)
4351 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
4353 #endif
4355 PRE(sys_signalfd)
4357 PRINT("sys_signalfd ( %d, %#" FMT_REGWORD "x, %llu )", (Int)ARG1, ARG2,
4358 (ULong)ARG3);
4359 PRE_REG_READ3(long, "sys_signalfd",
4360 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
4361 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4362 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4363 SET_STATUS_Failure( VKI_EBADF );
4365 POST(sys_signalfd)
4367 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
4368 VG_(close)(RES);
4369 SET_STATUS_Failure( VKI_EMFILE );
4370 } else {
4371 if (VG_(clo_track_fds))
4372 ML_(record_fd_open_nameless) (tid, RES);
4376 PRE(sys_signalfd4)
4378 PRINT("sys_signalfd4 ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
4379 SARG1, ARG2, ARG3, SARG4);
4380 PRE_REG_READ4(long, "sys_signalfd4",
4381 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
4382 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
4383 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
4384 SET_STATUS_Failure( VKI_EBADF );
4386 POST(sys_signalfd4)
4388 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
4389 VG_(close)(RES);
4390 SET_STATUS_Failure( VKI_EMFILE );
4391 } else {
4392 if (VG_(clo_track_fds))
4393 ML_(record_fd_open_nameless) (tid, RES);
4398 /* ---------------------------------------------------------------------
4399 rt_sig* wrappers
4400 ------------------------------------------------------------------ */
4402 PRE(sys_rt_sigaction)
4404 PRINT("sys_rt_sigaction ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4405 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4406 PRE_REG_READ4(long, "rt_sigaction",
4407 int, signum, const struct sigaction *, act,
4408 struct sigaction *, oldact, vki_size_t, sigsetsize);
4410 if (ARG2 != 0) {
4411 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)(Addr)ARG2;
4412 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
4413 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
4414 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
4415 if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
4416 && (sa->sa_flags & VKI_SA_RESTORER))
4417 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
4419 if (ARG3 != 0)
4420 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
4422 /* If the new or old sigaction is not NULL, but the structs
4423 aren't accessible then sigaction returns EFAULT and we cannot
4424 use either struct for our own bookkeeping. Just fail early. */
4425 if (ARG2 != 0
4426 && ! ML_(safe_to_deref)((void *)(Addr)ARG2,
4427 sizeof(vki_sigaction_toK_t))) {
4428 VG_(umsg)("Warning: bad act handler address %p in rt_sigaction()\n",
4429 (void *)(Addr)ARG2);
4430 SET_STATUS_Failure ( VKI_EFAULT );
4431 } else if ((ARG3 != 0
4432 && ! ML_(safe_to_deref)((void *)(Addr)ARG3,
4433 sizeof(vki_sigaction_fromK_t)))) {
4434 VG_(umsg)("Warning: bad oldact handler address %p in rt_sigaction()\n",
4435 (void *)(Addr)ARG3);
4436 SET_STATUS_Failure ( VKI_EFAULT );
4437 } else {
4439 // XXX: doesn't seem right to be calling do_sys_sigaction for
4440 // sys_rt_sigaction... perhaps this function should be renamed
4441 // VG_(do_sys_rt_sigaction)() --njn
4443 SET_STATUS_from_SysRes(
4444 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)(Addr)ARG2,
4445 (vki_sigaction_fromK_t *)(Addr)ARG3)
4449 POST(sys_rt_sigaction)
4451 vg_assert(SUCCESS);
4452 if (RES == 0 && ARG3 != 0)
4453 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
4456 PRE(sys_rt_sigprocmask)
4458 PRINT("sys_rt_sigprocmask ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %"
4459 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
4460 PRE_REG_READ4(long, "rt_sigprocmask",
4461 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
4462 vki_size_t, sigsetsize);
4463 if (ARG2 != 0)
4464 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
4465 if (ARG3 != 0)
4466 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
4468 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
4469 // Since we want to use the set and oldset for bookkeeping we also want
4470 // to make sure they are addressable otherwise, like the kernel, we EFAULT.
4471 if (sizeof(vki_sigset_t) != ARG4)
4472 SET_STATUS_Failure( VKI_EINVAL );
4473 else if (ARG2 != 0
4474 && ! ML_(safe_to_deref)((void *)(Addr)ARG2, sizeof(vki_sigset_t))) {
4475 VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
4476 (void *)(Addr)ARG2);
4477 SET_STATUS_Failure ( VKI_EFAULT );
4479 else if (ARG3 != 0
4480 && ! ML_(safe_to_deref)((void *)(Addr)ARG3, sizeof(vki_sigset_t))) {
4481 VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
4482 (void *)(Addr)ARG3);
4483 SET_STATUS_Failure ( VKI_EFAULT );
4486 else {
4487 SET_STATUS_from_SysRes(
4488 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
4489 (vki_sigset_t*) (Addr)ARG2,
4490 (vki_sigset_t*) (Addr)ARG3 )
4494 if (SUCCESS)
4495 *flags |= SfPollAfter;
4497 POST(sys_rt_sigprocmask)
4499 vg_assert(SUCCESS);
4500 if (RES == 0 && ARG3 != 0)
4501 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
4504 PRE(sys_rt_sigpending)
4506 PRINT( "sys_rt_sigpending ( %#" FMT_REGWORD "x )", ARG1 );
4507 PRE_REG_READ2(long, "rt_sigpending",
4508 vki_sigset_t *, set, vki_size_t, sigsetsize);
4509 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
4511 POST(sys_rt_sigpending)
4513 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
4516 PRE(sys_rt_sigtimedwait)
4518 *flags |= SfMayBlock;
4519 PRINT("sys_rt_sigtimedwait ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4520 FMT_REGWORD "x, %" FMT_REGWORD "u )",
4521 ARG1, ARG2, ARG3, ARG4);
4522 PRE_REG_READ4(long, "rt_sigtimedwait",
4523 const vki_sigset_t *, set, vki_siginfo_t *, info,
4524 const struct timespec *, timeout, vki_size_t, sigsetsize);
4525 if (ARG1 != 0)
4526 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
4527 if (ARG2 != 0)
4528 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
4529 if (ARG3 != 0)
4530 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
4531 ARG3, sizeof(struct vki_timespec) );
4533 POST(sys_rt_sigtimedwait)
4535 if (ARG2 != 0)
4536 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4539 PRE(sys_rt_sigtimedwait_time64)
4541 *flags |= SfMayBlock;
4542 PRINT("sys_rt_sigtimedwait_time64 ( %#" FMT_REGWORD "x, %#"
4543 FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4544 ARG1, ARG2, ARG3, ARG4);
4545 PRE_REG_READ4(long, "rt_sigtimedwait_time64",
4546 const vki_sigset_t *, set, vki_siginfo_t *, info,
4547 const struct vki_timespec64 *, timeout,
4548 vki_size_t, sigsetsize);
4549 if (ARG1 != 0)
4550 PRE_MEM_READ( "rt_sigtimedwait_time64(set)", ARG1, sizeof(vki_sigset_t) );
4551 if (ARG2 != 0)
4552 PRE_MEM_WRITE( "rt_sigtimedwait_time64(info)", ARG2,
4553 sizeof(vki_siginfo_t) );
4554 if (ARG3 != 0)
4555 pre_read_timespec64(tid, "rt_sigtimedwait_time64(timeout)", ARG3);
4557 POST(sys_rt_sigtimedwait_time64)
4559 if (ARG2 != 0)
4560 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
4563 PRE(sys_rt_sigqueueinfo)
4565 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#" FMT_REGWORD "x)",
4566 SARG1, SARG2, ARG3);
4567 PRE_REG_READ3(long, "rt_sigqueueinfo",
4568 int, pid, int, sig, vki_siginfo_t *, uinfo);
4569 if (ARG2 != 0)
4570 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
4572 POST(sys_rt_sigqueueinfo)
4574 if (!ML_(client_signal_OK)(ARG2))
4575 SET_STATUS_Failure( VKI_EINVAL );
4578 PRE(sys_rt_tgsigqueueinfo)
4580 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#" FMT_REGWORD "x)",
4581 SARG1, SARG2, SARG3, ARG4);
4582 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
4583 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
4584 if (ARG3 != 0)
4585 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
4588 POST(sys_rt_tgsigqueueinfo)
4590 if (!ML_(client_signal_OK)(ARG3))
4591 SET_STATUS_Failure( VKI_EINVAL );
4594 // XXX: x86-specific? The kernel prototypes for the different archs are
4595 // hard to decipher.
4596 PRE(sys_rt_sigsuspend)
4598 /* The C library interface to sigsuspend just takes a pointer to
4599 a signal mask but this system call has two arguments - a pointer
4600 to the mask and the number of bytes used by it. The kernel insists
4601 on the size being equal to sizeof(sigset_t) however and will just
4602 return EINVAL if it isn't.
4604 *flags |= SfMayBlock;
4605 PRINT("sys_rt_sigsuspend ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4606 ARG1, ARG2 );
4607 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
4608 if (ARG1 != (Addr)NULL) {
4609 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
4610 if (ML_(safe_to_deref)((vki_sigset_t *) (Addr)ARG1, sizeof(vki_sigset_t))) {
4611 VG_(sigdelset)((vki_sigset_t *) (Addr)ARG1, VG_SIGVGKILL);
4612 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4613 be killable by VG_(nuke_all_threads_except).
4614 We thus silently ignore the user request to mask this signal.
4615 Note that this is similar to what is done for e.g.
4616 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4617 } else {
4618 SET_STATUS_Failure(VKI_EFAULT);
4623 /* ---------------------------------------------------------------------
4624 linux msg* wrapper helpers
4625 ------------------------------------------------------------------ */
4627 void
4628 ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
4629 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
4631 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
4632 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4633 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4634 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4637 void
4638 ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
4639 UWord arg0, UWord arg1, UWord arg2,
4640 UWord arg3, UWord arg4 )
4642 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
4643 long msgtyp, int msgflg); */
4644 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4645 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4646 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
4648 void
4649 ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
4650 UWord res,
4651 UWord arg0, UWord arg1, UWord arg2,
4652 UWord arg3, UWord arg4 )
4654 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
4655 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
4656 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
4659 void
4660 ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
4661 UWord arg0, UWord arg1, UWord arg2 )
4663 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
4664 switch (arg1 /* cmd */) {
4665 case VKI_IPC_INFO:
4666 case VKI_MSG_INFO:
4667 case VKI_IPC_INFO|VKI_IPC_64:
4668 case VKI_MSG_INFO|VKI_IPC_64:
4669 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
4670 arg2, sizeof(struct vki_msginfo) );
4671 break;
4672 case VKI_IPC_STAT:
4673 case VKI_MSG_STAT:
4674 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
4675 arg2, sizeof(struct vki_msqid_ds) );
4676 break;
4677 case VKI_IPC_STAT|VKI_IPC_64:
4678 case VKI_MSG_STAT|VKI_IPC_64:
4679 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
4680 arg2, sizeof(struct vki_msqid64_ds) );
4681 break;
4682 case VKI_IPC_SET:
4683 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4684 arg2, sizeof(struct vki_msqid_ds) );
4685 break;
4686 case VKI_IPC_SET|VKI_IPC_64:
4687 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
4688 arg2, sizeof(struct vki_msqid64_ds) );
4689 break;
4692 void
4693 ML_(linux_POST_sys_msgctl) ( ThreadId tid,
4694 UWord res,
4695 UWord arg0, UWord arg1, UWord arg2 )
4697 switch (arg1 /* cmd */) {
4698 case VKI_IPC_INFO:
4699 case VKI_MSG_INFO:
4700 case VKI_IPC_INFO|VKI_IPC_64:
4701 case VKI_MSG_INFO|VKI_IPC_64:
4702 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
4703 break;
4704 case VKI_IPC_STAT:
4705 case VKI_MSG_STAT:
4706 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
4707 break;
4708 case VKI_IPC_STAT|VKI_IPC_64:
4709 case VKI_MSG_STAT|VKI_IPC_64:
4710 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
4711 break;
4715 /* ---------------------------------------------------------------------
4716 Generic handler for sys_ipc
4717 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
4718 are either direct system calls, or are all implemented via sys_ipc.
4719 ------------------------------------------------------------------ */
4720 #ifdef __NR_ipc
4721 static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
4723 Addr* a_p = (Addr*)a;
4724 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
4725 return *a_p;
4728 static Bool semctl_cmd_has_4args (UWord cmd)
4730 switch (cmd & ~VKI_IPC_64)
4732 case VKI_IPC_INFO:
4733 case VKI_SEM_INFO:
4734 case VKI_IPC_STAT:
4735 case VKI_SEM_STAT:
4736 case VKI_IPC_SET:
4737 case VKI_GETALL:
4738 case VKI_SETALL:
4739 return True;
4740 default:
4741 return False;
4745 PRE(sys_ipc)
4747 PRINT("sys_ipc ( %lu, %ld, %ld, %ld, %#lx, %ld )",
4748 ARG1, SARG2, SARG3, SARG4, ARG5, SARG6);
4750 switch (ARG1 /* call */) {
4751 case VKI_SEMOP:
4752 PRE_REG_READ5(int, "ipc",
4753 vki_uint, call, int, first, int, second, int, third,
4754 void *, ptr);
4755 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
4756 *flags |= SfMayBlock;
4757 break;
4758 case VKI_SEMGET:
4759 PRE_REG_READ4(int, "ipc",
4760 vki_uint, call, int, first, int, second, int, third);
4761 break;
4762 case VKI_SEMCTL:
4764 PRE_REG_READ5(int, "ipc",
4765 vki_uint, call, int, first, int, second, int, third,
4766 void *, ptr);
4767 UWord arg;
4768 if (semctl_cmd_has_4args(ARG4))
4769 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4770 else
4771 arg = 0;
4772 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
4773 break;
4775 case VKI_SEMTIMEDOP:
4776 PRE_REG_READ6(int, "ipc",
4777 vki_uint, call, int, first, int, second, int, third,
4778 void *, ptr, long, fifth);
4779 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
4780 *flags |= SfMayBlock;
4781 break;
4782 case VKI_MSGSND:
4783 PRE_REG_READ5(int, "ipc",
4784 vki_uint, call, int, first, int, second, int, third,
4785 void *, ptr);
4786 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
4787 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4788 *flags |= SfMayBlock;
4789 break;
4790 case VKI_MSGRCV:
4792 PRE_REG_READ5(int, "ipc",
4793 vki_uint, call, int, first, int, second, int, third,
4794 void *, ptr);
4795 Addr msgp;
4796 Word msgtyp;
4798 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4799 "msgrcv(msgp)" );
4800 msgtyp = deref_Addr( tid,
4801 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4802 "msgrcv(msgp)" );
4804 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
4806 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
4807 *flags |= SfMayBlock;
4808 break;
4810 case VKI_MSGGET:
4811 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
4812 break;
4813 case VKI_MSGCTL:
4814 PRE_REG_READ5(int, "ipc",
4815 vki_uint, call, int, first, int, second, int, third,
4816 void *, ptr);
4817 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
4818 break;
4819 case VKI_SHMAT:
4821 PRE_REG_READ5(int, "ipc",
4822 vki_uint, call, int, first, int, second, int, third,
4823 void *, ptr);
4824 UWord w;
4825 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
4826 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
4827 if (w == 0)
4828 SET_STATUS_Failure( VKI_EINVAL );
4829 else
4830 ARG5 = w;
4831 break;
4833 case VKI_SHMDT:
4834 PRE_REG_READ5(int, "ipc",
4835 vki_uint, call, int, first, int, second, int, third,
4836 void *, ptr);
4837 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
4838 SET_STATUS_Failure( VKI_EINVAL );
4839 break;
4840 case VKI_SHMGET:
4841 PRE_REG_READ4(int, "ipc",
4842 vki_uint, call, int, first, int, second, int, third);
4843 if (ARG4 & VKI_SHM_HUGETLB) {
4844 static Bool warning_given = False;
4845 ARG4 &= ~VKI_SHM_HUGETLB;
4846 if (!warning_given) {
4847 warning_given = True;
4848 VG_(umsg)(
4849 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
4852 break;
4853 case VKI_SHMCTL: /* IPCOP_shmctl */
4854 PRE_REG_READ5(int, "ipc",
4855 vki_uint, call, int, first, int, second, int, third,
4856 void *, ptr);
4857 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
4858 break;
4859 default:
4860 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %lu\n", ARG1 );
4861 VG_(core_panic)("... bye!\n");
4862 break; /*NOTREACHED*/
4866 POST(sys_ipc)
4868 vg_assert(SUCCESS);
4869 switch (ARG1 /* call */) {
4870 case VKI_SEMOP:
4871 case VKI_SEMGET:
4872 break;
4873 case VKI_SEMCTL:
4875 UWord arg;
4876 if (semctl_cmd_has_4args(ARG4))
4877 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
4878 else
4879 arg = 0;
4880 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
4881 break;
4883 case VKI_SEMTIMEDOP:
4884 case VKI_MSGSND:
4885 break;
4886 case VKI_MSGRCV:
4888 Addr msgp;
4889 Word msgtyp;
4891 msgp = deref_Addr( tid,
4892 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgp),
4893 "msgrcv(msgp)" );
4894 msgtyp = deref_Addr( tid,
4895 (Addr) (&((struct vki_ipc_kludge *)(Addr)ARG5)->msgtyp),
4896 "msgrcv(msgp)" );
4898 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
4899 break;
4901 case VKI_MSGGET:
4902 break;
4903 case VKI_MSGCTL:
4904 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
4905 break;
4906 case VKI_SHMAT:
4908 Addr addr;
4910 /* force readability. before the syscall it is
4911 * indeed uninitialized, as can be seen in
4912 * glibc/sysdeps/unix/sysv/linux/shmat.c */
4913 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
4915 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
4916 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
4917 break;
4919 case VKI_SHMDT:
4920 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
4921 break;
4922 case VKI_SHMGET:
4923 break;
4924 case VKI_SHMCTL:
4925 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
4926 break;
4927 default:
4928 VG_(message)(Vg_DebugMsg,
4929 "FATAL: unhandled syscall(ipc) %lu\n",
4930 ARG1 );
4931 VG_(core_panic)("... bye!\n");
4932 break; /*NOTREACHED*/
4935 #endif
4937 PRE(sys_semget)
4939 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4940 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
4943 PRE(sys_semop)
4945 *flags |= SfMayBlock;
4946 PRINT("sys_semop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
4947 SARG1, ARG2, ARG3);
4948 PRE_REG_READ3(long, "semop",
4949 int, semid, struct sembuf *, sops, unsigned, nsoops);
4950 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
4953 PRE(sys_semctl)
4955 switch (ARG3 & ~VKI_IPC_64) {
4956 case VKI_IPC_INFO:
4957 case VKI_SEM_INFO:
4958 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4959 SARG3, ARG4);
4960 PRE_REG_READ4(long, "semctl",
4961 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
4962 break;
4963 case VKI_IPC_STAT:
4964 case VKI_SEM_STAT:
4965 case VKI_IPC_SET:
4966 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4967 SARG3, ARG4);
4968 PRE_REG_READ4(long, "semctl",
4969 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
4970 break;
4971 case VKI_GETALL:
4972 case VKI_SETALL:
4973 PRINT("sys_semctl ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
4974 SARG3, ARG4);
4975 PRE_REG_READ4(long, "semctl",
4976 int, semid, int, semnum, int, cmd, unsigned short *, arg);
4977 break;
4978 default:
4979 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
4980 PRE_REG_READ3(long, "semctl",
4981 int, semid, int, semnum, int, cmd);
4982 break;
4984 #ifdef VGP_amd64_linux
4985 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4986 #else
4987 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
4988 #endif
4991 POST(sys_semctl)
4993 #ifdef VGP_amd64_linux
4994 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
4995 #else
4996 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
4997 #endif
5000 PRE(sys_semtimedop)
5002 *flags |= SfMayBlock;
5003 PRINT("sys_semtimedop ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5004 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5005 PRE_REG_READ4(long, "semtimedop",
5006 int, semid, struct sembuf *, sops, unsigned, nsoops,
5007 struct timespec *, timeout);
5008 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
5011 PRE(sys_semtimedop_time64)
5013 *flags |= SfMayBlock;
5014 PRINT("sys_semtimedop_time64 ( %ld, %#" FMT_REGWORD "x, %"
5015 FMT_REGWORD "u, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5016 PRE_REG_READ4(long, "semtimedop_time64",
5017 int, semid, struct sembuf *, sops, unsigned, nsoops,
5018 struct vki_timespec64 *, timeout);
5019 PRE_MEM_READ( "semtimedop_time64(sops)", ARG1,
5020 ARG2 * sizeof(struct vki_sembuf) );
5021 if (ARG3 != 0)
5022 pre_read_timespec64(tid, "semtimedop_time64(timeout)", ARG3);
5025 PRE(sys_msgget)
5027 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
5028 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
5031 PRE(sys_msgsnd)
5033 PRINT("sys_msgsnd ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
5034 SARG1, ARG2, ARG3, SARG4);
5035 PRE_REG_READ4(long, "msgsnd",
5036 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
5037 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
5038 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
5039 *flags |= SfMayBlock;
5042 PRE(sys_msgrcv)
5044 PRINT("sys_msgrcv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld, %ld )",
5045 SARG1, ARG2, ARG3, SARG4, SARG5);
5046 PRE_REG_READ5(long, "msgrcv",
5047 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
5048 long, msgytp, int, msgflg);
5049 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5050 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
5051 *flags |= SfMayBlock;
5053 POST(sys_msgrcv)
5055 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
5058 PRE(sys_msgctl)
5060 PRINT("sys_msgctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5061 PRE_REG_READ3(long, "msgctl",
5062 int, msqid, int, cmd, struct msqid_ds *, buf);
5063 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
5066 POST(sys_msgctl)
5068 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
5071 PRE(sys_shmget)
5073 PRINT("sys_shmget ( %ld, %" FMT_REGWORD "u, %ld )", SARG1, ARG2, SARG3);
5074 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
5075 if (ARG3 & VKI_SHM_HUGETLB) {
5076 static Bool warning_given = False;
5077 ARG3 &= ~VKI_SHM_HUGETLB;
5078 if (!warning_given) {
5079 warning_given = True;
5080 VG_(umsg)(
5081 "WARNING: valgrind ignores shmget(shmflg) SHM_HUGETLB\n");
5086 PRE(sys_shmat)
5088 UWord arg2tmp;
5089 PRINT("sys_shmat ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5090 PRE_REG_READ3(long, "shmat",
5091 int, shmid, const void *, shmaddr, int, shmflg);
5092 #if defined(VGP_arm_linux)
5093 /* Round the attach address down to an VKI_SHMLBA boundary if the
5094 client requested rounding. See #222545. This is necessary only
5095 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
5096 other linux targets it is the same as the page size. */
5097 if (ARG3 & VKI_SHM_RND)
5098 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
5099 #endif
5100 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
5101 if (arg2tmp == 0)
5102 SET_STATUS_Failure( VKI_EINVAL );
5103 else
5104 ARG2 = arg2tmp; // used in POST
5107 POST(sys_shmat)
5109 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
5112 PRE(sys_shmdt)
5114 PRINT("sys_shmdt ( %#" FMT_REGWORD "x )",ARG1);
5115 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
5116 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
5117 SET_STATUS_Failure( VKI_EINVAL );
5120 POST(sys_shmdt)
5122 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
5125 PRE(sys_shmctl)
5127 PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3);
5128 PRE_REG_READ3(long, "shmctl",
5129 int, shmid, int, cmd, struct shmid_ds *, buf);
5130 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5131 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
5132 #else
5133 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
5134 #endif
5137 POST(sys_shmctl)
5139 #if defined(VGP_amd64_linux) || defined(VGP_arm64_linux)
5140 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
5141 #else
5142 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
5143 #endif
5147 /* ---------------------------------------------------------------------
5148 Generic handler for sys_socketcall
5149 Depending on the platform, some socket related syscalls (e.g. socketpair,
5150 socket, bind, ...)
5151 are either direct system calls, or are all implemented via sys_socketcall.
5152 ------------------------------------------------------------------ */
5153 #ifdef __NR_socketcall
5154 PRE(sys_socketcall)
5156 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5157 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5158 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5159 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5160 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5161 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5163 // call PRE_MEM_READ and check for EFAULT result.
5164 #define PRE_MEM_READ_ef(msg, arg, size) \
5166 PRE_MEM_READ( msg, arg, size); \
5167 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
5168 SET_STATUS_Failure( VKI_EFAULT ); \
5169 break; \
5173 *flags |= SfMayBlock;
5174 PRINT("sys_socketcall ( %ld, %#lx )", SARG1, ARG2);
5175 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5177 switch (ARG1 /* request */) {
5179 case VKI_SYS_SOCKETPAIR:
5180 /* int socketpair(int d, int type, int protocol, int sv[2]); */
5181 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
5182 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5183 break;
5185 case VKI_SYS_SOCKET:
5186 /* int socket(int domain, int type, int protocol); */
5187 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
5188 break;
5190 case VKI_SYS_BIND:
5191 /* int bind(int sockfd, struct sockaddr *my_addr,
5192 int addrlen); */
5193 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
5194 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
5195 break;
5197 case VKI_SYS_LISTEN:
5198 /* int listen(int s, int backlog); */
5199 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
5200 break;
5202 case VKI_SYS_ACCEPT:
5203 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5204 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
5205 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5206 break;
5208 case VKI_SYS_ACCEPT4:
5209 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5210 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
5211 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
5212 break;
5214 case VKI_SYS_SENDTO:
5215 /* int sendto(int s, const void *msg, int len,
5216 unsigned int flags,
5217 const struct sockaddr *to, int tolen); */
5218 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
5219 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
5220 ARG2_3, ARG2_4, ARG2_5 );
5221 break;
5223 case VKI_SYS_SEND:
5224 /* int send(int s, const void *msg, size_t len, int flags); */
5225 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
5226 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
5227 break;
5229 case VKI_SYS_RECVFROM:
5230 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5231 struct sockaddr *from, int *fromlen); */
5232 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
5233 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
5234 ARG2_3, ARG2_4, ARG2_5 );
5235 break;
5237 case VKI_SYS_RECV:
5238 /* int recv(int s, void *buf, int len, unsigned int flags); */
5239 /* man 2 recv says:
5240 The recv call is normally used only on a connected socket
5241 (see connect(2)) and is identical to recvfrom with a NULL
5242 from parameter.
5244 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
5245 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
5246 break;
5248 case VKI_SYS_CONNECT:
5249 /* int connect(int sockfd,
5250 struct sockaddr *serv_addr, int addrlen ); */
5251 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
5252 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
5253 break;
5255 case VKI_SYS_SETSOCKOPT:
5256 /* int setsockopt(int s, int level, int optname,
5257 const void *optval, int optlen); */
5258 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
5259 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5260 ARG2_3, ARG2_4 );
5261 break;
5263 case VKI_SYS_GETSOCKOPT:
5264 /* int getsockopt(int s, int level, int optname,
5265 void *optval, socklen_t *optlen); */
5266 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
5267 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
5268 ARG2_3, ARG2_4 );
5269 break;
5271 case VKI_SYS_GETSOCKNAME:
5272 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
5273 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
5274 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
5275 break;
5277 case VKI_SYS_GETPEERNAME:
5278 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
5279 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
5280 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
5281 break;
5283 case VKI_SYS_SHUTDOWN:
5284 /* int shutdown(int s, int how); */
5285 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
5286 break;
5288 case VKI_SYS_SENDMSG:
5289 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5290 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
5291 ML_(generic_PRE_sys_sendmsg)( tid, "msg",
5292 (struct vki_msghdr *)(Addr)ARG2_1 );
5293 break;
5295 case VKI_SYS_RECVMSG:
5296 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5297 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
5298 ML_(generic_PRE_sys_recvmsg)( tid, "msg",
5299 (struct vki_msghdr *)(Addr)ARG2_1 );
5300 break;
5302 case VKI_SYS_RECVMMSG:
5303 /* int recvmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags,
5304 struct timespec *timeout); */
5305 PRE_MEM_READ_ef("socketcall.recvmmsg(args)", ARG2, 5*sizeof(Addr) );
5306 ML_(linux_PRE_sys_recvmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3,
5307 ARG2_4 );
5308 break;
5310 case VKI_SYS_SENDMMSG:
5311 /* int sendmmsg(int s, struct mmsghdr *mmsg, int vlen, int flags); */
5312 PRE_MEM_READ_ef("socketcall.sendmmsg(args)", ARG2, 4*sizeof(Addr) );
5313 ML_(linux_PRE_sys_sendmmsg)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5314 break;
5316 default:
5317 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
5318 SET_STATUS_Failure( VKI_EINVAL );
5319 break;
5321 # undef ARG2_0
5322 # undef ARG2_1
5323 # undef ARG2_2
5324 # undef ARG2_3
5325 # undef ARG2_4
5326 # undef ARG2_5
5329 POST(sys_socketcall)
5331 # define ARG2_0 (((UWord*)(Addr)ARG2)[0])
5332 # define ARG2_1 (((UWord*)(Addr)ARG2)[1])
5333 # define ARG2_2 (((UWord*)(Addr)ARG2)[2])
5334 # define ARG2_3 (((UWord*)(Addr)ARG2)[3])
5335 # define ARG2_4 (((UWord*)(Addr)ARG2)[4])
5336 # define ARG2_5 (((UWord*)(Addr)ARG2)[5])
5338 SysRes r;
5339 vg_assert(SUCCESS);
5340 switch (ARG1 /* request */) {
5342 case VKI_SYS_SOCKETPAIR:
5343 r = ML_(generic_POST_sys_socketpair)(
5344 tid, VG_(mk_SysRes_Success)(RES),
5345 ARG2_0, ARG2_1, ARG2_2, ARG2_3
5347 SET_STATUS_from_SysRes(r);
5348 break;
5350 case VKI_SYS_SOCKET:
5351 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
5352 SET_STATUS_from_SysRes(r);
5353 break;
5355 case VKI_SYS_BIND:
5356 /* int bind(int sockfd, struct sockaddr *my_addr,
5357 int addrlen); */
5358 break;
5360 case VKI_SYS_LISTEN:
5361 /* int listen(int s, int backlog); */
5362 break;
5364 case VKI_SYS_ACCEPT:
5365 case VKI_SYS_ACCEPT4:
5366 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
5367 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
5368 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
5369 ARG2_0, ARG2_1, ARG2_2 );
5370 SET_STATUS_from_SysRes(r);
5371 break;
5373 case VKI_SYS_SENDTO:
5374 break;
5376 case VKI_SYS_SEND:
5377 break;
5379 case VKI_SYS_RECVFROM:
5380 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
5381 ARG2_0, ARG2_1, ARG2_2,
5382 ARG2_3, ARG2_4, ARG2_5 );
5383 break;
5385 case VKI_SYS_RECV:
5386 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
5387 break;
5389 case VKI_SYS_CONNECT:
5390 break;
5392 case VKI_SYS_SETSOCKOPT:
5393 break;
5395 case VKI_SYS_GETSOCKOPT:
5396 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
5397 ARG2_0, ARG2_1,
5398 ARG2_2, ARG2_3, ARG2_4 );
5399 break;
5401 case VKI_SYS_GETSOCKNAME:
5402 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
5403 ARG2_0, ARG2_1, ARG2_2 );
5404 break;
5406 case VKI_SYS_GETPEERNAME:
5407 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
5408 ARG2_0, ARG2_1, ARG2_2 );
5409 break;
5411 case VKI_SYS_SHUTDOWN:
5412 break;
5414 case VKI_SYS_SENDMSG:
5415 break;
5417 case VKI_SYS_RECVMSG:
5418 ML_(generic_POST_sys_recvmsg)( tid, "msg",
5419 (struct vki_msghdr *)(Addr)ARG2_1, RES );
5420 break;
5422 case VKI_SYS_RECVMMSG:
5423 ML_(linux_POST_sys_recvmmsg)( tid, RES,
5424 ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4 );
5425 break;
5427 case VKI_SYS_SENDMMSG:
5428 ML_(linux_POST_sys_sendmmsg)( tid, RES, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
5429 break;
5431 default:
5432 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
5433 VG_(core_panic)("... bye!\n");
5434 break; /*NOTREACHED*/
5436 # undef ARG2_0
5437 # undef ARG2_1
5438 # undef ARG2_2
5439 # undef ARG2_3
5440 # undef ARG2_4
5441 # undef ARG2_5
5443 #endif
5445 PRE(sys_socket)
5447 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
5448 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
5450 POST(sys_socket)
5452 SysRes r;
5453 vg_assert(SUCCESS);
5454 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
5455 SET_STATUS_from_SysRes(r);
5458 PRE(sys_setsockopt)
5460 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
5461 "u )", SARG1, SARG2, SARG3, ARG4, ARG5);
5462 PRE_REG_READ5(long, "setsockopt",
5463 int, s, int, level, int, optname,
5464 const void *, optval, unsigned, optlen); // socklen_t
5465 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5468 PRE(sys_getsockopt)
5470 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#" FMT_REGWORD "x, %ld )",
5471 SARG1, SARG2, SARG3, ARG4, SARG5);
5472 PRE_REG_READ5(long, "getsockopt",
5473 int, s, int, level, int, optname,
5474 void *, optval, int, *optlen);
5475 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
5477 POST(sys_getsockopt)
5479 vg_assert(SUCCESS);
5480 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
5481 ARG1,ARG2,ARG3,ARG4,ARG5);
5484 PRE(sys_connect)
5486 *flags |= SfMayBlock;
5487 PRINT("sys_connect ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5488 PRE_REG_READ3(long, "connect",
5489 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
5490 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
5493 PRE(sys_accept)
5495 *flags |= SfMayBlock;
5496 PRINT("sys_accept ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5497 SARG1, ARG2, ARG3);
5498 PRE_REG_READ3(long, "accept",
5499 int, s, struct sockaddr *, addr, int *, addrlen);
5500 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5502 POST(sys_accept)
5504 SysRes r;
5505 vg_assert(SUCCESS);
5506 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5507 ARG1,ARG2,ARG3);
5508 SET_STATUS_from_SysRes(r);
5511 PRE(sys_accept4)
5513 *flags |= SfMayBlock;
5514 PRINT("sys_accept4 ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )",
5515 SARG1, ARG2, ARG3, SARG4);
5516 PRE_REG_READ4(long, "accept4",
5517 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
5518 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
5520 POST(sys_accept4)
5522 SysRes r;
5523 vg_assert(SUCCESS);
5524 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
5525 ARG1,ARG2,ARG3);
5526 SET_STATUS_from_SysRes(r);
5529 PRE(sys_send)
5531 *flags |= SfMayBlock;
5532 PRINT("sys_send ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
5533 FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4);
5534 PRE_REG_READ4(long, "send",
5535 int, s, const void *, msg, vki_size_t, len,
5536 int, flags);
5538 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
5541 PRE(sys_sendto)
5543 *flags |= SfMayBlock;
5544 PRINT("sys_sendto ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5545 FMT_REGWORD "u, %#" FMT_REGWORD "x, %ld )",
5546 SARG1, ARG2, ARG3, ARG4, ARG5, SARG6);
5547 PRE_REG_READ6(long, "sendto",
5548 int, s, const void *, msg, vki_size_t, len,
5549 unsigned int, flags,
5550 const struct sockaddr *, to, int, tolen);
5551 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5554 PRE (sys_recv)
5556 *flags |= SfMayBlock;
5557 PRINT ("sys_recv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5558 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
5559 PRE_REG_READ4 (long, "recv", int, s, void *, buf, vki_size_t, len,
5560 unsigned int, flags);
5561 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
5564 POST (sys_recv)
5566 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
5569 PRE(sys_recvfrom)
5571 *flags |= SfMayBlock;
5572 PRINT("sys_recvfrom ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
5573 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5574 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
5575 PRE_REG_READ6(long, "recvfrom",
5576 int, s, void *, buf, vki_size_t, len, unsigned int, flags,
5577 struct sockaddr *, from, int *, fromlen);
5578 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5580 POST(sys_recvfrom)
5582 vg_assert(SUCCESS);
5583 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
5584 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
5587 PRE(sys_sendmsg)
5589 *flags |= SfMayBlock;
5590 PRINT("sys_sendmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5591 SARG1, ARG2, ARG3);
5592 PRE_REG_READ3(long, "sendmsg",
5593 int, s, const struct msghdr *, msg, unsigned int, flags);
5594 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5597 PRE(sys_recvmsg)
5599 *flags |= SfMayBlock;
5600 PRINT("sys_recvmsg ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
5601 SARG1, ARG2, ARG3);
5602 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg,
5603 unsigned int, flags);
5604 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2);
5606 POST(sys_recvmsg)
5608 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)(Addr)ARG2,
5609 RES);
5612 PRE(sys_shutdown)
5614 *flags |= SfMayBlock;
5615 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
5616 PRE_REG_READ2(int, "shutdown", int, s, int, how);
5619 PRE(sys_bind)
5621 PRINT("sys_bind ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5622 PRE_REG_READ3(long, "bind",
5623 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
5624 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
5627 PRE(sys_listen)
5629 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
5630 PRE_REG_READ2(long, "listen", int, s, int, backlog);
5633 PRE(sys_getsockname)
5635 PRINT("sys_getsockname ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5636 SARG1, ARG2, ARG3);
5637 PRE_REG_READ3(long, "getsockname",
5638 int, s, struct sockaddr *, name, int *, namelen);
5639 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
5641 POST(sys_getsockname)
5643 vg_assert(SUCCESS);
5644 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
5645 ARG1,ARG2,ARG3);
5648 PRE(sys_getpeername)
5650 PRINT("sys_getpeername ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
5651 SARG1, ARG2, ARG3);
5652 PRE_REG_READ3(long, "getpeername",
5653 int, s, struct sockaddr *, name, int *, namelen);
5654 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
5656 POST(sys_getpeername)
5658 vg_assert(SUCCESS);
5659 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
5660 ARG1,ARG2,ARG3);
5663 PRE(sys_socketpair)
5665 PRINT("sys_socketpair ( %ld, %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2,
5666 SARG3, ARG4);
5667 PRE_REG_READ4(long, "socketpair",
5668 int, d, int, type, int, protocol, int*, sv);
5669 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
5671 POST(sys_socketpair)
5673 vg_assert(SUCCESS);
5674 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
5675 ARG1,ARG2,ARG3,ARG4);
5679 /* ---------------------------------------------------------------------
5680 *at wrappers
5681 ------------------------------------------------------------------ */
5683 PRE(sys_openat)
5685 HChar name[30]; // large enough
5686 SysRes sres;
5688 if (ARG3 & VKI_O_CREAT) {
5689 // 4-arg version
5690 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
5691 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
5692 PRE_REG_READ4(long, "openat",
5693 int, dfd, const char *, filename, int, flags, int, mode);
5694 } else {
5695 // 3-arg version
5696 PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5697 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5698 PRE_REG_READ3(long, "openat",
5699 int, dfd, const char *, filename, int, flags);
5702 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
5704 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
5705 filename is relative to cwd. When comparing dfd against AT_FDCWD,
5706 be sure only to compare the bottom 32 bits. */
5707 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5708 && *(Char *)(Addr)ARG2 != '/'
5709 && ((Int)ARG1) != ((Int)VKI_AT_FDCWD)
5710 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
5711 SET_STATUS_Failure( VKI_EBADF );
5713 /* Handle the case where the open is of /proc/self/cmdline or
5714 /proc/<pid>/cmdline, and just give it a copy of the fd for the
5715 fake file we cooked up at startup (in m_main). Also, seek the
5716 cloned fd back to the start. */
5718 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
5719 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5720 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5721 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/cmdline") == 0)) {
5722 sres = VG_(dup)( VG_(cl_cmdline_fd) );
5723 SET_STATUS_from_SysRes( sres );
5724 if (!sr_isError(sres)) {
5725 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5726 if (off < 0)
5727 SET_STATUS_Failure( VKI_EMFILE );
5729 return;
5732 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
5734 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
5735 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5736 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5737 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/auxv") == 0)) {
5738 sres = VG_(dup)( VG_(cl_auxv_fd) );
5739 SET_STATUS_from_SysRes( sres );
5740 if (!sr_isError(sres)) {
5741 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5742 if (off < 0)
5743 SET_STATUS_Failure( VKI_EMFILE );
5745 return;
5748 /* And for /proc/self/exe or /proc/<pid>/exe case. */
5750 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5751 if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 )
5752 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5753 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5754 sres = VG_(dup)( VG_(cl_exec_fd) );
5755 SET_STATUS_from_SysRes( sres );
5756 if (!sr_isError(sres)) {
5757 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
5758 if (off < 0)
5759 SET_STATUS_Failure( VKI_EMFILE );
5761 return;
5764 /* Otherwise handle normally */
5765 *flags |= SfMayBlock;
5768 POST(sys_openat)
5770 vg_assert(SUCCESS);
5771 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
5772 VG_(close)(RES);
5773 SET_STATUS_Failure( VKI_EMFILE );
5774 } else {
5775 if (VG_(clo_track_fds))
5776 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
5780 PRE(sys_mkdirat)
5782 *flags |= SfMayBlock;
5783 PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
5784 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
5785 PRE_REG_READ3(long, "mkdirat",
5786 int, dfd, const char *, pathname, int, mode);
5787 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
5790 PRE(sys_mknodat)
5792 PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5793 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 );
5794 PRE_REG_READ4(long, "mknodat",
5795 int, dfd, const char *, pathname, int, mode, unsigned, dev);
5796 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
5799 PRE(sys_fchownat)
5801 PRINT("sys_fchownat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
5802 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5803 PRE_REG_READ4(long, "fchownat",
5804 int, dfd, const char *, path,
5805 vki_uid_t, owner, vki_gid_t, group);
5806 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
5809 PRE(sys_futimesat)
5811 PRINT("sys_futimesat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5812 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5813 PRE_REG_READ3(long, "futimesat",
5814 int, dfd, char *, filename, struct timeval *, tvp);
5815 if (ARG2 != 0)
5816 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
5817 if (ARG3 != 0)
5818 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
5821 PRE(sys_utimensat)
5823 PRINT("sys_utimensat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, 0x%"
5824 FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5825 PRE_REG_READ4(long, "utimensat",
5826 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5827 if (ARG2 != 0)
5828 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
5829 if (ARG3 != 0) {
5830 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5831 then the tv_sec field is ignored. */
5832 struct vki_timespec *times = (struct vki_timespec *)(Addr)ARG3;
5833 PRE_MEM_READ( "utimensat(times[0].tv_nsec)",
5834 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5835 PRE_MEM_READ( "utimensat(times[1].tv_nsec)",
5836 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5837 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec))) {
5838 if (times[0].tv_nsec != VKI_UTIME_NOW
5839 && times[0].tv_nsec != VKI_UTIME_OMIT)
5840 PRE_MEM_READ( "utimensat(times[0].tv_sec)",
5841 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5842 if (times[1].tv_nsec != VKI_UTIME_NOW
5843 && times[1].tv_nsec != VKI_UTIME_OMIT)
5844 PRE_MEM_READ( "utimensat(times[1].tv_sec)",
5845 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5850 PRE(sys_utimensat_time64)
5852 PRINT("sys_utimensat_time64 ( %ld, %#" FMT_REGWORD "x(%s), %#"
5853 FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
5854 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5855 PRE_REG_READ4(long, "utimensat_time64",
5856 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
5857 if (ARG2 != 0)
5858 PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 );
5859 if (ARG3 != 0) {
5860 /* If timespec.tv_nsec has the special value UTIME_NOW or UTIME_OMIT
5861 then the tv_sec field is ignored. */
5862 struct vki_timespec64 *times = (struct vki_timespec64 *)(Addr)ARG3;
5863 PRE_MEM_READ( "utimensat_time64(times[0].tv_nsec)",
5864 (Addr)&times[0].tv_nsec, sizeof(times[0].tv_nsec));
5865 PRE_MEM_READ( "utimensat_time64(times[1].tv_nsec)",
5866 (Addr)&times[1].tv_nsec, sizeof(times[1].tv_nsec));
5867 if (ML_(safe_to_deref)(times, 2 * sizeof(struct vki_timespec64))) {
5868 if (times[0].tv_nsec != VKI_UTIME_NOW
5869 && times[0].tv_nsec != VKI_UTIME_OMIT)
5870 PRE_MEM_READ( "utimensat_time64(times[0].tv_sec)",
5871 (Addr)&times[0].tv_sec, sizeof(times[0].tv_sec));
5872 if (times[1].tv_nsec != VKI_UTIME_NOW
5873 && times[1].tv_nsec != VKI_UTIME_OMIT)
5874 PRE_MEM_READ( "utimensat_time64(times[1].tv_sec)",
5875 (Addr)&times[1].tv_sec, sizeof(times[1].tv_sec));
5880 #if !defined(VGP_nanomips_linux)
5881 PRE(sys_newfstatat)
5883 FUSE_COMPATIBLE_MAY_BLOCK();
5884 PRINT("sys_newfstatat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5885 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5886 PRE_REG_READ3(long, "fstatat",
5887 int, dfd, char *, file_name, struct stat *, buf);
5888 // See the comment about Rust in PRE(sys_statx). When glibc does support
5889 // statx rust uses that instead of the system call, but glibc's statx is
5890 // implemented in terms of fstatat, so the filename being NULL is
5891 // transferred here.
5892 if (ARG2 != 0) {
5893 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
5894 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
5898 POST(sys_newfstatat)
5900 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
5902 #endif
5904 PRE(sys_unlinkat)
5906 *flags |= SfMayBlock;
5907 PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2,
5908 (HChar*)(Addr)ARG2);
5909 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
5910 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
5913 PRE(sys_renameat)
5915 PRINT("sys_renameat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#"
5916 FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5917 ARG4, (HChar*)(Addr)ARG4);
5918 PRE_REG_READ4(long, "renameat",
5919 int, olddfd, const char *, oldpath,
5920 int, newdfd, const char *, newpath);
5921 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
5922 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
5925 PRE(sys_renameat2)
5927 PRINT("sys_renameat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5928 "x(%s), %" FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3,
5929 ARG4, (HChar*)(Addr)ARG4, ARG5);
5930 PRE_REG_READ5(long, "renameat2",
5931 int, olddfd, const char *, oldpath,
5932 int, newdfd, const char *, newpath,
5933 unsigned int, flags);
5934 PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 );
5935 PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 );
5938 PRE(sys_linkat)
5940 *flags |= SfMayBlock;
5941 PRINT("sys_linkat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5942 "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4,
5943 (HChar*)(Addr)ARG4, SARG5);
5944 PRE_REG_READ5(long, "linkat",
5945 int, olddfd, const char *, oldpath,
5946 int, newdfd, const char *, newpath,
5947 int, flags);
5948 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
5949 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
5952 PRE(sys_symlinkat)
5954 *flags |= SfMayBlock;
5955 PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %ld, %#" FMT_REGWORD
5956 "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3);
5957 PRE_REG_READ3(long, "symlinkat",
5958 const char *, oldpath, int, newdfd, const char *, newpath);
5959 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
5960 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
5963 PRE(sys_readlinkat)
5965 HChar name[30]; // large enough
5966 Word saved = SYSNO;
5968 PRINT("sys_readlinkat ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %"
5969 FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
5970 PRE_REG_READ4(long, "readlinkat",
5971 int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz);
5972 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
5973 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
5976 * Handle the case where readlinkat is looking at /proc/self/exe or
5977 * /proc/<pid>/exe.
5979 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
5980 if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1)
5981 && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0
5982 || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) {
5983 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5984 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
5985 ARG3, ARG4));
5986 } else {
5987 /* Normal case */
5988 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
5991 if (SUCCESS && RES > 0)
5992 POST_MEM_WRITE( ARG3, RES );
5995 PRE(sys_fchmodat)
5997 PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
5998 SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
5999 PRE_REG_READ3(long, "fchmodat",
6000 int, dfd, const char *, path, vki_mode_t, mode);
6001 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
6004 PRE(sys_faccessat)
6006 PRINT("sys_faccessat ( %ld, %#" FMT_REGWORD "x(%s), %ld )",
6007 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3);
6008 PRE_REG_READ3(long, "faccessat",
6009 int, dfd, const char *, pathname, int, mode);
6010 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
6013 PRE(sys_faccessat2)
6015 PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )",
6016 SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4);
6017 PRE_REG_READ4(long, "faccessat2",
6018 int, dfd, const char *, pathname, int, mode, int, flags);
6019 PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 );
6022 PRE(sys_name_to_handle_at)
6024 PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#"
6025 FMT_REGWORD "x, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2,
6026 (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6027 PRE_REG_READ5(int, "name_to_handle_at",
6028 int, dfd, const char *, name,
6029 struct vki_file_handle *, handle,
6030 int *, mnt_id, int, flag);
6031 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
6032 if (ML_(safe_to_deref)( (void*)(Addr)ARG3, sizeof(struct vki_file_handle))) {
6033 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6034 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
6035 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
6037 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
6040 POST(sys_name_to_handle_at)
6042 struct vki_file_handle *fh = (struct vki_file_handle *)(Addr)ARG3;
6043 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
6044 POST_MEM_WRITE( ARG4, sizeof(int) );
6047 PRE(sys_open_by_handle_at)
6049 *flags |= SfMayBlock;
6050 PRINT("sys_open_by_handle_at ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1,
6051 ARG2, SARG3);
6052 PRE_REG_READ3(int, "open_by_handle_at",
6053 int, mountdirfd,
6054 struct vki_file_handle *, handle,
6055 int, flags);
6056 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2,
6057 sizeof(struct vki_file_handle) +
6058 ((struct vki_file_handle*)(Addr)ARG2)->handle_bytes);
6061 POST(sys_open_by_handle_at)
6063 vg_assert(SUCCESS);
6064 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
6065 VG_(close)(RES);
6066 SET_STATUS_Failure( VKI_EMFILE );
6067 } else {
6068 if (VG_(clo_track_fds))
6069 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG2);
6073 /* ---------------------------------------------------------------------
6074 p{read,write}v wrappers
6075 ------------------------------------------------------------------ */
6076 /* This handles the common part of the PRE macro for preadv and preadv2. */
6077 void handle_pre_sys_preadv(ThreadId tid, SyscallStatus* status,
6078 Int fd, Addr vector, Int count, const char *str)
6080 struct vki_iovec * vec;
6081 Int i;
6082 /* safe size for the "preadv/preadv2(vector[i])" string */
6083 char tmp[30];
6085 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6086 SET_STATUS_Failure( VKI_EBADF );
6087 } else if (count > 0) {
6088 VG_(strcpy) (tmp, str);
6089 VG_(strcat) (tmp, "(vector)");
6090 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6092 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6093 count * sizeof(struct vki_iovec))) {
6094 vec = (struct vki_iovec *)(Addr)vector;
6095 for (i = 0; i < count; i++) {
6096 /* Note: building such a dynamic error string is *not*
6097 a pattern to follow. See bug 417075. */
6098 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6099 PRE_MEM_WRITE( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6105 /* This handles the common part of the POST macro for preadv and preadv2. */
6106 void handle_post_sys_preadv(ThreadId tid, SyscallStatus* status, Addr vector, Int count)
6108 vg_assert(SUCCESS);
6109 if (RES > 0) {
6110 Int i;
6111 struct vki_iovec * vec = (struct vki_iovec *)(Addr)vector;
6112 Int remains = RES;
6114 /* RES holds the number of bytes read. */
6115 for (i = 0; i < count; i++) {
6116 Int nReadThisBuf = vec[i].iov_len;
6117 if (nReadThisBuf > remains) nReadThisBuf = remains;
6118 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6119 remains -= nReadThisBuf;
6120 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
6125 PRE(sys_preadv)
6127 *flags |= SfMayBlock;
6128 const char *str = "preadv";
6129 #if VG_WORDSIZE == 4
6130 /* Note that the offset argument here is in lo+hi order on both
6131 big and little endian platforms... */
6132 PRINT("sys_preadv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6133 "u, %lld )",
6134 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6135 PRE_REG_READ5(ssize_t, "preadv",
6136 unsigned long, fd, const struct iovec *, vector,
6137 unsigned long, count, vki_u32, offset_low,
6138 vki_u32, offset_high);
6139 #elif VG_WORDSIZE == 8
6140 PRINT("sys_preadv ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6141 PRE_REG_READ4(ssize_t, "preadv",
6142 unsigned long, fd, const struct iovec *, vector,
6143 unsigned long, count, Word, offset);
6144 #else
6145 # error Unexpected word size
6146 #endif
6147 Int fd = ARG1;
6148 Addr vector = ARG2;
6149 Int count = ARG3;
6151 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6155 POST(sys_preadv)
6157 Addr vector = ARG2;
6158 Int count = ARG3;
6160 handle_post_sys_preadv(tid, status, vector, count);
6163 PRE(sys_preadv2)
6165 *flags |= SfMayBlock;
6166 const char *str = "preadv2";
6167 #if VG_WORDSIZE == 4
6168 /* Note that the offset argument here is in lo+hi order on both
6169 big and little endian platforms... */
6170 PRINT("sys_preadv2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6171 "u, %lld, %" FMT_REGWORD "u )",
6172 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6173 PRE_REG_READ6(ssize_t, "preadv2",
6174 unsigned long, fd, const struct iovec *, vector,
6175 unsigned long, count, vki_u32, offset_low,
6176 vki_u32, offset_high, unsigned long, flags);
6177 #elif VG_WORDSIZE == 8
6178 PRINT("sys_preadv2 ( %lu, %#lx, %lu, %ld, %lu )", ARG1, ARG2, ARG3, SARG4, ARG5);
6179 PRE_REG_READ5(ssize_t, "preadv2",
6180 unsigned long, fd, const struct iovec *, vector,
6181 unsigned long, count, Word, offset, unsigned long, flags);
6182 #else
6183 # error Unexpected word size
6184 #endif
6185 Int fd = ARG1;
6186 Addr vector = ARG2;
6187 Int count = ARG3;
6189 handle_pre_sys_preadv(tid, status, fd, vector, count, str);
6192 POST(sys_preadv2)
6194 Addr vector = ARG2;
6195 Int count = ARG3;
6197 handle_post_sys_preadv(tid, status, vector, count);
6200 /* This handles the common part of the PRE macro for pwritev and pwritev2. */
6201 void handle_sys_pwritev(ThreadId tid, SyscallStatus* status,
6202 Int fd, Addr vector, Int count, const char *str)
6204 Int i;
6205 struct vki_iovec * vec;
6206 /* safe size for the "preadv/preadv2(vector[i])" string */
6207 char tmp[30];
6209 if (!ML_(fd_allowed)(fd, str, tid, False)) {
6210 SET_STATUS_Failure( VKI_EBADF );
6211 } else if (count > 0) {
6212 VG_(strcpy) (tmp, str);
6213 VG_(strcat) (tmp, "(vector)");
6214 PRE_MEM_READ( tmp, vector, count * sizeof(struct vki_iovec) );
6215 if (ML_(safe_to_deref) ((void *)(Addr)vector,
6216 count * sizeof(struct vki_iovec))) {
6217 vec = (struct vki_iovec *)(Addr)vector;
6218 for (i = 0; i < count; i++) {
6219 /* Note: building such a dynamic error string is *not*
6220 a pattern to follow. See bug 417075. */
6221 VG_(snprintf) (tmp, 30, "%s(vector[%d])", str, i);
6222 PRE_MEM_READ( tmp, (Addr)vec[i].iov_base, vec[i].iov_len );
6228 PRE(sys_pwritev)
6230 *flags |= SfMayBlock;
6231 const char *str = "pwritev";
6232 #if VG_WORDSIZE == 4
6233 /* Note that the offset argument here is in lo+hi order on both
6234 big and little endian platforms... */
6235 PRINT("sys_pwritev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6236 "u, %lld )", ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5));
6237 PRE_REG_READ5(ssize_t, "pwritev",
6238 unsigned long, fd, const struct iovec *, vector,
6239 unsigned long, count, vki_u32, offset_low,
6240 vki_u32, offset_high);
6241 #elif VG_WORDSIZE == 8
6242 PRINT("sys_pwritev ( %lu, %#lx, %lu, %ld )", ARG1, ARG2, ARG3, SARG4);
6243 PRE_REG_READ4(ssize_t, "pwritev",
6244 unsigned long, fd, const struct iovec *, vector,
6245 unsigned long, count, Word, offset);
6246 #else
6247 # error Unexpected word size
6248 #endif
6249 Int fd = ARG1;
6250 Addr vector = ARG2;
6251 Int count = ARG3;
6253 handle_sys_pwritev(tid, status, fd, vector, count, str);
6256 PRE(sys_pwritev2)
6258 *flags |= SfMayBlock;
6259 const char *str = "pwritev2";
6260 #if VG_WORDSIZE == 4
6261 /* Note that the offset argument here is in lo+hi order on both
6262 big and little endian platforms... */
6263 PRINT("sys_pwritev2 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
6264 "u, %lld, %" FMT_REGWORD "u )",
6265 ARG1, ARG2, ARG3, (Long)LOHI64(ARG4,ARG5), ARG6);
6266 PRE_REG_READ6(ssize_t, "pwritev2",
6267 unsigned long, fd, const struct iovec *, vector,
6268 unsigned long, count, vki_u32, offset_low,
6269 vki_u32, offset_high, unsigned long, flags);
6270 #elif VG_WORDSIZE == 8
6271 /* Note offset_high isn't actually used? */
6272 PRE_REG_READ6(ssize_t, "pwritev2",
6273 unsigned long, fd, const struct iovec *, vector,
6274 unsigned long, count, Word, offset,
6275 Word, offset_high, unsigned long, flags);
6276 #else
6277 # error Unexpected word size
6278 #endif
6279 Int fd = ARG1;
6280 Addr vector = ARG2;
6281 Int count = ARG3;
6283 handle_sys_pwritev(tid, status, fd, vector, count, str);
6286 /* ---------------------------------------------------------------------
6287 process_vm_{read,write}v wrappers
6288 ------------------------------------------------------------------ */
6290 PRE(sys_process_vm_readv)
6292 PRINT("sys_process_vm_readv ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6293 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6294 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6295 PRE_REG_READ6(ssize_t, "process_vm_readv",
6296 vki_pid_t, pid,
6297 const struct iovec *, lvec,
6298 unsigned long, liovcnt,
6299 const struct iovec *, rvec,
6300 unsigned long, riovcnt,
6301 unsigned long, flags);
6302 PRE_MEM_READ( "process_vm_readv(lvec)",
6303 ARG2, ARG3 * sizeof(struct vki_iovec) );
6304 PRE_MEM_READ( "process_vm_readv(rvec)",
6305 ARG4, ARG5 * sizeof(struct vki_iovec) );
6306 if (ARG2 != 0
6307 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6308 sizeof(struct vki_iovec) * ARG3)) {
6309 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6310 UInt i;
6311 for (i = 0; i < ARG3; i++)
6312 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
6313 (Addr)vec[i].iov_base, vec[i].iov_len );
6317 POST(sys_process_vm_readv)
6319 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6320 UInt remains = RES;
6321 UInt i;
6322 for (i = 0; i < ARG3; i++) {
6323 UInt nReadThisBuf = vec[i].iov_len <= remains ?
6324 vec[i].iov_len : remains;
6325 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
6326 remains -= nReadThisBuf;
6330 PRE(sys_process_vm_writev)
6332 PRINT("sys_process_vm_writev ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6333 "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
6334 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
6335 PRE_REG_READ6(ssize_t, "process_vm_writev",
6336 vki_pid_t, pid,
6337 const struct iovec *, lvec,
6338 unsigned long, liovcnt,
6339 const struct iovec *, rvec,
6340 unsigned long, riovcnt,
6341 unsigned long, flags);
6342 PRE_MEM_READ( "process_vm_writev(lvec)",
6343 ARG2, ARG3 * sizeof(struct vki_iovec) );
6344 PRE_MEM_READ( "process_vm_writev(rvec)",
6345 ARG4, ARG5 * sizeof(struct vki_iovec) );
6346 if (ARG2 != 0
6347 && ML_(safe_to_deref) ((void *)(Addr)ARG2,
6348 sizeof(struct vki_iovec) * ARG3)) {
6349 const struct vki_iovec *vec = (const struct vki_iovec *)(Addr)ARG2;
6350 UInt i;
6351 for (i = 0; i < ARG3; i++)
6352 PRE_MEM_READ( "process_vm_writev(lvec[...])",
6353 (Addr)vec[i].iov_base, vec[i].iov_len );
6357 /* ---------------------------------------------------------------------
6358 {send,recv}mmsg wrappers
6359 ------------------------------------------------------------------ */
6361 PRE(sys_sendmmsg)
6363 *flags |= SfMayBlock;
6364 PRINT("sys_sendmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld )", SARG1, ARG2,
6365 SARG3, SARG4);
6366 PRE_REG_READ4(long, "sendmmsg",
6367 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
6368 ML_(linux_PRE_sys_sendmmsg)(tid, ARG1,ARG2,ARG3,ARG4);
6371 POST(sys_sendmmsg)
6373 ML_(linux_POST_sys_sendmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4);
6376 PRE(sys_recvmmsg)
6378 *flags |= SfMayBlock;
6379 PRINT("sys_recvmmsg ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6380 FMT_REGWORD "x )",
6381 SARG1, ARG2, SARG3, SARG4, ARG5);
6382 PRE_REG_READ5(long, "recvmmsg",
6383 int, s, struct mmsghdr *, mmsg, int, vlen,
6384 int, flags, struct timespec *, timeout);
6385 ML_(linux_PRE_sys_recvmmsg)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
6388 POST(sys_recvmmsg)
6390 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6393 PRE(sys_recvmmsg_time64)
6395 *flags |= SfMayBlock;
6396 PRINT("sys_recvmmsg_time64 ( %ld, %#" FMT_REGWORD "x, %ld, %ld, %#"
6397 FMT_REGWORD "x )",
6398 SARG1, ARG2, SARG3, SARG4, ARG5);
6399 PRE_REG_READ5(long, "recvmmsg_time64",
6400 int, s, struct mmsghdr *, mmsg, int, vlen,
6401 int, flags, struct vki_timespec64 *, timeout);
6402 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
6403 HChar name[40]; // large enough
6404 UInt i;
6405 for (i = 0; i < ARG3; i++) {
6406 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
6407 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
6408 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
6409 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
6411 if (ARG5)
6412 pre_read_timespec64(tid, "recvmmsg(timeout)", ARG5);
6415 POST(sys_recvmmsg_time64)
6417 /* ARG5 isn't actually used, so just use the generic POST. */
6418 ML_(linux_POST_sys_recvmmsg) (tid, RES, ARG1,ARG2,ARG3,ARG4,ARG5);
6421 /* ---------------------------------------------------------------------
6422 key retention service wrappers
6423 ------------------------------------------------------------------ */
6425 PRE(sys_request_key)
6427 PRINT("sys_request_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6428 FMT_REGWORD "x(%s), %ld )", ARG1, (HChar*)(Addr)ARG1, ARG2,
6429 (HChar*)(Addr)ARG2, ARG3, (HChar*)(Addr)ARG3, SARG4);
6430 PRE_REG_READ4(long, "request_key",
6431 const char *, type, const char *, description,
6432 const char *, callout_info, vki_key_serial_t, keyring);
6433 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
6434 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
6435 if (ARG3 != (UWord)NULL)
6436 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
6439 PRE(sys_add_key)
6441 PRINT("sys_add_key ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s), %#"
6442 FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )", ARG1, (HChar*)(Addr)ARG1,
6443 ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4, SARG5);
6444 PRE_REG_READ5(long, "add_key",
6445 const char *, type, const char *, description,
6446 const void *, payload, vki_size_t, plen,
6447 vki_key_serial_t, keyring);
6448 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
6449 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
6450 if (ARG3 != (UWord)NULL)
6451 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
6454 PRE(sys_keyctl)
6456 switch (ARG1 /* option */) {
6457 case VKI_KEYCTL_GET_KEYRING_ID:
6458 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", SARG2, SARG3);
6459 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
6460 int, option, vki_key_serial_t, id, int, create);
6461 break;
6462 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
6463 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#" FMT_REGWORD
6464 "x(%s) )", ARG2,(char*)(Addr)ARG2);
6465 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
6466 int, option, const char *, name);
6467 if (ARG2 != (UWord)NULL)
6468 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
6469 break;
6470 case VKI_KEYCTL_UPDATE:
6471 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#" FMT_REGWORD "x, %"
6472 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6473 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
6474 int, option, vki_key_serial_t, key,
6475 const void *, payload, vki_size_t, plen);
6476 if (ARG3 != (UWord)NULL)
6477 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
6478 break;
6479 case VKI_KEYCTL_REVOKE:
6480 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", SARG2);
6481 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
6482 int, option, vki_key_serial_t, id);
6483 break;
6484 case VKI_KEYCTL_CHOWN:
6485 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %" FMT_REGWORD "u, %"
6486 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6487 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
6488 int, option, vki_key_serial_t, id,
6489 vki_uid_t, uid, vki_gid_t, gid);
6490 break;
6491 case VKI_KEYCTL_SETPERM:
6492 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %" FMT_REGWORD "u )",
6493 SARG2, ARG3);
6494 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
6495 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
6496 break;
6497 case VKI_KEYCTL_DESCRIBE:
6498 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#" FMT_REGWORD "x, %"
6499 FMT_REGWORD "u )", SARG2, ARG3, ARG4);
6500 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
6501 int, option, vki_key_serial_t, id,
6502 char *, buffer, vki_size_t, buflen);
6503 if (ARG3 != (UWord)NULL)
6504 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
6505 break;
6506 case VKI_KEYCTL_CLEAR:
6507 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", SARG2);
6508 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
6509 int, option, vki_key_serial_t, keyring);
6510 break;
6511 case VKI_KEYCTL_LINK:
6512 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", SARG2, SARG3);
6513 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
6514 vki_key_serial_t, keyring, vki_key_serial_t, key);
6515 break;
6516 case VKI_KEYCTL_UNLINK:
6517 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", SARG2, SARG3);
6518 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
6519 vki_key_serial_t, keyring, vki_key_serial_t, key);
6520 break;
6521 case VKI_KEYCTL_SEARCH:
6522 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#" FMT_REGWORD "x(%s), %#"
6523 FMT_REGWORD "x(%s), %ld )", SARG2, ARG3, (HChar*)(Addr)ARG3,
6524 ARG4, (HChar*)(Addr)ARG4, SARG5);
6525 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
6526 int, option, vki_key_serial_t, keyring,
6527 const char *, type, const char *, description,
6528 vki_key_serial_t, destring);
6529 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
6530 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
6531 break;
6532 case VKI_KEYCTL_READ:
6533 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD
6534 "u )", SARG2, ARG3, ARG4);
6535 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
6536 int, option, vki_key_serial_t, keyring,
6537 char *, buffer, vki_size_t, buflen);
6538 if (ARG3 != (UWord)NULL)
6539 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
6540 break;
6541 case VKI_KEYCTL_INSTANTIATE:
6542 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#" FMT_REGWORD "x, %"
6543 FMT_REGWORD "u, %ld )", SARG2, ARG3, ARG4, SARG5);
6544 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
6545 int, option, vki_key_serial_t, key,
6546 char *, payload, vki_size_t, plen,
6547 vki_key_serial_t, keyring);
6548 if (ARG3 != (UWord)NULL)
6549 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
6550 break;
6551 case VKI_KEYCTL_NEGATE:
6552 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %" FMT_REGWORD "u, %ld )",
6553 SARG2, ARG3, SARG4);
6554 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
6555 int, option, vki_key_serial_t, key,
6556 unsigned, timeout, vki_key_serial_t, keyring);
6557 break;
6558 case VKI_KEYCTL_SET_REQKEY_KEYRING:
6559 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", SARG2);
6560 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
6561 int, option, int, reqkey_defl);
6562 break;
6563 case VKI_KEYCTL_SET_TIMEOUT:
6564 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %" FMT_REGWORD "u )",
6565 SARG2, ARG3);
6566 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
6567 int, option, vki_key_serial_t, key, unsigned, timeout);
6568 break;
6569 case VKI_KEYCTL_ASSUME_AUTHORITY:
6570 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", SARG2);
6571 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
6572 int, option, vki_key_serial_t, key);
6573 break;
6574 default:
6575 PRINT("sys_keyctl ( %ld ) ", SARG1);
6576 PRE_REG_READ1(long, "keyctl", int, option);
6577 break;
6581 POST(sys_keyctl)
6583 vg_assert(SUCCESS);
6584 switch (ARG1 /* option */) {
6585 case VKI_KEYCTL_DESCRIBE:
6586 case VKI_KEYCTL_READ:
6587 if (RES > ARG4)
6588 POST_MEM_WRITE(ARG3, ARG4);
6589 else
6590 POST_MEM_WRITE(ARG3, RES);
6591 break;
6592 default:
6593 break;
6597 /* ---------------------------------------------------------------------
6598 ioprio_ wrappers
6599 ------------------------------------------------------------------ */
6601 PRE(sys_ioprio_set)
6603 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
6604 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
6607 PRE(sys_ioprio_get)
6609 PRINT("sys_ioprio_get ( %ld, %ld )", SARG1, SARG2);
6610 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
6613 /* ---------------------------------------------------------------------
6614 _module wrappers
6615 ------------------------------------------------------------------ */
6617 PRE(sys_init_module)
6619 *flags |= SfMayBlock;
6620 PRINT("sys_init_module ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
6621 FMT_REGWORD "x(\"%s\") )", ARG1, ARG2, ARG3, (HChar*)(Addr)ARG3);
6622 PRE_REG_READ3(long, "init_module",
6623 void *, umod, unsigned long, len, const char *, uargs);
6624 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
6625 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
6628 PRE(sys_finit_module)
6630 *flags |= SfMayBlock;
6632 PRINT("sys_finit_module ( %" FMT_REGWORD "x, %#" FMT_REGWORD "x(\"%s\"), %"
6633 FMT_REGWORD "x )", ARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
6634 PRE_REG_READ3(long, "finit_module",
6635 int, fd, const char *, params, int, flags);
6636 PRE_MEM_RASCIIZ("finit_module(params)", ARG2);
6639 PRE(sys_delete_module)
6641 *flags |= SfMayBlock;
6642 PRINT("sys_delete_module ( %#" FMT_REGWORD "x(\"%s\"), 0x%" FMT_REGWORD
6643 "x )", ARG1, (HChar*)(Addr)ARG1, ARG2);
6644 PRE_REG_READ2(long, "delete_module",
6645 const char *, name_user, unsigned int, flags);
6646 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
6649 /* ---------------------------------------------------------------------
6650 splice wrappers
6651 ------------------------------------------------------------------ */
6653 PRE(sys_splice)
6655 *flags |= SfMayBlock;
6656 PRINT("sys_splice ( %ld, %#" FMT_REGWORD "x, %ld, %#"
6657 FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6658 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
6659 PRE_REG_READ6(vki_ssize_t, "splice",
6660 int, fd_in, vki_loff_t *, off_in,
6661 int, fd_out, vki_loff_t *, off_out,
6662 vki_size_t, len, unsigned int, flags);
6663 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
6664 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
6665 SET_STATUS_Failure( VKI_EBADF );
6666 } else {
6667 if (ARG2 != 0)
6668 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
6669 if (ARG4 != 0)
6670 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
6674 PRE(sys_tee)
6676 *flags |= SfMayBlock;
6677 PRINT("sys_tree ( %ld, %ld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
6678 SARG1, SARG2, ARG3, ARG4);
6679 PRE_REG_READ4(vki_ssize_t, "tee",
6680 int, fd_in, int, fd_out,
6681 vki_size_t, len, unsigned int, flags);
6682 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
6683 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
6684 SET_STATUS_Failure( VKI_EBADF );
6688 PRE(sys_vmsplice)
6690 Int fdfl;
6691 *flags |= SfMayBlock;
6692 PRINT("sys_vmsplice ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
6693 FMT_REGWORD "u )", SARG1, ARG2, ARG3, ARG4);
6694 PRE_REG_READ4(vki_ssize_t, "splice",
6695 int, fd, struct vki_iovec *, iov,
6696 unsigned long, nr_segs, unsigned int, flags);
6697 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
6698 SET_STATUS_Failure( VKI_EBADF );
6699 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
6700 SET_STATUS_Failure( VKI_EBADF );
6701 } else {
6702 const struct vki_iovec *iov;
6703 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
6704 for (iov = (struct vki_iovec *)(Addr)ARG2;
6705 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6707 if (ML_(safe_to_deref) (iov, sizeof(struct vki_iovec))) {
6708 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6709 PRE_MEM_WRITE( "vmsplice(iov[...])",
6710 (Addr)iov->iov_base, iov->iov_len );
6711 else
6712 PRE_MEM_READ( "vmsplice(iov[...])",
6713 (Addr)iov->iov_base, iov->iov_len );
6719 POST(sys_vmsplice)
6721 vg_assert(SUCCESS);
6722 if (RES > 0) {
6723 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
6724 vg_assert(fdfl >= 0);
6725 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
6727 const struct vki_iovec *iov;
6728 for (iov = (struct vki_iovec *)(Addr)ARG2;
6729 iov < (struct vki_iovec *)(Addr)ARG2 + ARG3; iov++)
6731 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
6737 /* ---------------------------------------------------------------------
6738 oprofile-related wrappers
6739 ------------------------------------------------------------------ */
6741 #if defined(VGP_x86_linux)
6742 PRE(sys_lookup_dcookie)
6744 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %lu)",
6745 MERGE64(ARG1,ARG2), ARG3, ARG4);
6746 PRE_REG_READ4(long, "lookup_dcookie",
6747 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
6748 char *, buf, vki_size_t, len);
6749 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
6751 POST(sys_lookup_dcookie)
6753 vg_assert(SUCCESS);
6754 if (ARG3 != (Addr)NULL)
6755 POST_MEM_WRITE( ARG3, RES);
6757 #endif
6759 #if defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
6760 || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux)
6761 PRE(sys_lookup_dcookie)
6763 *flags |= SfMayBlock;
6764 PRINT("sys_lookup_dcookie ( %lu, %#lx, %lu )", ARG1, ARG2, ARG3);
6765 PRE_REG_READ3(int, "lookup_dcookie",
6766 unsigned long long, cookie, char *, buf, vki_size_t, len);
6768 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
6771 POST(sys_lookup_dcookie)
6773 vg_assert(SUCCESS);
6774 if (ARG2 != (Addr)NULL)
6775 POST_MEM_WRITE( ARG2, RES );
6777 #endif
6779 /* ---------------------------------------------------------------------
6780 fcntl wrappers
6781 ------------------------------------------------------------------ */
6783 PRE(sys_fcntl)
6785 switch (ARG2) {
6786 // These ones ignore ARG3.
6787 case VKI_F_GETFD:
6788 case VKI_F_GETFL:
6789 case VKI_F_GETOWN:
6790 case VKI_F_GETSIG:
6791 case VKI_F_GETLEASE:
6792 case VKI_F_GETPIPE_SZ:
6793 case VKI_F_GET_SEALS:
6794 PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6795 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
6796 break;
6798 // These ones use ARG3 as "arg".
6799 case VKI_F_DUPFD:
6800 case VKI_F_DUPFD_CLOEXEC:
6801 case VKI_F_SETFD:
6802 case VKI_F_SETFL:
6803 case VKI_F_SETLEASE:
6804 case VKI_F_NOTIFY:
6805 case VKI_F_SETOWN:
6806 case VKI_F_SETSIG:
6807 case VKI_F_SETPIPE_SZ:
6808 case VKI_F_ADD_SEALS:
6809 PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6810 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6811 PRE_REG_READ3(long, "fcntl",
6812 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6813 break;
6815 // These ones use ARG3 as "lock".
6816 case VKI_F_GETLK:
6817 case VKI_F_SETLK:
6818 case VKI_F_SETLKW:
6819 case VKI_F_OFD_GETLK:
6820 case VKI_F_OFD_SETLK:
6821 case VKI_F_OFD_SETLKW:
6822 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6823 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6824 PRE_REG_READ3(long, "fcntl",
6825 unsigned int, fd, unsigned int, cmd,
6826 struct vki_flock *, lock);
6828 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6829 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6830 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6831 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6832 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6833 if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6834 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6837 break;
6839 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6840 case VKI_F_GETLK64:
6841 case VKI_F_SETLK64:
6842 case VKI_F_SETLKW64:
6843 PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6844 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6845 PRE_REG_READ3(long, "fcntl",
6846 unsigned int, fd, unsigned int, cmd,
6847 struct flock64 *, lock);
6849 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6850 PRE_FIELD_READ("fcntl(lock->l_type)", lock->l_type);
6851 PRE_FIELD_READ("fcntl(lock->l_whence)", lock->l_whence);
6852 PRE_FIELD_READ("fcntl(lock->l_start)", lock->l_start);
6853 PRE_FIELD_READ("fcntl(lock->l_len)", lock->l_len);
6854 if (ARG2 == VKI_F_GETLK64) {
6855 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6858 break;
6859 # endif
6861 case VKI_F_SETOWN_EX:
6862 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6863 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6864 PRE_REG_READ3(long, "fcntl",
6865 unsigned int, fd, unsigned int, cmd,
6866 struct vki_f_owner_ex *, arg);
6867 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6868 break;
6870 case VKI_F_GETOWN_EX:
6871 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6872 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6873 PRE_REG_READ3(long, "fcntl",
6874 unsigned int, fd, unsigned int, cmd,
6875 struct vki_f_owner_ex *, arg);
6876 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6877 break;
6879 default:
6880 PRINT("sys_fcntl[UNKNOWN] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
6881 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6882 VG_(umsg)("Warning: unimplemented fcntl command: %" FMT_REGWORD "u\n",
6883 ARG2);
6884 SET_STATUS_Failure( VKI_EINVAL );
6885 break;
6888 # if defined(VGP_x86_linux)
6889 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
6890 # else
6891 if (ARG2 == VKI_F_SETLKW)
6892 # endif
6893 *flags |= SfMayBlock;
6896 POST(sys_fcntl)
6898 vg_assert(SUCCESS);
6899 if (ARG2 == VKI_F_DUPFD) {
6900 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
6901 VG_(close)(RES);
6902 SET_STATUS_Failure( VKI_EMFILE );
6903 } else {
6904 if (VG_(clo_track_fds))
6905 ML_(record_fd_open_named)(tid, RES);
6908 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
6909 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
6910 VG_(close)(RES);
6911 SET_STATUS_Failure( VKI_EMFILE );
6912 } else {
6913 if (VG_(clo_track_fds))
6914 ML_(record_fd_open_named)(tid, RES);
6916 } else if (ARG2 == VKI_F_GETOWN_EX) {
6917 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
6918 } else if (ARG2 == VKI_F_GETLK || ARG2 == VKI_F_OFD_GETLK) {
6919 struct vki_flock *lock = (struct vki_flock *) (Addr)ARG3;
6920 POST_FIELD_WRITE(lock->l_pid);
6921 # if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
6922 } else if (ARG2 == VKI_F_GETLK64) {
6923 struct vki_flock64 *lock = (struct vki_flock64 *) (Addr)ARG3;
6924 PRE_FIELD_WRITE("fcntl(lock->l_pid)", lock->l_pid);
6925 # endif
6929 // XXX: wrapper only suitable for 32-bit systems
6930 PRE(sys_fcntl64)
6932 switch (ARG2) {
6933 // These ones ignore ARG3.
6934 case VKI_F_GETFD:
6935 case VKI_F_GETFL:
6936 case VKI_F_GETOWN:
6937 case VKI_F_SETOWN:
6938 case VKI_F_GETSIG:
6939 case VKI_F_SETSIG:
6940 case VKI_F_GETLEASE:
6941 case VKI_F_GET_SEALS:
6942 PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
6943 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
6944 break;
6946 // These ones use ARG3 as "arg".
6947 case VKI_F_DUPFD:
6948 case VKI_F_DUPFD_CLOEXEC:
6949 case VKI_F_SETFD:
6950 case VKI_F_SETFL:
6951 case VKI_F_SETLEASE:
6952 case VKI_F_NOTIFY:
6953 case VKI_F_ADD_SEALS:
6954 PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6955 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6956 PRE_REG_READ3(long, "fcntl64",
6957 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
6958 break;
6960 // These ones use ARG3 as "lock".
6961 case VKI_F_GETLK:
6962 case VKI_F_SETLK:
6963 case VKI_F_SETLKW:
6964 # if defined(VGP_x86_linux)
6965 case VKI_F_GETLK64:
6966 case VKI_F_SETLK64:
6967 case VKI_F_SETLKW64:
6968 # endif
6969 case VKI_F_OFD_GETLK:
6970 case VKI_F_OFD_SETLK:
6971 case VKI_F_OFD_SETLKW:
6972 PRINT("sys_fcntl64[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6973 "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3);
6974 PRE_REG_READ3(long, "fcntl64",
6975 unsigned int, fd, unsigned int, cmd,
6976 struct flock64 *, lock);
6977 break;
6979 case VKI_F_SETOWN_EX:
6980 PRINT("sys_fcntl[F_SETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6981 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6982 PRE_REG_READ3(long, "fcntl",
6983 unsigned int, fd, unsigned int, cmd,
6984 struct vki_f_owner_ex *, arg);
6985 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6986 break;
6988 case VKI_F_GETOWN_EX:
6989 PRINT("sys_fcntl[F_GETOWN_EX] ( %" FMT_REGWORD "u, %" FMT_REGWORD
6990 "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
6991 PRE_REG_READ3(long, "fcntl",
6992 unsigned int, fd, unsigned int, cmd,
6993 struct vki_f_owner_ex *, arg);
6994 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
6995 break;
6998 # if defined(VGP_x86_linux)
6999 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
7000 # else
7001 if (ARG2 == VKI_F_SETLKW)
7002 # endif
7003 *flags |= SfMayBlock;
7006 POST(sys_fcntl64)
7008 vg_assert(SUCCESS);
7009 if (ARG2 == VKI_F_DUPFD) {
7010 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
7011 VG_(close)(RES);
7012 SET_STATUS_Failure( VKI_EMFILE );
7013 } else {
7014 if (VG_(clo_track_fds))
7015 ML_(record_fd_open_named)(tid, RES);
7018 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
7019 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
7020 VG_(close)(RES);
7021 SET_STATUS_Failure( VKI_EMFILE );
7022 } else {
7023 if (VG_(clo_track_fds))
7024 ML_(record_fd_open_named)(tid, RES);
7026 } else if (ARG2 == VKI_F_GETOWN_EX) {
7027 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
7031 /* ---------------------------------------------------------------------
7032 ioctl wrappers
7033 ------------------------------------------------------------------ */
7035 struct vg_drm_version_info {
7036 struct vki_drm_version data;
7037 struct vki_drm_version *orig; // Original ARG3 pointer value at syscall entry.
7040 PRE(sys_ioctl)
7042 *flags |= SfMayBlock;
7044 ARG2 = (UInt)ARG2;
7046 // We first handle the ones that don't use ARG3 (even as a
7047 // scalar/non-pointer argument).
7048 switch (ARG2 /* request */) {
7050 /* asm-generic/ioctls.h */
7051 case VKI_FIOCLEX:
7052 case VKI_FIONCLEX:
7053 case VKI_TIOCNOTTY:
7055 /* linux perf_event ioctls */
7056 case VKI_PERF_EVENT_IOC_ENABLE:
7057 case VKI_PERF_EVENT_IOC_DISABLE:
7059 /* linux/soundcard interface (ALSA) */
7060 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7061 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7062 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7063 case VKI_SNDRV_PCM_IOCTL_RESET:
7064 case VKI_SNDRV_PCM_IOCTL_START:
7065 case VKI_SNDRV_PCM_IOCTL_DROP:
7066 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7067 case VKI_SNDRV_PCM_IOCTL_RESUME:
7068 case VKI_SNDRV_PCM_IOCTL_XRUN:
7069 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7070 case VKI_SNDRV_TIMER_IOCTL_START:
7071 case VKI_SNDRV_TIMER_IOCTL_STOP:
7072 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7073 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
7075 /* SCSI no operand */
7076 case VKI_SCSI_IOCTL_DOORLOCK:
7077 case VKI_SCSI_IOCTL_DOORUNLOCK:
7079 /* CDROM stuff. */
7080 case VKI_CDROM_DISC_STATUS:
7081 case VKI_CDROMSTOP:
7083 /* DVD stuff */
7084 case VKI_DVD_READ_STRUCT:
7086 /* KVM ioctls that don't check for a numeric value as parameter */
7087 case VKI_KVM_S390_ENABLE_SIE:
7088 case VKI_KVM_CREATE_IRQCHIP:
7089 case VKI_KVM_S390_INITIAL_RESET:
7090 case VKI_KVM_KVMCLOCK_CTRL:
7092 /* vhost without parameter */
7093 case VKI_VHOST_SET_OWNER:
7094 case VKI_VHOST_RESET_OWNER:
7096 /* User input device creation */
7097 case VKI_UI_DEV_CREATE:
7098 case VKI_UI_DEV_DESTROY:
7100 /* InfiniBand */
7101 case VKI_IB_USER_MAD_ENABLE_PKEY:
7103 /* Lustre */
7104 case VKI_LL_IOC_GROUP_LOCK:
7105 case VKI_LL_IOC_GROUP_UNLOCK:
7107 /* V4L2 */
7108 case VKI_V4L2_LOG_STATUS:
7110 /* Mesa */
7111 case VKI_DRM_IOCTL_I915_GEM_THROTTLE:
7113 /* DVB */
7114 case VKI_DMX_STOP:
7115 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x )", ARG1, ARG2);
7116 PRE_REG_READ2(long, "ioctl",
7117 unsigned int, fd, unsigned int, request);
7118 return;
7120 default:
7121 PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, 0x%"
7122 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
7123 PRE_REG_READ3(long, "ioctl",
7124 unsigned int, fd, unsigned int, request, unsigned long, arg);
7125 break;
7128 // We now handle those that do look at ARG3 (and unknown ones fall into
7129 // this category). Nb: some of these may well belong in the
7130 // doesn't-use-ARG3 switch above.
7131 switch (ARG2 /* request */) {
7133 case VKI_ION_IOC_ALLOC: {
7134 struct vki_ion_allocation_data* data
7135 = (struct vki_ion_allocation_data*)(Addr)ARG3;
7136 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).len", data->len);
7137 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).align", data->align);
7138 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).heap_id_mask", data->heap_id_mask);
7139 PRE_FIELD_READ ("ioctl(ION_IOC_ALLOC).flags", data->flags);
7140 PRE_FIELD_WRITE("ioctl(ION_IOC_ALLOC).handle", data->handle);
7141 break;
7143 case VKI_ION_IOC_MAP: {
7144 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7145 PRE_FIELD_READ ("ioctl(ION_IOC_MAP).handle", data->handle);
7146 PRE_FIELD_WRITE("ioctl(ION_IOC_MAP).fd", data->fd);
7147 break;
7149 case VKI_ION_IOC_IMPORT: {
7150 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
7151 PRE_FIELD_READ ("ioctl(ION_IOC_IMPORT).fd", data->fd);
7152 PRE_FIELD_WRITE("ioctl(ION_IOC_IMPORT).handle", data->handle);
7153 break;
7156 case VKI_SYNC_IOC_MERGE: {
7157 struct vki_sync_merge_data* data =
7158 (struct vki_sync_merge_data*)(Addr)ARG3;
7159 PRE_FIELD_READ ("ioctl(SYNC_IOC_MERGE).fd2", data->fd2);
7160 PRE_MEM_RASCIIZ("ioctl(SYNC_IOC_MERGE).name", (Addr)(&data->name[0]));
7161 PRE_FIELD_WRITE("ioctl(SYNC_IOC_MERGE).fence", data->fence);
7162 break;
7165 case VKI_TCSETS:
7166 case VKI_TCSETSW:
7167 case VKI_TCSETSF:
7168 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
7169 break;
7170 case VKI_TCGETS:
7171 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
7172 break;
7173 case VKI_TCSETA:
7174 case VKI_TCSETAW:
7175 case VKI_TCSETAF:
7176 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
7177 break;
7178 case VKI_TCGETA:
7179 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
7180 break;
7181 case VKI_TCSBRK:
7182 case VKI_TCXONC:
7183 case VKI_TCSBRKP:
7184 case VKI_TCFLSH:
7185 case VKI_TIOCSIG:
7186 /* These just take an int by value */
7187 break;
7188 case VKI_TIOCGWINSZ:
7189 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
7190 break;
7191 case VKI_TIOCSWINSZ:
7192 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
7193 break;
7194 case VKI_TIOCMBIS:
7195 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
7196 break;
7197 case VKI_TIOCMBIC:
7198 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
7199 break;
7200 case VKI_TIOCMSET:
7201 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
7202 break;
7203 case VKI_TIOCMGET:
7204 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
7205 break;
7206 case VKI_TIOCLINUX:
7207 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
7208 if (*(char *)(Addr)ARG3 == 11) {
7209 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
7211 break;
7212 case VKI_TIOCGPGRP:
7213 /* Get process group ID for foreground processing group. */
7214 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7215 break;
7216 case VKI_TIOCSPGRP:
7217 /* Set a process group ID? */
7218 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
7219 break;
7220 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7221 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
7222 break;
7223 case VKI_TIOCSCTTY:
7224 /* Just takes an int value. */
7225 break;
7226 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7227 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
7228 break;
7229 case VKI_FIONBIO:
7230 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
7231 break;
7232 case VKI_FIOASYNC:
7233 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
7234 break;
7235 case VKI_FIONREAD: /* identical to SIOCINQ */
7236 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
7237 break;
7238 case VKI_FIOQSIZE:
7239 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
7240 break;
7242 case VKI_TIOCSERGETLSR:
7243 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
7244 break;
7245 case VKI_TIOCGICOUNT:
7246 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
7247 sizeof(struct vki_serial_icounter_struct) );
7248 break;
7250 case VKI_SG_SET_COMMAND_Q:
7251 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
7252 break;
7253 case VKI_SG_IO:
7254 PRE_MEM_READ( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
7256 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
7257 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->cmdp, sgio->cmd_len );
7258 if ( sgio->dxfer_direction == VKI_SG_DXFER_TO_DEV ||
7259 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
7260 PRE_MEM_READ( "ioctl(SG_IO)", (Addr)sgio->dxferp, sgio->dxfer_len );
7263 break;
7264 case VKI_SG_GET_SCSI_ID:
7265 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
7266 break;
7267 case VKI_SG_SET_RESERVED_SIZE:
7268 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
7269 break;
7270 case VKI_SG_SET_TIMEOUT:
7271 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
7272 break;
7273 case VKI_SG_GET_RESERVED_SIZE:
7274 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
7275 break;
7276 case VKI_SG_GET_TIMEOUT:
7277 break;
7278 case VKI_SG_GET_VERSION_NUM:
7279 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
7280 break;
7281 case VKI_SG_EMULATED_HOST: /* 0x2203 */
7282 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
7283 break;
7284 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
7285 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
7286 break;
7288 case VKI_IIOCGETCPS:
7289 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
7290 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7291 break;
7292 case VKI_IIOCNETGPN:
7293 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
7294 (Addr)&((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name,
7295 sizeof(((vki_isdn_net_ioctl_phone *)(Addr)ARG3)->name) );
7296 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
7297 sizeof(vki_isdn_net_ioctl_phone) );
7298 break;
7300 /* These all use struct ifreq AFAIK */
7301 case VKI_SIOCGIFINDEX: /* get iface index */
7302 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
7303 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7304 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
7305 break;
7306 case VKI_SIOCGIFFLAGS: /* get flags */
7307 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
7308 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7309 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7310 break;
7311 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7312 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
7313 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7314 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
7315 break;
7316 case VKI_SIOCGIFMTU: /* get MTU size */
7317 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
7318 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7319 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
7320 break;
7321 case VKI_SIOCGIFADDR: /* get PA address */
7322 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
7323 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7324 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
7325 break;
7326 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7327 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
7328 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7329 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
7330 break;
7331 case VKI_SIOCGIFMETRIC: /* get metric */
7332 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
7333 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7334 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
7335 break;
7336 case VKI_SIOCGIFMAP: /* Get device parameters */
7337 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
7338 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7339 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
7340 break;
7341 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7342 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
7343 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7344 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
7345 break;
7346 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7347 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
7348 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7349 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
7350 break;
7351 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7352 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
7353 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7354 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
7355 break;
7356 case VKI_SIOCGIFNAME: /* get iface name */
7357 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
7358 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
7359 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
7360 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
7361 break;
7363 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
7364 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
7365 // The kernel will have to look at ifr_data to determine which operation
7366 // to perform.
7367 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir->ifr_data)",
7368 (Addr)ir->vki_ifr_data, sizeof(vki_u32) );
7370 PRINT("SIOCETHTOOL( 0x%x )", *(vki_u32 *)ir->vki_ifr_data );
7372 // Is this correct? Is ifr_name *always* looked at?
7373 PRE_MEM_RASCIIZ( "ioctl(SIOCETHTOOL,ir->ifr_name)",
7374 (Addr)ir->vki_ifr_name );
7376 // At least for ETHTOOL_GSET, it is apparently incorrect to insist that
7377 // the whole structure is defined. So in this case, just check it's
7378 // accessible.
7379 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7380 case VKI_ETHTOOL_GSET:
7381 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,ir)",
7382 (Addr)ir, sizeof(struct vki_ifreq) );
7383 break;
7384 default:
7385 PRE_MEM_READ( "ioctl(SIOCETHTOOL,ir)",
7386 (Addr)ir, sizeof(struct vki_ifreq) );
7387 break;
7390 // Now perform the relevant pre-action for the operation.
7391 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
7392 case VKI_ETHTOOL_GSET:
7393 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSET)",
7394 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7395 break;
7396 case VKI_ETHTOOL_SSET:
7397 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SSET)",
7398 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd) );
7399 break;
7400 case VKI_ETHTOOL_GDRVINFO:
7401 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GDRVINFO)",
7402 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
7403 break;
7404 case VKI_ETHTOOL_GREGS:
7405 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GREGS)",
7406 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_regs) );
7407 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GREGS)",
7408 (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
7409 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
7410 break;
7411 case VKI_ETHTOOL_GWOL:
7412 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GWOL)",
7413 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7414 break;
7415 case VKI_ETHTOOL_SWOL:
7416 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SWOL)",
7417 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
7418 break;
7419 case VKI_ETHTOOL_GMSGLVL:
7420 case VKI_ETHTOOL_GLINK:
7421 case VKI_ETHTOOL_GRXCSUM:
7422 case VKI_ETHTOOL_GSG:
7423 case VKI_ETHTOOL_GTSO:
7424 case VKI_ETHTOOL_GUFO:
7425 case VKI_ETHTOOL_GGSO:
7426 case VKI_ETHTOOL_GFLAGS:
7427 case VKI_ETHTOOL_GGRO:
7428 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,Gvalue)",
7429 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7430 break;
7431 case VKI_ETHTOOL_SMSGLVL:
7432 case VKI_ETHTOOL_SRXCSUM:
7433 case VKI_ETHTOOL_SSG:
7434 case VKI_ETHTOOL_STSO:
7435 case VKI_ETHTOOL_SUFO:
7436 case VKI_ETHTOOL_SGSO:
7437 case VKI_ETHTOOL_SFLAGS:
7438 case VKI_ETHTOOL_SGRO:
7439 PRE_MEM_READ( "ioctl(SIOCETHTOOL,Svalue)",
7440 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value) );
7441 break;
7442 case VKI_ETHTOOL_NWAY_RST:
7443 break;
7444 case VKI_ETHTOOL_GRINGPARAM:
7445 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GRINGPARAM)",
7446 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7447 break;
7448 case VKI_ETHTOOL_SRINGPARAM:
7449 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SRINGPARAM)",
7450 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam) );
7451 break;
7452 case VKI_ETHTOOL_TEST:
7453 PRE_MEM_READ( "ioctl(SIOCETHTOOL,TEST)",
7454 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_test) );
7455 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,TEST)",
7456 (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
7457 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
7458 break;
7459 case VKI_ETHTOOL_PHYS_ID:
7460 break;
7461 case VKI_ETHTOOL_GPERMADDR:
7462 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GPERMADDR)",
7463 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_perm_addr) );
7464 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GPERMADDR)",
7465 (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
7466 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
7467 break;
7468 case VKI_ETHTOOL_RESET:
7469 break;
7470 case VKI_ETHTOOL_GSSET_INFO:
7471 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7472 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sset_info) );
7473 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GSSET_INFO)",
7474 (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
7475 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
7476 break;
7477 case VKI_ETHTOOL_GFEATURES:
7478 PRE_MEM_READ( "ioctl(SIOCETHTOOL,GFEATURES)",
7479 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_gfeatures) );
7480 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GFEATURES)",
7481 (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
7482 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
7483 break;
7484 case VKI_ETHTOOL_SFEATURES:
7485 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7486 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_sfeatures) );
7487 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SFEATURES)",
7488 (Addr)((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->features,
7489 ((struct vki_ethtool_sfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_set_features_block) );
7490 break;
7491 case VKI_ETHTOOL_GCHANNELS:
7492 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GCHANNELS)",
7493 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7494 break;
7495 case VKI_ETHTOOL_SCHANNELS:
7496 PRE_MEM_READ( "ioctl(SIOCETHTOOL,SCHANNELS)",
7497 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
7498 break;
7499 case VKI_ETHTOOL_GET_TS_INFO:
7500 PRE_MEM_WRITE( "ioctl(SIOCETHTOOL,GET_TS_INFO)",
7501 (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
7502 break;
7504 break;
7505 } /* case VKI_SIOCETHTOOL */
7507 case VKI_SIOCGMIIPHY: /* get hardware entry */
7508 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
7509 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7510 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
7511 break;
7512 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7513 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
7514 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7515 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7516 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7517 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7518 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
7519 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7520 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7521 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
7522 sizeof(struct vki_ifreq));
7523 break;
7524 case VKI_SIOCGIFCONF: /* get iface list */
7525 /* WAS:
7526 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7527 KERNEL_DO_SYSCALL(tid,RES);
7528 if (!VG_(is_kerror)(RES) && RES == 0)
7529 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7531 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7532 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->ifc_len,
7533 sizeof(((struct vki_ifconf *)(Addr)ARG3)->ifc_len));
7534 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
7535 (Addr)&((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf,
7536 sizeof(((struct vki_ifconf *)(Addr)ARG3)->vki_ifc_buf));
7537 if ( ARG3 ) {
7538 // TODO len must be readable and writable
7539 // buf pointer only needs to be readable
7540 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
7541 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
7542 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7544 break;
7545 case VKI_SIOCGSTAMP:
7546 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
7547 break;
7548 case VKI_SIOCGSTAMPNS:
7549 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
7550 break;
7551 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7552 the number of bytes currently in that socket's send buffer.
7553 It writes this value as an int to the memory location
7554 indicated by the third argument of ioctl(2). */
7555 case VKI_SIOCOUTQ:
7556 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
7557 break;
7558 case VKI_SIOCGRARP: /* get RARP table entry */
7559 case VKI_SIOCGARP: /* get ARP table entry */
7560 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
7561 break;
7563 case VKI_SIOCSIFFLAGS: /* set flags */
7564 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
7565 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7566 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
7567 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7568 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7569 break;
7570 case VKI_SIOCSIFMAP: /* Set device parameters */
7571 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
7572 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7573 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
7574 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
7575 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
7576 break;
7577 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
7578 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
7579 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7580 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
7581 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data,
7582 sizeof(struct vki_hwtstamp_config) );
7583 break;
7584 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7585 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
7586 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7587 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
7588 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
7589 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
7590 break;
7591 case VKI_SIOCSIFADDR: /* set PA address */
7592 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7593 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7594 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7595 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
7596 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7597 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
7598 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
7599 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
7600 break;
7601 case VKI_SIOCSIFMETRIC: /* set metric */
7602 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
7603 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7604 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
7605 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
7606 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
7607 break;
7608 case VKI_SIOCSIFMTU: /* set MTU size */
7609 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
7610 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7611 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
7612 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
7613 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
7614 break;
7615 case VKI_SIOCSIFHWADDR: /* set hardware address */
7616 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
7617 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7618 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
7619 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
7620 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr) );
7621 break;
7622 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7623 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
7624 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7625 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7626 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
7627 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
7628 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7629 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num,
7630 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->reg_num));
7631 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
7632 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in,
7633 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_in));
7634 break;
7635 /* Routing table calls. */
7636 case VKI_SIOCADDRT: /* add routing table entry */
7637 case VKI_SIOCDELRT: /* delete routing table entry */
7638 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
7639 sizeof(struct vki_rtentry));
7640 break;
7642 /* tun/tap related ioctls */
7643 case VKI_TUNSETNOCSUM:
7644 case VKI_TUNSETDEBUG:
7645 break;
7646 case VKI_TUNSETIFF:
7647 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
7648 (Addr)((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name );
7649 PRE_MEM_READ( "ioctl(TUNSETIFF)",
7650 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7651 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7652 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3, sizeof(struct vki_ifreq) );
7653 break;
7654 case VKI_TUNSETPERSIST:
7655 case VKI_TUNSETOWNER:
7656 case VKI_TUNSETLINK:
7657 case VKI_TUNSETGROUP:
7658 break;
7659 case VKI_TUNGETFEATURES:
7660 PRE_MEM_WRITE( "ioctl(TUNGETFEATURES)", ARG3, sizeof(unsigned int) );
7661 break;
7662 case VKI_TUNSETOFFLOAD:
7663 break;
7664 case VKI_TUNGETIFF:
7665 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3, sizeof(struct vki_ifreq) );
7666 break;
7667 case VKI_TUNGETSNDBUF:
7668 PRE_MEM_WRITE( "ioctl(TUNGETSNDBUF)", ARG3, sizeof(int) );
7669 break;
7670 case VKI_TUNSETSNDBUF:
7671 PRE_MEM_READ( "ioctl(TUNSETSNDBUF)", ARG3, sizeof(int) );
7672 break;
7673 case VKI_TUNGETVNETHDRSZ:
7674 PRE_MEM_WRITE( "ioctl(TUNGETVNETHDRSZ)", ARG3, sizeof(int) );
7675 break;
7676 case VKI_TUNSETVNETHDRSZ:
7677 PRE_MEM_READ( "ioctl(TUNSETVNETHDRSZ)", ARG3, sizeof(int) );
7678 break;
7679 case VKI_TUNSETQUEUE:
7680 PRE_MEM_READ( "ioctl(TUNSETQUEUE)",
7681 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
7682 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
7683 break;
7684 case VKI_TUNSETIFINDEX:
7685 PRE_MEM_READ( "ioctl(TUNSETIFINDEX)", ARG3, sizeof(unsigned int));
7686 break;
7688 /* RARP cache control calls. */
7689 case VKI_SIOCDRARP: /* delete RARP table entry */
7690 case VKI_SIOCSRARP: /* set RARP table entry */
7691 /* ARP cache control calls. */
7692 case VKI_SIOCSARP: /* set ARP table entry */
7693 case VKI_SIOCDARP: /* delete ARP table entry */
7694 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
7695 break;
7697 case VKI_SIOCGPGRP:
7698 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
7699 break;
7700 case VKI_SIOCSPGRP:
7701 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
7702 //tst->sys_flags &= ~SfMayBlock;
7703 break;
7705 case VKI_SIOCATMARK:
7706 PRE_MEM_READ( "ioctl(SIOCATMARK)", ARG3, sizeof(int) );
7707 break;
7709 /* linux/soundcard interface (OSS) */
7710 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7711 case VKI_SNDCTL_SEQ_GETINCOUNT:
7712 case VKI_SNDCTL_SEQ_PERCMODE:
7713 case VKI_SNDCTL_SEQ_TESTMIDI:
7714 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7715 case VKI_SNDCTL_SEQ_NRSYNTHS:
7716 case VKI_SNDCTL_SEQ_NRMIDIS:
7717 case VKI_SNDCTL_SEQ_GETTIME:
7718 case VKI_SNDCTL_DSP_GETBLKSIZE:
7719 case VKI_SNDCTL_DSP_GETFMTS:
7720 case VKI_SNDCTL_DSP_GETTRIGGER:
7721 case VKI_SNDCTL_DSP_GETODELAY:
7722 case VKI_SNDCTL_DSP_GETSPDIF:
7723 case VKI_SNDCTL_DSP_GETCAPS:
7724 case VKI_SOUND_PCM_READ_RATE:
7725 case VKI_SOUND_PCM_READ_CHANNELS:
7726 case VKI_SOUND_PCM_READ_BITS:
7727 case VKI_SOUND_PCM_READ_FILTER:
7728 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
7729 ARG3, sizeof(int));
7730 break;
7731 case VKI_SNDCTL_SEQ_CTRLRATE:
7732 case VKI_SNDCTL_DSP_SPEED:
7733 case VKI_SNDCTL_DSP_STEREO:
7734 case VKI_SNDCTL_DSP_CHANNELS:
7735 case VKI_SOUND_PCM_WRITE_FILTER:
7736 case VKI_SNDCTL_DSP_SUBDIVIDE:
7737 case VKI_SNDCTL_DSP_SETFRAGMENT:
7738 case VKI_SNDCTL_DSP_SETFMT:
7739 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7740 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7741 case VKI_SNDCTL_TMR_TIMEBASE:
7742 case VKI_SNDCTL_TMR_TEMPO:
7743 case VKI_SNDCTL_TMR_SOURCE:
7744 case VKI_SNDCTL_MIDI_PRETIME:
7745 case VKI_SNDCTL_MIDI_MPUMODE:
7746 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7747 ARG3, sizeof(int));
7748 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
7749 ARG3, sizeof(int));
7750 break;
7751 case VKI_SNDCTL_DSP_GETOSPACE:
7752 case VKI_SNDCTL_DSP_GETISPACE:
7753 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
7754 ARG3, sizeof(vki_audio_buf_info));
7755 break;
7756 case VKI_SNDCTL_DSP_NONBLOCK:
7757 break;
7758 case VKI_SNDCTL_DSP_SETTRIGGER:
7759 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
7760 ARG3, sizeof(int));
7761 break;
7763 case VKI_SNDCTL_DSP_POST:
7764 case VKI_SNDCTL_DSP_RESET:
7765 case VKI_SNDCTL_DSP_SYNC:
7766 case VKI_SNDCTL_DSP_SETSYNCRO:
7767 case VKI_SNDCTL_DSP_SETDUPLEX:
7768 break;
7770 /* linux/soundcard interface (ALSA) */
7771 case VKI_SNDRV_PCM_IOCTL_PAUSE:
7772 case VKI_SNDRV_PCM_IOCTL_LINK:
7773 /* these just take an int by value */
7774 break;
7775 case VKI_SNDRV_CTL_IOCTL_PVERSION:
7776 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
7777 break;
7778 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
7779 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
7780 break;
7781 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
7782 struct vki_snd_ctl_elem_list *data =
7783 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
7784 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
7785 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
7786 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
7787 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
7788 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
7789 if (data->pids) {
7790 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
7792 break;
7794 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
7795 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7796 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
7797 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
7798 PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
7799 break;
7801 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
7802 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
7803 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
7804 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
7805 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
7806 PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
7807 break;
7810 /* Real Time Clock (/dev/rtc) ioctls */
7811 case VKI_RTC_UIE_ON:
7812 case VKI_RTC_UIE_OFF:
7813 case VKI_RTC_AIE_ON:
7814 case VKI_RTC_AIE_OFF:
7815 case VKI_RTC_PIE_ON:
7816 case VKI_RTC_PIE_OFF:
7817 case VKI_RTC_IRQP_SET:
7818 break;
7819 case VKI_RTC_RD_TIME:
7820 case VKI_RTC_ALM_READ:
7821 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
7822 ARG3, sizeof(struct vki_rtc_time));
7823 break;
7824 case VKI_RTC_ALM_SET:
7825 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
7826 break;
7827 case VKI_RTC_IRQP_READ:
7828 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
7829 break;
7831 /* Block devices */
7832 case VKI_BLKROSET:
7833 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
7834 break;
7835 case VKI_BLKROGET:
7836 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
7837 break;
7838 case VKI_BLKGETSIZE:
7839 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
7840 break;
7841 case VKI_BLKFLSBUF:
7842 break;
7843 case VKI_BLKRASET:
7844 break;
7845 case VKI_BLKRAGET:
7846 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
7847 break;
7848 case VKI_BLKFRASET:
7849 break;
7850 case VKI_BLKFRAGET:
7851 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
7852 break;
7853 case VKI_BLKSECTGET:
7854 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
7855 break;
7856 case VKI_BLKSSZGET:
7857 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
7858 break;
7859 case VKI_BLKBSZGET:
7860 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
7861 break;
7862 case VKI_BLKBSZSET:
7863 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
7864 break;
7865 case VKI_BLKGETSIZE64:
7866 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
7867 break;
7868 case VKI_BLKPBSZGET:
7869 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
7870 break;
7871 case VKI_BLKIOMIN:
7872 PRE_MEM_WRITE( "ioctl(BLKIOMIN)", ARG3, sizeof(vki_uint));
7873 break;
7874 case VKI_BLKIOOPT:
7875 PRE_MEM_WRITE( "ioctl(BLKIOOPT)", ARG3, sizeof(vki_uint));
7876 break;
7877 case VKI_BLKALIGNOFF:
7878 PRE_MEM_WRITE( "ioctl(BLKALIGNOFF)", ARG3, sizeof(int));
7879 break;
7880 case VKI_BLKDISCARDZEROES:
7881 PRE_MEM_WRITE( "ioctl(BLKDISCARDZEROES)", ARG3, sizeof(vki_uint));
7882 break;
7883 case VKI_BLKREPORTZONE:
7884 PRE_MEM_READ("ioctl(BLKREPORTZONE)", ARG3,
7885 sizeof(struct vki_blk_zone_report));
7886 break;
7887 case VKI_BLKRESETZONE:
7888 PRE_MEM_READ("ioctl(BLKRESETZONE)", ARG3,
7889 sizeof(struct vki_blk_zone_range));
7890 break;
7892 /* Hard disks */
7893 case VKI_HDIO_GETGEO: /* 0x0301 */
7894 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
7895 break;
7896 case VKI_HDIO_GET_DMA: /* 0x030b */
7897 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
7898 break;
7899 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7900 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
7901 VKI_SIZEOF_STRUCT_HD_DRIVEID );
7902 break;
7904 /* SCSI */
7905 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7906 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
7907 break;
7908 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7909 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
7910 break;
7912 /* CD ROM stuff (??) */
7913 case VKI_CDROM_GET_MCN:
7914 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
7915 sizeof(struct vki_cdrom_mcn) );
7916 break;
7917 case VKI_CDROM_SEND_PACKET:
7918 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
7919 sizeof(struct vki_cdrom_generic_command));
7920 break;
7921 case VKI_CDROMSUBCHNL:
7922 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
7923 (Addr) &(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format),
7924 sizeof(((struct vki_cdrom_subchnl*) (Addr)ARG3)->cdsc_format));
7925 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
7926 sizeof(struct vki_cdrom_subchnl));
7927 break;
7928 case VKI_CDROMREADMODE1: /*0x530d*/
7929 PRE_MEM_READ("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7930 PRE_MEM_WRITE("ioctl(CDROMREADMODE1)", ARG3, VKI_CD_FRAMESIZE_RAW1);
7931 break;
7932 case VKI_CDROMREADMODE2: /*0x530c*/
7933 PRE_MEM_READ("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7934 PRE_MEM_WRITE("ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0);
7935 break;
7936 case VKI_CDROMREADTOCHDR:
7937 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
7938 sizeof(struct vki_cdrom_tochdr));
7939 break;
7940 case VKI_CDROMREADTOCENTRY:
7941 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
7942 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format),
7943 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_format));
7944 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
7945 (Addr) &(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track),
7946 sizeof(((struct vki_cdrom_tocentry*) (Addr)ARG3)->cdte_track));
7947 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
7948 sizeof(struct vki_cdrom_tocentry));
7949 break;
7950 case VKI_CDROMMULTISESSION: /* 0x5310 */
7951 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
7952 sizeof(struct vki_cdrom_multisession));
7953 break;
7954 case VKI_CDROMVOLREAD: /* 0x5313 */
7955 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
7956 sizeof(struct vki_cdrom_volctrl));
7957 break;
7958 case VKI_CDROMREADRAW: /* 0x5314 */
7959 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
7960 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
7961 break;
7962 case VKI_CDROMREADAUDIO: /* 0x530e */
7963 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
7964 sizeof (struct vki_cdrom_read_audio));
7965 if ( ARG3 ) {
7966 /* ToDo: don't do any of the following if the structure is invalid */
7967 struct vki_cdrom_read_audio *cra =
7968 (struct vki_cdrom_read_audio *) (Addr)ARG3;
7969 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
7970 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7972 break;
7973 case VKI_CDROMPLAYMSF:
7974 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
7975 break;
7976 /* The following two are probably bogus (should check args
7977 for readability). JRS 20021117 */
7978 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7979 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7980 break;
7981 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7982 break;
7984 case VKI_FIGETBSZ:
7985 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
7986 break;
7987 case VKI_FIBMAP:
7988 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
7989 break;
7990 case VKI_FICLONE:
7991 /* The direction of FICLONE (W) is incorrectly specified
7992 * as it expects a file descriptor and not a pointer to
7993 * user data */
7994 break;
7996 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
7997 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
7998 sizeof(struct vki_fb_var_screeninfo));
7999 break;
8000 case VKI_FBIOPUT_VSCREENINFO:
8001 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
8002 sizeof(struct vki_fb_var_screeninfo));
8003 break;
8004 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
8005 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
8006 sizeof(struct vki_fb_fix_screeninfo));
8007 break;
8008 case VKI_FBIOPAN_DISPLAY:
8009 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
8010 sizeof(struct vki_fb_var_screeninfo));
8012 break;
8013 case VKI_PPCLAIM:
8014 case VKI_PPEXCL:
8015 case VKI_PPYIELD:
8016 case VKI_PPRELEASE:
8017 break;
8018 case VKI_PPSETMODE:
8019 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
8020 break;
8021 case VKI_PPGETMODE:
8022 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
8023 break;
8024 case VKI_PPSETPHASE:
8025 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
8026 break;
8027 case VKI_PPGETPHASE:
8028 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
8029 break;
8030 case VKI_PPGETMODES:
8031 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
8032 break;
8033 case VKI_PPSETFLAGS:
8034 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
8035 break;
8036 case VKI_PPGETFLAGS:
8037 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
8038 break;
8039 case VKI_PPRSTATUS:
8040 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
8041 break;
8042 case VKI_PPRDATA:
8043 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
8044 break;
8045 case VKI_PPRCONTROL:
8046 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
8047 break;
8048 case VKI_PPWDATA:
8049 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
8050 break;
8051 case VKI_PPWCONTROL:
8052 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
8053 break;
8054 case VKI_PPFCONTROL:
8055 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
8056 break;
8057 case VKI_PPDATADIR:
8058 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
8059 break;
8060 case VKI_PPNEGOT:
8061 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
8062 break;
8063 case VKI_PPWCTLONIRQ:
8064 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
8065 break;
8066 case VKI_PPCLRIRQ:
8067 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
8068 break;
8069 case VKI_PPSETTIME:
8070 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
8071 break;
8072 case VKI_PPGETTIME:
8073 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
8074 break;
8076 case VKI_GIO_FONT:
8077 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
8078 break;
8079 case VKI_PIO_FONT:
8080 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
8081 break;
8083 case VKI_GIO_FONTX:
8084 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8085 if ( ARG3 ) {
8086 /* ToDo: don't do any of the following if the structure is invalid */
8087 struct vki_consolefontdesc *cfd =
8088 (struct vki_consolefontdesc *)(Addr)ARG3;
8089 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
8090 32 * cfd->charcount );
8092 break;
8093 case VKI_PIO_FONTX:
8094 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
8095 if ( ARG3 ) {
8096 /* ToDo: don't do any of the following if the structure is invalid */
8097 struct vki_consolefontdesc *cfd =
8098 (struct vki_consolefontdesc *)(Addr)ARG3;
8099 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
8100 32 * cfd->charcount );
8102 break;
8104 case VKI_PIO_FONTRESET:
8105 break;
8107 case VKI_GIO_CMAP:
8108 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
8109 break;
8110 case VKI_PIO_CMAP:
8111 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
8112 break;
8114 case VKI_KIOCSOUND:
8115 case VKI_KDMKTONE:
8116 break;
8118 case VKI_KDGETLED:
8119 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
8120 break;
8121 case VKI_KDSETLED:
8122 break;
8124 case VKI_KDGKBTYPE:
8125 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
8126 break;
8128 case VKI_KDADDIO:
8129 case VKI_KDDELIO:
8130 case VKI_KDENABIO:
8131 case VKI_KDDISABIO:
8132 break;
8134 case VKI_KDSETMODE:
8135 break;
8136 case VKI_KDGETMODE:
8137 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
8138 break;
8140 case VKI_KDMAPDISP:
8141 case VKI_KDUNMAPDISP:
8142 break;
8144 case VKI_GIO_SCRNMAP:
8145 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8146 break;
8147 case VKI_PIO_SCRNMAP:
8148 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
8149 break;
8150 case VKI_GIO_UNISCRNMAP:
8151 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
8152 VKI_E_TABSZ * sizeof(unsigned short) );
8153 break;
8154 case VKI_PIO_UNISCRNMAP:
8155 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
8156 VKI_E_TABSZ * sizeof(unsigned short) );
8157 break;
8159 case VKI_GIO_UNIMAP:
8160 if ( ARG3 ) {
8161 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
8162 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
8163 sizeof(unsigned short));
8164 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
8165 sizeof(struct vki_unipair *));
8166 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
8167 desc->entry_ct * sizeof(struct vki_unipair));
8169 break;
8170 case VKI_PIO_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_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
8178 desc->entry_ct * sizeof(struct vki_unipair) );
8180 break;
8181 case VKI_PIO_UNIMAPCLR:
8182 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
8183 break;
8185 case VKI_KDGKBMODE:
8186 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
8187 break;
8188 case VKI_KDSKBMODE:
8189 break;
8191 case VKI_KDGKBMETA:
8192 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
8193 break;
8194 case VKI_KDSKBMETA:
8195 break;
8197 case VKI_KDGKBLED:
8198 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
8199 break;
8200 case VKI_KDSKBLED:
8201 break;
8203 case VKI_KDGKBENT:
8204 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
8205 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_table,
8206 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_table) );
8207 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
8208 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8209 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8210 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
8211 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8212 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8213 break;
8214 case VKI_KDSKBENT:
8215 PRE_MEM_READ( "ioctl(KDSKBENT).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(KDSKBENT).kb_index",
8219 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_index,
8220 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_index) );
8221 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
8222 (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
8223 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
8224 break;
8226 case VKI_KDGKBSENT:
8227 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
8228 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8229 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8230 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
8231 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
8232 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
8233 break;
8234 case VKI_KDSKBSENT:
8235 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
8236 (Addr)&((struct vki_kbsentry *)(Addr)ARG3)->kb_func,
8237 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_func) );
8238 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
8239 (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string );
8240 break;
8242 case VKI_KDGKBDIACR:
8243 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8244 break;
8245 case VKI_KDSKBDIACR:
8246 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
8247 break;
8249 case VKI_KDGETKEYCODE:
8250 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
8251 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8252 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8253 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
8254 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8255 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8256 break;
8257 case VKI_KDSETKEYCODE:
8258 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
8259 (Addr)&((struct vki_kbkeycode *)(Addr)ARG3)->scancode,
8260 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->scancode) );
8261 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
8262 (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
8263 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
8264 break;
8266 case VKI_KDSIGACCEPT:
8267 break;
8269 case VKI_KDKBDREP:
8270 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
8271 break;
8273 case VKI_KDFONTOP:
8274 if ( ARG3 ) {
8275 struct vki_console_font_op *op =
8276 (struct vki_console_font_op *) (Addr)ARG3;
8277 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
8278 sizeof(struct vki_console_font_op) );
8279 switch ( op->op ) {
8280 case VKI_KD_FONT_OP_SET:
8281 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
8282 (Addr)op->data,
8283 (op->width + 7) / 8 * 32 * op->charcount );
8284 break;
8285 case VKI_KD_FONT_OP_GET:
8286 if ( op->data )
8287 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
8288 (Addr)op->data,
8289 (op->width + 7) / 8 * 32 * op->charcount );
8290 break;
8291 case VKI_KD_FONT_OP_SET_DEFAULT:
8292 if ( op->data )
8293 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
8294 (Addr)op->data );
8295 break;
8296 case VKI_KD_FONT_OP_COPY:
8297 break;
8300 break;
8302 case VKI_VT_OPENQRY:
8303 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
8304 break;
8305 case VKI_VT_GETMODE:
8306 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8307 break;
8308 case VKI_VT_SETMODE:
8309 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
8310 break;
8311 case VKI_VT_GETSTATE:
8312 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
8313 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
8314 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active));
8315 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
8316 (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
8317 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state));
8318 break;
8319 case VKI_VT_RELDISP:
8320 case VKI_VT_ACTIVATE:
8321 case VKI_VT_WAITACTIVE:
8322 case VKI_VT_DISALLOCATE:
8323 break;
8324 case VKI_VT_RESIZE:
8325 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
8326 break;
8327 case VKI_VT_RESIZEX:
8328 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
8329 break;
8330 case VKI_VT_LOCKSWITCH:
8331 case VKI_VT_UNLOCKSWITCH:
8332 break;
8334 case VKI_USBDEVFS_CONTROL:
8335 if ( ARG3 ) {
8336 struct vki_usbdevfs_ctrltransfer *vkuc =
8337 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
8338 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
8339 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
8340 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
8341 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
8342 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
8343 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
8344 if (vkuc->bRequestType & 0x80)
8345 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8346 else
8347 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
8349 break;
8350 case VKI_USBDEVFS_BULK:
8351 if ( ARG3 ) {
8352 struct vki_usbdevfs_bulktransfer *vkub =
8353 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
8354 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
8355 if (vkub->ep & 0x80)
8356 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8357 else
8358 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
8360 break;
8361 case VKI_USBDEVFS_GETDRIVER:
8362 if ( ARG3 ) {
8363 struct vki_usbdevfs_getdriver *vkugd =
8364 (struct vki_usbdevfs_getdriver *) (Addr)ARG3;
8365 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
8367 break;
8368 case VKI_USBDEVFS_SUBMITURB:
8369 if ( ARG3 ) {
8370 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)(Addr)ARG3;
8372 /* Not the whole struct needs to be initialized */
8373 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
8374 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
8375 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
8376 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
8377 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
8378 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
8379 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
8380 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
8381 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8382 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
8383 if (vkusp->bRequestType & 0x80)
8384 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8385 else
8386 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
8387 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8388 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
8389 int total_length = 0;
8390 int i;
8391 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
8392 for(i=0; i<vkuu->number_of_packets; i++) {
8393 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
8394 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));
8395 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
8396 total_length += vkuu->iso_frame_desc[i].length;
8398 if (vkuu->endpoint & 0x80)
8399 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8400 else
8401 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
8402 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
8403 } else {
8404 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
8405 if (vkuu->endpoint & 0x80)
8406 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8407 else
8408 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
8409 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
8412 break;
8413 case VKI_USBDEVFS_DISCARDURB:
8414 break;
8415 case VKI_USBDEVFS_REAPURB:
8416 if ( ARG3 ) {
8417 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8419 break;
8420 case VKI_USBDEVFS_REAPURBNDELAY:
8421 if ( ARG3 ) {
8422 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
8424 break;
8425 case VKI_USBDEVFS_CONNECTINFO:
8426 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
8427 break;
8428 case VKI_USBDEVFS_IOCTL:
8429 if ( ARG3 ) {
8430 struct vki_usbdevfs_ioctl *vkui =
8431 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
8432 UInt dir2, size2;
8433 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
8434 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
8435 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
8436 if (size2 > 0) {
8437 if (dir2 & _VKI_IOC_WRITE)
8438 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
8439 else if (dir2 & _VKI_IOC_READ)
8440 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
8443 break;
8444 case VKI_USBDEVFS_RESET:
8445 break;
8447 /* I2C (/dev/i2c-*) ioctls */
8448 case VKI_I2C_SLAVE:
8449 case VKI_I2C_SLAVE_FORCE:
8450 case VKI_I2C_TENBIT:
8451 case VKI_I2C_PEC:
8452 break;
8453 case VKI_I2C_FUNCS:
8454 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
8455 break;
8456 case VKI_I2C_RDWR:
8457 if ( ARG3 ) {
8458 struct vki_i2c_rdwr_ioctl_data *vkui =
8459 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
8460 UInt i;
8461 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
8462 for (i=0; i < vkui->nmsgs; i++) {
8463 struct vki_i2c_msg *msg = vkui->msgs + i;
8464 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
8465 if (msg->flags & VKI_I2C_M_RD)
8466 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8467 else
8468 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
8471 break;
8472 case VKI_I2C_SMBUS:
8473 if ( ARG3 ) {
8474 struct vki_i2c_smbus_ioctl_data *vkis
8475 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
8476 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.read_write",
8477 (Addr)&vkis->read_write, sizeof(vkis->read_write));
8478 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.size",
8479 (Addr)&vkis->size, sizeof(vkis->size));
8480 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS).i2c_smbus_ioctl_data.command",
8481 (Addr)&vkis->command, sizeof(vkis->command));
8482 /* i2c_smbus_write_quick hides its value in read_write, so
8483 this variable can have a different meaning */
8484 /* to make matters worse i2c_smbus_write_byte stores its
8485 value in command */
8486 if ( ! ((vkis->size == VKI_I2C_SMBUS_QUICK) ||
8487 ((vkis->size == VKI_I2C_SMBUS_BYTE)
8488 && (vkis->read_write == VKI_I2C_SMBUS_WRITE)))) {
8489 /* the rest uses the byte array to store the data,
8490 some the first byte for size */
8491 UInt size;
8492 switch(vkis->size) {
8493 case VKI_I2C_SMBUS_BYTE_DATA:
8494 size = 1;
8495 break;
8496 case VKI_I2C_SMBUS_WORD_DATA:
8497 case VKI_I2C_SMBUS_PROC_CALL:
8498 size = 2;
8499 break;
8500 case VKI_I2C_SMBUS_BLOCK_DATA:
8501 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
8502 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
8503 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
8504 size = 1 + vkis->data->block[0];
8505 break;
8506 default:
8507 size = 0;
8510 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
8511 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
8512 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL))
8513 PRE_MEM_WRITE("ioctl(VKI_I2C_SMBUS)"
8514 ".i2c_smbus_ioctl_data.data",
8515 (Addr)&vkis->data->block[0], size);
8516 else
8517 PRE_MEM_READ("ioctl(VKI_I2C_SMBUS)."
8518 "i2c_smbus_ioctl_data.data",
8519 (Addr)&vkis->data->block[0], size);
8522 break;
8524 /* Wireless extensions ioctls */
8525 case VKI_SIOCSIWCOMMIT:
8526 case VKI_SIOCSIWNWID:
8527 case VKI_SIOCSIWFREQ:
8528 case VKI_SIOCSIWMODE:
8529 case VKI_SIOCSIWSENS:
8530 case VKI_SIOCSIWRANGE:
8531 case VKI_SIOCSIWPRIV:
8532 case VKI_SIOCSIWSTATS:
8533 case VKI_SIOCSIWSPY:
8534 case VKI_SIOCSIWTHRSPY:
8535 case VKI_SIOCSIWAP:
8536 case VKI_SIOCSIWSCAN:
8537 case VKI_SIOCSIWESSID:
8538 case VKI_SIOCSIWRATE:
8539 case VKI_SIOCSIWNICKN:
8540 case VKI_SIOCSIWRTS:
8541 case VKI_SIOCSIWFRAG:
8542 case VKI_SIOCSIWTXPOW:
8543 case VKI_SIOCSIWRETRY:
8544 case VKI_SIOCSIWENCODE:
8545 case VKI_SIOCSIWPOWER:
8546 case VKI_SIOCSIWGENIE:
8547 case VKI_SIOCSIWMLME:
8548 case VKI_SIOCSIWAUTH:
8549 case VKI_SIOCSIWENCODEEXT:
8550 case VKI_SIOCSIWPMKSA:
8551 break;
8552 case VKI_SIOCGIWNAME:
8553 if (ARG3) {
8554 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
8555 (Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
8556 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
8558 break;
8559 case VKI_SIOCGIWNWID:
8560 case VKI_SIOCGIWSENS:
8561 case VKI_SIOCGIWRATE:
8562 case VKI_SIOCGIWRTS:
8563 case VKI_SIOCGIWFRAG:
8564 case VKI_SIOCGIWTXPOW:
8565 case VKI_SIOCGIWRETRY:
8566 case VKI_SIOCGIWPOWER:
8567 case VKI_SIOCGIWAUTH:
8568 if (ARG3) {
8569 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
8570 "RETRY|PARAM|AUTH])",
8571 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.nwid,
8572 sizeof(struct vki_iw_param));
8574 break;
8575 case VKI_SIOCGIWFREQ:
8576 if (ARG3) {
8577 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
8578 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
8579 sizeof(struct vki_iw_freq));
8581 break;
8582 case VKI_SIOCGIWMODE:
8583 if (ARG3) {
8584 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
8585 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
8586 sizeof(__vki_u32));
8588 break;
8589 case VKI_SIOCGIWRANGE:
8590 case VKI_SIOCGIWPRIV:
8591 case VKI_SIOCGIWSTATS:
8592 case VKI_SIOCGIWSPY:
8593 case VKI_SIOCGIWTHRSPY:
8594 case VKI_SIOCGIWAPLIST:
8595 case VKI_SIOCGIWSCAN:
8596 case VKI_SIOCGIWESSID:
8597 case VKI_SIOCGIWNICKN:
8598 case VKI_SIOCGIWENCODE:
8599 case VKI_SIOCGIWGENIE:
8600 case VKI_SIOCGIWENCODEEXT:
8601 if (ARG3) {
8602 struct vki_iw_point* point;
8603 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
8604 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
8605 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
8606 (Addr)point->pointer, point->length);
8608 break;
8609 case VKI_SIOCGIWAP:
8610 if (ARG3) {
8611 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
8612 (Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
8613 sizeof(struct vki_sockaddr));
8615 break;
8617 /* User input device creation */
8618 case VKI_UI_SET_EVBIT:
8619 case VKI_UI_SET_KEYBIT:
8620 case VKI_UI_SET_RELBIT:
8621 case VKI_UI_SET_ABSBIT:
8622 case VKI_UI_SET_MSCBIT:
8623 case VKI_UI_SET_LEDBIT:
8624 case VKI_UI_SET_SNDBIT:
8625 case VKI_UI_SET_FFBIT:
8626 case VKI_UI_SET_SWBIT:
8627 case VKI_UI_SET_PROPBIT:
8628 /* These just take an int by value */
8629 break;
8631 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
8632 || defined(VGPV_mips32_linux_android) \
8633 || defined(VGPV_arm64_linux_android)
8634 /* ashmem */
8635 case VKI_ASHMEM_GET_SIZE:
8636 case VKI_ASHMEM_SET_SIZE:
8637 case VKI_ASHMEM_GET_PROT_MASK:
8638 case VKI_ASHMEM_SET_PROT_MASK:
8639 case VKI_ASHMEM_GET_PIN_STATUS:
8640 case VKI_ASHMEM_PURGE_ALL_CACHES:
8641 break;
8642 case VKI_ASHMEM_GET_NAME:
8643 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
8644 break;
8645 case VKI_ASHMEM_SET_NAME:
8646 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
8647 break;
8648 case VKI_ASHMEM_PIN:
8649 case VKI_ASHMEM_UNPIN:
8650 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
8651 ARG3, sizeof(struct vki_ashmem_pin) );
8652 break;
8654 /* binder */
8655 case VKI_BINDER_WRITE_READ:
8656 if (ARG3) {
8657 struct vki_binder_write_read* bwr
8658 = (struct vki_binder_write_read*)(Addr)ARG3;
8660 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
8661 bwr->write_buffer);
8662 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
8663 bwr->write_size);
8664 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
8665 bwr->write_consumed);
8666 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
8667 bwr->read_buffer);
8668 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
8669 bwr->read_size);
8670 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
8671 bwr->read_consumed);
8673 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
8674 bwr->write_consumed);
8675 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
8676 bwr->read_consumed);
8678 if (bwr->read_size)
8679 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
8680 (Addr)bwr->read_buffer, bwr->read_size);
8681 if (bwr->write_size)
8682 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
8683 (Addr)bwr->write_buffer, bwr->write_size);
8685 break;
8687 case VKI_BINDER_SET_IDLE_TIMEOUT:
8688 case VKI_BINDER_SET_MAX_THREADS:
8689 case VKI_BINDER_SET_IDLE_PRIORITY:
8690 case VKI_BINDER_SET_CONTEXT_MGR:
8691 case VKI_BINDER_THREAD_EXIT:
8692 break;
8693 case VKI_BINDER_VERSION:
8694 if (ARG3) {
8695 struct vki_binder_version* bv =
8696 (struct vki_binder_version*)(Addr)ARG3;
8697 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
8699 break;
8700 # endif /* defined(VGPV_*_linux_android) */
8702 case VKI_HCIGETDEVLIST:
8703 if (ARG3) {
8704 struct vki_hci_dev_list_req* dlr =
8705 (struct vki_hci_dev_list_req*)(Addr)ARG3;
8706 PRE_MEM_READ("ioctl(HCIGETDEVLIST)",
8707 (Addr)ARG3, sizeof(struct vki_hci_dev_list_req));
8708 PRE_MEM_WRITE("ioctl(HCIGETDEVLIST)",
8709 (Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
8710 dlr->dev_num * sizeof(struct vki_hci_dev_req));
8712 break;
8714 case VKI_HCIINQUIRY:
8715 if (ARG3) {
8716 struct vki_hci_inquiry_req* ir =
8717 (struct vki_hci_inquiry_req*)(Addr)ARG3;
8718 PRE_MEM_READ("ioctl(HCIINQUIRY)",
8719 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
8720 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
8721 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
8722 ir->num_rsp * sizeof(struct vki_inquiry_info));
8724 break;
8726 case VKI_DRM_IOCTL_VERSION:
8727 if (ARG3) {
8728 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
8729 struct vg_drm_version_info* info;
8730 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
8731 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
8732 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
8733 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
8734 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
8735 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
8736 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
8737 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
8738 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
8739 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
8740 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
8741 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
8742 info = VG_(malloc)("syswrap.ioctl.1", sizeof(*info));
8743 // To ensure we VG_(free) info even when syscall fails:
8744 *flags |= SfPostOnFail;
8745 info->data = *data;
8746 info->orig = data;
8747 ARG3 = (Addr)&info->data;
8749 break;
8750 case VKI_DRM_IOCTL_GET_UNIQUE:
8751 if (ARG3) {
8752 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
8753 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
8754 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
8755 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
8757 break;
8758 case VKI_DRM_IOCTL_GET_MAGIC:
8759 if (ARG3) {
8760 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
8761 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
8763 break;
8764 case VKI_DRM_IOCTL_WAIT_VBLANK:
8765 if (ARG3) {
8766 union vki_drm_wait_vblank *data =
8767 (union vki_drm_wait_vblank *)(Addr)ARG3;
8768 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
8769 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
8770 /* XXX: It seems request.signal isn't used */
8771 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
8773 break;
8774 case VKI_DRM_IOCTL_GEM_CLOSE:
8775 if (ARG3) {
8776 struct vki_drm_gem_close *data =
8777 (struct vki_drm_gem_close *)(Addr)ARG3;
8778 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
8780 break;
8781 case VKI_DRM_IOCTL_GEM_FLINK:
8782 if (ARG3) {
8783 struct vki_drm_gem_flink *data =
8784 (struct vki_drm_gem_flink *)(Addr)ARG3;
8785 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
8786 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
8788 break;
8789 case VKI_DRM_IOCTL_GEM_OPEN:
8790 if (ARG3) {
8791 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
8792 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
8793 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
8794 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
8796 break;
8797 case VKI_DRM_IOCTL_I915_GETPARAM:
8798 if (ARG3) {
8799 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
8800 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
8801 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
8803 break;
8804 case VKI_DRM_IOCTL_I915_GEM_BUSY:
8805 if (ARG3) {
8806 struct vki_drm_i915_gem_busy *data =
8807 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
8808 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
8809 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
8811 break;
8812 case VKI_DRM_IOCTL_I915_GEM_CREATE:
8813 if (ARG3) {
8814 struct vki_drm_i915_gem_create *data =
8815 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
8816 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
8817 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
8819 break;
8820 case VKI_DRM_IOCTL_I915_GEM_PREAD:
8821 if (ARG3) {
8822 struct vki_drm_i915_gem_pread *data =
8823 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
8824 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
8825 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
8826 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
8827 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8828 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
8830 break;
8831 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
8832 if (ARG3) {
8833 struct vki_drm_i915_gem_pwrite *data =
8834 (struct vki_drm_i915_gem_pwrite *)(Addr)ARG3;
8835 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
8836 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
8837 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
8838 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
8839 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
8840 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
8841 * interleaved vertex attributes may have a wide stride with uninitialized data between
8842 * consecutive vertices) */
8844 break;
8845 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
8846 if (ARG3) {
8847 struct vki_drm_i915_gem_mmap_v1 *data =
8848 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
8849 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).handle", (Addr)&data->handle, sizeof(data->handle));
8850 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).offset", (Addr)&data->offset, sizeof(data->offset));
8851 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAPv1).size", (Addr)&data->size, sizeof(data->size));
8852 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAPv1).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8854 break;
8855 case VKI_DRM_IOCTL_I915_GEM_MMAP:
8856 if (ARG3) {
8857 struct vki_drm_i915_gem_mmap *data =
8858 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
8859 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).handle", (Addr)&data->handle, sizeof(data->handle));
8860 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).offset", (Addr)&data->offset, sizeof(data->offset));
8861 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).size", (Addr)&data->size, sizeof(data->size));
8862 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP).flags", (Addr)&data->size, sizeof(data->flags));
8863 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP).addr_ptr", (Addr)&data->addr_ptr, sizeof(data->addr_ptr));
8865 break;
8866 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
8867 if (ARG3) {
8868 struct vki_drm_i915_gem_mmap_gtt *data =
8869 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
8870 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
8871 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
8873 break;
8874 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
8875 if (ARG3) {
8876 struct vki_drm_i915_gem_set_domain *data =
8877 (struct vki_drm_i915_gem_set_domain *)(Addr)ARG3;
8878 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
8879 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
8880 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
8882 break;
8883 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
8884 if (ARG3) {
8885 struct vki_drm_i915_gem_set_tiling *data =
8886 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
8887 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8888 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8889 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
8890 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8892 break;
8893 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
8894 if (ARG3) {
8895 struct vki_drm_i915_gem_get_tiling *data =
8896 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
8897 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
8898 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
8899 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
8901 break;
8902 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
8903 if (ARG3) {
8904 struct vki_drm_i915_gem_get_aperture *data =
8905 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
8906 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
8907 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
8909 break;
8911 /* KVM ioctls that check for a numeric value as parameter */
8912 case VKI_KVM_GET_API_VERSION:
8913 case VKI_KVM_CREATE_VM:
8914 case VKI_KVM_GET_VCPU_MMAP_SIZE:
8915 case VKI_KVM_CHECK_EXTENSION:
8916 case VKI_KVM_SET_TSS_ADDR:
8917 case VKI_KVM_CREATE_VCPU:
8918 case VKI_KVM_RUN:
8919 break;
8921 case VKI_KVM_S390_MEM_OP: {
8922 struct vki_kvm_s390_mem_op *args =
8923 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
8924 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP)", ARG3,
8925 sizeof(struct vki_kvm_s390_mem_op));
8926 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
8927 break;
8928 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
8929 PRE_MEM_WRITE("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8930 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_WRITE)
8931 PRE_MEM_READ("ioctl(KVM_S390_MEM_OP).buf", (Addr)args->buf, args->size);
8933 break;
8936 #ifdef ENABLE_XEN
8937 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8938 SyscallArgs harrghs;
8939 struct vki_xen_privcmd_hypercall *args =
8940 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
8942 if (!args)
8943 break;
8945 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8946 harrghs.sysno = args->op;
8947 harrghs.arg1 = args->arg[0];
8948 harrghs.arg2 = args->arg[1];
8949 harrghs.arg3 = args->arg[2];
8950 harrghs.arg4 = args->arg[3];
8951 harrghs.arg5 = args->arg[4];
8952 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8954 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
8956 /* HACK. arg8 is used to return the number of hypercall
8957 * arguments actually consumed! */
8958 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
8959 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
8961 break;
8964 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
8965 struct vki_xen_privcmd_mmap *args =
8966 (struct vki_xen_privcmd_mmap *)(Addr)(ARG3);
8967 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
8968 (Addr)&args->num, sizeof(args->num));
8969 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
8970 (Addr)&args->dom, sizeof(args->dom));
8971 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
8972 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
8973 break;
8975 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8976 struct vki_xen_privcmd_mmapbatch *args =
8977 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
8978 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
8979 (Addr)&args->num, sizeof(args->num));
8980 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
8981 (Addr)&args->dom, sizeof(args->dom));
8982 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
8983 (Addr)&args->addr, sizeof(args->addr));
8984 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
8985 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8986 break;
8988 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8989 struct vki_xen_privcmd_mmapbatch_v2 *args =
8990 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
8991 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
8992 (Addr)&args->num, sizeof(args->num));
8993 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
8994 (Addr)&args->dom, sizeof(args->dom));
8995 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
8996 (Addr)&args->addr, sizeof(args->addr));
8997 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
8998 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
8999 break;
9002 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ: {
9003 struct vki_xen_ioctl_evtchn_bind_virq *args =
9004 (struct vki_xen_ioctl_evtchn_bind_virq *)(Addr)(ARG3);
9005 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ(virq)",
9006 (Addr)&args->virq, sizeof(args->virq));
9008 break;
9009 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN: {
9010 struct vki_xen_ioctl_evtchn_bind_interdomain *args =
9011 (struct vki_xen_ioctl_evtchn_bind_interdomain *)(Addr)(ARG3);
9012 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_domain)",
9013 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9014 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN(remote_port)",
9015 (Addr)&args->remote_port, sizeof(args->remote_port));
9017 break;
9018 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
9019 struct vki_xen_ioctl_evtchn_bind_unbound_port *args =
9020 (struct vki_xen_ioctl_evtchn_bind_unbound_port *)(Addr)(ARG3);
9021 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT(remote_domain)",
9022 (Addr)&args->remote_domain, sizeof(args->remote_domain));
9024 break;
9025 case VKI_XEN_IOCTL_EVTCHN_UNBIND: {
9026 struct vki_xen_ioctl_evtchn_unbind *args =
9027 (struct vki_xen_ioctl_evtchn_unbind *)(Addr)(ARG3);
9028 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_UNBIND(port)",
9029 (Addr)&args->port, sizeof(args->port));
9031 break;
9032 case VKI_XEN_IOCTL_EVTCHN_NOTIFY: {
9033 struct vki_xen_ioctl_evtchn_notify *args =
9034 (struct vki_xen_ioctl_evtchn_notify*)(Addr)(ARG3);
9035 PRE_MEM_READ("VKI_XEN_IOCTL_EVTCHN_notify(port)",
9036 (Addr)&args->port, sizeof(args->port));
9038 break;
9039 case VKI_XEN_IOCTL_EVTCHN_RESET:
9040 /* No input*/
9041 break;
9042 #endif
9044 /* Lustre */
9045 case VKI_OBD_IOC_FID2PATH: {
9046 struct vki_getinfo_fid2path *gf =
9047 (struct vki_getinfo_fid2path *)(Addr)ARG3;
9048 PRE_MEM_READ("VKI_OBD_IOC_FID2PATH(args)", ARG3, sizeof(struct vki_getinfo_fid2path));
9049 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_recno", gf->gf_recno);
9050 PRE_FIELD_WRITE("VKI_OBD_IOC_FID2PATH(args).gf_linkno", gf->gf_linkno);
9051 PRE_MEM_WRITE("VKI_OBD_IOC_FID2PATH(args)", (Addr)gf->gf_path, gf->gf_pathlen);
9052 break;
9055 case VKI_LL_IOC_PATH2FID:
9056 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_PATH2FID)", ARG3, sizeof(struct vki_lu_fid));
9057 break;
9059 case VKI_LL_IOC_GETPARENT: {
9060 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
9061 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_linkno", gp->gp_linkno);
9062 PRE_FIELD_READ("ioctl(VKI_LL_IOC_GETPARENT).gp_name_size", gp->gp_name_size);
9063 PRE_FIELD_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_fid", gp->gp_fid);
9064 PRE_MEM_WRITE("ioctl(VKI_LL_IOC_GETPARENT).gp_name", (Addr)gp->gp_name, gp->gp_name_size);
9065 break;
9068 /* V4L2 */
9069 case VKI_V4L2_QUERYCAP: {
9070 struct vki_v4l2_capability *data =
9071 (struct vki_v4l2_capability *)(Addr)ARG3;
9072 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCAP)", (Addr)data, sizeof(*data));
9073 break;
9075 case VKI_V4L2_ENUM_FMT: {
9076 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
9077 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).index", data->index);
9078 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FMT).type", data->type);
9079 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).flags", data->flags);
9080 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).description", data->description);
9081 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).pixelformat", data->pixelformat);
9082 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FMT).reserved", data->reserved);
9083 break;
9085 case VKI_V4L2_G_FMT: {
9086 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9087 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).type", data->type);
9088 switch (data->type) {
9089 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9090 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9091 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.pix.priv", data->fmt.pix.priv);
9092 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix", data->fmt.pix);
9093 PRE_MEM_READ("ioctl(VKI_V4L2_G_FMT)",
9094 (Addr)&data->type + sizeof(data->type) + sizeof(data->fmt.pix),
9095 sizeof(*data) - sizeof(data->type) - sizeof(data->fmt.pix));
9096 break;
9097 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9098 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9099 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.vbi", data->fmt.vbi);
9100 break;
9101 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9102 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9103 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sliced", data->fmt.sliced);
9104 break;
9105 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9106 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9107 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clips", data->fmt.win.clips);
9108 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.bitmap", data->fmt.win.bitmap);
9109 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9110 if (data->fmt.win.clipcount && data->fmt.win.clips)
9111 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clips[]",
9112 (Addr)data->fmt.win.clips,
9113 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9114 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.clipcount", data->fmt.win.clipcount);
9115 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.w", data->fmt.win.w);
9116 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.field", data->fmt.win.field);
9117 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.chromakey", data->fmt.win.chromakey);
9118 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.win.global_alpha", data->fmt.win.global_alpha);
9119 break;
9120 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9121 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9122 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.pix_mp", data->fmt.pix_mp);
9123 break;
9124 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9125 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FMT).fmt.sdr", data->fmt.sdr);
9126 break;
9128 break;
9130 case VKI_V4L2_S_FMT: {
9131 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9132 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).type", data->type);
9133 switch (data->type) {
9134 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9135 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9136 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT)",
9137 (Addr)&data->type + sizeof(data->type),
9138 sizeof(*data) - sizeof(data->type));
9139 break;
9140 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9141 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9142 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.vbi", data->fmt.vbi);
9143 break;
9144 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9145 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9146 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sliced", data->fmt.sliced);
9147 break;
9148 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9149 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9150 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.win", data->fmt.win);
9151 if (data->fmt.win.clipcount && data->fmt.win.clips)
9152 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.clips[]",
9153 (Addr)data->fmt.win.clips,
9154 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9155 if (data->fmt.win.bitmap)
9156 PRE_MEM_READ("ioctl(VKI_V4L2_S_FMT).fmt.win.bitmap[]",
9157 (Addr)data->fmt.win.bitmap,
9158 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9159 break;
9160 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9161 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9162 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.pix_mp", data->fmt.pix_mp);
9163 break;
9164 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9165 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FMT).fmt.sdr", data->fmt.sdr);
9166 break;
9168 break;
9170 case VKI_V4L2_TRY_FMT: {
9171 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
9172 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).type", data->type);
9173 switch (data->type) {
9174 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9175 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9176 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT)",
9177 (Addr)&data->type + sizeof(data->type),
9178 sizeof(*data) - sizeof(data->type));
9179 break;
9180 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9181 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9182 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.vbi", data->fmt.vbi);
9183 break;
9184 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9185 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9186 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sliced", data->fmt.sliced);
9187 break;
9188 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9189 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9190 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win", data->fmt.win);
9191 if (data->fmt.win.clipcount && data->fmt.win.clips)
9192 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.clips[]",
9193 (Addr)data->fmt.win.clips,
9194 data->fmt.win.clipcount * sizeof(data->fmt.win.clips[0]));
9195 if (data->fmt.win.bitmap)
9196 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.win.bitmap[]",
9197 (Addr)data->fmt.win.bitmap,
9198 data->fmt.win.w.height * ((data->fmt.win.w.width + 7) / 8));
9199 break;
9200 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9201 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9202 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.pix_mp", data->fmt.pix_mp);
9203 break;
9204 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9205 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_FMT).fmt.sdr", data->fmt.sdr);
9206 break;
9208 break;
9210 case VKI_V4L2_REQBUFS: {
9211 struct vki_v4l2_requestbuffers *data =
9212 (struct vki_v4l2_requestbuffers *)(Addr)ARG3;
9213 PRE_MEM_READ("ioctl(VKI_V4L2_REQBUFS)", (Addr)data, sizeof(*data));
9214 break;
9216 case VKI_V4L2_QUERYBUF: {
9217 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9218 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).type", data->type);
9219 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).index", data->index);
9220 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved", data->reserved);
9221 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).reserved2", data->reserved2);
9222 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9223 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9224 unsigned i;
9226 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9227 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYBUF).m.planes", data->m.planes);
9228 for (i = 0; i < data->length; i++) {
9229 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9230 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].length", data->m.planes[i].length);
9231 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].m", data->m.planes[i].m);
9232 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9233 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m.planes[].reserved", data->m.planes[i].reserved);
9235 } else {
9236 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).m", data->m);
9237 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).length", data->length);
9239 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).bytesused", data->bytesused);
9240 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).flags", data->flags);
9241 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).field", data->field);
9242 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timestamp", data->timestamp);
9243 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).timecode", data->timecode);
9244 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9245 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).memory", data->memory);
9246 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QUERYBUF).sequence", data->sequence);
9247 break;
9249 case VKI_V4L2_G_FBUF: {
9250 struct vki_v4l2_framebuffer *data =
9251 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9252 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_FBUF)", (Addr)data, sizeof(*data));
9253 break;
9255 case VKI_V4L2_S_FBUF: {
9256 struct vki_v4l2_framebuffer *data =
9257 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
9258 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_FBUF).capability", data->capability);
9259 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).flags", data->flags);
9260 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).base", data->base);
9261 PRE_FIELD_READ("ioctl(VKI_V4L2_S_FBUF).fmt", data->fmt);
9262 break;
9264 case VKI_V4L2_OVERLAY: {
9265 int *data = (int *)(Addr)ARG3;
9266 PRE_MEM_READ("ioctl(VKI_V4L2_OVERLAY)", (Addr)data, sizeof(*data));
9267 break;
9269 case VKI_V4L2_QBUF: {
9270 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9271 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9272 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9273 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9274 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9276 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).type", data->type);
9277 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).index", data->index);
9278 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).flags", data->flags);
9279 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).memory", data->memory);
9280 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved", data->reserved);
9281 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).reserved2", data->reserved2);
9282 if (is_output) {
9283 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9284 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9286 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9287 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9288 unsigned i;
9290 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).length", data->length);
9291 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes", data->m.planes);
9292 for (i = 0; i < data->length; i++) {
9293 if (is_output) {
9294 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9295 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9297 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9298 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9299 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9300 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m.fd", data->m.planes[i].m.fd);
9301 else
9302 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].m", data->m.planes[i].m);
9303 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.planes[].reserved", data->m.planes[i].reserved);
9305 } else {
9306 if (data->memory == VKI_V4L2_MEMORY_MMAP)
9307 PRE_FIELD_WRITE("ioctl(VKI_V4L2_QBUF).m", data->m);
9308 else if (data->memory == VKI_V4L2_MEMORY_DMABUF)
9309 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m.fd", data->m.fd);
9310 else
9311 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).m", data->m);
9312 if (is_output) {
9313 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).bytesused", data->bytesused);
9314 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).field", data->field);
9317 if (is_output && (data->flags & VKI_V4L2_BUF_FLAG_TIMESTAMP_MASK) == VKI_V4L2_BUF_FLAG_TIMESTAMP_COPY) {
9318 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timestamp", data->timestamp);
9319 PRE_FIELD_READ("ioctl(VKI_V4L2_QBUF).timecode", data->timecode);
9321 break;
9323 case VKI_V4L2_EXPBUF: {
9324 struct vki_v4l2_exportbuffer *data =
9325 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
9326 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).type", data->type);
9327 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).index", data->index);
9328 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).plane", data->plane);
9329 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).flags", data->flags);
9330 PRE_FIELD_WRITE("ioctl(VKI_V4L2_EXPBUF).fd", data->fd);
9331 PRE_FIELD_READ("ioctl(VKI_V4L2_EXPBUF).reserved", data->reserved);
9332 break;
9334 case VKI_V4L2_DQBUF: {
9335 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9336 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).type", data->type);
9337 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).index", data->index);
9338 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).memory", data->memory);
9339 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved", data->reserved);
9340 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).reserved2", data->reserved2);
9341 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9342 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9343 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9344 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9345 unsigned i;
9347 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).length", data->length);
9348 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes", data->m.planes);
9349 for (i = 0; i < data->length; i++) {
9350 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].bytesused", data->m.planes[i].bytesused);
9351 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].data_offset", data->m.planes[i].data_offset);
9352 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].length", data->m.planes[i].length);
9353 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m.planes[].m", data->m.planes[i].m);
9354 PRE_FIELD_READ("ioctl(VKI_V4L2_DQBUF).m.planes[].reserved", data->m.planes[i].reserved);
9356 } else {
9357 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).m", data->m);
9358 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).length", data->length);
9359 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).bytesused", data->bytesused);
9360 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).field", data->field);
9362 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timestamp", data->timestamp);
9363 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).timecode", data->timecode);
9364 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DQBUF).sequence", data->sequence);
9365 break;
9367 case VKI_V4L2_STREAMON: {
9368 int *data = (int *)(Addr)ARG3;
9369 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMON)", (Addr)data, sizeof(*data));
9370 break;
9372 case VKI_V4L2_STREAMOFF: {
9373 int *data = (int *)(Addr)ARG3;
9374 PRE_MEM_READ("ioctl(VKI_V4L2_STREAMOFF)", (Addr)data, sizeof(*data));
9375 break;
9377 case VKI_V4L2_G_PARM: {
9378 struct vki_v4l2_streamparm *data =
9379 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9380 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9381 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9382 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9383 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9385 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).type", data->type);
9386 if (is_output) {
9387 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.output,
9388 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
9389 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.output.reserved", data->parm.output.reserved);
9390 } else {
9391 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PARM)", (Addr)&data->parm.capture,
9392 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
9393 PRE_FIELD_READ("ioctl(VKI_V4L2_G_PARM).parm.capture.reserved", data->parm.capture.reserved);
9395 break;
9397 case VKI_V4L2_S_PARM: {
9398 struct vki_v4l2_streamparm *data =
9399 (struct vki_v4l2_streamparm *)(Addr)ARG3;
9400 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
9401 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
9402 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
9403 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
9405 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).type", data->type);
9406 if (is_output)
9407 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.output", data->parm.output);
9408 else
9409 PRE_FIELD_READ("ioctl(VKI_V4L2_S_PARM).parm.capture", data->parm.capture);
9410 break;
9412 case VKI_V4L2_G_STD: {
9413 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9414 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_STD)", (Addr)data, sizeof(*data));
9415 break;
9417 case VKI_V4L2_S_STD: {
9418 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9419 PRE_MEM_READ("ioctl(VKI_V4L2_S_STD)", (Addr)data, sizeof(*data));
9420 break;
9422 case VKI_V4L2_ENUMSTD: {
9423 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
9424 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMSTD).index", data->index);
9425 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMSTD)", (Addr)&data->id, sizeof(*data) - sizeof(data->index));
9426 break;
9428 case VKI_V4L2_ENUMINPUT: {
9429 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
9430 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMINPUT).index", data->index);
9431 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMINPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9432 break;
9434 case VKI_V4L2_G_CTRL: {
9435 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9436 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CTRL).id", data->id);
9437 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CTRL).value", data->value);
9438 break;
9440 case VKI_V4L2_S_CTRL: {
9441 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
9442 PRE_MEM_READ("ioctl(VKI_V4L2_S_CTRL)", (Addr)data, sizeof(*data));
9443 break;
9445 case VKI_V4L2_G_TUNER: {
9446 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9447 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).index", data->index);
9448 PRE_FIELD_READ("ioctl(VKI_V4L2_G_TUNER).reserved", data->reserved);
9449 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_TUNER)", (Addr)data->name,
9450 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9451 break;
9453 case VKI_V4L2_S_TUNER: {
9454 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
9455 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).index", data->index);
9456 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).audmode", data->audmode);
9457 PRE_FIELD_READ("ioctl(VKI_V4L2_S_TUNER).reserved", data->reserved);
9458 break;
9460 case VKI_V4L2_G_AUDIO: {
9461 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9462 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDIO)", (Addr)data,
9463 sizeof(*data) - sizeof(data->reserved));
9464 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDIO).reserved", data->reserved);
9465 break;
9467 case VKI_V4L2_S_AUDIO: {
9468 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9469 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).index", data->index);
9470 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).mode", data->mode);
9471 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDIO).reserved", data->reserved);
9472 break;
9474 case VKI_V4L2_QUERYCTRL: {
9475 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
9476 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYCTRL).id", data->id);
9477 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYCTRL)", (Addr)&data->type,
9478 sizeof(*data) - sizeof(data->id));
9479 break;
9481 case VKI_V4L2_QUERYMENU: {
9482 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
9483 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).id", data->id);
9484 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERYMENU).index", data->index);
9485 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYMENU)", (Addr)data->name,
9486 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
9487 break;
9489 case VKI_V4L2_G_INPUT: {
9490 int *data = (int *)(Addr)ARG3;
9491 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_INPUT)", (Addr)data, sizeof(*data));
9492 break;
9494 case VKI_V4L2_S_INPUT: {
9495 int *data = (int *)(Addr)ARG3;
9496 PRE_MEM_READ("ioctl(VKI_V4L2_S_INPUT)", (Addr)data, sizeof(*data));
9497 break;
9499 case VKI_V4L2_G_EDID: {
9500 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9501 PRE_MEM_READ("ioctl(VKI_V4L2_G_EDID)", (Addr)data, sizeof(*data));
9502 if (data->blocks && data->edid)
9503 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EDID)", (Addr)data->edid, data->blocks * 128);
9504 break;
9506 case VKI_V4L2_S_EDID: {
9507 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
9508 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data, sizeof(*data));
9509 if (data->blocks && data->edid)
9510 PRE_MEM_READ("ioctl(VKI_V4L2_S_EDID)", (Addr)data->edid, data->blocks * 128);
9511 break;
9513 case VKI_V4L2_G_OUTPUT: {
9514 int *data = (int *)(Addr)ARG3;
9515 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_OUTPUT)", (Addr)data, sizeof(*data));
9516 break;
9518 case VKI_V4L2_S_OUTPUT: {
9519 int *data = (int *)(Addr)ARG3;
9520 PRE_MEM_READ("ioctl(VKI_V4L2_S_OUTPUT)", (Addr)data, sizeof(*data));
9521 break;
9523 case VKI_V4L2_ENUMOUTPUT: {
9524 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
9525 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMOUTPUT).index", data->index);
9526 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMOUTPUT)", (Addr)data->name, sizeof(*data) - sizeof(data->index));
9527 break;
9529 case VKI_V4L2_G_AUDOUT: {
9530 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9531 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_AUDOUT)", (Addr)data,
9532 sizeof(*data) - sizeof(data->reserved));
9533 PRE_FIELD_READ("ioctl(VKI_V4L2_G_AUDOUT).reserved", data->reserved);
9534 break;
9536 case VKI_V4L2_S_AUDOUT: {
9537 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9538 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).index", data->index);
9539 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).reserved", data->reserved);
9540 PRE_FIELD_READ("ioctl(VKI_V4L2_S_AUDOUT).mode", data->mode);
9541 break;
9543 case VKI_V4L2_G_MODULATOR: {
9544 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9545 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).index", data->index);
9546 PRE_FIELD_READ("ioctl(VKI_V4L2_G_MODULATOR).reserved", data->reserved);
9547 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_MODULATOR)", (Addr)data->name,
9548 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9549 break;
9551 case VKI_V4L2_S_MODULATOR: {
9552 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
9553 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).index", data->index);
9554 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).txsubchans", data->txsubchans);
9555 PRE_FIELD_READ("ioctl(VKI_V4L2_S_MODULATOR).reserved", data->reserved);
9556 break;
9558 case VKI_V4L2_G_FREQUENCY: {
9559 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9560 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).tuner", data->tuner);
9561 PRE_FIELD_READ("ioctl(VKI_V4L2_G_FREQUENCY).reserved", data->reserved);
9562 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).type", data->type);
9563 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_FREQUENCY).frequency", data->frequency);
9564 break;
9566 case VKI_V4L2_S_FREQUENCY: {
9567 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
9568 PRE_MEM_READ("ioctl(VKI_V4L2_S_FREQUENCY)", (Addr)data, sizeof(*data));
9569 break;
9571 case VKI_V4L2_CROPCAP: {
9572 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
9573 PRE_FIELD_READ("ioctl(VKI_V4L2_CROPCAP)", data->type);
9574 PRE_MEM_WRITE("ioctl(VKI_V4L2_CROPCAP)", (Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
9575 break;
9577 case VKI_V4L2_G_CROP: {
9578 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9579 PRE_FIELD_READ("ioctl(VKI_V4L2_G_CROP).type", data->type);
9580 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_CROP).c", data->c);
9581 break;
9583 case VKI_V4L2_S_CROP: {
9584 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
9585 PRE_MEM_READ("ioctl(VKI_V4L2_S_CROP)", (Addr)data, sizeof(*data));
9586 break;
9588 case VKI_V4L2_G_JPEGCOMP: {
9589 struct vki_v4l2_jpegcompression *data =
9590 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9591 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_JPEGCOMP)", (Addr)data, sizeof(*data));
9592 break;
9594 case VKI_V4L2_S_JPEGCOMP: {
9595 struct vki_v4l2_jpegcompression *data =
9596 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
9597 PRE_MEM_READ("ioctl(VKI_V4L2_S_JPEGCOMP)", (Addr)data, sizeof(*data));
9598 break;
9600 case VKI_V4L2_QUERYSTD: {
9601 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
9602 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERYSTD)", (Addr)data, sizeof(*data));
9603 break;
9605 case VKI_V4L2_ENUMAUDIO: {
9606 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
9607 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).index", data->index);
9608 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDIO).reserved", data->reserved);
9609 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDIO)", (Addr)data->name,
9610 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9611 break;
9613 case VKI_V4L2_ENUMAUDOUT: {
9614 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
9615 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).index", data->index);
9616 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUMAUDOUT).reserved", data->reserved);
9617 PRE_MEM_WRITE("ioctl(VKI_V4L2_ENUMAUDOUT)", (Addr)data->name,
9618 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
9619 break;
9621 case VKI_V4L2_G_PRIORITY: {
9622 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9623 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_PRIORITY)", (Addr)data, sizeof(*data));
9624 break;
9626 case VKI_V4L2_S_PRIORITY: {
9627 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
9628 PRE_MEM_READ("ioctl(VKI_V4L2_S_PRIORITY)", (Addr)data, sizeof(*data));
9629 break;
9631 case VKI_V4L2_G_SLICED_VBI_CAP: {
9632 struct vki_v4l2_sliced_vbi_cap *data =
9633 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
9634 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).type", data->type);
9635 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SLICED_VBI_CAP).reserved", data->reserved);
9636 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_SLICED_VBI_CAP)", (Addr)data,
9637 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
9638 break;
9640 case VKI_V4L2_G_EXT_CTRLS: {
9641 struct vki_v4l2_ext_controls *data =
9642 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9643 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).ctrl_class", data->ctrl_class);
9644 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).count", data->count);
9645 if (data->count) {
9646 unsigned i;
9648 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls", data->controls);
9649 for (i = 0; i < data->count; i++) {
9650 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].id", data->controls[i].id);
9651 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].size", data->controls[i].size);
9652 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].reserved2", data->controls[i].reserved2);
9653 if (data->controls[i].size) {
9654 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr", data->controls[i].ptr);
9655 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].ptr[]",
9656 (Addr)data->controls[i].ptr, data->controls[i].size);
9657 } else {
9658 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).controls[].value64",
9659 data->controls[i].value64);
9663 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_EXT_CTRLS).error_idx", data->error_idx);
9664 PRE_FIELD_READ("ioctl(VKI_V4L2_G_EXT_CTRLS).reserved", data->reserved);
9665 break;
9667 case VKI_V4L2_S_EXT_CTRLS: {
9668 struct vki_v4l2_ext_controls *data =
9669 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9670 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).ctrl_class", data->ctrl_class);
9671 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).count", data->count);
9672 if (data->count) {
9673 unsigned i;
9675 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls", data->controls);
9676 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS)", (Addr)data->controls,
9677 data->count * sizeof(data->controls[0]));
9678 for (i = 0; i < data->count; i++) {
9679 if (data->controls[i].size) {
9680 PRE_MEM_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).controls[].ptr[]",
9681 (Addr)data->controls[i].ptr, data->controls[i].size);
9685 PRE_FIELD_WRITE("ioctl(VKI_V4L2_S_EXT_CTRLS).error_idx", data->error_idx);
9686 PRE_FIELD_READ("ioctl(VKI_V4L2_S_EXT_CTRLS).reserved", data->reserved);
9687 break;
9689 case VKI_V4L2_TRY_EXT_CTRLS: {
9690 struct vki_v4l2_ext_controls *data =
9691 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
9692 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).ctrl_class", data->ctrl_class);
9693 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).count", data->count);
9694 if (data->count) {
9695 unsigned i;
9697 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls", data->controls);
9698 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS)", (Addr)data->controls,
9699 data->count * sizeof(data->controls[0]));
9700 for (i = 0; i < data->count; i++) {
9701 if (data->controls[i].size) {
9702 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).controls[].ptr[]",
9703 (Addr)data->controls[i].ptr, data->controls[i].size);
9707 PRE_FIELD_WRITE("ioctl(VKI_V4L2_TRY_EXT_CTRLS).error_idx", data->error_idx);
9708 PRE_FIELD_READ("ioctl(VKI_V4L2_TRY_EXT_CTRLS).reserved", data->reserved);
9709 break;
9711 case VKI_V4L2_ENUM_FRAMESIZES: {
9712 struct vki_v4l2_frmsizeenum *data =
9713 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
9714 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).index", data->index);
9715 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).pixel_format", data->pixel_format);
9716 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMESIZES).reserved", data->reserved);
9717 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).type", data->type);
9718 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMESIZES).stepwise", data->stepwise);
9719 break;
9721 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
9722 struct vki_v4l2_frmivalenum *data =
9723 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
9724 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).index", data->index);
9725 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).pixel_format", data->pixel_format);
9726 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).width", data->width);
9727 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).height", data->height);
9728 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).reserved", data->reserved);
9729 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).type", data->type);
9730 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FRAMEINTERVALS).stepwise", data->stepwise);
9731 break;
9733 case VKI_V4L2_G_ENC_INDEX: {
9734 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
9735 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_ENC_INDEX)", (Addr)data, sizeof(*data));
9736 break;
9738 case VKI_V4L2_ENCODER_CMD: {
9739 struct vki_v4l2_encoder_cmd *data =
9740 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9741 PRE_MEM_READ("ioctl(VKI_V4L2_ENCODER_CMD)", (Addr)data, sizeof(*data));
9742 break;
9744 case VKI_V4L2_TRY_ENCODER_CMD: {
9745 struct vki_v4l2_encoder_cmd *data =
9746 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
9747 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_ENCODER_CMD)", (Addr)data, sizeof(*data));
9748 break;
9750 case VKI_V4L2_DBG_S_REGISTER: {
9751 struct vki_v4l2_dbg_register *data =
9752 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9753 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.type", data->match.type);
9754 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).match.addr", data->match.addr);
9755 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).reg", data->reg);
9756 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_S_REGISTER).val", data->val);
9757 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_S_REGISTER).size", data->size);
9758 break;
9760 case VKI_V4L2_DBG_G_REGISTER: {
9761 struct vki_v4l2_dbg_register *data =
9762 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
9763 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.type", data->match.type);
9764 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).match.addr", data->match.addr);
9765 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_REGISTER).reg", data->reg);
9766 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).val", data->val);
9767 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_REGISTER).size", data->size);
9768 break;
9770 case VKI_V4L2_S_HW_FREQ_SEEK: {
9771 struct vki_v4l2_hw_freq_seek *data =
9772 (struct vki_v4l2_hw_freq_seek *)(Addr)ARG3;
9773 PRE_MEM_READ("ioctl(VKI_V4L2_S_HW_FREQ_SEEK)", (Addr)data, sizeof(*data));
9774 break;
9776 case VKI_V4L2_S_DV_TIMINGS: {
9777 struct vki_v4l2_dv_timings *data =
9778 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9779 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).type", data->type);
9780 PRE_FIELD_READ("ioctl(VKI_V4L2_S_DV_TIMINGS).bt", data->bt);
9781 break;
9783 case VKI_V4L2_G_DV_TIMINGS: {
9784 struct vki_v4l2_dv_timings *data =
9785 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9786 PRE_MEM_WRITE("ioctl(VKI_V4L2_G_DV_TIMINGS)", (Addr)data, sizeof(*data));
9787 break;
9789 case VKI_V4L2_DQEVENT: {
9790 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
9791 PRE_MEM_WRITE("ioctl(VKI_V4L2_DQEVENT)", (Addr)data, sizeof(*data));
9792 break;
9794 case VKI_V4L2_SUBSCRIBE_EVENT: {
9795 struct vki_v4l2_event_subscription *data =
9796 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9797 PRE_MEM_READ("ioctl(VKI_V4L2_SUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9798 break;
9800 case VKI_V4L2_UNSUBSCRIBE_EVENT: {
9801 struct vki_v4l2_event_subscription *data =
9802 (struct vki_v4l2_event_subscription *)(Addr)ARG3;
9803 PRE_MEM_READ("ioctl(VKI_V4L2_UNSUBSCRIBE_EVENT)", (Addr)data, sizeof(*data));
9804 break;
9806 case VKI_V4L2_CREATE_BUFS: {
9807 struct vki_v4l2_create_buffers *data =
9808 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
9809 struct vki_v4l2_format *fmt = &data->format;
9810 PRE_FIELD_WRITE("ioctl(VKI_V4L2_CREATE_BUFS).index", data->index);
9811 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).count", data->count);
9812 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).memory", data->memory);
9813 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).reserved", data->reserved);
9814 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.type", fmt->type);
9815 switch (fmt->type) {
9816 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
9817 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
9818 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix", fmt->fmt.raw_data);
9819 break;
9820 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
9821 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
9822 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.vbi", fmt->fmt.vbi);
9823 break;
9824 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
9825 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
9826 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sliced", fmt->fmt.sliced);
9827 break;
9828 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
9829 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
9830 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.win", fmt->fmt.win);
9831 break;
9832 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
9833 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
9834 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.pix_mp", fmt->fmt.pix_mp);
9835 break;
9836 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
9837 PRE_FIELD_READ("ioctl(VKI_V4L2_CREATE_BUFS).format.sdr", fmt->fmt.sdr);
9838 break;
9840 break;
9842 case VKI_V4L2_PREPARE_BUF: {
9843 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
9844 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).index", data->index);
9845 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).type", data->type);
9846 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).memory", data->memory);
9847 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved", data->reserved);
9848 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).reserved2", data->reserved2);
9849 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
9850 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
9851 unsigned i;
9853 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).length", data->length);
9854 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes", data->m.planes);
9855 for (i = 0; i < data->length; i++) {
9856 PRE_FIELD_READ("ioctl(VKI_V4L2_PREPARE_BUF).m.planes[].reserved", data->m.planes[i].reserved);
9859 break;
9861 case VKI_V4L2_G_SELECTION: {
9862 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9863 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).type", data->type);
9864 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).target", data->target);
9865 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).flags", data->flags);
9866 PRE_FIELD_READ("ioctl(VKI_V4L2_G_SELECTION).reserved", data->reserved);
9867 PRE_FIELD_WRITE("ioctl(VKI_V4L2_G_SELECTION).r", data->r);
9868 break;
9870 case VKI_V4L2_S_SELECTION: {
9871 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
9872 PRE_MEM_READ("ioctl(VKI_V4L2_S_SELECTION)", (Addr)data, sizeof(*data));
9873 break;
9875 case VKI_V4L2_DECODER_CMD: {
9876 struct vki_v4l2_decoder_cmd *data =
9877 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9878 PRE_MEM_READ("ioctl(VKI_V4L2_DECODER_CMD)", (Addr)data, sizeof(*data));
9879 break;
9881 case VKI_V4L2_TRY_DECODER_CMD: {
9882 struct vki_v4l2_decoder_cmd *data =
9883 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
9884 PRE_MEM_READ("ioctl(VKI_V4L2_TRY_DECODER_CMD)", (Addr)data, sizeof(*data));
9885 break;
9887 case VKI_V4L2_ENUM_DV_TIMINGS: {
9888 struct vki_v4l2_enum_dv_timings *data =
9889 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
9890 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).index", data->index);
9891 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).pad", data->pad);
9892 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).reserved", data->reserved);
9893 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_DV_TIMINGS).timings", data->timings);
9894 break;
9896 case VKI_V4L2_QUERY_DV_TIMINGS: {
9897 struct vki_v4l2_dv_timings *data =
9898 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
9899 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_DV_TIMINGS)", (Addr)data, sizeof(*data));
9900 break;
9902 case VKI_V4L2_DV_TIMINGS_CAP: {
9903 struct vki_v4l2_dv_timings_cap *data =
9904 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
9905 PRE_MEM_WRITE("ioctl(VKI_V4L2_DV_TIMINGS_CAP)", (Addr)data, sizeof(*data));
9906 break;
9908 case VKI_V4L2_ENUM_FREQ_BANDS: {
9909 struct vki_v4l2_frequency_band *data =
9910 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
9911 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).tuner", data->tuner);
9912 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).type", data->type);
9913 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).index", data->index);
9914 PRE_FIELD_READ("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).reserved", data->reserved);
9915 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).capability", data->capability);
9916 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangelow", data->rangelow);
9917 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).rangehigh", data->rangehigh);
9918 PRE_FIELD_WRITE("ioctl(VKI_V4L2_ENUM_FREQ_BANDS).modulation", data->modulation);
9919 break;
9921 case VKI_V4L2_DBG_G_CHIP_INFO: {
9922 struct vki_v4l2_dbg_chip_info *data =
9923 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
9924 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.type", data->match.type);
9925 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).match.addr", data->match.addr);
9926 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).name", data->name);
9927 PRE_FIELD_WRITE("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).flags", data->flags);
9928 PRE_FIELD_READ("ioctl(VKI_V4L2_DBG_G_CHIP_INFO).reserved", data->reserved);
9929 break;
9931 case VKI_V4L2_QUERY_EXT_CTRL: {
9932 struct vki_v4l2_query_ext_ctrl *data =
9933 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
9934 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).id", data->id);
9935 PRE_FIELD_READ("ioctl(VKI_V4L2_QUERY_EXT_CTRL).reserved", data->reserved);
9936 PRE_MEM_WRITE("ioctl(VKI_V4L2_QUERY_EXT_CTRL)", (Addr)&data->type,
9937 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
9938 break;
9940 case VKI_V4L2_SUBDEV_G_FMT: {
9941 struct vki_v4l2_subdev_format *data =
9942 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9943 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).pad", data->pad);
9944 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).which", data->which);
9945 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FMT).reserved", data->reserved);
9946 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FMT).format", data->format);
9947 break;
9949 case VKI_V4L2_SUBDEV_S_FMT: {
9950 struct vki_v4l2_subdev_format *data =
9951 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
9952 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FMT)", (Addr)data, sizeof(*data));
9953 break;
9955 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
9956 struct vki_v4l2_subdev_frame_interval *data =
9957 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9958 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).pad", data->pad);
9959 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).reserved", data->reserved);
9960 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_FRAME_SIZE).interval", data->interval);
9961 break;
9963 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL: {
9964 struct vki_v4l2_subdev_frame_interval *data =
9965 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
9966 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_FRAME_INTERVAL)", (Addr)data, sizeof(*data));
9967 break;
9969 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
9970 struct vki_v4l2_subdev_mbus_code_enum *data =
9971 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
9972 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).index", data->index);
9973 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).pad", data->pad);
9974 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).code", data->code);
9975 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).which", data->which);
9976 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_MBUS_CODE).reserved", data->reserved);
9977 break;
9979 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
9980 struct vki_v4l2_subdev_frame_size_enum *data =
9981 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
9982 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).index", data->index);
9983 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).pad", data->pad);
9984 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).code", data->code);
9985 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).which", data->which);
9986 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).reserved", data->reserved);
9987 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_width", data->min_width);
9988 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).min_height", data->min_height);
9989 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_width", data->max_width);
9990 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE).max_height", data->max_height);
9991 break;
9993 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
9994 struct vki_v4l2_subdev_frame_interval_enum *data =
9995 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
9996 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).index", data->index);
9997 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).pad", data->pad);
9998 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).code", data->code);
9999 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).width", data->width);
10000 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).height", data->height);
10001 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).which", data->which);
10002 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).reserved", data->reserved);
10003 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL).interval", data->interval);
10004 break;
10006 case VKI_V4L2_SUBDEV_G_CROP: {
10007 struct vki_v4l2_subdev_crop *data =
10008 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10009 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).pad", data->pad);
10010 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).which", data->which);
10011 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_CROP).reserved", data->reserved);
10012 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_CROP).rect", data->rect);
10013 break;
10015 case VKI_V4L2_SUBDEV_S_CROP: {
10016 struct vki_v4l2_subdev_crop *data =
10017 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
10018 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_CROP)", (Addr)data, sizeof(*data));
10019 break;
10021 case VKI_V4L2_SUBDEV_G_SELECTION: {
10022 struct vki_v4l2_subdev_selection *data =
10023 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10024 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).pad", data->pad);
10025 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).which", data->which);
10026 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).target", data->target);
10027 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).flags", data->flags);
10028 PRE_FIELD_READ("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).reserved", data->reserved);
10029 PRE_FIELD_WRITE("ioctl(VKI_V4L2_SUBDEV_G_SELECTION).r", data->r);
10030 break;
10032 case VKI_V4L2_SUBDEV_S_SELECTION: {
10033 struct vki_v4l2_subdev_selection *data =
10034 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
10035 PRE_MEM_READ("ioctl(VKI_V4L2_SUBDEV_S_SELECTION)", (Addr)data, sizeof(*data));
10036 break;
10038 case VKI_MEDIA_IOC_DEVICE_INFO: {
10039 struct vki_media_device_info *data =
10040 (struct vki_media_device_info *)(Addr)ARG3;
10041 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_DEVICE_INFO).reserved", data->reserved);
10042 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_DEVICE_INFO)",
10043 (Addr)data, sizeof(*data) - sizeof(data->reserved));
10044 break;
10046 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
10047 struct vki_media_entity_desc *data =
10048 (struct vki_media_entity_desc *)(Addr)ARG3;
10049 PRE_FIELD_READ("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES).id", data->id);
10050 PRE_MEM_WRITE("ioctl(VKI_MEDIA_IOC_ENUM_ENTITIES)",
10051 (Addr)data->name, sizeof(*data) - sizeof(data->id));
10052 break;
10054 case VKI_MEDIA_IOC_ENUM_LINKS: {
10055 struct vki_media_links_enum *data =
10056 (struct vki_media_links_enum *)(Addr)ARG3;
10057 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_ENUM_LINKS)", (Addr)data, sizeof(*data));
10058 break;
10060 case VKI_MEDIA_IOC_SETUP_LINK: {
10061 struct vki_media_link_desc *data =
10062 (struct vki_media_link_desc *)(Addr)ARG3;
10063 PRE_MEM_READ("ioctl(VKI_MEDIA_IOC_SETUP_LINK)", (Addr)data, sizeof(*data));
10064 break;
10067 /* Serial */
10068 case VKI_TIOCGSERIAL: {
10069 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10070 PRE_MEM_WRITE("ioctl(VKI_TIOCGSERIAL)", (Addr)data, sizeof(*data));
10071 break;
10073 case VKI_TIOCSSERIAL: {
10074 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
10075 PRE_MEM_READ("ioctl(VKI_TIOCSSERIAL)", (Addr)data, sizeof(*data));
10076 break;
10079 case VKI_PERF_EVENT_IOC_RESET:
10080 case VKI_PERF_EVENT_IOC_REFRESH:
10081 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
10082 case VKI_PERF_EVENT_IOC_SET_BPF:
10083 /* These take scalar arguments, so already handled above */
10084 break;
10086 case VKI_PERF_EVENT_IOC_PERIOD:
10087 PRE_MEM_READ("ioctl(VKI_PERF_EVENT_IOC_PERIOD)", (Addr)ARG3, sizeof(__vki_u64));
10088 break;
10090 case VKI_PERF_EVENT_IOC_SET_FILTER:
10091 PRE_MEM_RASCIIZ("ioctl(VKI_PERF_EVENT_IOC_SET_FILTER).filter", ARG3);
10092 break;
10094 case VKI_PERF_EVENT_IOC_ID:
10095 PRE_MEM_WRITE("ioctl(VKI_PERF_EVENT_IOC_ID)", (Addr)ARG3, sizeof(__vki_u64));
10096 break;
10098 /* Pulse Per Second (PPS) */
10099 case VKI_PPS_GETPARAMS: {
10100 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10101 PRE_MEM_WRITE("ioctl(PPS_GETPARAMS)", (Addr)data, sizeof(*data));
10102 break;
10104 case VKI_PPS_SETPARAMS: {
10105 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
10106 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).mode", data->mode);
10107 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.sec",
10108 data->assert_off_tu.sec);
10109 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).assert_off_tu.nsec",
10110 data->assert_off_tu.nsec);
10111 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.sec",
10112 data->clear_off_tu.sec);
10113 PRE_FIELD_READ("ioctl(PPS_SETPARAMS).clear_off_tu.nsec",
10114 data->clear_off_tu.nsec);
10115 break;
10117 case VKI_PPS_GETCAP:
10118 PRE_MEM_WRITE("ioctl(PPS_GETCAP)", (Addr)ARG3, sizeof(int));
10119 break;
10120 case VKI_PPS_FETCH: {
10121 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
10122 PRE_FIELD_READ("ioctl(PPS_FETCH).timeout", data->timeout);
10123 PRE_FIELD_WRITE("ioctl(PPS_FETCH).info", data->info);
10124 break;
10126 case VKI_PPS_KC_BIND: {
10127 struct vki_pps_bind_args *data = (struct vki_pps_bind_args *)(Addr)ARG3;
10128 PRE_MEM_READ("ioctl(PPS_KC_BIND)", (Addr)data, sizeof(*data));
10129 break;
10132 /* PTP Hardware Clock */
10133 case VKI_PTP_CLOCK_GETCAPS: {
10134 struct vki_ptp_clock_caps *data =
10135 (struct vki_ptp_clock_caps *)(Addr)ARG3;
10136 PRE_MEM_WRITE("ioctl(PTP_CLOCK_GETCAPS)", (Addr)data, sizeof(*data));
10137 break;
10139 case VKI_PTP_EXTTS_REQUEST: {
10140 struct vki_ptp_extts_request *data =
10141 (struct vki_ptp_extts_request *)(Addr)ARG3;
10142 PRE_MEM_READ("ioctl(PTP_EXTTS_REQUEST)", (Addr)data, sizeof(*data));
10143 break;
10145 case VKI_PTP_PEROUT_REQUEST: {
10146 struct vki_ptp_perout_request *data =
10147 (struct vki_ptp_perout_request *)(Addr)ARG3;
10148 PRE_MEM_READ("ioctl(PTP_PEROUT_REQUEST)", (Addr)data, sizeof(*data));
10149 break;
10151 case VKI_PTP_ENABLE_PPS:
10152 break;
10153 case VKI_PTP_SYS_OFFSET: {
10154 struct vki_ptp_sys_offset *data =
10155 (struct vki_ptp_sys_offset *)(Addr)ARG3;
10156 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET).n_samples", data->n_samples);
10157 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10158 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET).ts", (Addr)data->ts,
10159 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
10160 break;
10162 case VKI_PTP_PIN_GETFUNC: {
10163 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10164 PRE_FIELD_READ("ioctl(PTP_PIN_GETFUNC).index", data->index);
10165 PRE_MEM_WRITE("ioctl(PTP_PIN_GETFUNC)", (Addr)data, sizeof(*data));
10166 break;
10168 case VKI_PTP_PIN_SETFUNC: {
10169 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
10170 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).index", data->index);
10171 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).func", data->func);
10172 PRE_FIELD_READ("ioctl(PTP_PIN_SETFUNC).chan", data->chan);
10173 break;
10175 case VKI_PTP_SYS_OFFSET_PRECISE: {
10176 struct vki_ptp_sys_offset_precise *data =
10177 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
10178 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_PRECISE)", (Addr)data, sizeof(*data));
10179 break;
10181 case VKI_PTP_SYS_OFFSET_EXTENDED: {
10182 struct vki_ptp_sys_offset_extended *data =
10183 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
10184 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).n_samples", data->n_samples);
10185 PRE_FIELD_READ("ioctl(PTP_SYS_OFFSET_EXTENDED).rsv", data->rsv);
10186 if (data->n_samples <= VKI_PTP_MAX_SAMPLES)
10187 PRE_MEM_WRITE("ioctl(PTP_SYS_OFFSET_EXTENDED).ts", (Addr)data->ts,
10188 3 * data->n_samples * sizeof(data->ts[0][0]));
10189 break;
10192 default:
10193 /* EVIOC* are variable length and return size written on success */
10194 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
10195 case VKI_EVIOCGNAME(0):
10196 case VKI_EVIOCGPHYS(0):
10197 case VKI_EVIOCGUNIQ(0):
10198 case VKI_EVIOCGKEY(0):
10199 case VKI_EVIOCGLED(0):
10200 case VKI_EVIOCGSND(0):
10201 case VKI_EVIOCGSW(0):
10202 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
10203 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
10204 case VKI_EVIOCGBIT(VKI_EV_REL,0):
10205 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
10206 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
10207 case VKI_EVIOCGBIT(VKI_EV_SW,0):
10208 case VKI_EVIOCGBIT(VKI_EV_LED,0):
10209 case VKI_EVIOCGBIT(VKI_EV_SND,0):
10210 case VKI_EVIOCGBIT(VKI_EV_REP,0):
10211 case VKI_EVIOCGBIT(VKI_EV_FF,0):
10212 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
10213 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
10214 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
10215 break;
10216 default:
10217 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
10218 break;
10220 break;
10224 POST(sys_ioctl)
10226 ARG2 = (UInt)ARG2;
10228 vg_assert(SUCCESS || (FAILURE && VKI_DRM_IOCTL_VERSION == ARG2));
10230 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
10232 /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10233 if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
10234 VG_(clo_kernel_variant))) {
10236 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
10237 /* What's going on here: there appear to be a bunch of ioctls
10238 of the form 0xC01C67xx which are undocumented, and if
10239 unhandled give rise to a vast number of false positives in
10240 Memcheck.
10242 The "normal" interpretation of an ioctl of this form would
10243 be that the 3rd arg is a pointer to an area of size 0x1C
10244 (28 bytes) which is filled in by the kernel. Hence you
10245 might think that "POST_MEM_WRITE(ARG3, 28)" would fix it.
10246 But it doesn't.
10248 It requires POST_MEM_WRITE(ARG3, 256) to silence them.
10249 One interpretation of this is that ARG3 really does point
10250 to a 28 byte struct, but inside that are pointers to other
10251 areas also filled in by the kernel. If these happen to be
10252 allocated just back up the stack then the 256 byte paint
10253 might cover them too, somewhat indiscriminately.
10255 By printing out ARG3 and also the 28 bytes that it points
10256 at, it's possible to guess that the 7 word structure has
10257 this form
10259 0 1 2 3 4 5 6
10260 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
10262 Unfortunately that doesn't seem to work for some reason,
10263 so stay with the blunt-instrument approach for the time
10264 being.
10266 if (1) {
10267 /* blunt-instrument approach */
10268 POST_MEM_WRITE(ARG3, 256);
10269 } else {
10270 /* be a bit more sophisticated */
10271 POST_MEM_WRITE(ARG3, 28);
10272 UInt* word = (UInt*)(Addr)ARG3;
10273 if (word && word[2] && word[3] < 0x200/*stay sane*/)
10274 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
10275 if (word && word[4] && word[5] < 0x200/*stay sane*/)
10276 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
10278 goto post_sys_ioctl__out;
10281 /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
10283 /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */
10284 if (KernelVariantiS(KernelVariant_android_gpu_adreno3xx,
10285 VG_(clo_kernel_variant))) {
10286 if (ARG2 == 0xC00C0902) {
10287 POST_MEM_WRITE(ARG3, 24); // 16 is not enough
10288 goto post_sys_ioctl__out;
10291 /* END undocumented ioctls for Qualcomm Adreno 3xx */
10293 /* --- END special IOCTL handlers for specific Android hardware --- */
10295 /* --- normal handling --- */
10296 switch (ARG2 /* request */) {
10298 /* The Linux kernel "ion" memory allocator, used on Android. Note:
10299 this is pretty poor given that there's no pre-handling to check
10300 that writable areas are addressable. */
10301 case VKI_ION_IOC_ALLOC: {
10302 struct vki_ion_allocation_data* data
10303 = (struct vki_ion_allocation_data*)(Addr)ARG3;
10304 POST_FIELD_WRITE(data->handle);
10305 break;
10307 case VKI_ION_IOC_MAP: {
10308 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10309 POST_FIELD_WRITE(data->fd);
10310 break;
10312 case VKI_ION_IOC_FREE: // is this necessary?
10313 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data));
10314 break;
10315 case VKI_ION_IOC_SHARE:
10316 break;
10317 case VKI_ION_IOC_IMPORT: {
10318 struct vki_ion_fd_data* data = (struct vki_ion_fd_data*)(Addr)ARG3;
10319 POST_FIELD_WRITE(data->handle);
10320 break;
10322 case VKI_ION_IOC_SYNC:
10323 break;
10324 case VKI_ION_IOC_CUSTOM: // is this necessary?
10325 POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data));
10326 break;
10328 case VKI_SYNC_IOC_MERGE: {
10329 struct vki_sync_merge_data* data =
10330 (struct vki_sync_merge_data*)(Addr)ARG3;
10331 POST_FIELD_WRITE(data->fence);
10332 break;
10335 case VKI_TCSETS:
10336 case VKI_TCSETSW:
10337 case VKI_TCSETSF:
10338 case VKI_IB_USER_MAD_ENABLE_PKEY:
10339 break;
10340 case VKI_TCGETS:
10341 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
10342 break;
10343 case VKI_TCSETA:
10344 case VKI_TCSETAW:
10345 case VKI_TCSETAF:
10346 break;
10347 case VKI_TCGETA:
10348 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
10349 break;
10350 case VKI_TCSBRK:
10351 case VKI_TCXONC:
10352 case VKI_TCSBRKP:
10353 case VKI_TCFLSH:
10354 case VKI_TIOCSIG:
10355 break;
10356 case VKI_TIOCGWINSZ:
10357 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
10358 break;
10359 case VKI_TIOCSWINSZ:
10360 case VKI_TIOCMBIS:
10361 case VKI_TIOCMBIC:
10362 case VKI_TIOCMSET:
10363 break;
10364 case VKI_TIOCMGET:
10365 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10366 break;
10367 case VKI_TIOCLINUX:
10368 POST_MEM_WRITE( ARG3, sizeof(char *) );
10369 break;
10370 case VKI_TIOCGPGRP:
10371 /* Get process group ID for foreground processing group. */
10372 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10373 break;
10374 case VKI_TIOCSPGRP:
10375 /* Set a process group ID? */
10376 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
10377 break;
10378 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
10379 POST_MEM_WRITE( ARG3, sizeof(int));
10380 break;
10381 case VKI_TIOCSCTTY:
10382 break;
10383 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
10384 break;
10385 case VKI_FIONBIO:
10386 break;
10387 case VKI_FIONCLEX:
10388 break;
10389 case VKI_FIOCLEX:
10390 break;
10391 case VKI_TIOCNOTTY:
10392 break;
10393 case VKI_FIOASYNC:
10394 break;
10395 case VKI_FIONREAD: /* identical to SIOCINQ */
10396 POST_MEM_WRITE( ARG3, sizeof(int) );
10397 break;
10398 case VKI_FIOQSIZE:
10399 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
10400 break;
10402 case VKI_TIOCSERGETLSR:
10403 POST_MEM_WRITE( ARG3, sizeof(int) );
10404 break;
10405 case VKI_TIOCGICOUNT:
10406 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
10407 break;
10409 case VKI_SG_SET_COMMAND_Q:
10410 break;
10411 case VKI_SG_IO:
10413 vki_sg_io_hdr_t *sgio = (vki_sg_io_hdr_t*)(Addr)ARG3;
10414 if ( sgio->sbp ) {
10415 POST_MEM_WRITE( (Addr)sgio->sbp, sgio->sb_len_wr );
10417 if ( sgio->dxfer_direction == VKI_SG_DXFER_FROM_DEV ||
10418 sgio->dxfer_direction == VKI_SG_DXFER_TO_FROM_DEV ) {
10419 int transferred = sgio->dxfer_len - sgio->resid;
10420 POST_MEM_WRITE( (Addr)sgio->dxferp, transferred );
10423 break;
10424 case VKI_SG_GET_SCSI_ID:
10425 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
10426 break;
10427 case VKI_SG_SET_RESERVED_SIZE:
10428 break;
10429 case VKI_SG_SET_TIMEOUT:
10430 break;
10431 case VKI_SG_GET_RESERVED_SIZE:
10432 POST_MEM_WRITE(ARG3, sizeof(int));
10433 break;
10434 case VKI_SG_GET_TIMEOUT:
10435 break;
10436 case VKI_SG_GET_VERSION_NUM:
10437 POST_MEM_WRITE(ARG3, sizeof(int));
10438 break;
10439 case VKI_SG_EMULATED_HOST:
10440 POST_MEM_WRITE(ARG3, sizeof(int));
10441 break;
10442 case VKI_SG_GET_SG_TABLESIZE:
10443 POST_MEM_WRITE(ARG3, sizeof(int));
10444 break;
10446 case VKI_IIOCGETCPS:
10447 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
10448 break;
10449 case VKI_IIOCNETGPN:
10450 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
10451 break;
10453 /* These all use struct ifreq AFAIK */
10454 case VKI_SIOCGIFINDEX: /* get iface index */
10455 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex,
10456 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_ifindex));
10457 break;
10458 case VKI_SIOCGIFFLAGS: /* get flags */
10459 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10460 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags));
10461 break;
10462 case VKI_SIOCGIFHWADDR: /* Get hardware address */
10463 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr,
10464 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_hwaddr));
10465 break;
10466 case VKI_SIOCGIFMTU: /* get MTU size */
10467 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu,
10468 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_mtu) );
10469 break;
10470 case VKI_SIOCGIFADDR: /* get PA address */
10471 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
10472 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
10473 case VKI_SIOCGIFNETMASK: /* get network PA mask */
10474 POST_MEM_WRITE(
10475 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr,
10476 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_addr) );
10477 break;
10478 case VKI_SIOCGIFMETRIC: /* get metric */
10479 POST_MEM_WRITE(
10480 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric,
10481 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_metric) );
10482 break;
10483 case VKI_SIOCGIFMAP: /* Get device parameters */
10484 POST_MEM_WRITE(
10485 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map,
10486 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_map) );
10487 break;
10488 break;
10489 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
10490 POST_MEM_WRITE(
10491 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen,
10492 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_qlen) );
10493 break;
10494 case VKI_SIOCGIFNAME: /* get iface name */
10495 POST_MEM_WRITE(
10496 (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10497 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10498 break;
10499 case VKI_SIOCETHTOOL: { /* ethtool(8) interface */
10500 struct vki_ifreq *ir = (struct vki_ifreq *)(Addr)ARG3;
10501 switch ( *(vki_u32 *)ir->vki_ifr_data ) {
10502 case VKI_ETHTOOL_GSET:
10503 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_cmd));
10504 break;
10505 case VKI_ETHTOOL_SSET:
10506 break;
10507 case VKI_ETHTOOL_GDRVINFO:
10508 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_drvinfo) );
10509 break;
10510 case VKI_ETHTOOL_GREGS:
10511 POST_MEM_WRITE( (Addr)((struct vki_ethtool_regs *)ir->vki_ifr_data)->data,
10512 ((struct vki_ethtool_regs *)ir->vki_ifr_data)->len );
10513 break;
10514 case VKI_ETHTOOL_GWOL:
10515 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_wolinfo) );
10516 break;
10517 case VKI_ETHTOOL_SWOL:
10518 break;
10519 case VKI_ETHTOOL_GMSGLVL:
10520 case VKI_ETHTOOL_GLINK:
10521 case VKI_ETHTOOL_GRXCSUM:
10522 case VKI_ETHTOOL_GSG:
10523 case VKI_ETHTOOL_GTSO:
10524 case VKI_ETHTOOL_GUFO:
10525 case VKI_ETHTOOL_GGSO:
10526 case VKI_ETHTOOL_GFLAGS:
10527 case VKI_ETHTOOL_GGRO:
10528 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_value));
10529 break;
10530 case VKI_ETHTOOL_SMSGLVL:
10531 case VKI_ETHTOOL_SRXCSUM:
10532 case VKI_ETHTOOL_SSG:
10533 case VKI_ETHTOOL_STSO:
10534 case VKI_ETHTOOL_SUFO:
10535 case VKI_ETHTOOL_SGSO:
10536 case VKI_ETHTOOL_SFLAGS:
10537 case VKI_ETHTOOL_SGRO:
10538 break;
10539 case VKI_ETHTOOL_NWAY_RST:
10540 break;
10541 case VKI_ETHTOOL_GRINGPARAM:
10542 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ringparam));
10543 break;
10544 case VKI_ETHTOOL_SRINGPARAM:
10545 break;
10546 case VKI_ETHTOOL_TEST:
10547 POST_MEM_WRITE( (Addr)((struct vki_ethtool_test *)ir->vki_ifr_data)->data,
10548 ((struct vki_ethtool_test *)ir->vki_ifr_data)->len * sizeof(__vki_u64) );
10549 break;
10550 case VKI_ETHTOOL_PHYS_ID:
10551 break;
10552 case VKI_ETHTOOL_GPERMADDR:
10553 POST_MEM_WRITE( (Addr)((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->data,
10554 ((struct vki_ethtool_perm_addr *)ir->vki_ifr_data)->size );
10555 break;
10556 case VKI_ETHTOOL_RESET:
10557 break;
10558 case VKI_ETHTOOL_GSSET_INFO:
10559 POST_MEM_WRITE( (Addr)((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->data,
10560 __builtin_popcountll(((struct vki_ethtool_sset_info *)ir->vki_ifr_data)->sset_mask) * sizeof(__vki_u32) );
10561 break;
10562 case VKI_ETHTOOL_GFEATURES:
10563 POST_MEM_WRITE( (Addr)((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->features,
10564 ((struct vki_ethtool_gfeatures *)ir->vki_ifr_data)->size * sizeof(struct vki_ethtool_get_features_block) );
10565 break;
10566 case VKI_ETHTOOL_SFEATURES:
10567 break;
10568 case VKI_ETHTOOL_GCHANNELS:
10569 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_channels) );
10570 break;
10571 case VKI_ETHTOOL_SCHANNELS:
10572 break;
10573 case VKI_ETHTOOL_GET_TS_INFO:
10574 POST_MEM_WRITE( (Addr)ir->vki_ifr_data, sizeof(struct vki_ethtool_ts_info) );
10575 break;
10577 break;
10579 case VKI_SIOCGMIIPHY: /* get hardware entry */
10580 POST_MEM_WRITE(
10581 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id,
10582 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->phy_id));
10583 break;
10584 case VKI_SIOCGMIIREG: /* get hardware entry registers */
10585 POST_MEM_WRITE(
10586 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out,
10587 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_data)->val_out));
10588 break;
10590 /* tun/tap related ioctls */
10591 case VKI_TUNSETIFF:
10592 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10593 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10594 break;
10595 case VKI_TUNGETFEATURES:
10596 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10597 break;
10598 case VKI_TUNGETIFF:
10599 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name,
10600 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_name) );
10601 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags,
10602 sizeof(((struct vki_ifreq *)(Addr)ARG3)->vki_ifr_flags) );
10603 break;
10604 case VKI_TUNGETSNDBUF:
10605 POST_MEM_WRITE( ARG3, sizeof(int) );
10606 break;
10607 case VKI_TUNGETVNETHDRSZ:
10608 POST_MEM_WRITE( ARG3, sizeof(int) );
10609 break;
10611 case VKI_SIOCGIFCONF: /* get iface list */
10612 /* WAS:
10613 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
10614 KERNEL_DO_SYSCALL(tid,RES);
10615 if (!VG_(is_kerror)(RES) && RES == 0)
10616 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
10618 if (RES == 0 && ARG3 ) {
10619 struct vki_ifconf *ifc = (struct vki_ifconf *) (Addr)ARG3;
10620 if (ifc->vki_ifc_buf != NULL)
10621 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
10623 break;
10624 case VKI_SIOCGSTAMP:
10625 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10626 break;
10627 case VKI_SIOCGSTAMPNS:
10628 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
10629 break;
10630 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
10631 the number of bytes currently in that socket's send buffer.
10632 It writes this value as an int to the memory location
10633 indicated by the third argument of ioctl(2). */
10634 case VKI_SIOCOUTQ:
10635 POST_MEM_WRITE(ARG3, sizeof(int));
10636 break;
10637 case VKI_SIOCGRARP: /* get RARP table entry */
10638 case VKI_SIOCGARP: /* get ARP table entry */
10639 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
10640 break;
10642 case VKI_SIOCSIFFLAGS: /* set flags */
10643 case VKI_SIOCSIFMAP: /* Set device parameters */
10644 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
10645 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
10646 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
10647 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
10648 case VKI_SIOCSIFNETMASK: /* set network PA mask */
10649 case VKI_SIOCSIFMETRIC: /* set metric */
10650 case VKI_SIOCSIFADDR: /* set PA address */
10651 case VKI_SIOCSIFMTU: /* set MTU size */
10652 case VKI_SIOCSIFHWADDR: /* set hardware address */
10653 case VKI_SIOCSMIIREG: /* set hardware entry registers */
10654 break;
10655 /* Routing table calls. */
10656 case VKI_SIOCADDRT: /* add routing table entry */
10657 case VKI_SIOCDELRT: /* delete routing table entry */
10658 break;
10660 /* RARP cache control calls. */
10661 case VKI_SIOCDRARP: /* delete RARP table entry */
10662 case VKI_SIOCSRARP: /* set RARP table entry */
10663 /* ARP cache control calls. */
10664 case VKI_SIOCSARP: /* set ARP table entry */
10665 case VKI_SIOCDARP: /* delete ARP table entry */
10666 break;
10668 case VKI_SIOCGPGRP:
10669 POST_MEM_WRITE(ARG3, sizeof(int));
10670 break;
10671 case VKI_SIOCSPGRP:
10672 break;
10674 case VKI_SIOCATMARK:
10675 POST_MEM_WRITE(ARG3, sizeof(int));
10676 break;
10678 /* linux/soundcard interface (OSS) */
10679 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
10680 case VKI_SNDCTL_SEQ_GETINCOUNT:
10681 case VKI_SNDCTL_SEQ_PERCMODE:
10682 case VKI_SNDCTL_SEQ_TESTMIDI:
10683 case VKI_SNDCTL_SEQ_RESETSAMPLES:
10684 case VKI_SNDCTL_SEQ_NRSYNTHS:
10685 case VKI_SNDCTL_SEQ_NRMIDIS:
10686 case VKI_SNDCTL_SEQ_GETTIME:
10687 case VKI_SNDCTL_DSP_GETBLKSIZE:
10688 case VKI_SNDCTL_DSP_GETFMTS:
10689 case VKI_SNDCTL_DSP_SETFMT:
10690 case VKI_SNDCTL_DSP_GETTRIGGER:
10691 case VKI_SNDCTL_DSP_GETODELAY:
10692 case VKI_SNDCTL_DSP_GETSPDIF:
10693 case VKI_SNDCTL_DSP_GETCAPS:
10694 case VKI_SOUND_PCM_READ_RATE:
10695 case VKI_SOUND_PCM_READ_CHANNELS:
10696 case VKI_SOUND_PCM_READ_BITS:
10697 case VKI_SOUND_PCM_READ_FILTER:
10698 POST_MEM_WRITE(ARG3, sizeof(int));
10699 break;
10700 case VKI_SNDCTL_SEQ_CTRLRATE:
10701 case VKI_SNDCTL_DSP_SPEED:
10702 case VKI_SNDCTL_DSP_STEREO:
10703 case VKI_SNDCTL_DSP_CHANNELS:
10704 case VKI_SOUND_PCM_WRITE_FILTER:
10705 case VKI_SNDCTL_DSP_SUBDIVIDE:
10706 case VKI_SNDCTL_DSP_SETFRAGMENT:
10707 case VKI_SNDCTL_DSP_GETCHANNELMASK:
10708 case VKI_SNDCTL_DSP_BIND_CHANNEL:
10709 case VKI_SNDCTL_TMR_TIMEBASE:
10710 case VKI_SNDCTL_TMR_TEMPO:
10711 case VKI_SNDCTL_TMR_SOURCE:
10712 case VKI_SNDCTL_MIDI_PRETIME:
10713 case VKI_SNDCTL_MIDI_MPUMODE:
10714 break;
10715 case VKI_SNDCTL_DSP_GETOSPACE:
10716 case VKI_SNDCTL_DSP_GETISPACE:
10717 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
10718 break;
10719 case VKI_SNDCTL_DSP_NONBLOCK:
10720 break;
10721 case VKI_SNDCTL_DSP_SETTRIGGER:
10722 break;
10724 case VKI_SNDCTL_DSP_POST:
10725 case VKI_SNDCTL_DSP_RESET:
10726 case VKI_SNDCTL_DSP_SYNC:
10727 case VKI_SNDCTL_DSP_SETSYNCRO:
10728 case VKI_SNDCTL_DSP_SETDUPLEX:
10729 break;
10731 /* linux/soundcard interface (ALSA) */
10732 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
10733 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
10734 case VKI_SNDRV_PCM_IOCTL_PREPARE:
10735 case VKI_SNDRV_PCM_IOCTL_RESET:
10736 case VKI_SNDRV_PCM_IOCTL_START:
10737 case VKI_SNDRV_PCM_IOCTL_DROP:
10738 case VKI_SNDRV_PCM_IOCTL_DRAIN:
10739 case VKI_SNDRV_PCM_IOCTL_RESUME:
10740 case VKI_SNDRV_PCM_IOCTL_XRUN:
10741 case VKI_SNDRV_PCM_IOCTL_UNLINK:
10742 case VKI_SNDRV_TIMER_IOCTL_START:
10743 case VKI_SNDRV_TIMER_IOCTL_STOP:
10744 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
10745 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
10746 break;
10748 case VKI_SNDRV_CTL_IOCTL_PVERSION: {
10749 POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
10750 break;
10752 case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
10753 POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
10754 break;
10755 case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
10756 struct vki_snd_ctl_elem_list *data =
10757 (struct vki_snd_ctl_elem_list *)(Addr)ARG3;
10758 POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
10759 POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
10760 if (data->pids) {
10761 POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
10763 break;
10765 case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
10766 struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)(Addr)ARG3;
10767 POST_MEM_WRITE( (Addr)data->tlv, data->length );
10768 break;
10770 case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
10771 case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
10772 break;
10774 /* SCSI no operand */
10775 case VKI_SCSI_IOCTL_DOORLOCK:
10776 case VKI_SCSI_IOCTL_DOORUNLOCK:
10777 break;
10779 /* Real Time Clock (/dev/rtc) ioctls */
10780 case VKI_RTC_UIE_ON:
10781 case VKI_RTC_UIE_OFF:
10782 case VKI_RTC_AIE_ON:
10783 case VKI_RTC_AIE_OFF:
10784 case VKI_RTC_PIE_ON:
10785 case VKI_RTC_PIE_OFF:
10786 case VKI_RTC_IRQP_SET:
10787 break;
10788 case VKI_RTC_RD_TIME:
10789 case VKI_RTC_ALM_READ:
10790 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
10791 break;
10792 case VKI_RTC_ALM_SET:
10793 break;
10794 case VKI_RTC_IRQP_READ:
10795 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10796 break;
10798 /* Block devices */
10799 case VKI_BLKROSET:
10800 break;
10801 case VKI_BLKROGET:
10802 POST_MEM_WRITE(ARG3, sizeof(int));
10803 break;
10804 case VKI_BLKGETSIZE:
10805 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10806 break;
10807 case VKI_BLKFLSBUF:
10808 break;
10809 case VKI_BLKRASET:
10810 break;
10811 case VKI_BLKRAGET:
10812 POST_MEM_WRITE(ARG3, sizeof(long));
10813 break;
10814 case VKI_BLKFRASET:
10815 break;
10816 case VKI_BLKFRAGET:
10817 POST_MEM_WRITE(ARG3, sizeof(long));
10818 break;
10819 case VKI_BLKSECTGET:
10820 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
10821 break;
10822 case VKI_BLKSSZGET:
10823 POST_MEM_WRITE(ARG3, sizeof(int));
10824 break;
10825 case VKI_BLKBSZGET:
10826 POST_MEM_WRITE(ARG3, sizeof(int));
10827 break;
10828 case VKI_BLKBSZSET:
10829 break;
10830 case VKI_BLKGETSIZE64:
10831 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
10832 break;
10833 case VKI_BLKPBSZGET:
10834 POST_MEM_WRITE(ARG3, sizeof(int));
10835 break;
10836 case VKI_BLKIOMIN:
10837 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10838 break;
10839 case VKI_BLKIOOPT:
10840 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10841 break;
10842 case VKI_BLKALIGNOFF:
10843 POST_MEM_WRITE(ARG3, sizeof(int));
10844 break;
10845 case VKI_BLKDISCARDZEROES:
10846 POST_MEM_WRITE(ARG3, sizeof(vki_uint));
10847 break;
10848 case VKI_BLKREPORTZONE: {
10849 const struct vki_blk_zone_report *zr = (void *)(Addr)ARG3;
10851 POST_MEM_WRITE(ARG3, sizeof(*zr) + zr->nr_zones * sizeof(zr->zones[0]));
10852 break;
10854 case VKI_BLKRESETZONE:
10855 break;
10857 /* Hard disks */
10858 case VKI_HDIO_GETGEO: /* 0x0301 */
10859 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
10860 break;
10861 case VKI_HDIO_GET_DMA: /* 0x030b */
10862 POST_MEM_WRITE(ARG3, sizeof(long));
10863 break;
10864 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
10865 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
10866 break;
10868 /* SCSI */
10869 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
10870 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
10871 break;
10872 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
10873 POST_MEM_WRITE(ARG3, sizeof(int));
10874 break;
10876 /* CD ROM stuff (??) */
10877 case VKI_CDROM_DISC_STATUS:
10878 case VKI_CDROMSTOP:
10879 break;
10880 case VKI_CDROMSUBCHNL:
10881 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
10882 break;
10883 case VKI_CDROMREADTOCHDR:
10884 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
10885 break;
10886 case VKI_CDROMREADTOCENTRY:
10887 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
10888 break;
10889 case VKI_CDROMMULTISESSION:
10890 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
10891 break;
10892 case VKI_CDROMVOLREAD:
10893 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
10894 break;
10895 case VKI_CDROMREADMODE1:
10896 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW1);
10897 break;
10898 case VKI_CDROMREADMODE2:
10899 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW0);
10900 break;
10901 case VKI_CDROMREADRAW:
10902 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
10903 break;
10904 case VKI_CDROMREADAUDIO:
10906 struct vki_cdrom_read_audio *cra =
10907 (struct vki_cdrom_read_audio *) (Addr)ARG3;
10908 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
10909 break;
10912 case VKI_CDROMPLAYMSF:
10913 break;
10914 /* The following two are probably bogus (should check args
10915 for readability). JRS 20021117 */
10916 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
10917 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
10918 break;
10919 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
10920 break;
10922 /* DVD stuff */
10923 case VKI_DVD_READ_STRUCT:
10924 break;
10926 case VKI_FIGETBSZ:
10927 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
10928 break;
10929 case VKI_FIBMAP:
10930 POST_MEM_WRITE(ARG3, sizeof(int));
10931 break;
10932 case VKI_FICLONE:
10933 break;
10935 case VKI_FBIOGET_VSCREENINFO: //0x4600
10936 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
10937 break;
10938 case VKI_FBIOGET_FSCREENINFO: //0x4602
10939 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
10940 break;
10942 case VKI_PPCLAIM:
10943 case VKI_PPEXCL:
10944 case VKI_PPYIELD:
10945 case VKI_PPRELEASE:
10946 case VKI_PPSETMODE:
10947 case VKI_PPSETPHASE:
10948 case VKI_PPSETFLAGS:
10949 case VKI_PPWDATA:
10950 case VKI_PPWCONTROL:
10951 case VKI_PPFCONTROL:
10952 case VKI_PPDATADIR:
10953 case VKI_PPNEGOT:
10954 case VKI_PPWCTLONIRQ:
10955 case VKI_PPSETTIME:
10956 break;
10957 case VKI_PPGETMODE:
10958 POST_MEM_WRITE( ARG3, sizeof(int) );
10959 break;
10960 case VKI_PPGETPHASE:
10961 POST_MEM_WRITE( ARG3, sizeof(int) );
10962 break;
10963 case VKI_PPGETMODES:
10964 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
10965 break;
10966 case VKI_PPGETFLAGS:
10967 POST_MEM_WRITE( ARG3, sizeof(int) );
10968 break;
10969 case VKI_PPRSTATUS:
10970 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10971 break;
10972 case VKI_PPRDATA:
10973 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10974 break;
10975 case VKI_PPRCONTROL:
10976 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
10977 break;
10978 case VKI_PPCLRIRQ:
10979 POST_MEM_WRITE( ARG3, sizeof(int) );
10980 break;
10981 case VKI_PPGETTIME:
10982 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
10983 break;
10985 case VKI_GIO_FONT:
10986 POST_MEM_WRITE( ARG3, 32 * 256 );
10987 break;
10988 case VKI_PIO_FONT:
10989 break;
10991 case VKI_GIO_FONTX:
10992 POST_MEM_WRITE((Addr)((struct vki_consolefontdesc *)(Addr)ARG3)->chardata,
10993 32 * ((struct vki_consolefontdesc *)(Addr)ARG3)->charcount);
10994 break;
10995 case VKI_PIO_FONTX:
10996 break;
10998 case VKI_PIO_FONTRESET:
10999 break;
11001 case VKI_GIO_CMAP:
11002 POST_MEM_WRITE( ARG3, 16 * 3 );
11003 break;
11004 case VKI_PIO_CMAP:
11005 break;
11007 case VKI_KIOCSOUND:
11008 case VKI_KDMKTONE:
11009 break;
11011 case VKI_KDGETLED:
11012 POST_MEM_WRITE( ARG3, sizeof(char) );
11013 break;
11014 case VKI_KDSETLED:
11015 break;
11017 case VKI_KDGKBTYPE:
11018 POST_MEM_WRITE( ARG3, sizeof(char) );
11019 break;
11021 case VKI_KDADDIO:
11022 case VKI_KDDELIO:
11023 case VKI_KDENABIO:
11024 case VKI_KDDISABIO:
11025 break;
11027 case VKI_KDSETMODE:
11028 break;
11029 case VKI_KDGETMODE:
11030 POST_MEM_WRITE( ARG3, sizeof(int) );
11031 break;
11033 case VKI_KDMAPDISP:
11034 case VKI_KDUNMAPDISP:
11035 break;
11037 case VKI_GIO_SCRNMAP:
11038 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
11039 break;
11040 case VKI_PIO_SCRNMAP:
11041 break;
11042 case VKI_GIO_UNISCRNMAP:
11043 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
11044 break;
11045 case VKI_PIO_UNISCRNMAP:
11046 break;
11048 case VKI_GIO_UNIMAP:
11049 if ( ARG3 ) {
11050 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) (Addr)ARG3;
11051 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
11052 POST_MEM_WRITE( (Addr)desc->entries,
11053 desc->entry_ct * sizeof(struct vki_unipair) );
11055 break;
11056 case VKI_PIO_UNIMAP:
11057 break;
11058 case VKI_PIO_UNIMAPCLR:
11059 break;
11061 case VKI_KDGKBMODE:
11062 POST_MEM_WRITE( ARG3, sizeof(int) );
11063 break;
11064 case VKI_KDSKBMODE:
11065 break;
11067 case VKI_KDGKBMETA:
11068 POST_MEM_WRITE( ARG3, sizeof(int) );
11069 break;
11070 case VKI_KDSKBMETA:
11071 break;
11073 case VKI_KDGKBLED:
11074 POST_MEM_WRITE( ARG3, sizeof(char) );
11075 break;
11076 case VKI_KDSKBLED:
11077 break;
11079 case VKI_KDGKBENT:
11080 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)(Addr)ARG3)->kb_value,
11081 sizeof(((struct vki_kbentry *)(Addr)ARG3)->kb_value) );
11082 break;
11083 case VKI_KDSKBENT:
11084 break;
11086 case VKI_KDGKBSENT:
11087 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)(Addr)ARG3)->kb_string,
11088 sizeof(((struct vki_kbsentry *)(Addr)ARG3)->kb_string) );
11089 break;
11090 case VKI_KDSKBSENT:
11091 break;
11093 case VKI_KDGKBDIACR:
11094 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
11095 break;
11096 case VKI_KDSKBDIACR:
11097 break;
11099 case VKI_KDGETKEYCODE:
11100 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)(Addr)ARG3)->keycode,
11101 sizeof(((struct vki_kbkeycode *)(Addr)ARG3)->keycode) );
11102 break;
11103 case VKI_KDSETKEYCODE:
11104 break;
11106 case VKI_KDSIGACCEPT:
11107 break;
11109 case VKI_KDKBDREP:
11110 break;
11112 case VKI_KDFONTOP:
11113 if ( ARG3 ) {
11114 struct vki_console_font_op *op =
11115 (struct vki_console_font_op *) (Addr)ARG3;
11116 switch ( op->op ) {
11117 case VKI_KD_FONT_OP_SET:
11118 break;
11119 case VKI_KD_FONT_OP_GET:
11120 if ( op->data )
11121 POST_MEM_WRITE( (Addr) op->data,
11122 (op->width + 7) / 8 * 32 * op->charcount );
11123 break;
11124 case VKI_KD_FONT_OP_SET_DEFAULT:
11125 break;
11126 case VKI_KD_FONT_OP_COPY:
11127 break;
11129 POST_MEM_WRITE( (Addr) op, sizeof(*op));
11131 break;
11133 case VKI_VT_OPENQRY:
11134 POST_MEM_WRITE( ARG3, sizeof(int) );
11135 break;
11136 case VKI_VT_GETMODE:
11137 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
11138 break;
11139 case VKI_VT_SETMODE:
11140 break;
11141 case VKI_VT_GETSTATE:
11142 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_active),
11143 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_active) );
11144 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) (Addr)ARG3)->v_state),
11145 sizeof(((struct vki_vt_stat*) (Addr)ARG3)->v_state) );
11146 break;
11147 case VKI_VT_RELDISP:
11148 case VKI_VT_ACTIVATE:
11149 case VKI_VT_WAITACTIVE:
11150 case VKI_VT_DISALLOCATE:
11151 break;
11152 case VKI_VT_RESIZE:
11153 break;
11154 case VKI_VT_RESIZEX:
11155 break;
11156 case VKI_VT_LOCKSWITCH:
11157 case VKI_VT_UNLOCKSWITCH:
11158 break;
11160 case VKI_USBDEVFS_CONTROL:
11161 if ( ARG3 ) {
11162 struct vki_usbdevfs_ctrltransfer *vkuc =
11163 (struct vki_usbdevfs_ctrltransfer *)(Addr)ARG3;
11164 if (vkuc->bRequestType & 0x80)
11165 POST_MEM_WRITE((Addr)vkuc->data, RES);
11167 break;
11168 case VKI_USBDEVFS_BULK:
11169 if ( ARG3 ) {
11170 struct vki_usbdevfs_bulktransfer *vkub =
11171 (struct vki_usbdevfs_bulktransfer *)(Addr)ARG3;
11172 if (vkub->ep & 0x80)
11173 POST_MEM_WRITE((Addr)vkub->data, RES);
11175 break;
11176 case VKI_USBDEVFS_GETDRIVER:
11177 if ( ARG3 ) {
11178 struct vki_usbdevfs_getdriver *vkugd =
11179 (struct vki_usbdevfs_getdriver *)(Addr)ARG3;
11180 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
11182 break;
11183 case VKI_USBDEVFS_REAPURB:
11184 case VKI_USBDEVFS_REAPURBNDELAY:
11185 if ( ARG3 ) {
11186 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)(Addr)ARG3;
11187 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
11188 if (!*vkuu)
11189 break;
11190 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
11191 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
11192 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
11193 if (vkusp->bRequestType & 0x80)
11194 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
11195 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11196 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
11197 char *bp = (*vkuu)->buffer;
11198 int i;
11199 for(i=0; i<(*vkuu)->number_of_packets; i++) {
11200 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
11201 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
11202 if ((*vkuu)->endpoint & 0x80)
11203 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
11204 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
11206 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
11207 } else {
11208 if ((*vkuu)->endpoint & 0x80)
11209 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
11210 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
11213 break;
11214 case VKI_USBDEVFS_CONNECTINFO:
11215 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
11216 break;
11217 case VKI_USBDEVFS_IOCTL:
11218 if ( ARG3 ) {
11219 struct vki_usbdevfs_ioctl *vkui =
11220 (struct vki_usbdevfs_ioctl *)(Addr)ARG3;
11221 UInt dir2, size2;
11222 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
11223 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
11224 if (size2 > 0) {
11225 if (dir2 & _VKI_IOC_READ)
11226 POST_MEM_WRITE((Addr)vkui->data, size2);
11229 break;
11231 /* I2C (/dev/i2c-*) ioctls */
11232 case VKI_I2C_SLAVE:
11233 case VKI_I2C_SLAVE_FORCE:
11234 case VKI_I2C_TENBIT:
11235 case VKI_I2C_PEC:
11236 break;
11237 case VKI_I2C_FUNCS:
11238 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
11239 break;
11240 case VKI_I2C_RDWR:
11241 if ( ARG3 ) {
11242 struct vki_i2c_rdwr_ioctl_data *vkui =
11243 (struct vki_i2c_rdwr_ioctl_data *)(Addr)ARG3;
11244 UInt i;
11245 for (i=0; i < vkui->nmsgs; i++) {
11246 struct vki_i2c_msg *msg = vkui->msgs + i;
11247 if (msg->flags & VKI_I2C_M_RD)
11248 POST_MEM_WRITE((Addr)msg->buf, msg->len);
11251 break;
11252 case VKI_I2C_SMBUS:
11253 if ( ARG3 ) {
11254 struct vki_i2c_smbus_ioctl_data *vkis
11255 = (struct vki_i2c_smbus_ioctl_data *) (Addr)ARG3;
11256 /* i2c_smbus_write_quick hides its value in read_write, so
11257 this variable can have a different meaning */
11258 if ((vkis->read_write == VKI_I2C_SMBUS_READ)
11259 || (vkis->size == VKI_I2C_SMBUS_PROC_CALL)
11260 || (vkis->size == VKI_I2C_SMBUS_BLOCK_PROC_CALL)) {
11261 if ( ! (vkis->size == VKI_I2C_SMBUS_QUICK)) {
11262 UInt size;
11263 switch(vkis->size) {
11264 case VKI_I2C_SMBUS_BYTE:
11265 case VKI_I2C_SMBUS_BYTE_DATA:
11266 size = 1;
11267 break;
11268 case VKI_I2C_SMBUS_WORD_DATA:
11269 case VKI_I2C_SMBUS_PROC_CALL:
11270 size = 2;
11271 break;
11272 case VKI_I2C_SMBUS_BLOCK_DATA:
11273 case VKI_I2C_SMBUS_I2C_BLOCK_BROKEN:
11274 case VKI_I2C_SMBUS_BLOCK_PROC_CALL:
11275 case VKI_I2C_SMBUS_I2C_BLOCK_DATA:
11276 size = 1 + vkis->data->block[0];
11277 break;
11278 default:
11279 size = 0;
11281 POST_MEM_WRITE((Addr)&vkis->data->block[0], size);
11285 break;
11287 /* Wireless extensions ioctls */
11288 case VKI_SIOCSIWCOMMIT:
11289 case VKI_SIOCSIWNWID:
11290 case VKI_SIOCSIWFREQ:
11291 case VKI_SIOCSIWMODE:
11292 case VKI_SIOCSIWSENS:
11293 case VKI_SIOCSIWRANGE:
11294 case VKI_SIOCSIWPRIV:
11295 case VKI_SIOCSIWSTATS:
11296 case VKI_SIOCSIWSPY:
11297 case VKI_SIOCSIWTHRSPY:
11298 case VKI_SIOCSIWAP:
11299 case VKI_SIOCSIWSCAN:
11300 case VKI_SIOCSIWESSID:
11301 case VKI_SIOCSIWRATE:
11302 case VKI_SIOCSIWNICKN:
11303 case VKI_SIOCSIWRTS:
11304 case VKI_SIOCSIWFRAG:
11305 case VKI_SIOCSIWTXPOW:
11306 case VKI_SIOCSIWRETRY:
11307 case VKI_SIOCSIWENCODE:
11308 case VKI_SIOCSIWPOWER:
11309 case VKI_SIOCSIWGENIE:
11310 case VKI_SIOCSIWMLME:
11311 case VKI_SIOCSIWAUTH:
11312 case VKI_SIOCSIWENCODEEXT:
11313 case VKI_SIOCSIWPMKSA:
11314 break;
11315 case VKI_SIOCGIWNAME:
11316 if (ARG3) {
11317 POST_MEM_WRITE((Addr)((struct vki_iwreq *)(Addr)ARG3)->u.name,
11318 sizeof(((struct vki_iwreq *)(Addr)ARG3)->u.name));
11320 break;
11321 case VKI_SIOCGIWNWID:
11322 case VKI_SIOCGIWSENS:
11323 case VKI_SIOCGIWRATE:
11324 case VKI_SIOCGIWRTS:
11325 case VKI_SIOCGIWFRAG:
11326 case VKI_SIOCGIWTXPOW:
11327 case VKI_SIOCGIWRETRY:
11328 case VKI_SIOCGIWPOWER:
11329 case VKI_SIOCGIWAUTH:
11330 if (ARG3) {
11331 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.param,
11332 sizeof(struct vki_iw_param));
11334 break;
11335 case VKI_SIOCGIWFREQ:
11336 if (ARG3) {
11337 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.freq,
11338 sizeof(struct vki_iw_freq));
11340 break;
11341 case VKI_SIOCGIWMODE:
11342 if (ARG3) {
11343 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.mode,
11344 sizeof(__vki_u32));
11346 break;
11347 case VKI_SIOCGIWRANGE:
11348 case VKI_SIOCGIWPRIV:
11349 case VKI_SIOCGIWSTATS:
11350 case VKI_SIOCGIWSPY:
11351 case VKI_SIOCGIWTHRSPY:
11352 case VKI_SIOCGIWAPLIST:
11353 case VKI_SIOCGIWSCAN:
11354 case VKI_SIOCGIWESSID:
11355 case VKI_SIOCGIWNICKN:
11356 case VKI_SIOCGIWENCODE:
11357 case VKI_SIOCGIWGENIE:
11358 case VKI_SIOCGIWENCODEEXT:
11359 if (ARG3) {
11360 struct vki_iw_point* point;
11361 point = &((struct vki_iwreq *)(Addr)ARG3)->u.data;
11362 POST_MEM_WRITE((Addr)point->pointer, point->length);
11364 break;
11365 case VKI_SIOCGIWAP:
11366 if (ARG3) {
11367 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)(Addr)ARG3)->u.ap_addr,
11368 sizeof(struct vki_sockaddr));
11370 break;
11372 # if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
11373 || defined(VGPV_mips32_linux_android) \
11374 || defined(VGPV_arm64_linux_android)
11375 /* ashmem */
11376 case VKI_ASHMEM_GET_SIZE:
11377 case VKI_ASHMEM_SET_SIZE:
11378 case VKI_ASHMEM_GET_PROT_MASK:
11379 case VKI_ASHMEM_SET_PROT_MASK:
11380 case VKI_ASHMEM_GET_PIN_STATUS:
11381 case VKI_ASHMEM_PURGE_ALL_CACHES:
11382 case VKI_ASHMEM_SET_NAME:
11383 case VKI_ASHMEM_PIN:
11384 case VKI_ASHMEM_UNPIN:
11385 break;
11386 case VKI_ASHMEM_GET_NAME:
11387 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
11388 break;
11390 /* binder */
11391 case VKI_BINDER_WRITE_READ:
11392 if (ARG3) {
11393 struct vki_binder_write_read* bwr
11394 = (struct vki_binder_write_read*)(Addr)ARG3;
11395 POST_FIELD_WRITE(bwr->write_consumed);
11396 POST_FIELD_WRITE(bwr->read_consumed);
11398 if (bwr->read_size)
11399 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
11401 break;
11403 case VKI_BINDER_SET_IDLE_TIMEOUT:
11404 case VKI_BINDER_SET_MAX_THREADS:
11405 case VKI_BINDER_SET_IDLE_PRIORITY:
11406 case VKI_BINDER_SET_CONTEXT_MGR:
11407 case VKI_BINDER_THREAD_EXIT:
11408 break;
11409 case VKI_BINDER_VERSION:
11410 if (ARG3) {
11411 struct vki_binder_version* bv =
11412 (struct vki_binder_version*)(Addr)ARG3;
11413 POST_FIELD_WRITE(bv->protocol_version);
11415 break;
11416 # endif /* defined(VGPV_*_linux_android) */
11418 case VKI_HCIGETDEVLIST:
11419 if (ARG3) {
11420 struct vki_hci_dev_list_req* dlr =
11421 (struct vki_hci_dev_list_req*)(Addr)ARG3;
11422 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_dev_list_req),
11423 dlr->dev_num * sizeof(struct vki_hci_dev_req));
11425 break;
11427 case VKI_HCIINQUIRY:
11428 if (ARG3) {
11429 struct vki_hci_inquiry_req* ir =
11430 (struct vki_hci_inquiry_req*)(Addr)ARG3;
11431 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
11432 ir->num_rsp * sizeof(struct vki_inquiry_info));
11434 break;
11436 case VKI_DRM_IOCTL_VERSION:
11437 if (ARG3) {
11438 struct vki_drm_version* data = (struct vki_drm_version *)(Addr)ARG3;
11439 struct vg_drm_version_info* info = container_of(data, struct vg_drm_version_info, data);
11440 const vki_size_t orig_name_len = info->orig->name_len;
11441 const vki_size_t orig_date_len = info->orig->date_len;
11442 const vki_size_t orig_desc_len = info->orig->desc_len;
11443 *info->orig = info->data;
11444 ARG3 = (Addr)info->orig;
11445 data = info->orig;
11446 VG_(free)(info);
11447 if (SUCCESS) {
11448 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
11449 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
11450 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
11451 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
11452 POST_MEM_WRITE((Addr)data->name, VG_MIN(data->name_len, orig_name_len));
11453 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
11454 POST_MEM_WRITE((Addr)data->date, VG_MIN(data->date_len, orig_date_len));
11455 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
11456 POST_MEM_WRITE((Addr)data->desc, VG_MIN(data->desc_len, orig_desc_len));
11459 break;
11460 case VKI_DRM_IOCTL_GET_UNIQUE:
11461 if (ARG3) {
11462 struct vki_drm_unique *data = (struct vki_drm_unique *)(Addr)ARG3;
11463 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
11465 break;
11466 case VKI_DRM_IOCTL_GET_MAGIC:
11467 if (ARG3) {
11468 struct vki_drm_auth *data = (struct vki_drm_auth *)(Addr)ARG3;
11469 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
11471 break;
11472 case VKI_DRM_IOCTL_WAIT_VBLANK:
11473 if (ARG3) {
11474 union vki_drm_wait_vblank *data =
11475 (union vki_drm_wait_vblank *)(Addr)ARG3;
11476 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
11478 break;
11479 case VKI_DRM_IOCTL_GEM_FLINK:
11480 if (ARG3) {
11481 struct vki_drm_gem_flink *data =
11482 (struct vki_drm_gem_flink *)(Addr)ARG3;
11483 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
11485 break;
11486 case VKI_DRM_IOCTL_GEM_OPEN:
11487 if (ARG3) {
11488 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)(Addr)ARG3;
11489 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11490 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
11492 break;
11493 case VKI_DRM_IOCTL_I915_GETPARAM:
11494 if (ARG3) {
11495 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)(Addr)ARG3;
11496 POST_MEM_WRITE((Addr)data->value, sizeof(int));
11498 break;
11499 case VKI_DRM_IOCTL_I915_GEM_BUSY:
11500 if (ARG3) {
11501 struct vki_drm_i915_gem_busy *data =
11502 (struct vki_drm_i915_gem_busy *)(Addr)ARG3;
11503 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
11505 break;
11506 case VKI_DRM_IOCTL_I915_GEM_CREATE:
11507 if (ARG3) {
11508 struct vki_drm_i915_gem_create *data =
11509 (struct vki_drm_i915_gem_create *)(Addr)ARG3;
11510 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
11512 break;
11513 case VKI_DRM_IOCTL_I915_GEM_PREAD:
11514 if (ARG3) {
11515 struct vki_drm_i915_gem_pread *data =
11516 (struct vki_drm_i915_gem_pread *)(Addr)ARG3;
11517 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
11519 break;
11520 case VKI_DRM_IOCTL_I915_GEM_MMAPv1:
11521 if (ARG3) {
11522 struct vki_drm_i915_gem_mmap_v1 *data =
11523 (struct vki_drm_i915_gem_mmap_v1 *)(Addr)ARG3;
11524 Addr addr = data->addr_ptr;
11525 SizeT size = data->size;
11526 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11527 "ioctl(DRM_IOCTL_I915_GEM_MMAPv1)"));
11528 ML_(notify_core_and_tool_of_mmap)(addr, size,
11529 VKI_PROT_READ | VKI_PROT_WRITE,
11530 VKI_MAP_ANONYMOUS, -1, 0 );
11531 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11533 break;
11534 case VKI_DRM_IOCTL_I915_GEM_MMAP:
11535 if (ARG3) {
11536 struct vki_drm_i915_gem_mmap *data =
11537 (struct vki_drm_i915_gem_mmap *)(Addr)ARG3;
11538 Addr addr = data->addr_ptr;
11539 SizeT size = data->size;
11540 vg_assert(ML_(valid_client_addr)(addr, size, tid,
11541 "ioctl(DRM_IOCTL_I915_GEM_MMAP)"));
11542 ML_(notify_core_and_tool_of_mmap)(addr, size,
11543 VKI_PROT_READ | VKI_PROT_WRITE,
11544 VKI_MAP_ANONYMOUS, -1, 0 );
11545 POST_MEM_WRITE((Addr)&data->addr_ptr, sizeof(data->addr_ptr));
11547 break;
11548 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
11549 if (ARG3) {
11550 struct vki_drm_i915_gem_mmap_gtt *data =
11551 (struct vki_drm_i915_gem_mmap_gtt *)(Addr)ARG3;
11552 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
11554 break;
11555 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
11556 if (ARG3) {
11557 struct vki_drm_i915_gem_set_tiling *data =
11558 (struct vki_drm_i915_gem_set_tiling *)(Addr)ARG3;
11559 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11560 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
11561 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11563 break;
11564 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
11565 if (ARG3) {
11566 struct vki_drm_i915_gem_get_tiling *data =
11567 (struct vki_drm_i915_gem_get_tiling *)(Addr)ARG3;
11568 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
11569 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
11571 break;
11572 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
11573 if (ARG3) {
11574 struct vki_drm_i915_gem_get_aperture *data =
11575 (struct vki_drm_i915_gem_get_aperture *)(Addr)ARG3;
11576 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
11577 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
11579 break;
11581 /* KVM ioctls that only write the system call return value */
11582 case VKI_KVM_GET_API_VERSION:
11583 case VKI_KVM_CREATE_VM:
11584 case VKI_KVM_CHECK_EXTENSION:
11585 case VKI_KVM_GET_VCPU_MMAP_SIZE:
11586 case VKI_KVM_S390_ENABLE_SIE:
11587 case VKI_KVM_CREATE_VCPU:
11588 case VKI_KVM_SET_TSS_ADDR:
11589 case VKI_KVM_CREATE_IRQCHIP:
11590 case VKI_KVM_RUN:
11591 case VKI_KVM_S390_INITIAL_RESET:
11592 case VKI_KVM_KVMCLOCK_CTRL:
11593 break;
11595 case VKI_KVM_S390_MEM_OP: {
11596 struct vki_kvm_s390_mem_op *args =
11597 (struct vki_kvm_s390_mem_op *)(Addr)(ARG3);
11598 if (args->flags & VKI_KVM_S390_MEMOP_F_CHECK_ONLY)
11599 break;
11600 if (args->op == VKI_KVM_S390_MEMOP_LOGICAL_READ)
11601 POST_MEM_WRITE((Addr)args->buf, args->size);
11603 break;
11605 #ifdef ENABLE_XEN
11606 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
11607 SyscallArgs harrghs;
11608 struct vki_xen_privcmd_hypercall *args =
11609 (struct vki_xen_privcmd_hypercall *)(Addr)(ARG3);
11611 if (!args)
11612 break;
11614 VG_(memset)(&harrghs, 0, sizeof(harrghs));
11615 harrghs.sysno = args->op;
11616 harrghs.arg1 = args->arg[0];
11617 harrghs.arg2 = args->arg[1];
11618 harrghs.arg3 = args->arg[2];
11619 harrghs.arg4 = args->arg[3];
11620 harrghs.arg5 = args->arg[4];
11621 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
11623 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
11625 break;
11627 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
11628 break;
11629 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
11630 struct vki_xen_privcmd_mmapbatch *args =
11631 (struct vki_xen_privcmd_mmapbatch *)(Addr)(ARG3);
11632 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
11634 break;
11635 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
11636 struct vki_xen_privcmd_mmapbatch_v2 *args =
11637 (struct vki_xen_privcmd_mmapbatch_v2 *)(Addr)(ARG3);
11638 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
11640 break;
11642 case VKI_XEN_IOCTL_EVTCHN_BIND_VIRQ:
11643 case VKI_XEN_IOCTL_EVTCHN_BIND_INTERDOMAIN:
11644 case VKI_XEN_IOCTL_EVTCHN_BIND_UNBOUND_PORT:
11645 case VKI_XEN_IOCTL_EVTCHN_UNBIND:
11646 case VKI_XEN_IOCTL_EVTCHN_NOTIFY:
11647 case VKI_XEN_IOCTL_EVTCHN_RESET:
11648 /* No output */
11649 break;
11650 #endif
11652 /* Lustre */
11653 case VKI_OBD_IOC_FID2PATH: {
11654 struct vki_getinfo_fid2path *args = (void *)(Addr)(ARG3);
11655 POST_FIELD_WRITE(args->gf_recno);
11656 POST_FIELD_WRITE(args->gf_linkno);
11657 POST_MEM_WRITE((Addr)args->gf_path, VG_(strlen)(args->gf_path)+1);
11658 break;
11661 case VKI_LL_IOC_PATH2FID:
11662 POST_MEM_WRITE(ARG3, sizeof(struct vki_lu_fid));
11663 break;
11665 case VKI_LL_IOC_GETPARENT: {
11666 struct vki_getparent *gp = (struct vki_getparent *)(Addr)ARG3;
11667 POST_FIELD_WRITE(gp->gp_fid);
11668 POST_MEM_WRITE((Addr)gp->gp_name, VG_(strlen)(gp->gp_name)+1);
11669 break;
11672 /* V4L2 */
11673 case VKI_V4L2_S_FMT:
11674 case VKI_V4L2_TRY_FMT:
11675 case VKI_V4L2_REQBUFS:
11676 case VKI_V4L2_OVERLAY:
11677 case VKI_V4L2_STREAMON:
11678 case VKI_V4L2_STREAMOFF:
11679 case VKI_V4L2_S_PARM:
11680 case VKI_V4L2_S_STD:
11681 case VKI_V4L2_S_FREQUENCY:
11682 case VKI_V4L2_S_CTRL:
11683 case VKI_V4L2_S_TUNER:
11684 case VKI_V4L2_S_AUDIO:
11685 case VKI_V4L2_S_INPUT:
11686 case VKI_V4L2_S_EDID:
11687 case VKI_V4L2_S_OUTPUT:
11688 case VKI_V4L2_S_AUDOUT:
11689 case VKI_V4L2_S_MODULATOR:
11690 case VKI_V4L2_S_JPEGCOMP:
11691 case VKI_V4L2_S_CROP:
11692 case VKI_V4L2_S_PRIORITY:
11693 case VKI_V4L2_S_HW_FREQ_SEEK:
11694 case VKI_V4L2_S_DV_TIMINGS:
11695 case VKI_V4L2_SUBSCRIBE_EVENT:
11696 case VKI_V4L2_UNSUBSCRIBE_EVENT:
11697 case VKI_V4L2_PREPARE_BUF:
11698 break;
11699 case VKI_V4L2_QUERYCAP: {
11700 struct vki_v4l2_capability *data =
11701 (struct vki_v4l2_capability *)(Addr)ARG3;
11702 POST_MEM_WRITE((Addr)data, sizeof(*data));
11703 break;
11705 case VKI_V4L2_ENUM_FMT: {
11706 struct vki_v4l2_fmtdesc *data = (struct vki_v4l2_fmtdesc *)(Addr)ARG3;
11707 POST_FIELD_WRITE(data->flags);
11708 POST_FIELD_WRITE(data->description);
11709 POST_FIELD_WRITE(data->pixelformat);
11710 POST_FIELD_WRITE(data->reserved);
11711 break;
11713 case VKI_V4L2_G_FMT: {
11714 struct vki_v4l2_format *data = (struct vki_v4l2_format *)(Addr)ARG3;
11715 switch (data->type) {
11716 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE:
11717 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT:
11718 POST_FIELD_WRITE(data->fmt.pix);
11719 break;
11720 case VKI_V4L2_BUF_TYPE_VBI_CAPTURE:
11721 case VKI_V4L2_BUF_TYPE_VBI_OUTPUT:
11722 POST_FIELD_WRITE(data->fmt.vbi);
11723 break;
11724 case VKI_V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
11725 case VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
11726 POST_FIELD_WRITE(data->fmt.sliced);
11727 break;
11728 case VKI_V4L2_BUF_TYPE_VIDEO_OVERLAY:
11729 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
11730 POST_FIELD_WRITE(data->fmt.win);
11731 break;
11732 case VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
11733 case VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
11734 POST_FIELD_WRITE(data->fmt.pix_mp);
11735 break;
11736 case VKI_V4L2_BUF_TYPE_SDR_CAPTURE:
11737 POST_FIELD_WRITE(data->fmt.sdr);
11738 break;
11740 break;
11742 case VKI_V4L2_QUERYBUF: {
11743 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11744 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11745 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11746 unsigned i;
11748 for (i = 0; i < data->length; i++) {
11749 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11750 POST_FIELD_WRITE(data->m.planes[i].length);
11751 POST_FIELD_WRITE(data->m.planes[i].m);
11752 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11753 POST_FIELD_WRITE(data->m.planes[i].reserved);
11755 } else {
11756 POST_FIELD_WRITE(data->m);
11757 POST_FIELD_WRITE(data->length);
11759 POST_FIELD_WRITE(data->bytesused);
11760 POST_FIELD_WRITE(data->flags);
11761 POST_FIELD_WRITE(data->field);
11762 POST_FIELD_WRITE(data->timestamp);
11763 POST_FIELD_WRITE(data->timecode);
11764 POST_FIELD_WRITE(data->sequence);
11765 POST_FIELD_WRITE(data->memory);
11766 POST_FIELD_WRITE(data->sequence);
11767 break;
11769 case VKI_V4L2_G_FBUF: {
11770 struct vki_v4l2_framebuffer *data =
11771 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11772 POST_MEM_WRITE((Addr)data, sizeof(*data));
11773 break;
11775 case VKI_V4L2_S_FBUF: {
11776 struct vki_v4l2_framebuffer *data =
11777 (struct vki_v4l2_framebuffer *)(Addr)ARG3;
11778 POST_FIELD_WRITE(data->capability);
11779 POST_FIELD_WRITE(data->flags);
11780 POST_FIELD_WRITE(data->fmt);
11781 break;
11783 case VKI_V4L2_QBUF: {
11784 struct vki_v4l2_buffer *data = (struct vki_v4l2_buffer *)(Addr)ARG3;
11786 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11787 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11788 unsigned i;
11790 for (i = 0; i < data->length; i++) {
11791 POST_FIELD_WRITE(data->m.planes[i].length);
11792 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11793 POST_FIELD_WRITE(data->m.planes[i].m);
11795 } else {
11796 if (data->memory == VKI_V4L2_MEMORY_MMAP)
11797 POST_FIELD_WRITE(data->m);
11798 POST_FIELD_WRITE(data->length);
11800 break;
11802 case VKI_V4L2_EXPBUF: {
11803 struct vki_v4l2_exportbuffer *data =
11804 (struct vki_v4l2_exportbuffer *)(Addr)ARG3;
11805 POST_FIELD_WRITE(data->fd);
11806 break;
11808 case VKI_V4L2_DQBUF: {
11809 struct vki_v4l2_buffer *data =
11810 (struct vki_v4l2_buffer *)(Addr)ARG3;
11811 POST_FIELD_WRITE(data->index);
11812 POST_FIELD_WRITE(data->bytesused);
11813 POST_FIELD_WRITE(data->field);
11814 if (data->type == VKI_V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
11815 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
11816 unsigned i;
11818 for (i = 0; i < data->length; i++) {
11819 POST_FIELD_WRITE(data->m.planes[i].bytesused);
11820 POST_FIELD_WRITE(data->m.planes[i].data_offset);
11821 POST_FIELD_WRITE(data->m.planes[i].length);
11822 POST_FIELD_WRITE(data->m.planes[i].m);
11824 } else {
11825 POST_FIELD_WRITE(data->m);
11826 POST_FIELD_WRITE(data->length);
11827 POST_FIELD_WRITE(data->bytesused);
11828 POST_FIELD_WRITE(data->field);
11830 POST_FIELD_WRITE(data->timestamp);
11831 POST_FIELD_WRITE(data->timecode);
11832 POST_FIELD_WRITE(data->sequence);
11833 break;
11835 case VKI_V4L2_G_PARM: {
11836 struct vki_v4l2_streamparm *data =
11837 (struct vki_v4l2_streamparm *)(Addr)ARG3;
11838 int is_output = data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT ||
11839 data->type == VKI_V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
11840 data->type == VKI_V4L2_BUF_TYPE_VBI_OUTPUT ||
11841 data->type == VKI_V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
11843 if (is_output)
11844 POST_MEM_WRITE((Addr)&data->parm.output,
11845 sizeof(data->parm.output) - sizeof(data->parm.output.reserved));
11846 else
11847 POST_MEM_WRITE((Addr)&data->parm.capture,
11848 sizeof(data->parm.capture) - sizeof(data->parm.capture.reserved));
11849 break;
11851 case VKI_V4L2_G_STD: {
11852 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11853 POST_MEM_WRITE((Addr)data, sizeof(*data));
11854 break;
11856 case VKI_V4L2_ENUMSTD: {
11857 struct vki_v4l2_standard *data = (struct vki_v4l2_standard *)(Addr)ARG3;
11858 POST_MEM_WRITE((Addr)&data->id, sizeof(*data) - sizeof(data->index));
11859 break;
11861 case VKI_V4L2_ENUMINPUT: {
11862 struct vki_v4l2_input *data = (struct vki_v4l2_input *)(Addr)ARG3;
11863 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11864 break;
11866 case VKI_V4L2_G_CTRL: {
11867 struct vki_v4l2_control *data = (struct vki_v4l2_control *)(Addr)ARG3;
11868 POST_FIELD_WRITE(data->value);
11869 break;
11871 case VKI_V4L2_G_TUNER: {
11872 struct vki_v4l2_tuner *data = (struct vki_v4l2_tuner *)(Addr)ARG3;
11873 POST_MEM_WRITE((Addr)data->name,
11874 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11875 break;
11877 case VKI_V4L2_G_AUDIO: {
11878 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11879 POST_MEM_WRITE((Addr)data,
11880 sizeof(*data) - sizeof(data->reserved));
11881 break;
11883 case VKI_V4L2_QUERYCTRL: {
11884 struct vki_v4l2_queryctrl *data = (struct vki_v4l2_queryctrl *)(Addr)ARG3;
11885 POST_MEM_WRITE((Addr)&data->type,
11886 sizeof(*data) - sizeof(data->id));
11887 break;
11889 case VKI_V4L2_QUERYMENU: {
11890 struct vki_v4l2_querymenu *data = (struct vki_v4l2_querymenu *)(Addr)ARG3;
11891 POST_MEM_WRITE((Addr)data->name,
11892 sizeof(*data) - sizeof(data->id) - sizeof(data->index));
11893 break;
11895 case VKI_V4L2_G_INPUT: {
11896 int *data = (int *)(Addr)ARG3;
11897 POST_MEM_WRITE((Addr)data, sizeof(*data));
11898 break;
11900 case VKI_V4L2_G_EDID: {
11901 struct vki_v4l2_edid *data = (struct vki_v4l2_edid *)(Addr)ARG3;
11902 if (data->blocks && data->edid)
11903 POST_MEM_WRITE((Addr)data->edid, data->blocks * 128);
11904 break;
11906 case VKI_V4L2_G_OUTPUT: {
11907 int *data = (int *)(Addr)ARG3;
11908 POST_MEM_WRITE((Addr)data, sizeof(*data));
11909 break;
11911 case VKI_V4L2_ENUMOUTPUT: {
11912 struct vki_v4l2_output *data = (struct vki_v4l2_output *)(Addr)ARG3;
11913 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->index));
11914 break;
11916 case VKI_V4L2_G_AUDOUT: {
11917 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11918 POST_MEM_WRITE((Addr)data,
11919 sizeof(*data) - sizeof(data->reserved));
11920 break;
11922 case VKI_V4L2_G_MODULATOR: {
11923 struct vki_v4l2_modulator *data = (struct vki_v4l2_modulator *)(Addr)ARG3;
11924 POST_MEM_WRITE((Addr)data->name,
11925 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11926 break;
11928 case VKI_V4L2_G_FREQUENCY: {
11929 struct vki_v4l2_frequency *data = (struct vki_v4l2_frequency *)(Addr)ARG3;
11930 POST_FIELD_WRITE(data->type);
11931 POST_FIELD_WRITE(data->frequency);
11932 break;
11934 case VKI_V4L2_CROPCAP: {
11935 struct vki_v4l2_cropcap *data = (struct vki_v4l2_cropcap *)(Addr)ARG3;
11936 POST_MEM_WRITE((Addr)&data->bounds, sizeof(*data) - sizeof(data->type));
11937 break;
11939 case VKI_V4L2_G_CROP: {
11940 struct vki_v4l2_crop *data = (struct vki_v4l2_crop *)(Addr)ARG3;
11941 POST_FIELD_WRITE(data->c);
11942 break;
11944 case VKI_V4L2_G_JPEGCOMP: {
11945 struct vki_v4l2_jpegcompression *data =
11946 (struct vki_v4l2_jpegcompression *)(Addr)ARG3;
11947 POST_MEM_WRITE((Addr)data, sizeof(*data));
11948 break;
11950 case VKI_V4L2_QUERYSTD: {
11951 vki_v4l2_std_id *data = (vki_v4l2_std_id *)(Addr)ARG3;
11952 POST_MEM_WRITE((Addr)data, sizeof(*data));
11953 break;
11955 case VKI_V4L2_ENUMAUDIO: {
11956 struct vki_v4l2_audio *data = (struct vki_v4l2_audio *)(Addr)ARG3;
11957 POST_MEM_WRITE((Addr)data->name,
11958 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11959 break;
11961 case VKI_V4L2_ENUMAUDOUT: {
11962 struct vki_v4l2_audioout *data = (struct vki_v4l2_audioout *)(Addr)ARG3;
11963 POST_MEM_WRITE((Addr)data->name,
11964 sizeof(*data) - sizeof(data->index) - sizeof(data->reserved));
11965 break;
11967 case VKI_V4L2_G_PRIORITY: {
11968 __vki_u32 *data = (__vki_u32 *)(Addr)ARG3;
11969 POST_MEM_WRITE((Addr)data, sizeof(*data));
11970 break;
11972 case VKI_V4L2_G_SLICED_VBI_CAP: {
11973 struct vki_v4l2_sliced_vbi_cap *data =
11974 (struct vki_v4l2_sliced_vbi_cap *)(Addr)ARG3;
11975 POST_MEM_WRITE((Addr)data,
11976 sizeof(*data) - sizeof(data->type) - sizeof(data->reserved));
11977 break;
11979 case VKI_V4L2_G_EXT_CTRLS: {
11980 struct vki_v4l2_ext_controls *data =
11981 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11982 if (data->count) {
11983 unsigned i;
11985 for (i = 0; i < data->count; i++) {
11986 if (data->controls[i].size)
11987 POST_MEM_WRITE((Addr)data->controls[i].ptr, data->controls[i].size);
11988 else
11989 POST_FIELD_WRITE(data->controls[i].value64);
11992 POST_FIELD_WRITE(data->error_idx);
11993 break;
11995 case VKI_V4L2_S_EXT_CTRLS: {
11996 struct vki_v4l2_ext_controls *data =
11997 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
11998 POST_FIELD_WRITE(data->error_idx);
11999 break;
12001 case VKI_V4L2_TRY_EXT_CTRLS: {
12002 struct vki_v4l2_ext_controls *data =
12003 (struct vki_v4l2_ext_controls *)(Addr)ARG3;
12004 POST_FIELD_WRITE(data->error_idx);
12005 break;
12007 case VKI_V4L2_ENUM_FRAMESIZES: {
12008 struct vki_v4l2_frmsizeenum *data =
12009 (struct vki_v4l2_frmsizeenum *)(Addr)ARG3;
12010 POST_FIELD_WRITE(data->type);
12011 POST_FIELD_WRITE(data->stepwise);
12012 break;
12014 case VKI_V4L2_ENUM_FRAMEINTERVALS: {
12015 struct vki_v4l2_frmivalenum *data =
12016 (struct vki_v4l2_frmivalenum *)(Addr)ARG3;
12017 POST_FIELD_WRITE(data->type);
12018 POST_FIELD_WRITE(data->stepwise);
12019 break;
12021 case VKI_V4L2_G_ENC_INDEX: {
12022 struct vki_v4l2_enc_idx *data = (struct vki_v4l2_enc_idx *)(Addr)ARG3;
12023 POST_MEM_WRITE((Addr)data, sizeof(*data));
12024 break;
12026 case VKI_V4L2_ENCODER_CMD: {
12027 struct vki_v4l2_encoder_cmd *data =
12028 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12029 POST_FIELD_WRITE(data->flags);
12030 break;
12032 case VKI_V4L2_TRY_ENCODER_CMD: {
12033 struct vki_v4l2_encoder_cmd *data =
12034 (struct vki_v4l2_encoder_cmd *)(Addr)ARG3;
12035 POST_FIELD_WRITE(data->flags);
12036 break;
12038 case VKI_V4L2_DBG_S_REGISTER: {
12039 struct vki_v4l2_dbg_register *data =
12040 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12041 POST_FIELD_WRITE(data->size);
12042 break;
12044 case VKI_V4L2_DBG_G_REGISTER: {
12045 struct vki_v4l2_dbg_register *data =
12046 (struct vki_v4l2_dbg_register *)(Addr)ARG3;
12047 POST_FIELD_WRITE(data->val);
12048 POST_FIELD_WRITE(data->size);
12049 break;
12051 case VKI_V4L2_G_DV_TIMINGS: {
12052 struct vki_v4l2_dv_timings *data =
12053 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12054 POST_MEM_WRITE((Addr)data, sizeof(*data));
12055 break;
12057 case VKI_V4L2_DQEVENT: {
12058 struct vki_v4l2_event *data = (struct vki_v4l2_event *)(Addr)ARG3;
12059 POST_MEM_WRITE((Addr)data, sizeof(*data));
12060 break;
12062 case VKI_V4L2_CREATE_BUFS: {
12063 struct vki_v4l2_create_buffers *data =
12064 (struct vki_v4l2_create_buffers *)(Addr)ARG3;
12065 POST_FIELD_WRITE(data->index);
12066 break;
12068 case VKI_V4L2_G_SELECTION: {
12069 struct vki_v4l2_selection *data =
12070 (struct vki_v4l2_selection *)(Addr)ARG3;
12071 POST_FIELD_WRITE(data->r);
12072 break;
12074 case VKI_V4L2_S_SELECTION: {
12075 struct vki_v4l2_selection *data = (struct vki_v4l2_selection *)(Addr)ARG3;
12076 POST_FIELD_WRITE(data->r);
12077 break;
12079 case VKI_V4L2_DECODER_CMD: {
12080 struct vki_v4l2_decoder_cmd *data =
12081 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12082 POST_FIELD_WRITE(data->flags);
12083 break;
12085 case VKI_V4L2_TRY_DECODER_CMD: {
12086 struct vki_v4l2_decoder_cmd *data =
12087 (struct vki_v4l2_decoder_cmd *)(Addr)ARG3;
12088 POST_FIELD_WRITE(data->flags);
12089 break;
12091 case VKI_V4L2_ENUM_DV_TIMINGS: {
12092 struct vki_v4l2_enum_dv_timings *data =
12093 (struct vki_v4l2_enum_dv_timings *)(Addr)ARG3;
12094 POST_FIELD_WRITE(data->timings);
12095 break;
12097 case VKI_V4L2_QUERY_DV_TIMINGS: {
12098 struct vki_v4l2_dv_timings *data =
12099 (struct vki_v4l2_dv_timings *)(Addr)ARG3;
12100 POST_MEM_WRITE((Addr)data, sizeof(*data));
12101 break;
12103 case VKI_V4L2_DV_TIMINGS_CAP: {
12104 struct vki_v4l2_dv_timings_cap *data =
12105 (struct vki_v4l2_dv_timings_cap *)(Addr)ARG3;
12106 POST_MEM_WRITE((Addr)data, sizeof(*data));
12107 break;
12109 case VKI_V4L2_ENUM_FREQ_BANDS: {
12110 struct vki_v4l2_frequency_band *data =
12111 (struct vki_v4l2_frequency_band *)(Addr)ARG3;
12112 POST_FIELD_WRITE(data->capability);
12113 POST_FIELD_WRITE(data->rangelow);
12114 POST_FIELD_WRITE(data->rangehigh);
12115 POST_FIELD_WRITE(data->modulation);
12116 break;
12118 case VKI_V4L2_DBG_G_CHIP_INFO: {
12119 struct vki_v4l2_dbg_chip_info *data =
12120 (struct vki_v4l2_dbg_chip_info *)(Addr)ARG3;
12121 POST_FIELD_WRITE(data->name);
12122 POST_FIELD_WRITE(data->flags);
12123 break;
12125 case VKI_V4L2_QUERY_EXT_CTRL: {
12126 struct vki_v4l2_query_ext_ctrl *data =
12127 (struct vki_v4l2_query_ext_ctrl *)(Addr)ARG3;
12128 POST_MEM_WRITE((Addr)&data->type,
12129 sizeof(*data) - sizeof(data->id) - sizeof(data->reserved));
12130 break;
12133 case VKI_V4L2_SUBDEV_S_FMT:
12134 case VKI_V4L2_SUBDEV_S_FRAME_INTERVAL:
12135 case VKI_V4L2_SUBDEV_S_CROP:
12136 case VKI_V4L2_SUBDEV_S_SELECTION:
12137 break;
12139 case VKI_V4L2_SUBDEV_G_FMT: {
12140 struct vki_v4l2_subdev_format *data =
12141 (struct vki_v4l2_subdev_format *)(Addr)ARG3;
12142 POST_FIELD_WRITE(data->format);
12143 break;
12145 case VKI_V4L2_SUBDEV_G_FRAME_INTERVAL: {
12146 struct vki_v4l2_subdev_frame_interval *data =
12147 (struct vki_v4l2_subdev_frame_interval *)(Addr)ARG3;
12148 POST_FIELD_WRITE(data->interval);
12149 break;
12151 case VKI_V4L2_SUBDEV_ENUM_MBUS_CODE: {
12152 struct vki_v4l2_subdev_mbus_code_enum *data =
12153 (struct vki_v4l2_subdev_mbus_code_enum *)(Addr)ARG3;
12154 POST_FIELD_WRITE(data->code);
12155 break;
12157 case VKI_V4L2_SUBDEV_ENUM_FRAME_SIZE: {
12158 struct vki_v4l2_subdev_frame_size_enum *data =
12159 (struct vki_v4l2_subdev_frame_size_enum *)(Addr)ARG3;
12160 POST_FIELD_WRITE(data->min_width);
12161 POST_FIELD_WRITE(data->min_height);
12162 POST_FIELD_WRITE(data->max_width);
12163 POST_FIELD_WRITE(data->max_height);
12164 break;
12166 case VKI_V4L2_SUBDEV_ENUM_FRAME_INTERVAL: {
12167 struct vki_v4l2_subdev_frame_interval_enum *data =
12168 (struct vki_v4l2_subdev_frame_interval_enum *)(Addr)ARG3;
12169 POST_FIELD_WRITE(data->interval);
12170 break;
12172 case VKI_V4L2_SUBDEV_G_CROP: {
12173 struct vki_v4l2_subdev_crop *data =
12174 (struct vki_v4l2_subdev_crop *)(Addr)ARG3;
12175 POST_FIELD_WRITE(data->rect);
12176 break;
12178 case VKI_V4L2_SUBDEV_G_SELECTION: {
12179 struct vki_v4l2_subdev_selection *data =
12180 (struct vki_v4l2_subdev_selection *)(Addr)ARG3;
12181 POST_FIELD_WRITE(data->r);
12182 break;
12184 case VKI_MEDIA_IOC_DEVICE_INFO: {
12185 struct vki_media_device_info *data =
12186 (struct vki_media_device_info *)(Addr)ARG3;
12187 POST_MEM_WRITE((Addr)data, sizeof(*data) - sizeof(data->reserved));
12188 break;
12190 case VKI_MEDIA_IOC_ENUM_ENTITIES: {
12191 struct vki_media_entity_desc *data =
12192 (struct vki_media_entity_desc *)(Addr)ARG3;
12193 POST_MEM_WRITE((Addr)data->name, sizeof(*data) - sizeof(data->id));
12194 break;
12196 case VKI_MEDIA_IOC_ENUM_LINKS:
12198 * This ioctl does write to the provided pointers, but it's not
12199 * possible to deduce the size of the array those pointers point to.
12201 break;
12202 case VKI_MEDIA_IOC_SETUP_LINK:
12203 break;
12205 /* Serial */
12206 case VKI_TIOCGSERIAL: {
12207 struct vki_serial_struct *data = (struct vki_serial_struct *)(Addr)ARG3;
12208 POST_MEM_WRITE((Addr)data, sizeof(*data));
12209 break;
12211 case VKI_TIOCSSERIAL:
12212 break;
12214 case VKI_PERF_EVENT_IOC_ENABLE:
12215 case VKI_PERF_EVENT_IOC_DISABLE:
12216 case VKI_PERF_EVENT_IOC_REFRESH:
12217 case VKI_PERF_EVENT_IOC_RESET:
12218 case VKI_PERF_EVENT_IOC_PERIOD:
12219 case VKI_PERF_EVENT_IOC_SET_OUTPUT:
12220 case VKI_PERF_EVENT_IOC_SET_FILTER:
12221 case VKI_PERF_EVENT_IOC_SET_BPF:
12222 break;
12224 case VKI_PERF_EVENT_IOC_ID:
12225 POST_MEM_WRITE((Addr)ARG3, sizeof(__vki_u64));
12226 break;
12228 /* Pulse Per Second (PPS) */
12229 case VKI_PPS_GETPARAMS: {
12230 struct vki_pps_kparams *data = (struct vki_pps_kparams *)(Addr)ARG3;
12231 POST_MEM_WRITE((Addr)data, sizeof(*data));
12232 break;
12234 case VKI_PPS_GETCAP:
12235 POST_MEM_WRITE((Addr)ARG3, sizeof(int));
12236 break;
12237 case VKI_PPS_FETCH: {
12238 struct vki_pps_fdata *data = (struct vki_pps_fdata *)(Addr)ARG3;
12239 POST_FIELD_WRITE(data->info);
12240 break;
12242 case VKI_PPS_SETPARAMS:
12243 case VKI_PPS_KC_BIND:
12244 break;
12246 /* PTP Hardware Clock */
12247 case VKI_PTP_CLOCK_GETCAPS: {
12248 struct vki_ptp_clock_caps *data =
12249 (struct vki_ptp_clock_caps *)(Addr)ARG3;
12250 POST_MEM_WRITE((Addr)data, sizeof(*data));
12251 break;
12253 case VKI_PTP_SYS_OFFSET: {
12254 struct vki_ptp_sys_offset *data =
12255 (struct vki_ptp_sys_offset *)(Addr)ARG3;
12256 POST_MEM_WRITE((Addr)data->ts,
12257 (2 * data->n_samples + 1) * sizeof(data->ts[0]));
12258 break;
12260 case VKI_PTP_PIN_GETFUNC: {
12261 struct vki_ptp_pin_desc *data = (struct vki_ptp_pin_desc *)(Addr)ARG3;
12262 POST_MEM_WRITE((Addr)data, sizeof(*data));
12263 break;
12265 case VKI_PTP_SYS_OFFSET_PRECISE: {
12266 struct vki_ptp_sys_offset_precise *data =
12267 (struct vki_ptp_sys_offset_precise *)(Addr)ARG3;
12268 POST_MEM_WRITE((Addr)data, sizeof(*data));
12269 break;
12271 case VKI_PTP_SYS_OFFSET_EXTENDED: {
12272 struct vki_ptp_sys_offset_extended *data =
12273 (struct vki_ptp_sys_offset_extended *)(Addr)ARG3;
12274 POST_MEM_WRITE((Addr)data->ts,
12275 3 * data->n_samples * sizeof(data->ts[0][0]));
12276 break;
12278 case VKI_PTP_EXTTS_REQUEST:
12279 case VKI_PTP_PEROUT_REQUEST:
12280 case VKI_PTP_ENABLE_PPS:
12281 case VKI_PTP_PIN_SETFUNC:
12282 break;
12284 default:
12285 /* EVIOC* are variable length and return size written on success */
12286 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
12287 case VKI_EVIOCGNAME(0):
12288 case VKI_EVIOCGPHYS(0):
12289 case VKI_EVIOCGUNIQ(0):
12290 case VKI_EVIOCGKEY(0):
12291 case VKI_EVIOCGLED(0):
12292 case VKI_EVIOCGSND(0):
12293 case VKI_EVIOCGSW(0):
12294 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
12295 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
12296 case VKI_EVIOCGBIT(VKI_EV_REL,0):
12297 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
12298 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
12299 case VKI_EVIOCGBIT(VKI_EV_SW,0):
12300 case VKI_EVIOCGBIT(VKI_EV_LED,0):
12301 case VKI_EVIOCGBIT(VKI_EV_SND,0):
12302 case VKI_EVIOCGBIT(VKI_EV_REP,0):
12303 case VKI_EVIOCGBIT(VKI_EV_FF,0):
12304 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
12305 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
12306 if (RES > 0)
12307 POST_MEM_WRITE(ARG3, RES);
12308 break;
12309 default:
12310 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
12311 break;
12313 break;
12316 post_sys_ioctl__out:
12317 {} /* keep C compilers happy */
12320 /* ---------------------------------------------------------------------
12321 socketcall wrapper helpers
12322 ------------------------------------------------------------------ */
12324 void
12325 ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
12326 UWord arg0, UWord arg1, UWord arg2,
12327 UWord arg3, UWord arg4 )
12329 /* int getsockopt(int s, int level, int optname,
12330 void *optval, socklen_t *optlen); */
12331 Addr optval_p = arg3;
12332 Addr optlen_p = arg4;
12333 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
12334 if (optval_p != (Addr)NULL) {
12335 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
12336 "socketcall.getsockopt(optval)",
12337 "socketcall.getsockopt(optlen)" );
12338 if (arg1 == VKI_SOL_SCTP &&
12339 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12340 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12342 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12343 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
12344 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
12345 (Addr)ga->addrs, address_bytes );
12350 void
12351 ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
12352 SysRes res,
12353 UWord arg0, UWord arg1, UWord arg2,
12354 UWord arg3, UWord arg4 )
12356 Addr optval_p = arg3;
12357 Addr optlen_p = arg4;
12358 vg_assert(!sr_isError(res)); /* guaranteed by caller */
12359 if (optval_p != (Addr)NULL) {
12360 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
12361 "socketcall.getsockopt(optlen_out)" );
12362 if (arg1 == VKI_SOL_SCTP &&
12363 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
12364 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
12366 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
12367 struct vki_sockaddr *a = ga->addrs;
12368 int i;
12369 for (i = 0; i < ga->addr_num; i++) {
12370 int sl = 0;
12371 if (a->sa_family == VKI_AF_INET)
12372 sl = sizeof(struct vki_sockaddr_in);
12373 else if (a->sa_family == VKI_AF_INET6)
12374 sl = sizeof(struct vki_sockaddr_in6);
12375 else {
12376 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
12377 "address type %d\n", a->sa_family);
12379 a = (struct vki_sockaddr*)((char*)a + sl);
12381 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
12386 void
12387 ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
12388 UWord arg0, UWord arg1, UWord arg2,
12389 UWord arg3, UWord arg4 )
12391 /* int setsockopt(int s, int level, int optname,
12392 const void *optval, socklen_t optlen); */
12393 Addr optval_p = arg3;
12394 if (optval_p != (Addr)NULL) {
12396 * OK, let's handle at least some setsockopt levels and options
12397 * ourselves, so we don't get false claims of references to
12398 * uninitialized memory (such as padding in structures) and *do*
12399 * check what pointers in the argument point to.
12401 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
12403 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
12406 * struct sock_fprog has a 16-bit count of instructions,
12407 * followed by a pointer to an array of those instructions.
12408 * There's padding between those two elements.
12410 * So that we don't bogusly complain about the padding bytes,
12411 * we just report that we read len and and filter.
12413 * We then make sure that what filter points to is valid.
12415 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
12416 (Addr)&fp->len, sizeof(fp->len) );
12417 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
12418 (Addr)&fp->filter, sizeof(fp->filter) );
12420 /* len * sizeof (*filter) */
12421 if (fp->filter != NULL)
12423 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
12424 (Addr)(fp->filter),
12425 fp->len * sizeof(*fp->filter) );
12428 else
12430 PRE_MEM_READ( "socketcall.setsockopt(optval)",
12431 arg3, /* optval */
12432 arg4 /* optlen */ );
12437 void
12438 ML_(linux_PRE_sys_recvmmsg) ( ThreadId tid,
12439 UWord arg1, UWord arg2, UWord arg3,
12440 UWord arg4, UWord arg5 )
12442 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12443 HChar name[40]; // large enough
12444 UInt i;
12445 for (i = 0; i < arg3; i++) {
12446 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12447 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
12448 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
12449 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12451 if (arg5)
12452 PRE_MEM_READ( "recvmmsg(timeout)", arg5, sizeof(struct vki_timespec) );
12455 void
12456 ML_(linux_POST_sys_recvmmsg) (ThreadId tid, UWord res,
12457 UWord arg1, UWord arg2, UWord arg3,
12458 UWord arg4, UWord arg5 )
12460 if (res > 0) {
12461 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12462 HChar name[32]; // large enough
12463 UInt i;
12464 for (i = 0; i < res; i++) {
12465 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12466 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
12467 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12472 void
12473 ML_(linux_PRE_sys_sendmmsg) ( ThreadId tid,
12474 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12476 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12477 HChar name[40]; // large enough
12478 UInt i;
12479 for (i = 0; i < arg3; i++) {
12480 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
12481 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
12482 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
12483 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12487 void
12488 ML_(linux_POST_sys_sendmmsg) (ThreadId tid, UWord res,
12489 UWord arg1, UWord arg2, UWord arg3, UWord arg4 )
12491 if (res > 0) {
12492 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)arg2;
12493 UInt i;
12494 for (i = 0; i < res; i++) {
12495 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
12500 /* ---------------------------------------------------------------------
12501 ptrace wrapper helpers
12502 ------------------------------------------------------------------ */
12504 void
12505 ML_(linux_POST_traceme) ( ThreadId tid )
12507 ThreadState *tst = VG_(get_ThreadState)(tid);
12508 tst->ptrace = VKI_PT_PTRACED;
12511 void
12512 ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
12514 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12516 PRE_FIELD_READ("ptrace(getregset iovec->iov_base)", iov->iov_base);
12517 PRE_FIELD_READ("ptrace(getregset iovec->iov_len)", iov->iov_len);
12518 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12519 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
12520 (Addr) iov->iov_base, iov->iov_len);
12524 void
12525 ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
12527 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12529 PRE_FIELD_READ("ptrace(setregset iovec->iov_base)", iov->iov_base);
12530 PRE_FIELD_READ("ptrace(setregset iovec->iov_len)", iov->iov_len);
12531 if (ML_(safe_to_deref)(iov, sizeof(struct vki_iovec))) {
12532 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
12533 (Addr) iov->iov_base, iov->iov_len);
12537 void
12538 ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
12540 struct vki_iovec *iov = (struct vki_iovec *) arg4;
12542 /* XXX: The actual amount of data written by the kernel might be
12543 less than iov_len, depending on the regset (arg3). */
12544 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
12547 PRE(sys_kcmp)
12549 PRINT("kcmp ( %ld, %ld, %ld, %" FMT_REGWORD "u, %" FMT_REGWORD "u )",
12550 SARG1, SARG2, SARG3, ARG4, ARG5);
12551 switch (ARG3) {
12552 case VKI_KCMP_VM: case VKI_KCMP_FILES: case VKI_KCMP_FS:
12553 case VKI_KCMP_SIGHAND: case VKI_KCMP_IO: case VKI_KCMP_SYSVSEM:
12554 /* Most of the comparison types don't look at |idx1| or
12555 |idx2|. */
12556 PRE_REG_READ3(long, "kcmp",
12557 vki_pid_t, pid1, vki_pid_t, pid2, int, type);
12558 break;
12559 case VKI_KCMP_FILE:
12560 default:
12561 PRE_REG_READ5(long, "kcmp",
12562 vki_pid_t, pid1, vki_pid_t, pid2, int, type,
12563 unsigned long, idx1, unsigned long, idx2);
12564 break;
12568 /* ---------------------------------------------------------------------
12569 bpf wrappers
12570 ------------------------------------------------------------------ */
12572 static Bool bpf_map_get_sizes(Int fd, UInt *key_size, UInt *value_size)
12574 HChar path[32], buf[1024]; /* large enough */
12575 SysRes sres;
12576 HChar *comp;
12577 Int proc_fd;
12579 *key_size = 0;
12580 *value_size = 0;
12582 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12583 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12584 if (sr_isError(sres))
12585 return False;
12586 proc_fd = sr_Res(sres);
12588 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12589 return False;
12590 VG_(close)(proc_fd);
12592 comp = VG_(strstr)(buf, "key_size:");
12593 if (comp)
12594 *key_size = VG_(strtoull10)(comp + sizeof("key_size:"), NULL);
12596 comp = VG_(strstr)(buf, "value_size:");
12597 if (comp)
12598 *value_size = VG_(strtoull10)(comp + sizeof("value_size:"), NULL);
12600 return (*key_size && *value_size);
12604 * From a file descriptor for an eBPF object, try to determine the size of the
12605 * struct that will be written, i.e. determine if object is a map or a program.
12606 * There is no direct way to do this, so parse /proc/<pid>/fdinfo/<fd> and
12607 * search for strings "prog_type" or "map_type".
12609 static UInt bpf_obj_get_info_size(Int fd)
12611 HChar path[32], buf[1024]; /* large enough */
12612 SysRes sres;
12613 Int proc_fd;
12615 VG_(sprintf)(path, "/proc/%d/fdinfo/%d", VG_(getpid)(), fd);
12616 sres = VG_(open)(path, VKI_O_RDONLY, 0);
12617 if (sr_isError(sres))
12618 return 0;
12619 proc_fd = sr_Res(sres);
12621 if (VG_(read)(proc_fd, buf, sizeof(buf)) <= 0)
12622 return 0;
12623 VG_(close)(proc_fd);
12625 if (VG_(strstr)(buf, "prog_type:"))
12626 return sizeof(struct vki_bpf_prog_info);
12628 if (VG_(strstr)(buf, "map_type:"))
12629 return sizeof(struct vki_bpf_map_info);
12631 return 0;
12634 PRE(sys_bpf)
12636 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12637 UInt res, key_size, value_size;
12639 PRINT("sys_bpf ( %ld, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
12640 (Word)ARG1, ARG2, ARG3);
12641 PRE_REG_READ3(long, "bpf",
12642 int, cmd, union vki_bpf_attr *, attr, unsigned int, size);
12643 switch (ARG1) {
12644 case VKI_BPF_PROG_GET_NEXT_ID:
12645 case VKI_BPF_MAP_GET_NEXT_ID:
12646 PRE_MEM_WRITE("bpf(attr->next_id", (Addr)&attr->next_id, sizeof(attr->next_id));
12647 break;
12648 case VKI_BPF_PROG_GET_FD_BY_ID:
12649 PRE_MEM_READ("bpf(attr->prog_id", (Addr)&attr->prog_id, sizeof(attr->prog_id));
12650 break;
12651 case VKI_BPF_MAP_GET_FD_BY_ID:
12652 PRE_MEM_READ("bpf(attr->map_id", (Addr)&attr->map_id, sizeof(attr->map_id));
12653 break;
12654 case VKI_BPF_BTF_GET_FD_BY_ID:
12655 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12656 break;
12657 case VKI_BPF_MAP_CREATE:
12658 PRE_MEM_READ("bpf(attr->map_flags", (Addr)&attr->map_flags, sizeof(attr->map_flags));
12659 if (attr->map_flags & VKI_BPF_F_NUMA_NODE)
12660 PRE_MEM_READ("bpf(attr->numa_node", (Addr)&attr->numa_node, sizeof(attr->numa_node));
12661 PRE_MEM_READ("bpf(attr->map_type", (Addr)&attr->map_type, sizeof(attr->map_type));
12662 PRE_MEM_READ("bpf(attr->map_ifindex", (Addr)&attr->map_ifindex, sizeof(attr->map_ifindex));
12663 PRE_MEM_READ("bpf(attr->max_entries", (Addr)&attr->max_entries, sizeof(attr->max_entries));
12664 PRE_MEM_READ("bpf(attr->key_size", (Addr)&attr->key_size, sizeof(attr->key_size));
12665 PRE_MEM_READ("bpf(attr->value_size", (Addr)&attr->value_size, sizeof(attr->value_size));
12666 pre_asciiz_str(tid, (unsigned long int)attr->map_name,
12667 VKI_BPF_OBJ_NAME_LEN, "bpf(attr->map_name)");
12668 switch (attr->map_type) {
12669 case VKI_BPF_MAP_TYPE_ARRAY_OF_MAPS:
12670 case VKI_BPF_MAP_TYPE_HASH_OF_MAPS:
12671 PRE_MEM_READ("bpf(attr->inner_map_fd", (Addr)&attr->inner_map_fd, sizeof(attr->inner_map_fd));
12672 if (!ML_(fd_allowed)(attr->inner_map_fd, "bpf", tid, False))
12673 SET_STATUS_Failure(VKI_EBADF);
12674 break;
12675 case VKI_BPF_MAP_TYPE_ARRAY:
12676 if (ARG3 >= offsetof(union vki_bpf_attr, btf_value_type_id) + sizeof(__vki_u32)) {
12677 PRE_MEM_READ("bpf(attr->btf_key_type_id", (Addr)&attr->btf_key_type_id, sizeof(attr->btf_key_type_id));
12678 PRE_MEM_READ("bpf(attr->btf_value_type_id", (Addr)&attr->btf_value_type_id, sizeof(attr->btf_value_type_id));
12679 if (attr->btf_key_type_id && attr->btf_value_type_id) {
12680 PRE_MEM_READ("bpf(attr->btf_id", (Addr)&attr->btf_id, sizeof(attr->btf_id));
12681 if (!ML_(fd_allowed)(attr->btf_fd, "bpf", tid, False)) {
12682 SET_STATUS_Failure(VKI_EBADF);
12683 break;
12687 break;
12688 case VKI_BPF_MAP_TYPE_UNSPEC:
12689 case VKI_BPF_MAP_TYPE_HASH:
12690 case VKI_BPF_MAP_TYPE_PROG_ARRAY:
12691 case VKI_BPF_MAP_TYPE_PERF_EVENT_ARRAY:
12692 case VKI_BPF_MAP_TYPE_PERCPU_HASH:
12693 case VKI_BPF_MAP_TYPE_PERCPU_ARRAY:
12694 case VKI_BPF_MAP_TYPE_STACK_TRACE:
12695 case VKI_BPF_MAP_TYPE_CGROUP_ARRAY:
12696 case VKI_BPF_MAP_TYPE_LRU_HASH:
12697 case VKI_BPF_MAP_TYPE_LRU_PERCPU_HASH:
12698 case VKI_BPF_MAP_TYPE_LPM_TRIE:
12699 case VKI_BPF_MAP_TYPE_DEVMAP:
12700 case VKI_BPF_MAP_TYPE_SOCKMAP:
12701 case VKI_BPF_MAP_TYPE_CPUMAP:
12702 case VKI_BPF_MAP_TYPE_XSKMAP:
12703 case VKI_BPF_MAP_TYPE_SOCKHASH:
12704 default:
12705 break;
12707 break;
12708 case VKI_BPF_MAP_LOOKUP_ELEM:
12709 /* Perform a lookup on an eBPF map. Read key, write value. */
12710 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12711 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12712 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12713 if (ML_(safe_to_deref)(attr, ARG3)) {
12714 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12715 SET_STATUS_Failure(VKI_EBADF);
12716 break;
12718 /* Get size of key and value for this map. */
12719 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12720 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12721 PRE_MEM_WRITE("bpf(attr->value)", attr->value, value_size);
12724 break;
12725 case VKI_BPF_MAP_UPDATE_ELEM:
12726 /* Add or update a map element in kernel. Read key, read value. */
12727 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12728 PRE_MEM_READ("bpf(attr->value)", (Addr)&attr->value, sizeof(attr->value));
12729 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12730 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12731 if (ML_(safe_to_deref)(attr, ARG3)) {
12732 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12733 SET_STATUS_Failure(VKI_EBADF);
12734 break;
12736 /* Get size of key and value for this map. */
12737 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12738 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12739 PRE_MEM_READ("bpf(attr->value)", attr->value, value_size);
12742 break;
12743 case VKI_BPF_MAP_DELETE_ELEM:
12744 /* Delete a map element in kernel. Read key from user space. */
12745 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12746 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12747 if (ML_(safe_to_deref)(attr, ARG3)) {
12748 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12749 SET_STATUS_Failure(VKI_EBADF);
12750 break;
12752 /* Get size of key for this map. */
12753 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
12754 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12756 break;
12757 case VKI_BPF_MAP_GET_NEXT_KEY:
12758 /* From a key, get next key for the map. Read key, write next key. */
12759 PRE_MEM_READ("bpf(attr->key)", (Addr)&attr->key, sizeof(attr->key));
12760 PRE_MEM_READ("bpf(attr->next_key)", (Addr)&attr->next_key, sizeof(attr->next_key));
12761 PRE_MEM_READ("bpf(attr->map_fd)", (Addr)&attr->map_fd, sizeof(attr->map_fd));
12762 PRE_MEM_READ("bpf(attr->flags)", (Addr)&attr->flags, sizeof(attr->flags));
12763 if (ML_(safe_to_deref)(attr, ARG3)) {
12764 if (!ML_(fd_allowed)(attr->map_fd, "bpf", tid, False)) {
12765 SET_STATUS_Failure(VKI_EBADF);
12766 break;
12768 /* Get size of key for this map. */
12769 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size)) {
12770 PRE_MEM_READ("bpf(attr->key)", attr->key, key_size);
12771 PRE_MEM_WRITE("bpf(attr->next_key)", attr->next_key, key_size);
12774 break;
12775 case VKI_BPF_PROG_LOAD:
12776 /* Load a program into the kernel from an array of instructions. */
12777 PRE_MEM_READ("bpf(attr->prog_type)", (Addr)&attr->prog_type, sizeof(attr->prog_type));
12778 PRE_MEM_READ("bpf(attr->prog_flags)", (Addr)&attr->prog_flags, sizeof(attr->prog_flags));
12779 PRE_MEM_READ("bpf(attr->license)", (Addr)&attr->license, sizeof(attr->license));
12780 PRE_MEM_READ("bpf(attr->insn_cnt)", (Addr)&attr->insn_cnt, sizeof(attr->insn_cnt));
12781 PRE_MEM_READ("bpf(attr->expected_attach_type)", (Addr)&attr->expected_attach_type, sizeof(attr->expected_attach_type));
12782 PRE_MEM_READ("bpf(attr->prog_ifindex)", (Addr)&attr->prog_ifindex, sizeof(attr->prog_ifindex));
12783 PRE_MEM_READ("bpf(attr->log_level)", (Addr)&attr->log_level, sizeof(attr->log_level));
12784 PRE_MEM_READ("bpf(attr->log_buf)", (Addr)&attr->log_buf, sizeof(attr->log_buf));
12785 PRE_MEM_READ("bpf(attr->log_size)", (Addr)&attr->log_size, sizeof(attr->log_size));
12786 pre_asciiz_str(tid, (Addr)attr->prog_name, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->prog_name)");
12787 if (ML_(safe_to_deref)(attr, ARG3)) {
12788 if (attr->prog_type == VKI_BPF_PROG_TYPE_KPROBE)
12789 PRE_MEM_READ("bpf(attr->kern_version)", (Addr)&attr->kern_version, sizeof(attr->kern_version));
12790 /* Read instructions, license, program name. */
12791 PRE_MEM_READ("bpf(attr->insns)", attr->insns,
12792 attr->insn_cnt * sizeof(struct vki_bpf_insn));
12793 /* License is limited to 128 characters in kernel/bpf/syscall.c. */
12794 pre_asciiz_str(tid, attr->license, 128, "bpf(attr->license)");
12795 /* Possibly write up to log_len into user space log buffer. */
12796 if (attr->log_level || attr->log_size || attr->log_buf)
12797 PRE_MEM_WRITE("bpf(attr->log_buf)", attr->log_buf, attr->log_size);
12799 break;
12800 case VKI_BPF_OBJ_PIN:
12801 /* Pin eBPF program or map to given location under /sys/fs/bpf/. */
12802 /* fall through */
12803 case VKI_BPF_OBJ_GET:
12804 /* Get pinned eBPF program or map. Read path name. */
12805 PRE_MEM_READ("bpf(attr->file_flags)", (Addr)&attr->file_flags, sizeof(attr->file_flags));
12806 PRE_MEM_READ("bpf(attr->pathname)", (Addr)&attr->pathname, sizeof(attr->pathname));
12807 PRE_MEM_READ("bpf(attr->bpf_fd)", (Addr)&attr->bpf_fd, sizeof(attr->bpf_fd));
12808 if (ML_(safe_to_deref)(attr, ARG3)) {
12809 if (!ML_(fd_allowed)(attr->bpf_fd, "bpf", tid, False)) {
12810 SET_STATUS_Failure(VKI_EBADF);
12811 break;
12813 pre_asciiz_str(tid, attr->pathname, VKI_BPF_OBJ_NAME_LEN, "bpf(attr->pathname)");
12815 break;
12816 case VKI_BPF_PROG_ATTACH:
12817 case VKI_BPF_PROG_DETACH:
12818 /* Detach eBPF program from kernel attach point. */
12819 PRE_MEM_READ("bpf(attr->attach_type)", (Addr)&attr->attach_type, sizeof(attr->attach_type));
12820 PRE_MEM_READ("bpf(attr->target_fd)", (Addr)&attr->target_fd, sizeof(attr->target_fd));
12821 if (ML_(safe_to_deref)(attr, ARG3)) {
12822 if (!ML_(fd_allowed)(attr->target_fd, "bpf", tid, False))
12823 SET_STATUS_Failure(VKI_EBADF);
12824 if (ARG1 == VKI_BPF_PROG_ATTACH ||
12825 (attr->attach_type != VKI_BPF_SK_SKB_STREAM_PARSER &&
12826 attr->attach_type != VKI_BPF_SK_SKB_STREAM_VERDICT &&
12827 attr->attach_type != VKI_BPF_SK_MSG_VERDICT)) {
12828 PRE_MEM_READ("bpf(attr->attach_bpf_fd)", (Addr)&attr->attach_bpf_fd, sizeof(attr->attach_bpf_fd));
12829 if (!ML_(fd_allowed)(attr->attach_bpf_fd, "bpf", tid, False))
12830 SET_STATUS_Failure(VKI_EBADF);
12833 break;
12834 case VKI_BPF_PROG_TEST_RUN:
12835 /* Test prog. Read data_in, write up to data_size_out to data_out. */
12836 PRE_MEM_READ("bpf(attr->test.prog_fd)", (Addr)&attr->test.prog_fd, sizeof(attr->test.prog_fd));
12837 PRE_MEM_READ("bpf(attr->test.repeat)", (Addr)&attr->test.repeat, sizeof(attr->test.repeat));
12838 PRE_MEM_READ("bpf(attr->test.data_size_in)", (Addr)&attr->test.data_size_in, sizeof(attr->test.data_size_in));
12839 PRE_MEM_READ("bpf(attr->test.data_in)", (Addr)&attr->test.data_in, sizeof(attr->test.data_in));
12840 PRE_MEM_READ("bpf(attr->test.data_out)", (Addr)&attr->test.data_out, sizeof(attr->test.data_out));
12841 PRE_MEM_WRITE("bpf(attr->test.retval)", (Addr)&attr->test.retval, sizeof(attr->test.retval));
12842 PRE_MEM_WRITE("bpf(attr->test.data_size_out)", (Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
12843 PRE_MEM_WRITE("bpf(attr->test.duration)", (Addr)&attr->test.duration, sizeof(attr->test.duration));
12844 if (ML_(safe_to_deref)(attr, ARG3)) {
12845 if (!ML_(fd_allowed)(attr->test.prog_fd, "bpf", tid, False)) {
12846 SET_STATUS_Failure(VKI_EBADF);
12847 break;
12849 PRE_MEM_READ("bpf(attr->test.data_in)", attr->test.data_in, attr->test.data_size_in);
12850 /* should be data_size_in + VKI_XDP_PACKET_HEADROOM for VKI_BPF_PROG_TYPE_XDP */
12851 PRE_MEM_WRITE("bpf(attr->test.data_out)", attr->test.data_out, attr->test.data_size_in);
12853 break;
12854 case VKI_BPF_OBJ_GET_INFO_BY_FD:
12855 /* Get info for eBPF map or program. Write info. */
12856 PRE_MEM_READ("bpf(attr->info.bpf_fd)", (Addr)&attr->info.bpf_fd, sizeof(attr->info.bpf_fd));
12857 PRE_MEM_READ("bpf(attr->info.info)", (Addr)&attr->info.info, sizeof(attr->info.info));
12858 PRE_MEM_READ("bpf(attr->info.info_len)", (Addr)&attr->info.info_len, sizeof(attr->info.info_len));
12859 if (ML_(safe_to_deref)(attr, ARG3)) {
12860 if (!ML_(fd_allowed)(attr->info.bpf_fd, "bpf", tid, False)) {
12861 SET_STATUS_Failure(VKI_EBADF);
12862 break;
12864 /* Get size of struct to write: is object a program or a map? */
12865 res = bpf_obj_get_info_size(attr->info.bpf_fd);
12866 if (res)
12867 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12868 VG_MIN(attr->info.info_len, res));
12869 else
12870 PRE_MEM_WRITE("bpf(attr->info.info)", attr->info.info,
12871 VG_MIN(attr->info.info_len,
12872 VG_MAX(VG_MAX(sizeof(struct vki_bpf_prog_info),
12873 sizeof(struct vki_bpf_map_info)),
12874 sizeof(struct vki_bpf_btf_info))));
12876 break;
12877 case VKI_BPF_PROG_QUERY:
12879 * Query list of eBPF program attached to cgroup.
12880 * Write array of ids (up to attr->query.prog_cnt u32-long ids).
12882 PRE_MEM_READ("bpf(attr->query.query_flags)", (Addr)&attr->query.query_flags, sizeof(attr->query.query_flags));
12883 PRE_MEM_READ("bpf(attr->query.attach_type)", (Addr)&attr->query.attach_type, sizeof(attr->query.attach_type));
12884 PRE_MEM_READ("bpf(attr->query.target_fd)", (Addr)&attr->query.target_fd, sizeof(attr->query.target_fd));
12885 PRE_MEM_READ("bpf(attr->query.prog_cnt)", (Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
12886 PRE_MEM_WRITE("bpf(attr->query.attach_flags)", (Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
12887 if (ML_(safe_to_deref)(attr, ARG3)) {
12888 if (!ML_(fd_allowed)(attr->query.target_fd, "bpf", tid, False)) {
12889 SET_STATUS_Failure(VKI_EBADF);
12890 break;
12892 if (attr->query.prog_cnt > 0) {
12893 PRE_MEM_READ("bpf(attr->query.prog_ids)", (Addr)&attr->query.prog_ids, sizeof(attr->query.prog_ids));
12894 if (attr->query.prog_ids) {
12895 PRE_MEM_WRITE("bpf(attr->query.prog_ids)", attr->query.prog_ids,
12896 attr->query.prog_cnt * sizeof(__vki_u32));
12900 break;
12901 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12902 /* Open raw tracepoint. Read tracepoint name. */
12903 PRE_MEM_READ("bpf(attr->raw_tracepoint.name)", (Addr)&attr->raw_tracepoint.name, sizeof(attr->raw_tracepoint.name));
12904 PRE_MEM_READ("bpf(attr->raw_tracepoint.prog_fd)", (Addr)&attr->raw_tracepoint.prog_fd, sizeof(attr->raw_tracepoint.prog_fd));
12905 if (ML_(safe_to_deref)(attr, ARG3)) {
12906 if (!ML_(fd_allowed)(attr->raw_tracepoint.prog_fd,
12907 "bpf", tid, False)) {
12908 SET_STATUS_Failure(VKI_EBADF);
12909 break;
12911 /* Name is limited to 128 characters in kernel/bpf/syscall.c. */
12912 pre_asciiz_str(tid, attr->raw_tracepoint.name, 128,
12913 "bpf(attr->raw_tracepoint.name)");
12915 break;
12916 case VKI_BPF_BTF_LOAD:
12917 /* Load BTF information about a program into the kernel. */
12918 PRE_MEM_READ("bpf(attr->btf)", (Addr)&attr->btf, sizeof(attr->btf));
12919 PRE_MEM_READ("bpf(attr->btf_size)", (Addr)&attr->btf_size, sizeof(attr->btf_size));
12920 PRE_MEM_READ("bpf(attr->btf_log_buf)", (Addr)&attr->btf_log_buf, sizeof(attr->btf_log_buf));
12921 PRE_MEM_READ("bpf(attr->btf_log_size)", (Addr)&attr->btf_log_size, sizeof(attr->btf_log_size));
12922 PRE_MEM_READ("bpf(attr->btf_log_level)", (Addr)&attr->btf_log_level, sizeof(attr->btf_log_level));
12923 if (ML_(safe_to_deref)(attr, ARG3)) {
12924 /* Read BTF data. */
12925 PRE_MEM_READ("bpf(attr->btf)", attr->btf, attr->btf_size);
12926 /* Possibly write up to btf_log_len into user space log buffer. */
12927 if (attr->btf_log_level || attr->btf_log_size || attr->btf_log_buf)
12928 PRE_MEM_WRITE("bpf(attr->btf_log_buf)",
12929 attr->btf_log_buf, attr->btf_log_size);
12931 break;
12932 case VKI_BPF_TASK_FD_QUERY:
12933 /* Get info about the task. Write collected info. */
12934 PRE_MEM_READ("bpf(attr->task_fd_query.pid)", (Addr)&attr->task_fd_query.pid, sizeof(attr->task_fd_query.pid));
12935 PRE_MEM_READ("bpf(attr->task_fd_query.fd)", (Addr)&attr->task_fd_query.fd, sizeof(attr->task_fd_query.fd));
12936 PRE_MEM_READ("bpf(attr->task_fd_query.flags)", (Addr)&attr->task_fd_query.flags, sizeof(attr->task_fd_query.flags));
12937 PRE_MEM_READ("bpf(attr->task_fd_query.buf_len)", (Addr)&attr->task_fd_query.buf_len, sizeof(attr->task_fd_query.buf_len));
12938 PRE_MEM_READ("bpf(attr->task_fd_query.buf)", (Addr)&attr->task_fd_query.buf, sizeof(attr->task_fd_query.buf));
12939 PRE_MEM_WRITE("bpf(attr->task_fd_query.prog_id)", (Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
12940 PRE_MEM_WRITE("bpf(attr->task_fd_query.fd_type)", (Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
12941 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_offset)", (Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
12942 PRE_MEM_WRITE("bpf(attr->task_fd_query.probe_addr)", (Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
12943 if (ML_(safe_to_deref)(attr, ARG3)) {
12944 if (!ML_(fd_allowed)(attr->task_fd_query.fd, "bpf", tid, False)) {
12945 SET_STATUS_Failure(VKI_EBADF);
12946 break;
12948 if (attr->task_fd_query.buf_len > 0) {
12949 /* Write task or perf event name. */
12950 PRE_MEM_WRITE("bpf(attr->task_fd_query.buf)",
12951 attr->task_fd_query.buf,
12952 attr->task_fd_query.buf_len);
12955 break;
12956 default:
12957 VG_(message)(Vg_DebugMsg,
12958 "FATAL: unhandled eBPF command %lu\n", ARG1);
12959 VG_(core_panic)("... bye!\n");
12960 break;
12964 POST(sys_bpf)
12966 union vki_bpf_attr *attr = (union vki_bpf_attr *)(Addr)ARG2;
12967 UInt key_size, value_size;
12969 vg_assert(SUCCESS);
12971 switch (ARG1) {
12972 case VKI_BPF_PROG_GET_NEXT_ID:
12973 case VKI_BPF_MAP_GET_NEXT_ID:
12974 POST_MEM_WRITE(attr->next_id, sizeof(attr->next_id));
12975 break;
12976 case VKI_BPF_MAP_UPDATE_ELEM:
12977 case VKI_BPF_MAP_DELETE_ELEM:
12978 case VKI_BPF_OBJ_PIN:
12979 case VKI_BPF_PROG_ATTACH:
12980 case VKI_BPF_PROG_DETACH:
12981 break;
12982 /* Following commands have bpf() return a file descriptor. */
12983 case VKI_BPF_MAP_CREATE:
12984 case VKI_BPF_OBJ_GET:
12985 case VKI_BPF_PROG_GET_FD_BY_ID:
12986 case VKI_BPF_MAP_GET_FD_BY_ID:
12987 case VKI_BPF_BTF_GET_FD_BY_ID:
12988 case VKI_BPF_RAW_TRACEPOINT_OPEN:
12989 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
12990 VG_(close)(RES);
12991 SET_STATUS_Failure(VKI_EMFILE);
12992 } else {
12993 if (VG_(clo_track_fds))
12994 ML_(record_fd_open_nameless)(tid, RES);
12996 break;
12998 * TODO: Is there a way to pass information between PRE and POST hooks?
12999 * To avoid querying again for the size of keys and values.
13001 case VKI_BPF_MAP_LOOKUP_ELEM:
13002 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13003 POST_MEM_WRITE(attr->value, value_size);
13004 break;
13005 case VKI_BPF_MAP_GET_NEXT_KEY:
13006 if (bpf_map_get_sizes(attr->map_fd, &key_size, &value_size))
13007 POST_MEM_WRITE(attr->next_key, key_size);
13008 break;
13009 case VKI_BPF_PROG_LOAD:
13010 /* Return a file descriptor for loaded program, write into log_buf. */
13011 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13012 VG_(close)(RES);
13013 SET_STATUS_Failure(VKI_EMFILE);
13014 } else {
13015 if (VG_(clo_track_fds))
13016 ML_(record_fd_open_nameless)(tid, RES);
13018 if (attr->log_level || attr->log_size || attr->log_buf)
13019 POST_MEM_WRITE(attr->log_buf, attr->log_size);
13020 break;
13021 case VKI_BPF_PROG_TEST_RUN:
13022 POST_MEM_WRITE((Addr)&attr->test.retval, sizeof(attr->test.retval));
13023 POST_MEM_WRITE((Addr)&attr->test.data_size_out, sizeof(attr->test.data_size_out));
13024 POST_MEM_WRITE((Addr)&attr->test.duration, sizeof(attr->test.duration));
13025 POST_MEM_WRITE(attr->test.data_out, attr->test.data_size_out);
13026 break;
13027 case VKI_BPF_OBJ_GET_INFO_BY_FD:
13028 POST_MEM_WRITE(attr->info.info, attr->info.info_len);
13029 break;
13030 case VKI_BPF_PROG_QUERY:
13031 POST_MEM_WRITE((Addr)&attr->query.attach_flags, sizeof(attr->query.attach_flags));
13032 POST_MEM_WRITE((Addr)&attr->query.prog_cnt, sizeof(attr->query.prog_cnt));
13033 if (attr->query.prog_ids)
13034 POST_MEM_WRITE(attr->query.prog_ids,
13035 attr->query.prog_cnt * sizeof(__vki_u32));
13036 break;
13037 case VKI_BPF_BTF_LOAD:
13038 /* Return a file descriptor for BTF data, write into btf_log_buf. */
13039 if (!ML_(fd_allowed)(RES, "bpf", tid, True)) {
13040 VG_(close)(RES);
13041 SET_STATUS_Failure(VKI_EMFILE);
13042 } else {
13043 if (VG_(clo_track_fds))
13044 ML_(record_fd_open_nameless)(tid, RES);
13046 if (attr->btf_log_level)
13047 POST_MEM_WRITE(attr->btf_log_buf, attr->btf_log_size);
13048 break;
13049 case VKI_BPF_TASK_FD_QUERY:
13050 POST_MEM_WRITE(attr->task_fd_query.buf, attr->task_fd_query.buf_len);
13051 POST_MEM_WRITE((Addr)&attr->task_fd_query.prog_id, sizeof(attr->task_fd_query.prog_id));
13052 POST_MEM_WRITE((Addr)&attr->task_fd_query.fd_type, sizeof(attr->task_fd_query.fd_type));
13053 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_offset, sizeof(attr->task_fd_query.probe_offset));
13054 POST_MEM_WRITE((Addr)&attr->task_fd_query.probe_addr, sizeof(attr->task_fd_query.probe_addr));
13055 break;
13056 default:
13057 VG_(message)(Vg_DebugMsg,
13058 "FATAL: unhandled eBPF command %lu\n", ARG1);
13059 VG_(core_panic)("... bye!\n");
13060 break;
13064 PRE(sys_copy_file_range)
13066 PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
13067 ARG4, ARG5, ARG6);
13069 PRE_REG_READ6(vki_size_t, "copy_file_range",
13070 int, "fd_in",
13071 vki_loff_t *, "off_in",
13072 int, "fd_out",
13073 vki_loff_t *, "off_out",
13074 vki_size_t, "len",
13075 unsigned int, "flags");
13077 /* File descriptors are "specially" tracked by valgrind.
13078 valgrind itself uses some, so make sure someone didn't
13079 put in one of our own... */
13080 if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
13081 !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
13082 SET_STATUS_Failure( VKI_EBADF );
13083 } else {
13084 /* Now see if the offsets are defined. PRE_MEM_READ will
13085 double check it can dereference them. */
13086 if (ARG2 != 0)
13087 PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
13088 if (ARG4 != 0)
13089 PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
13093 PRE(sys_pkey_alloc)
13095 PRINT("pkey_alloc (%lu, %lu)", ARG1, ARG2);
13097 PRE_REG_READ2(long, "pkey_alloc",
13098 unsigned long, "flags",
13099 unsigned long, "access_rights");
13101 /* The kernel says: pkey_alloc() is always safe to call regardless of
13102 whether or not the operating system supports protection keys. It can be
13103 used in lieu of any other mechanism for detecting pkey support and will
13104 simply fail with the error ENOSPC if the operating system has no pkey
13105 support.
13107 So we simply always return ENOSPC to signal memory protection keys are
13108 not supported under valgrind, unless there are unknown flags, then we
13109 return EINVAL. */
13110 unsigned long pkey_flags = ARG1;
13111 if (pkey_flags != 0)
13112 SET_STATUS_Failure( VKI_EINVAL );
13113 else
13114 SET_STATUS_Failure( VKI_ENOSPC );
13117 PRE(sys_pkey_free)
13119 PRINT("pkey_free (%" FMT_REGWORD "u )", ARG1);
13121 PRE_REG_READ1(long, "pkey_free",
13122 unsigned long, "pkey");
13124 /* Since pkey_alloc () can never succeed, see above, freeing any pkey is
13125 always an error. */
13126 SET_STATUS_Failure( VKI_EINVAL );
13129 PRE(sys_pkey_mprotect)
13131 PRINT("sys_pkey_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13132 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13133 PRE_REG_READ4(long, "pkey_mprotect",
13134 unsigned long, addr, vki_size_t, len, unsigned long, prot,
13135 unsigned long, pkey);
13137 Addr addr = ARG1;
13138 SizeT len = ARG2;
13139 Int prot = ARG3;
13140 Int pkey = ARG4;
13142 /* Since pkey_alloc () can never succeed, see above, any pkey is
13143 invalid. Except for -1, then pkey_mprotect acts just like mprotect. */
13144 if (pkey != -1)
13145 SET_STATUS_Failure( VKI_EINVAL );
13146 else
13147 handle_sys_mprotect (tid, status, &addr, &len, &prot);
13149 ARG1 = addr;
13150 ARG2 = len;
13151 ARG3 = prot;
13154 POST(sys_pkey_mprotect)
13156 Addr addr = ARG1;
13157 SizeT len = ARG2;
13158 Int prot = ARG3;
13160 ML_(notify_core_and_tool_of_mprotect)(addr, len, prot);
13163 PRE(sys_io_uring_setup)
13165 PRINT("sys_io_uring_setup ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",
13166 ARG1, ARG2);
13167 PRE_REG_READ2(long, "io_uring_setup", unsigned int, entries,
13168 struct vki_io_uring_params *, p);
13169 if (ARG2)
13170 PRE_MEM_READ("io_uring_setup(p)", ARG2,
13171 offsetof(struct vki_io_uring_params, sq_off));
13174 POST(sys_io_uring_setup)
13176 vg_assert(SUCCESS);
13177 if (!ML_(fd_allowed)(RES, "io_uring_setup", tid, True)) {
13178 VG_(close)(RES);
13179 SET_STATUS_Failure( VKI_EMFILE );
13180 } else {
13181 if (VG_(clo_track_fds))
13182 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
13183 POST_MEM_WRITE(ARG2 + offsetof(struct vki_io_uring_params, sq_off),
13184 sizeof(struct vki_io_sqring_offsets) +
13185 sizeof(struct vki_io_cqring_offsets));
13189 PRE(sys_io_uring_enter)
13191 PRINT("sys_io_uring_enter ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13192 FMT_REGWORD "u %" FMT_REGWORD "u, %" FMT_REGWORD "u %"
13193 FMT_REGWORD "u )",
13194 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
13195 PRE_REG_READ6(long, "io_uring_enter",
13196 unsigned int, fd, unsigned int, to_submit,
13197 unsigned int, min_complete, unsigned int, flags,
13198 const void *, sig, unsigned long, sigsz);
13199 if (ARG5)
13200 PRE_MEM_READ("io_uring_enter(sig)", ARG5, ARG6);
13203 POST(sys_io_uring_enter)
13207 PRE(sys_io_uring_register)
13209 PRINT("sys_io_uring_register ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
13210 FMT_REGWORD "u %" FMT_REGWORD "u )", ARG1, ARG2, ARG3, ARG4);
13211 PRE_REG_READ4(long, "io_uring_register",
13212 unsigned int, fd, unsigned int, opcode,
13213 void *, arg, unsigned int, nr_args);
13214 switch (ARG2) {
13215 case VKI_IORING_REGISTER_BUFFERS:
13216 PRE_MEM_READ("", ARG3, ARG4 * sizeof(struct vki_iovec));
13217 break;
13218 case VKI_IORING_UNREGISTER_BUFFERS:
13219 break;
13220 case VKI_IORING_REGISTER_FILES:
13221 PRE_MEM_READ("", ARG3, ARG4 * sizeof(__vki_s32));
13222 break;
13223 case VKI_IORING_UNREGISTER_FILES:
13224 break;
13225 case VKI_IORING_REGISTER_EVENTFD:
13226 PRE_MEM_READ("", ARG3, sizeof(__vki_s32));
13227 break;
13228 case VKI_IORING_UNREGISTER_EVENTFD:
13229 break;
13233 POST(sys_io_uring_register)
13237 PRE(sys_execveat)
13239 PRINT("sys_execveat ( %lu, %#lx(%s), %#lx, %#lx, %lu", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
13240 PRE_REG_READ5(vki_off_t, "execveat",
13241 int, fd, char *, filename, char **, argv, char **, envp, int, flags);
13242 PRE_MEM_RASCIIZ( "execveat(filename)", ARG2);
13244 #if !defined(__NR_execveat)
13245 SET_STATUS_Failure(VKI_ENOSYS);
13246 return;
13247 #endif
13249 char *path = (char*) ARG2;
13250 Addr arg_2 = ARG3;
13251 Addr arg_3 = ARG4;
13252 const HChar *buf;
13253 HChar *abs_path = NULL;
13254 Bool check_at_symlink = False;
13255 Bool check_pathptr = True;
13257 if (ML_(safe_to_deref) (path, 1)) {
13258 /* If pathname is absolute, we'll ignore dirfd
13259 * and just pass the pathname, try to determine
13260 * the absolute path otherwise. */
13261 if (path[0] != '/') {
13262 /* Check dirfd is a valid fd. */
13263 if (!ML_(fd_allowed)(ARG1, "execveat", tid, False)) {
13264 SET_STATUS_Failure( VKI_EBADF );
13265 return;
13267 /* If pathname is empty and AT_EMPTY_PATH is
13268 set then dirfd describes the whole path. */
13269 if (path[0] == '\0') {
13270 if (ARG5 & VKI_AT_EMPTY_PATH) {
13271 if (VG_(resolve_filename)(ARG1, &buf)) {
13272 VG_(strcpy)(path, buf);
13273 check_pathptr = False;
13277 else if (ARG1 == VKI_AT_FDCWD) {
13278 check_at_symlink = True;
13279 } else
13280 if (ARG5 & VKI_AT_SYMLINK_NOFOLLOW)
13281 check_at_symlink = True;
13282 else if (VG_(resolve_filename)(ARG1, &buf)) {
13283 abs_path = VG_(malloc)("execveat",
13284 (VG_(strlen)(buf) + 1
13285 + VG_(strlen)(path) + 1));
13286 VG_(sprintf)(abs_path, "%s/%s", buf, path);
13287 path = abs_path;
13288 check_pathptr = False;
13290 else
13291 path = NULL;
13292 if (check_at_symlink) {
13293 struct vg_stat statbuf;
13294 SysRes statres;
13296 statres = VG_(stat)(path, &statbuf);
13297 if (sr_isError(statres) || VKI_S_ISLNK(statbuf.mode)) {
13298 SET_STATUS_Failure( VKI_ELOOP );
13299 return;
13303 } else {
13304 SET_STATUS_Failure(VKI_EFAULT);
13305 return;
13308 handle_pre_sys_execve(tid, status, (Addr) path, arg_2, arg_3, 1,
13309 check_pathptr);
13311 /* The exec failed, we keep running... cleanup. */
13312 VG_(free)(abs_path);
13318 #undef PRE
13319 #undef POST
13321 #endif // defined(VGO_linux)
13323 /*--------------------------------------------------------------------*/
13324 /*--- end ---*/
13325 /*--------------------------------------------------------------------*/