blob: 1b1e65ef7abf56071e00739043ebdcbd5bf8f229 [file] [log] [blame]
nethercotefd453532004-11-17 17:21:12 +00001
2/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00003/*--- Linux-specific syscalls, etc. syswrap-linux.c ---*/
nethercotefd453532004-11-17 17:21:12 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
nethercotefd453532004-11-17 17:21:12 +00009
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Nicholas Nethercote
njn2bc10122005-05-08 02:10:27 +000011 njn@valgrind.org
nethercotefd453532004-11-17 17:21:12 +000012
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.
17
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.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njn8b68b642009-06-24 00:37:09 +000031#if defined(VGO_linux)
32
njnc7561b92005-06-19 01:24:32 +000033#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000034#include "pub_core_vki.h"
35#include "pub_core_vkiscnums.h"
sewardj6c591e12011-04-11 16:17:51 +000036#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +000037#include "pub_core_threadstate.h"
sewardj55f9d1a2005-04-25 11:11:44 +000038#include "pub_core_aspacemgr.h"
sewardj45f4e7c2005-09-27 19:20:21 +000039#include "pub_core_debuginfo.h" // VG_(di_notify_*)
40#include "pub_core_transtab.h" // VG_(discard_translations)
sewardj14c7cc52007-02-25 15:08:24 +000041#include "pub_core_xarray.h"
tom363ec762006-03-21 10:58:35 +000042#include "pub_core_clientstate.h"
njn7b85dd52005-06-12 17:26:29 +000043#include "pub_core_debuglog.h"
sewardjbc22cf72005-06-08 00:02:49 +000044#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000045#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000046#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000047#include "pub_core_libcprint.h"
njn7b85dd52005-06-12 17:26:29 +000048#include "pub_core_libcproc.h"
njne1486662005-11-10 02:48:04 +000049#include "pub_core_libcsignal.h"
petarj36c2b8c2012-07-03 21:02:42 +000050#include "pub_core_machine.h" // VG_(get_SP)
njnaf1d7df2005-06-11 01:31:52 +000051#include "pub_core_mallocfree.h"
njn43b9a8a2005-05-10 04:37:01 +000052#include "pub_core_tooliface.h"
sewardja8d8e232005-06-07 20:04:56 +000053#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +000054#include "pub_core_scheduler.h"
njncd405ea2005-08-31 02:44:31 +000055#include "pub_core_signals.h"
njn9abd6082005-06-17 21:31:45 +000056#include "pub_core_syscall.h"
njna3afdfb2005-11-09 04:49:28 +000057#include "pub_core_syswrap.h"
florianc91f5842013-09-15 10:42:26 +000058#include "pub_core_inner.h"
philippe277eaff2012-03-03 12:01:48 +000059#if defined(ENABLE_INNER_CLIENT_REQUEST)
florian1a046d52013-09-16 20:56:35 +000060#include "pub_core_clreq.h"
philippe277eaff2012-03-03 12:01:48 +000061#endif
sewardja8d8e232005-06-07 20:04:56 +000062
63#include "priv_types_n_macros.h"
njnc1b01812005-06-17 22:19:06 +000064#include "priv_syswrap-generic.h"
65#include "priv_syswrap-linux.h"
bart0ab84fe2012-09-09 18:30:17 +000066#include "priv_syswrap-xen.h"
njna3afdfb2005-11-09 04:49:28 +000067
njn7b85dd52005-06-12 17:26:29 +000068// Run a thread from beginning to end and return the thread's
69// scheduler-return-code.
njne1486662005-11-10 02:48:04 +000070static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
njn7b85dd52005-06-12 17:26:29 +000071{
njn7b85dd52005-06-12 17:26:29 +000072 VgSchedReturnCode ret;
73 ThreadId tid = (ThreadId)tidW;
74 ThreadState* tst = VG_(get_ThreadState)(tid);
75
sewardjd98f68d2005-11-09 14:09:14 +000076 VG_(debugLog)(1, "syswrap-linux",
njne1486662005-11-10 02:48:04 +000077 "thread_wrapper(tid=%lld): entry\n",
tom60a4b0b2005-10-12 10:45:27 +000078 (ULong)tidW);
79
njn7b85dd52005-06-12 17:26:29 +000080 vg_assert(tst->status == VgTs_Init);
81
82 /* make sure we get the CPU lock before doing anything significant */
sewardjad0a3a82006-12-17 18:58:55 +000083 VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)");
njn7b85dd52005-06-12 17:26:29 +000084
85 if (0)
86 VG_(printf)("thread tid %d started: stack = %p\n",
87 tid, &tid);
88
sewardjdc873c02011-07-24 16:02:33 +000089 /* Make sure error reporting is enabled in the new thread. */
90 tst->err_disablement_level = 0;
91
sewardj7a387ea2007-11-25 14:06:06 +000092 VG_TRACK(pre_thread_first_insn, tid);
93
njn7b85dd52005-06-12 17:26:29 +000094 tst->os_state.lwpid = VG_(gettid)();
sewardjce215632010-02-22 11:03:10 +000095 /* Set the threadgroup for real. This overwrites the provisional
96 value set in do_clone() syswrap-*-linux.c. See comments in
97 do_clone for background, also #226116. */
njn7b85dd52005-06-12 17:26:29 +000098 tst->os_state.threadgroup = VG_(getpid)();
99
100 /* Thread created with all signals blocked; scheduler will set the
101 appropriate mask */
102
103 ret = VG_(scheduler)(tid);
104
105 vg_assert(VG_(is_exiting)(tid));
106
107 vg_assert(tst->status == VgTs_Runnable);
108 vg_assert(VG_(is_running_thread)(tid));
109
sewardjd98f68d2005-11-09 14:09:14 +0000110 VG_(debugLog)(1, "syswrap-linux",
philippeb8ba0312013-10-21 19:57:08 +0000111 "thread_wrapper(tid=%lld): exit, schedreturncode %s\n",
112 (ULong)tidW, VG_(name_of_VgSchedReturnCode)(ret));
njn7b85dd52005-06-12 17:26:29 +0000113
114 /* Return to caller, still holding the lock. */
115 return ret;
116}
117
118
nethercotefd453532004-11-17 17:21:12 +0000119/* ---------------------------------------------------------------------
njna3afdfb2005-11-09 04:49:28 +0000120 clone-related stuff
121 ------------------------------------------------------------------ */
122
123/* Run a thread all the way to the end, then do appropriate exit actions
124 (this is the last-one-out-turn-off-the-lights bit). */
njne1486662005-11-10 02:48:04 +0000125static void run_a_thread_NORETURN ( Word tidW )
njna3afdfb2005-11-09 04:49:28 +0000126{
127 ThreadId tid = (ThreadId)tidW;
128 VgSchedReturnCode src;
129 Int c;
sewardjdc873c02011-07-24 16:02:33 +0000130 ThreadState* tst;
philippe277eaff2012-03-03 12:01:48 +0000131#ifdef ENABLE_INNER_CLIENT_REQUEST
132 Int registered_vgstack_id;
133#endif
njna3afdfb2005-11-09 04:49:28 +0000134
sewardjd98f68d2005-11-09 14:09:14 +0000135 VG_(debugLog)(1, "syswrap-linux",
njne1486662005-11-10 02:48:04 +0000136 "run_a_thread_NORETURN(tid=%lld): pre-thread_wrapper\n",
137 (ULong)tidW);
njna3afdfb2005-11-09 04:49:28 +0000138
sewardjdc873c02011-07-24 16:02:33 +0000139 tst = VG_(get_ThreadState)(tid);
140 vg_assert(tst);
141
philippe277eaff2012-03-03 12:01:48 +0000142 /* An thread has two stacks:
143 * the simulated stack (used by the synthetic cpu. Guest process
144 is using this stack).
145 * the valgrind stack (used by the real cpu. Valgrind code is running
146 on this stack).
147 When Valgrind runs as an inner, it must signals that its (real) stack
148 is the stack to use by the outer to e.g. do stacktraces.
149 */
150 INNER_REQUEST
151 (registered_vgstack_id
152 = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
153 tst->os_state.valgrind_stack_init_SP));
154
njna3afdfb2005-11-09 04:49:28 +0000155 /* Run the thread all the way through. */
njne1486662005-11-10 02:48:04 +0000156 src = thread_wrapper(tid);
njna3afdfb2005-11-09 04:49:28 +0000157
sewardjd98f68d2005-11-09 14:09:14 +0000158 VG_(debugLog)(1, "syswrap-linux",
njne1486662005-11-10 02:48:04 +0000159 "run_a_thread_NORETURN(tid=%lld): post-thread_wrapper\n",
160 (ULong)tidW);
njna3afdfb2005-11-09 04:49:28 +0000161
162 c = VG_(count_living_threads)();
163 vg_assert(c >= 1); /* stay sane */
164
sewardjadb102f2007-11-09 23:21:44 +0000165 // Tell the tool this thread is exiting
166 VG_TRACK( pre_thread_ll_exit, tid );
167
sewardjdc873c02011-07-24 16:02:33 +0000168 /* If the thread is exiting with errors disabled, complain loudly;
169 doing so is bad (does the user know this has happened?) Also,
170 in all cases, be paranoid and clear the flag anyway so that the
171 thread slot is safe in this respect if later reallocated. This
172 should be unnecessary since the flag should be cleared when the
173 slot is reallocated, in thread_wrapper(). */
174 if (tst->err_disablement_level > 0) {
175 VG_(umsg)(
176 "WARNING: exiting thread has error reporting disabled.\n"
177 "WARNING: possibly as a result of some mistake in the use\n"
178 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
179 );
180 VG_(debugLog)(
181 1, "syswrap-linux",
182 "run_a_thread_NORETURN(tid=%lld): "
183 "WARNING: exiting thread has err_disablement_level = %u\n",
184 (ULong)tidW, tst->err_disablement_level
185 );
186 }
187 tst->err_disablement_level = 0;
188
njna3afdfb2005-11-09 04:49:28 +0000189 if (c == 1) {
190
sewardjd98f68d2005-11-09 14:09:14 +0000191 VG_(debugLog)(1, "syswrap-linux",
njna3afdfb2005-11-09 04:49:28 +0000192 "run_a_thread_NORETURN(tid=%lld): "
193 "last one standing\n",
194 (ULong)tidW);
195
196 /* We are the last one standing. Keep hold of the lock and
197 carry on to show final tool results, then exit the entire system.
198 Use the continuation pointer set at startup in m_main. */
199 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
njna3afdfb2005-11-09 04:49:28 +0000200 } else {
201
sewardjd98f68d2005-11-09 14:09:14 +0000202 VG_(debugLog)(1, "syswrap-linux",
njna3afdfb2005-11-09 04:49:28 +0000203 "run_a_thread_NORETURN(tid=%lld): "
204 "not last one standing\n",
205 (ULong)tidW);
206
207 /* OK, thread is dead, but others still exist. Just exit. */
njna3afdfb2005-11-09 04:49:28 +0000208
209 /* This releases the run lock */
210 VG_(exit_thread)(tid);
211 vg_assert(tst->status == VgTs_Zombie);
sewardjf0c12502014-01-12 12:54:00 +0000212 vg_assert(sizeof(tst->status) == 4);
213 vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word));
njna3afdfb2005-11-09 04:49:28 +0000214
philippe277eaff2012-03-03 12:01:48 +0000215 INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id));
216
njna3afdfb2005-11-09 04:49:28 +0000217 /* We have to use this sequence to terminate the thread to
218 prevent a subtle race. If VG_(exit_thread)() had left the
219 ThreadState as Empty, then it could have been reallocated,
220 reusing the stack while we're doing these last cleanups.
221 Instead, VG_(exit_thread) leaves it as Zombie to prevent
222 reallocation. We need to make sure we don't touch the stack
223 between marking it Empty and exiting. Hence the
224 assembler. */
225#if defined(VGP_x86_linux)
226 asm volatile (
philippe5d5dd8e2012-08-05 00:08:25 +0000227 "pushl %%ebx\n"
njna3afdfb2005-11-09 04:49:28 +0000228 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
229 "movl %2, %%eax\n" /* set %eax = __NR_exit */
230 "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
231 "int $0x80\n" /* exit(tst->os_state.exitcode) */
philippe5d5dd8e2012-08-05 00:08:25 +0000232 "popl %%ebx\n"
njna3afdfb2005-11-09 04:49:28 +0000233 : "=m" (tst->status)
sewardjf72a28d2011-09-26 17:50:46 +0000234 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
philippe5d5dd8e2012-08-05 00:08:25 +0000235 : "eax"
sewardjf72a28d2011-09-26 17:50:46 +0000236 );
njna3afdfb2005-11-09 04:49:28 +0000237#elif defined(VGP_amd64_linux)
238 asm volatile (
239 "movl %1, %0\n" /* set tst->status = VgTs_Empty */
240 "movq %2, %%rax\n" /* set %rax = __NR_exit */
241 "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
242 "syscall\n" /* exit(tst->os_state.exitcode) */
243 : "=m" (tst->status)
sewardjf72a28d2011-09-26 17:50:46 +0000244 : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
245 : "rax", "rdi"
246 );
sewardj2c48c7b2005-11-29 13:05:56 +0000247#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
njna3afdfb2005-11-09 04:49:28 +0000248 { UInt vgts_empty = (UInt)VgTs_Empty;
249 asm volatile (
250 "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
251 "li 0,%2\n\t" /* set r0 = __NR_exit */
252 "lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
253 "sc\n\t" /* exit(tst->os_state.exitcode) */
254 : "=m" (tst->status)
sewardjf72a28d2011-09-26 17:50:46 +0000255 : "r" (vgts_empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
256 : "r0", "r3"
257 );
njna3afdfb2005-11-09 04:49:28 +0000258 }
sewardj59570ff2010-01-01 11:59:33 +0000259#elif defined(VGP_arm_linux)
260 asm volatile (
261 "str %1, %0\n" /* set tst->status = VgTs_Empty */
262 "mov r7, %2\n" /* set %r7 = __NR_exit */
263 "ldr r0, %3\n" /* set %r0 = tst->os_state.exitcode */
264 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
265 : "=m" (tst->status)
sewardjf72a28d2011-09-26 17:50:46 +0000266 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
267 : "r0", "r7"
268 );
sewardjf0c12502014-01-12 12:54:00 +0000269#elif defined(VGP_arm64_linux)
270 asm volatile (
271 "str %w1, %0\n" /* set tst->status = VgTs_Empty (32-bit store) */
272 "mov x8, %2\n" /* set %r7 = __NR_exit */
273 "ldr x0, %3\n" /* set %r0 = tst->os_state.exitcode */
274 "svc 0x00000000\n" /* exit(tst->os_state.exitcode) */
275 : "=m" (tst->status)
276 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
277 : "r0", "r7"
278 );
sewardjb5b87402011-03-07 16:05:35 +0000279#elif defined(VGP_s390x_linux)
280 asm volatile (
281 "st %1, %0\n" /* set tst->status = VgTs_Empty */
282 "lg 2, %3\n" /* set r2 = tst->os_state.exitcode */
283 "svc %2\n" /* exit(tst->os_state.exitcode) */
284 : "=m" (tst->status)
285 : "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
sewardjf72a28d2011-09-26 17:50:46 +0000286 : "2"
287 );
petarj4df0bfc2013-02-27 23:17:33 +0000288#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
sewardj5db15402012-06-07 09:13:21 +0000289 asm volatile (
290 "sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
sewardjf0c12502014-01-12 12:54:00 +0000291 "li $2, %2\n\t" /* set v0 = __NR_exit */
sewardj5db15402012-06-07 09:13:21 +0000292 "lw $4, %3\n\t" /* set a0 = tst->os_state.exitcode */
293 "syscall\n\t" /* exit(tst->os_state.exitcode) */
294 "nop"
295 : "=m" (tst->status)
296 : "r" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
297 : "cc", "memory" , "v0", "a0"
298 );
njna3afdfb2005-11-09 04:49:28 +0000299#else
300# error Unknown platform
301#endif
302
303 VG_(core_panic)("Thread exit failed?\n");
304 }
305
306 /*NOTREACHED*/
307 vg_assert(0);
308}
309
njnffd9c1d2005-11-10 04:02:19 +0000310Word ML_(start_thread_NORETURN) ( void* arg )
njna3afdfb2005-11-09 04:49:28 +0000311{
312 ThreadState* tst = (ThreadState*)arg;
313 ThreadId tid = tst->tid;
314
njne1486662005-11-10 02:48:04 +0000315 run_a_thread_NORETURN ( (Word)tid );
njna3afdfb2005-11-09 04:49:28 +0000316 /*NOTREACHED*/
317 vg_assert(0);
318}
319
320/* Allocate a stack for this thread, if it doesn't already have one.
321 They're allocated lazily, and never freed. Returns the initial stack
322 pointer value to use, or 0 if allocation failed. */
323Addr ML_(allocstack)(ThreadId tid)
324{
325 ThreadState* tst = VG_(get_ThreadState)(tid);
326 VgStack* stack;
327 Addr initial_SP;
328
329 /* Either the stack_base and stack_init_SP are both zero (in which
330 case a stack hasn't been allocated) or they are both non-zero,
331 in which case it has. */
332
333 if (tst->os_state.valgrind_stack_base == 0)
334 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
335
336 if (tst->os_state.valgrind_stack_base != 0)
337 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
338
339 /* If no stack is present, allocate one. */
340
341 if (tst->os_state.valgrind_stack_base == 0) {
342 stack = VG_(am_alloc_VgStack)( &initial_SP );
343 if (stack) {
344 tst->os_state.valgrind_stack_base = (Addr)stack;
345 tst->os_state.valgrind_stack_init_SP = initial_SP;
346 }
347 }
348
349 if (0)
350 VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
351 tid,
352 (void*)tst->os_state.valgrind_stack_base,
353 (void*)tst->os_state.valgrind_stack_init_SP );
354
355 return tst->os_state.valgrind_stack_init_SP;
356}
357
358/* Allocate a stack for the main thread, and run it all the way to the
359 end. Although we already have a working VgStack
360 (VG_(interim_stack)) it's better to allocate a new one, so that
361 overflow detection works uniformly for all threads.
362*/
363void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
364{
365 Addr sp;
366 VG_(debugLog)(1, "syswrap-linux",
367 "entering VG_(main_thread_wrapper_NORETURN)\n");
368
369 sp = ML_(allocstack)(tid);
philippe277eaff2012-03-03 12:01:48 +0000370#if defined(ENABLE_INNER_CLIENT_REQUEST)
371 {
372 // we must register the main thread stack before the call
373 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
374 // reports 'write error' on the non registered stack.
375 ThreadState* tst = VG_(get_ThreadState)(tid);
376 INNER_REQUEST
377 ((void)
378 VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base,
379 tst->os_state.valgrind_stack_init_SP));
380 }
381#endif
njna3afdfb2005-11-09 04:49:28 +0000382
383#if defined(VGP_ppc32_linux)
384 /* make a stack frame */
385 sp -= 16;
386 sp &= ~0xF;
387 *(UWord *)sp = 0;
cerion21082042005-12-06 19:07:08 +0000388#elif defined(VGP_ppc64_linux)
389 /* make a stack frame */
390 sp -= 112;
391 sp &= ~((Addr)0xF);
392 *(UWord *)sp = 0;
sewardjb5b87402011-03-07 16:05:35 +0000393#elif defined(VGP_s390x_linux)
394 /* make a stack frame */
395 sp -= 160;
396 sp &= ~((Addr)0xF);
397 *(UWord *)sp = 0;
njna3afdfb2005-11-09 04:49:28 +0000398#endif
399
400 /* If we can't even allocate the first thread's stack, we're hosed.
401 Give up. */
402 vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
403
404 /* shouldn't be any other threads around yet */
405 vg_assert( VG_(count_living_threads)() == 1 );
406
407 ML_(call_on_new_stack_0_1)(
njne1486662005-11-10 02:48:04 +0000408 (Addr)sp, /* stack */
409 0, /* bogus return address */
410 run_a_thread_NORETURN, /* fn to call */
411 (Word)tid /* arg to give it */
njna3afdfb2005-11-09 04:49:28 +0000412 );
413
414 /*NOTREACHED*/
415 vg_assert(0);
416}
417
418
njne1486662005-11-10 02:48:04 +0000419/* Do a clone which is really a fork() */
420SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
421 Int* parent_tidptr, Int* child_tidptr )
422{
423 vki_sigset_t fork_saved_mask;
424 vki_sigset_t mask;
425 SysRes res;
426
427 if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
428 | VKI_CLONE_FILES | VKI_CLONE_VFORK))
429 return VG_(mk_SysRes_Error)( VKI_EINVAL );
430
431 /* Block all signals during fork, so that we can fix things up in
432 the child without being interrupted. */
433 VG_(sigfillset)(&mask);
434 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
435
njne9ba34a2008-10-13 04:19:15 +0000436 VG_(do_atfork_pre)(tid);
437
njne1486662005-11-10 02:48:04 +0000438 /* Since this is the fork() form of clone, we don't need all that
439 VG_(clone) stuff */
sewardj59570ff2010-01-01 11:59:33 +0000440#if defined(VGP_x86_linux) \
441 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
petarj4df0bfc2013-02-27 23:17:33 +0000442 || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
sewardjf0c12502014-01-12 12:54:00 +0000443 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
njne1486662005-11-10 02:48:04 +0000444 res = VG_(do_syscall5)( __NR_clone, flags,
445 (UWord)NULL, (UWord)parent_tidptr,
446 (UWord)NULL, (UWord)child_tidptr );
447#elif defined(VGP_amd64_linux)
448 /* note that the last two arguments are the opposite way round to x86 and
449 ppc32 as the amd64 kernel expects the arguments in a different order */
450 res = VG_(do_syscall5)( __NR_clone, flags,
451 (UWord)NULL, (UWord)parent_tidptr,
452 (UWord)child_tidptr, (UWord)NULL );
sewardjb5b87402011-03-07 16:05:35 +0000453#elif defined(VGP_s390x_linux)
454 /* Note that s390 has the stack first and then the flags */
455 res = VG_(do_syscall4)( __NR_clone, (UWord) NULL, flags,
456 (UWord)parent_tidptr, (UWord)child_tidptr);
njne1486662005-11-10 02:48:04 +0000457#else
458# error Unknown platform
459#endif
460
njncda2f0f2009-05-18 02:12:08 +0000461 if (!sr_isError(res) && sr_Res(res) == 0) {
njne1486662005-11-10 02:48:04 +0000462 /* child */
463 VG_(do_atfork_child)(tid);
464
465 /* restore signal mask */
466 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardj6e31f802007-11-17 22:29:25 +0000467
468 /* If --child-silent-after-fork=yes was specified, set the
sewardj738856f2009-07-15 14:48:32 +0000469 output file descriptors to 'impossible' values. This is
sewardj6e31f802007-11-17 22:29:25 +0000470 noticed by send_bytes_to_logging_sink in m_libcprint.c, which
sewardj738856f2009-07-15 14:48:32 +0000471 duly stops writing any further output. */
472 if (VG_(clo_child_silent_after_fork)) {
473 if (!VG_(log_output_sink).is_socket)
474 VG_(log_output_sink).fd = -1;
475 if (!VG_(xml_output_sink).is_socket)
476 VG_(xml_output_sink).fd = -1;
477 }
njne1486662005-11-10 02:48:04 +0000478 }
479 else
njncda2f0f2009-05-18 02:12:08 +0000480 if (!sr_isError(res) && sr_Res(res) > 0) {
njne1486662005-11-10 02:48:04 +0000481 /* parent */
njne9ba34a2008-10-13 04:19:15 +0000482 VG_(do_atfork_parent)(tid);
483
njne1486662005-11-10 02:48:04 +0000484 if (VG_(clo_trace_syscalls))
barta0b6b2c2008-07-07 06:49:24 +0000485 VG_(printf)(" clone(fork): process %d created child %ld\n",
njncda2f0f2009-05-18 02:12:08 +0000486 VG_(getpid)(), sr_Res(res));
njne1486662005-11-10 02:48:04 +0000487
488 /* restore signal mask */
489 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
490 }
491
492 return res;
493}
494
495
njna3afdfb2005-11-09 04:49:28 +0000496/* ---------------------------------------------------------------------
nethercotefd453532004-11-17 17:21:12 +0000497 PRE/POST wrappers for arch-generic, Linux-specific syscalls
498 ------------------------------------------------------------------ */
499
500// Nb: See the comment above the generic PRE/POST wrappers in
njnc1b01812005-06-17 22:19:06 +0000501// m_syswrap/syswrap-generic.c for notes about how they work.
nethercotefd453532004-11-17 17:21:12 +0000502
sewardja8d8e232005-06-07 20:04:56 +0000503#define PRE(name) DEFN_PRE_TEMPLATE(linux, name)
504#define POST(name) DEFN_POST_TEMPLATE(linux, name)
nethercotefd453532004-11-17 17:21:12 +0000505
tomca787242009-11-25 11:24:00 +0000506// Macros to support 64-bit syscall args split into two 32 bit values
tom41f4c852009-12-02 16:19:12 +0000507#define LOHI64(lo,hi) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
tomca787242009-11-25 11:24:00 +0000508#if defined(VG_LITTLEENDIAN)
509#define MERGE64(lo,hi) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
510#define MERGE64_FIRST(name) name##_low
511#define MERGE64_SECOND(name) name##_high
512#elif defined(VG_BIGENDIAN)
513#define MERGE64(hi,lo) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
514#define MERGE64_FIRST(name) name##_high
515#define MERGE64_SECOND(name) name##_low
516#else
517#error Unknown endianness
518#endif
tom20d35722005-07-27 22:57:18 +0000519
njn73975482005-08-30 02:45:44 +0000520/* ---------------------------------------------------------------------
521 *mount wrappers
522 ------------------------------------------------------------------ */
sewardjb5f6f512005-03-10 23:59:00 +0000523
sewardja8d8e232005-06-07 20:04:56 +0000524PRE(sys_mount)
nethercotefd453532004-11-17 17:21:12 +0000525{
526 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
527 // We are conservative and check everything, except the memory pointed to
528 // by 'data'.
sewardja8d8e232005-06-07 20:04:56 +0000529 *flags |= SfMayBlock;
njnb81078b2009-07-15 06:39:15 +0000530 PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx(%s), %#lx, %#lx )",
florian1636d332012-11-15 04:27:04 +0000531 ARG1,(HChar*)ARG1, ARG2,(HChar*)ARG2, ARG3,(HChar*)ARG3, ARG4, ARG5);
nethercotefd453532004-11-17 17:21:12 +0000532 PRE_REG_READ5(long, "mount",
533 char *, source, char *, target, char *, type,
534 unsigned long, flags, void *, data);
bart69ad7d82010-06-29 06:16:52 +0000535 if (ARG1)
536 PRE_MEM_RASCIIZ( "mount(source)", ARG1);
njn22cfccb2004-11-27 16:10:23 +0000537 PRE_MEM_RASCIIZ( "mount(target)", ARG2);
538 PRE_MEM_RASCIIZ( "mount(type)", ARG3);
nethercotefd453532004-11-17 17:21:12 +0000539}
540
sewardja8d8e232005-06-07 20:04:56 +0000541PRE(sys_oldumount)
nethercotefd453532004-11-17 17:21:12 +0000542{
barta0b6b2c2008-07-07 06:49:24 +0000543 PRINT("sys_oldumount( %#lx )", ARG1);
nethercotefd453532004-11-17 17:21:12 +0000544 PRE_REG_READ1(long, "umount", char *, path);
njn22cfccb2004-11-27 16:10:23 +0000545 PRE_MEM_RASCIIZ( "umount(path)", ARG1);
nethercotefd453532004-11-17 17:21:12 +0000546}
547
sewardja8d8e232005-06-07 20:04:56 +0000548PRE(sys_umount)
nethercotefd453532004-11-17 17:21:12 +0000549{
barta0b6b2c2008-07-07 06:49:24 +0000550 PRINT("sys_umount( %#lx, %ld )", ARG1, ARG2);
nethercotefd453532004-11-17 17:21:12 +0000551 PRE_REG_READ2(long, "umount2", char *, path, int, flags);
njn22cfccb2004-11-27 16:10:23 +0000552 PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
nethercotefd453532004-11-17 17:21:12 +0000553}
554
njn73975482005-08-30 02:45:44 +0000555/* ---------------------------------------------------------------------
556 16- and 32-bit uid/gid wrappers
557 ------------------------------------------------------------------ */
sewardj696c5512005-06-08 23:38:32 +0000558
559PRE(sys_setfsuid16)
560{
barta0b6b2c2008-07-07 06:49:24 +0000561 PRINT("sys_setfsuid16 ( %ld )", ARG1);
sewardj696c5512005-06-08 23:38:32 +0000562 PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
563}
564
sewardje6d5e722005-06-10 10:27:55 +0000565PRE(sys_setfsuid)
566{
barta0b6b2c2008-07-07 06:49:24 +0000567 PRINT("sys_setfsuid ( %ld )", ARG1);
sewardje6d5e722005-06-10 10:27:55 +0000568 PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
569}
sewardj696c5512005-06-08 23:38:32 +0000570
571PRE(sys_setfsgid16)
572{
barta0b6b2c2008-07-07 06:49:24 +0000573 PRINT("sys_setfsgid16 ( %ld )", ARG1);
sewardj696c5512005-06-08 23:38:32 +0000574 PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
575}
576
sewardje6d5e722005-06-10 10:27:55 +0000577PRE(sys_setfsgid)
578{
barta0b6b2c2008-07-07 06:49:24 +0000579 PRINT("sys_setfsgid ( %ld )", ARG1);
sewardje6d5e722005-06-10 10:27:55 +0000580 PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
581}
582
583PRE(sys_setresuid16)
584{
barta0b6b2c2008-07-07 06:49:24 +0000585 PRINT("sys_setresuid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000586 PRE_REG_READ3(long, "setresuid16",
587 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
588}
589
590PRE(sys_setresuid)
591{
barta0b6b2c2008-07-07 06:49:24 +0000592 PRINT("sys_setresuid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000593 PRE_REG_READ3(long, "setresuid",
594 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
595}
596
597PRE(sys_getresuid16)
598{
barta0b6b2c2008-07-07 06:49:24 +0000599 PRINT("sys_getresuid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000600 PRE_REG_READ3(long, "getresuid16",
601 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
602 vki_old_uid_t *, suid);
603 PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
604 PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
605 PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
606}
607POST(sys_getresuid16)
608{
609 vg_assert(SUCCESS);
610 if (RES == 0) {
611 POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
612 POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
613 POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
614 }
615}
sewardj78b50e42005-06-08 01:47:28 +0000616
617PRE(sys_getresuid)
618{
barta0b6b2c2008-07-07 06:49:24 +0000619 PRINT("sys_getresuid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
sewardj78b50e42005-06-08 01:47:28 +0000620 PRE_REG_READ3(long, "getresuid",
621 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
622 PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
623 PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
624 PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
625}
sewardj78b50e42005-06-08 01:47:28 +0000626POST(sys_getresuid)
627{
628 vg_assert(SUCCESS);
629 if (RES == 0) {
630 POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
631 POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
632 POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
633 }
634}
635
sewardje6d5e722005-06-10 10:27:55 +0000636PRE(sys_setresgid16)
637{
barta0b6b2c2008-07-07 06:49:24 +0000638 PRINT("sys_setresgid16 ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000639 PRE_REG_READ3(long, "setresgid16",
640 vki_old_gid_t, rgid,
641 vki_old_gid_t, egid, vki_old_gid_t, sgid);
642}
643
644PRE(sys_setresgid)
645{
barta0b6b2c2008-07-07 06:49:24 +0000646 PRINT("sys_setresgid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000647 PRE_REG_READ3(long, "setresgid",
648 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
649}
650
651PRE(sys_getresgid16)
652{
barta0b6b2c2008-07-07 06:49:24 +0000653 PRINT("sys_getresgid16 ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +0000654 PRE_REG_READ3(long, "getresgid16",
655 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
656 vki_old_gid_t *, sgid);
657 PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
658 PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
659 PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
660}
661POST(sys_getresgid16)
662{
663 vg_assert(SUCCESS);
664 if (RES == 0) {
665 POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
666 POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
667 POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
668 }
669}
sewardj78b50e42005-06-08 01:47:28 +0000670
671PRE(sys_getresgid)
672{
barta0b6b2c2008-07-07 06:49:24 +0000673 PRINT("sys_getresgid ( %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3);
sewardj78b50e42005-06-08 01:47:28 +0000674 PRE_REG_READ3(long, "getresgid",
675 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
676 PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
677 PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
678 PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
679}
sewardj78b50e42005-06-08 01:47:28 +0000680POST(sys_getresgid)
681{
682 vg_assert(SUCCESS);
683 if (RES == 0) {
684 POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
685 POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
686 POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
687 }
688}
689
njn73975482005-08-30 02:45:44 +0000690/* ---------------------------------------------------------------------
691 miscellaneous wrappers
692 ------------------------------------------------------------------ */
693
694PRE(sys_exit_group)
695{
696 ThreadId t;
697 ThreadState* tst;
698
barta0b6b2c2008-07-07 06:49:24 +0000699 PRINT("exit_group( %ld )", ARG1);
njnaab814e2009-03-03 05:39:23 +0000700 PRE_REG_READ1(void, "exit_group", int, status);
njn73975482005-08-30 02:45:44 +0000701
702 tst = VG_(get_ThreadState)(tid);
njn73975482005-08-30 02:45:44 +0000703 /* A little complex; find all the threads with the same threadgroup
704 as this one (including this one), and mark them to exit */
philippeb8ba0312013-10-21 19:57:08 +0000705 /* It is unclear how one can get a threadgroup in this process which
706 is not the threadgroup of the calling thread:
707 The assignments to threadgroups are:
708 = 0; /// scheduler.c os_state_clear
709 = getpid(); /// scheduler.c in child after fork
710 = getpid(); /// this file, in thread_wrapper
711 = ptst->os_state.threadgroup; /// syswrap-*-linux.c,
712 copying the thread group of the thread doing clone
713 So, the only case where the threadgroup might be different to the getpid
714 value is in the child, just after fork. But then the fork syscall is
715 still going on, the forked thread has had no chance yet to make this
716 syscall. */
njn73975482005-08-30 02:45:44 +0000717 for (t = 1; t < VG_N_THREADS; t++) {
718 if ( /* not alive */
719 VG_(threads)[t].status == VgTs_Empty
720 ||
721 /* not our group */
722 VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
723 )
724 continue;
philippeb8ba0312013-10-21 19:57:08 +0000725 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
726 the exitreason. */
njn73975482005-08-30 02:45:44 +0000727 VG_(threads)[t].os_state.exitcode = ARG1;
njn73975482005-08-30 02:45:44 +0000728 }
729
philippeb8ba0312013-10-21 19:57:08 +0000730 /* Indicate in all other threads that the process is exiting.
731 Then wait using VG_(reap_threads) for these threads to disappear.
732
733 Can this give a deadlock if another thread is calling exit in parallel
734 and would then wait for this thread to disappear ?
735 The answer is no:
736 Other threads are either blocked in a syscall or have yielded the CPU.
737
738 A thread that has yielded the CPU is trying to get the big lock in
739 VG_(scheduler). This thread will get the CPU thanks to the call
740 to VG_(reap_threads). The scheduler will then check for signals,
741 kill the process if this is a fatal signal, and otherwise prepare
742 the thread for handling this signal. After this preparation, if
743 the thread status is VG_(is_exiting), the scheduler exits the thread.
744 So, a thread that has yielded the CPU does not have a chance to
745 call exit => no deadlock for this thread.
746
747 VG_(nuke_all_threads_except) will send the VG_SIGVGKILL signal
748 to all threads blocked in a syscall.
749 The syscall will be interrupted, and the control will go to the
750 scheduler. The scheduler will then return, as the thread is in
751 exiting state. */
752
753 VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess );
754 VG_(reap_threads)(tid);
755 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
756 /* we do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
757 is the thread calling exit_group and so its registers must be considered
758 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
759
njn73975482005-08-30 02:45:44 +0000760 /* We have to claim the syscall already succeeded. */
761 SET_STATUS_Success(0);
762}
763
764PRE(sys_llseek)
765{
barta0b6b2c2008-07-07 06:49:24 +0000766 PRINT("sys_llseek ( %ld, 0x%lx, 0x%lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5);
njn73975482005-08-30 02:45:44 +0000767 PRE_REG_READ5(long, "llseek",
768 unsigned int, fd, unsigned long, offset_high,
769 unsigned long, offset_low, vki_loff_t *, result,
770 unsigned int, whence);
tom3e24fd82008-01-08 13:54:43 +0000771 if (!ML_(fd_allowed)(ARG1, "llseek", tid, False))
772 SET_STATUS_Failure( VKI_EBADF );
773 else
774 PRE_MEM_WRITE( "llseek(result)", ARG4, sizeof(vki_loff_t));
njn73975482005-08-30 02:45:44 +0000775}
776POST(sys_llseek)
777{
778 vg_assert(SUCCESS);
779 if (RES == 0)
780 POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
781}
782
tom9ceaa972009-11-24 16:38:21 +0000783PRE(sys_adjtimex)
784{
785 struct vki_timex *tx = (struct vki_timex *)ARG1;
786 PRINT("sys_adjtimex ( %#lx )", ARG1);
787 PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
788 PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
789
tome1c1a242009-12-21 11:29:54 +0000790#define ADJX(bits,field) \
791 if (tx->modes & (bits)) \
tom9ceaa972009-11-24 16:38:21 +0000792 PRE_MEM_READ( "adjtimex(timex->"#field")", \
793 (Addr)&tx->field, sizeof(tx->field))
794
tome1c1a242009-12-21 11:29:54 +0000795 if (tx->modes & VKI_ADJ_ADJTIME) {
796 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
797 PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
798 } else {
799 ADJX(VKI_ADJ_OFFSET, offset);
800 ADJX(VKI_ADJ_FREQUENCY, freq);
801 ADJX(VKI_ADJ_MAXERROR, maxerror);
802 ADJX(VKI_ADJ_ESTERROR, esterror);
803 ADJX(VKI_ADJ_STATUS, status);
804 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
805 ADJX(VKI_ADJ_TICK, tick);
806 }
tom9ceaa972009-11-24 16:38:21 +0000807#undef ADJX
808
809 PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
810}
811
812POST(sys_adjtimex)
813{
814 POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
815}
njn73975482005-08-30 02:45:44 +0000816
tomddc4a182014-01-30 22:33:02 +0000817PRE(sys_clock_adjtime)
818{
819 struct vki_timex *tx = (struct vki_timex *)ARG2;
820 PRINT("sys_clock_adjtime ( %ld, %#lx )", ARG1,ARG2);
821 PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
822 PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
823
824#define ADJX(bits,field) \
825 if (tx->modes & (bits)) \
826 PRE_MEM_READ( "clock_adjtime(timex->"#field")", \
827 (Addr)&tx->field, sizeof(tx->field))
828
829 if (tx->modes & VKI_ADJ_ADJTIME) {
830 if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
831 PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
832 } else {
833 ADJX(VKI_ADJ_OFFSET, offset);
834 ADJX(VKI_ADJ_FREQUENCY, freq);
835 ADJX(VKI_ADJ_MAXERROR, maxerror);
836 ADJX(VKI_ADJ_ESTERROR, esterror);
837 ADJX(VKI_ADJ_STATUS, status);
838 ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
839 ADJX(VKI_ADJ_TICK, tick);
840 }
841#undef ADJX
842
843 PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
844}
845
846POST(sys_clock_adjtime)
847{
848 POST_MEM_WRITE( ARG2, sizeof(struct vki_timex) );
849}
850
sewardj696c5512005-06-08 23:38:32 +0000851PRE(sys_ioperm)
852{
barta0b6b2c2008-07-07 06:49:24 +0000853 PRINT("sys_ioperm ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
sewardj696c5512005-06-08 23:38:32 +0000854 PRE_REG_READ3(long, "ioperm",
855 unsigned long, from, unsigned long, num, int, turn_on);
856}
857
858PRE(sys_syslog)
859{
860 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +0000861 PRINT("sys_syslog (%ld, %#lx, %ld)", ARG1,ARG2,ARG3);
sewardj696c5512005-06-08 23:38:32 +0000862 PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
863 switch (ARG1) {
864 // The kernel uses magic numbers here, rather than named constants,
865 // therefore so do we.
866 case 2: case 3: case 4:
867 PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
868 break;
869 default:
870 break;
871 }
872}
sewardj696c5512005-06-08 23:38:32 +0000873POST(sys_syslog)
874{
875 switch (ARG1) {
876 case 2: case 3: case 4:
877 POST_MEM_WRITE( ARG2, ARG3 );
878 break;
879 default:
880 break;
881 }
882}
883
884PRE(sys_vhangup)
885{
886 PRINT("sys_vhangup ( )");
887 PRE_REG_READ0(long, "vhangup");
888}
889
890PRE(sys_sysinfo)
891{
barta0b6b2c2008-07-07 06:49:24 +0000892 PRINT("sys_sysinfo ( %#lx )",ARG1);
sewardj696c5512005-06-08 23:38:32 +0000893 PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
894 PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
895}
sewardj696c5512005-06-08 23:38:32 +0000896POST(sys_sysinfo)
897{
898 POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
899}
900
901PRE(sys_personality)
902{
903 PRINT("sys_personality ( %llu )", (ULong)ARG1);
904 PRE_REG_READ1(long, "personality", vki_u_long, persona);
905}
nethercotefd453532004-11-17 17:21:12 +0000906
sewardja8d8e232005-06-07 20:04:56 +0000907PRE(sys_sysctl)
nethercotefd453532004-11-17 17:21:12 +0000908{
sewardje6d5e722005-06-10 10:27:55 +0000909 struct __vki_sysctl_args *args;
barta0b6b2c2008-07-07 06:49:24 +0000910 PRINT("sys_sysctl ( %#lx )", ARG1 );
sewardje6d5e722005-06-10 10:27:55 +0000911 args = (struct __vki_sysctl_args *)ARG1;
912 PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
njn22cfccb2004-11-27 16:10:23 +0000913 PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
sewardj45f4e7c2005-09-27 19:20:21 +0000914 if (!VG_(am_is_valid_for_client)(ARG1, sizeof(struct __vki_sysctl_args),
915 VKI_PROT_READ)) {
sewardja8d8e232005-06-07 20:04:56 +0000916 SET_STATUS_Failure( VKI_EFAULT );
sewardjb5f6f512005-03-10 23:59:00 +0000917 return;
918 }
919
sewardje6d5e722005-06-10 10:27:55 +0000920 PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
921 if (args->newval != NULL)
922 PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
923 if (args->oldlenp != NULL) {
924 PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
925 PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
sewardjb5f6f512005-03-10 23:59:00 +0000926 }
nethercotefd453532004-11-17 17:21:12 +0000927}
nethercotefd453532004-11-17 17:21:12 +0000928POST(sys_sysctl)
929{
sewardje6d5e722005-06-10 10:27:55 +0000930 struct __vki_sysctl_args *args;
931 args = (struct __vki_sysctl_args *)ARG1;
932 if (args->oldlenp != NULL) {
933 POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
934 POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
sewardjb5f6f512005-03-10 23:59:00 +0000935 }
nethercotefd453532004-11-17 17:21:12 +0000936}
937
sewardje6d5e722005-06-10 10:27:55 +0000938PRE(sys_prctl)
939{
940 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +0000941 PRINT( "sys_prctl ( %ld, %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4, ARG5 );
toma39ebc82006-12-18 15:22:46 +0000942 switch (ARG1) {
943 case VKI_PR_SET_PDEATHSIG:
944 PRE_REG_READ2(int, "prctl", int, option, int, signal);
945 break;
946 case VKI_PR_GET_PDEATHSIG:
947 PRE_REG_READ2(int, "prctl", int, option, int *, signal);
948 PRE_MEM_WRITE("prctl(get-death-signal)", ARG2, sizeof(Int));
949 break;
950 case VKI_PR_GET_DUMPABLE:
951 PRE_REG_READ1(int, "prctl", int, option);
952 break;
953 case VKI_PR_SET_DUMPABLE:
954 PRE_REG_READ2(int, "prctl", int, option, int, dump);
955 break;
956 case VKI_PR_GET_UNALIGN:
957 PRE_REG_READ2(int, "prctl", int, option, int *, value);
958 PRE_MEM_WRITE("prctl(get-unalign)", ARG2, sizeof(Int));
959 break;
960 case VKI_PR_SET_UNALIGN:
961 PRE_REG_READ2(int, "prctl", int, option, int, value);
962 break;
963 case VKI_PR_GET_KEEPCAPS:
964 PRE_REG_READ1(int, "prctl", int, option);
965 break;
966 case VKI_PR_SET_KEEPCAPS:
967 PRE_REG_READ2(int, "prctl", int, option, int, keepcaps);
968 break;
969 case VKI_PR_GET_FPEMU:
970 PRE_REG_READ2(int, "prctl", int, option, int *, value);
971 PRE_MEM_WRITE("prctl(get-fpemu)", ARG2, sizeof(Int));
972 break;
973 case VKI_PR_SET_FPEMU:
974 PRE_REG_READ2(int, "prctl", int, option, int, value);
975 break;
976 case VKI_PR_GET_FPEXC:
977 PRE_REG_READ2(int, "prctl", int, option, int *, value);
978 PRE_MEM_WRITE("prctl(get-fpexc)", ARG2, sizeof(Int));
979 break;
980 case VKI_PR_SET_FPEXC:
981 PRE_REG_READ2(int, "prctl", int, option, int, value);
982 break;
983 case VKI_PR_GET_TIMING:
984 PRE_REG_READ1(int, "prctl", int, option);
985 break;
986 case VKI_PR_SET_TIMING:
987 PRE_REG_READ2(int, "prctl", int, option, int, timing);
988 break;
989 case VKI_PR_SET_NAME:
990 PRE_REG_READ2(int, "prctl", int, option, char *, name);
991 PRE_MEM_RASCIIZ("prctl(set-name)", ARG2);
992 break;
993 case VKI_PR_GET_NAME:
994 PRE_REG_READ2(int, "prctl", int, option, char *, name);
995 PRE_MEM_WRITE("prctl(get-name)", ARG2, VKI_TASK_COMM_LEN);
996 break;
997 case VKI_PR_GET_ENDIAN:
998 PRE_REG_READ2(int, "prctl", int, option, int *, value);
999 PRE_MEM_WRITE("prctl(get-endian)", ARG2, sizeof(Int));
1000 break;
1001 case VKI_PR_SET_ENDIAN:
1002 PRE_REG_READ2(int, "prctl", int, option, int, value);
1003 break;
1004 default:
1005 PRE_REG_READ5(long, "prctl",
1006 int, option, unsigned long, arg2, unsigned long, arg3,
1007 unsigned long, arg4, unsigned long, arg5);
1008 break;
1009 }
1010}
1011POST(sys_prctl)
1012{
1013 switch (ARG1) {
1014 case VKI_PR_GET_PDEATHSIG:
1015 POST_MEM_WRITE(ARG2, sizeof(Int));
1016 break;
1017 case VKI_PR_GET_UNALIGN:
1018 POST_MEM_WRITE(ARG2, sizeof(Int));
1019 break;
1020 case VKI_PR_GET_FPEMU:
1021 POST_MEM_WRITE(ARG2, sizeof(Int));
1022 break;
1023 case VKI_PR_GET_FPEXC:
1024 POST_MEM_WRITE(ARG2, sizeof(Int));
1025 break;
1026 case VKI_PR_GET_NAME:
1027 POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
1028 break;
1029 case VKI_PR_GET_ENDIAN:
1030 POST_MEM_WRITE(ARG2, sizeof(Int));
1031 break;
florian49789512013-09-16 17:08:50 +00001032 case VKI_PR_SET_NAME:
1033 {
1034 const HChar* new_name = (const HChar*) ARG2;
1035 if (new_name) { // Paranoia
1036 ThreadState* tst = VG_(get_ThreadState)(tid);
florianb8911212013-09-18 14:00:10 +00001037 SizeT new_len = VG_(strlen)(new_name);
florian49789512013-09-16 17:08:50 +00001038
1039 /* Don't bother reusing the memory. This is a rare event. */
1040 tst->thread_name =
florianb8911212013-09-18 14:00:10 +00001041 VG_(arena_realloc)(VG_AR_CORE, "syswrap.prctl",
1042 tst->thread_name, new_len + 1);
1043 VG_(strcpy)(tst->thread_name, new_name);
florian49789512013-09-16 17:08:50 +00001044 }
1045 }
1046 break;
toma39ebc82006-12-18 15:22:46 +00001047 }
sewardje6d5e722005-06-10 10:27:55 +00001048}
1049
1050PRE(sys_sendfile)
1051{
1052 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001053 PRINT("sys_sendfile ( %ld, %ld, %#lx, %lu )", ARG1,ARG2,ARG3,ARG4);
sewardje6d5e722005-06-10 10:27:55 +00001054 PRE_REG_READ4(ssize_t, "sendfile",
1055 int, out_fd, int, in_fd, vki_off_t *, offset,
1056 vki_size_t, count);
1057 if (ARG3 != 0)
1058 PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
1059}
1060POST(sys_sendfile)
1061{
1062 if (ARG3 != 0 ) {
1063 POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
1064 }
1065}
1066
1067PRE(sys_sendfile64)
1068{
1069 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001070 PRINT("sendfile64 ( %ld, %ld, %#lx, %lu )",ARG1,ARG2,ARG3,ARG4);
sewardje6d5e722005-06-10 10:27:55 +00001071 PRE_REG_READ4(ssize_t, "sendfile64",
1072 int, out_fd, int, in_fd, vki_loff_t *, offset,
1073 vki_size_t, count);
1074 if (ARG3 != 0)
1075 PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
1076}
1077POST(sys_sendfile64)
1078{
1079 if (ARG3 != 0 ) {
1080 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
1081 }
1082}
sewardjbc22cf72005-06-08 00:02:49 +00001083
1084PRE(sys_futex)
1085{
1086 /*
1087 arg param used by ops
1088
1089 ARG1 - u32 *futex all
1090 ARG2 - int op
1091 ARG3 - int val WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
1092 ARG4 - struct timespec *utime WAIT:time* REQUEUE,CMP_REQUEUE:val2
1093 ARG5 - u32 *uaddr2 REQUEUE,CMP_REQUEUE
1094 ARG6 - int val3 CMP_REQUEUE
1095 */
barta0b6b2c2008-07-07 06:49:24 +00001096 PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
tomaedcc7a2009-07-29 11:09:01 +00001097 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
tomf26b6bf2006-06-07 17:47:51 +00001098 case VKI_FUTEX_CMP_REQUEUE:
tomaedcc7a2009-07-29 11:09:01 +00001099 case VKI_FUTEX_WAKE_OP:
1100 case VKI_FUTEX_CMP_REQUEUE_PI:
tomf26b6bf2006-06-07 17:47:51 +00001101 PRE_REG_READ6(long, "futex",
1102 vki_u32 *, futex, int, op, int, val,
1103 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
1104 break;
1105 case VKI_FUTEX_REQUEUE:
tomaedcc7a2009-07-29 11:09:01 +00001106 case VKI_FUTEX_WAIT_REQUEUE_PI:
tomf26b6bf2006-06-07 17:47:51 +00001107 PRE_REG_READ5(long, "futex",
1108 vki_u32 *, futex, int, op, int, val,
1109 struct timespec *, utime, vki_u32 *, uaddr2);
1110 break;
tomaedcc7a2009-07-29 11:09:01 +00001111 case VKI_FUTEX_WAIT_BITSET:
petarj8b73c6e2012-07-23 00:11:10 +00001112 /* Check that the address at least begins in client-accessible area. */
1113 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
1114 SET_STATUS_Failure( VKI_EFAULT );
1115 return;
1116 }
1117 if (*(vki_u32 *)ARG1 != ARG3) {
1118 PRE_REG_READ5(long, "futex",
1119 vki_u32 *, futex, int, op, int, val,
1120 struct timespec *, utime, int, dummy);
1121 } else {
1122 PRE_REG_READ6(long, "futex",
1123 vki_u32 *, futex, int, op, int, val,
1124 struct timespec *, utime, int, dummy, int, val3);
1125 }
tomaedcc7a2009-07-29 11:09:01 +00001126 break;
1127 case VKI_FUTEX_WAKE_BITSET:
1128 PRE_REG_READ6(long, "futex",
1129 vki_u32 *, futex, int, op, int, val,
1130 int, dummy, int, dummy2, int, val3);
1131 break;
tomf26b6bf2006-06-07 17:47:51 +00001132 case VKI_FUTEX_WAIT:
tomaedcc7a2009-07-29 11:09:01 +00001133 case VKI_FUTEX_LOCK_PI:
tomf26b6bf2006-06-07 17:47:51 +00001134 PRE_REG_READ4(long, "futex",
1135 vki_u32 *, futex, int, op, int, val,
1136 struct timespec *, utime);
1137 break;
1138 case VKI_FUTEX_WAKE:
1139 case VKI_FUTEX_FD:
tomaedcc7a2009-07-29 11:09:01 +00001140 case VKI_FUTEX_TRYLOCK_PI:
tomf26b6bf2006-06-07 17:47:51 +00001141 PRE_REG_READ3(long, "futex",
1142 vki_u32 *, futex, int, op, int, val);
1143 break;
tomaedcc7a2009-07-29 11:09:01 +00001144 case VKI_FUTEX_UNLOCK_PI:
tomf26b6bf2006-06-07 17:47:51 +00001145 default:
1146 PRE_REG_READ2(long, "futex", vki_u32 *, futex, int, op);
1147 break;
1148 }
sewardjbc22cf72005-06-08 00:02:49 +00001149
sewardjbc22cf72005-06-08 00:02:49 +00001150 *flags |= SfMayBlock;
1151
tomaedcc7a2009-07-29 11:09:01 +00001152 switch(ARG2 & ~(VKI_FUTEX_PRIVATE_FLAG|VKI_FUTEX_CLOCK_REALTIME)) {
sewardjbc22cf72005-06-08 00:02:49 +00001153 case VKI_FUTEX_WAIT:
tomaedcc7a2009-07-29 11:09:01 +00001154 case VKI_FUTEX_LOCK_PI:
1155 case VKI_FUTEX_WAIT_BITSET:
1156 case VKI_FUTEX_WAIT_REQUEUE_PI:
tom7a75b362010-02-16 15:05:55 +00001157 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
sewardjbc22cf72005-06-08 00:02:49 +00001158 if (ARG4 != 0)
1159 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
1160 break;
1161
1162 case VKI_FUTEX_REQUEUE:
1163 case VKI_FUTEX_CMP_REQUEUE:
tomaedcc7a2009-07-29 11:09:01 +00001164 case VKI_FUTEX_CMP_REQUEUE_PI:
1165 case VKI_FUTEX_WAKE_OP:
tom7a75b362010-02-16 15:05:55 +00001166 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
sewardjbc22cf72005-06-08 00:02:49 +00001167 PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
1168 break;
1169
sewardjbc22cf72005-06-08 00:02:49 +00001170 case VKI_FUTEX_FD:
tomaedcc7a2009-07-29 11:09:01 +00001171 case VKI_FUTEX_TRYLOCK_PI:
1172 case VKI_FUTEX_UNLOCK_PI:
tom7a75b362010-02-16 15:05:55 +00001173 PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
1174 break;
1175
1176 case VKI_FUTEX_WAKE:
1177 case VKI_FUTEX_WAKE_BITSET:
sewardjbc22cf72005-06-08 00:02:49 +00001178 /* no additional pointers */
1179 break;
1180
1181 default:
1182 SET_STATUS_Failure( VKI_ENOSYS ); // some futex function we don't understand
1183 break;
1184 }
1185}
sewardjbc22cf72005-06-08 00:02:49 +00001186POST(sys_futex)
1187{
1188 vg_assert(SUCCESS);
1189 POST_MEM_WRITE( ARG1, sizeof(int) );
1190 if (ARG2 == VKI_FUTEX_FD) {
sewardj7eb7c582005-06-23 01:02:53 +00001191 if (!ML_(fd_allowed)(RES, "futex", tid, True)) {
sewardjbc22cf72005-06-08 00:02:49 +00001192 VG_(close)(RES);
1193 SET_STATUS_Failure( VKI_EMFILE );
1194 } else {
1195 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00001196 ML_(record_fd_open_nameless)(tid, RES);
sewardjbc22cf72005-06-08 00:02:49 +00001197 }
1198 }
1199}
1200
tom05b1f9a2006-05-17 14:24:12 +00001201PRE(sys_set_robust_list)
1202{
barta0b6b2c2008-07-07 06:49:24 +00001203 PRINT("sys_set_robust_list ( %#lx, %ld )", ARG1,ARG2);
tom05b1f9a2006-05-17 14:24:12 +00001204 PRE_REG_READ2(long, "set_robust_list",
1205 struct vki_robust_list_head *, head, vki_size_t, len);
1206
1207 /* Just check the robust_list_head structure is readable - don't
1208 try and chase the list as the kernel will only read it when
1209 the thread exits so the current contents is irrelevant. */
1210 if (ARG1 != 0)
1211 PRE_MEM_READ("set_robust_list(head)", ARG1, ARG2);
1212}
1213
1214PRE(sys_get_robust_list)
1215{
barta0b6b2c2008-07-07 06:49:24 +00001216 PRINT("sys_get_robust_list ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
tom05b1f9a2006-05-17 14:24:12 +00001217 PRE_REG_READ3(long, "get_robust_list",
1218 int, pid,
1219 struct vki_robust_list_head **, head_ptr,
1220 vki_size_t *, len_ptr);
1221 PRE_MEM_WRITE("get_robust_list(head_ptr)",
1222 ARG2, sizeof(struct vki_robust_list_head *));
1223 PRE_MEM_WRITE("get_robust_list(len_ptr)",
1224 ARG3, sizeof(struct vki_size_t *));
1225}
1226POST(sys_get_robust_list)
1227{
1228 POST_MEM_WRITE(ARG2, sizeof(struct vki_robust_list_head *));
1229 POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
1230}
1231
tom363ec762006-03-21 10:58:35 +00001232PRE(sys_pselect6)
1233{
1234 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001235 PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
tom363ec762006-03-21 10:58:35 +00001236 PRE_REG_READ6(long, "pselect6",
1237 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
1238 vki_fd_set *, exceptfds, struct vki_timeval *, timeout,
1239 void *, sig);
1240 // XXX: this possibly understates how much memory is read.
1241 if (ARG2 != 0)
1242 PRE_MEM_READ( "pselect6(readfds)",
1243 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
1244 if (ARG3 != 0)
1245 PRE_MEM_READ( "pselect6(writefds)",
1246 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
1247 if (ARG4 != 0)
1248 PRE_MEM_READ( "pselect6(exceptfds)",
1249 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
1250 if (ARG5 != 0)
1251 PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
1252 if (ARG6 != 0)
1253 PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(void *)+sizeof(vki_size_t) );
1254}
1255
1256PRE(sys_ppoll)
1257{
1258 UInt i;
1259 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1260 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001261 PRINT("sys_ppoll ( %#lx, %ld, %#lx, %#lx, %llu )\n", ARG1,ARG2,ARG3,ARG4,(ULong)ARG5);
tom363ec762006-03-21 10:58:35 +00001262 PRE_REG_READ5(long, "ppoll",
1263 struct vki_pollfd *, ufds, unsigned int, nfds,
1264 struct vki_timespec *, tsp, vki_sigset_t *, sigmask,
1265 vki_size_t, sigsetsize);
1266
1267 for (i = 0; i < ARG2; i++) {
1268 PRE_MEM_READ( "ppoll(ufds.fd)",
1269 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
1270 PRE_MEM_READ( "ppoll(ufds.events)",
1271 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
tom68f338f2014-02-09 11:10:08 +00001272 PRE_MEM_WRITE( "ppoll(ufd.revents)",
tom363ec762006-03-21 10:58:35 +00001273 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1274 }
1275
1276 if (ARG3)
1277 PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
1278 if (ARG4)
1279 PRE_MEM_READ( "ppoll(sigmask)", ARG4, sizeof(vki_sigset_t) );
1280}
1281
1282POST(sys_ppoll)
1283{
1284 if (RES > 0) {
1285 UInt i;
1286 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
1287 for (i = 0; i < ARG2; i++)
1288 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
1289 }
1290}
1291
njn5c691752005-08-31 03:00:40 +00001292
njn73975482005-08-30 02:45:44 +00001293/* ---------------------------------------------------------------------
1294 epoll_* wrappers
1295 ------------------------------------------------------------------ */
1296
sewardje6d5e722005-06-10 10:27:55 +00001297PRE(sys_epoll_create)
1298{
barta0b6b2c2008-07-07 06:49:24 +00001299 PRINT("sys_epoll_create ( %ld )", ARG1);
sewardje6d5e722005-06-10 10:27:55 +00001300 PRE_REG_READ1(long, "epoll_create", int, size);
1301}
1302POST(sys_epoll_create)
1303{
1304 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00001305 if (!ML_(fd_allowed)(RES, "epoll_create", tid, True)) {
sewardje6d5e722005-06-10 10:27:55 +00001306 VG_(close)(RES);
1307 SET_STATUS_Failure( VKI_EMFILE );
1308 } else {
1309 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00001310 ML_(record_fd_open_nameless) (tid, RES);
sewardje6d5e722005-06-10 10:27:55 +00001311 }
1312}
1313
njn72715882009-07-10 12:02:03 +00001314PRE(sys_epoll_create1)
1315{
1316 PRINT("sys_epoll_create1 ( %ld )", ARG1);
1317 PRE_REG_READ1(long, "epoll_create1", int, flags);
1318}
1319POST(sys_epoll_create1)
1320{
1321 vg_assert(SUCCESS);
1322 if (!ML_(fd_allowed)(RES, "epoll_create1", tid, True)) {
1323 VG_(close)(RES);
1324 SET_STATUS_Failure( VKI_EMFILE );
1325 } else {
1326 if (VG_(clo_track_fds))
1327 ML_(record_fd_open_nameless) (tid, RES);
1328 }
1329}
1330
sewardje6d5e722005-06-10 10:27:55 +00001331PRE(sys_epoll_ctl)
1332{
1333 static const HChar* epoll_ctl_s[3] = {
1334 "EPOLL_CTL_ADD",
1335 "EPOLL_CTL_DEL",
1336 "EPOLL_CTL_MOD"
1337 };
barta0b6b2c2008-07-07 06:49:24 +00001338 PRINT("sys_epoll_ctl ( %ld, %s, %ld, %#lx )",
sewardje6d5e722005-06-10 10:27:55 +00001339 ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
1340 PRE_REG_READ4(long, "epoll_ctl",
njn40e73582005-06-24 21:41:28 +00001341 int, epfd, int, op, int, fd, struct vki_epoll_event *, event);
1342 if (ARG2 != VKI_EPOLL_CTL_DEL)
1343 PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) );
sewardje6d5e722005-06-10 10:27:55 +00001344}
1345
1346PRE(sys_epoll_wait)
1347{
1348 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001349 PRINT("sys_epoll_wait ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
sewardje6d5e722005-06-10 10:27:55 +00001350 PRE_REG_READ4(long, "epoll_wait",
njn40e73582005-06-24 21:41:28 +00001351 int, epfd, struct vki_epoll_event *, events,
sewardje6d5e722005-06-10 10:27:55 +00001352 int, maxevents, int, timeout);
njn40e73582005-06-24 21:41:28 +00001353 PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
sewardje6d5e722005-06-10 10:27:55 +00001354}
1355POST(sys_epoll_wait)
1356{
1357 vg_assert(SUCCESS);
1358 if (RES > 0)
njn40e73582005-06-24 21:41:28 +00001359 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
sewardje6d5e722005-06-10 10:27:55 +00001360}
sewardj8c257322005-06-08 01:01:48 +00001361
bartf5ceec82008-04-26 07:45:10 +00001362PRE(sys_epoll_pwait)
1363{
1364 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001365 PRINT("sys_epoll_pwait ( %ld, %#lx, %ld, %ld, %#lx, %llu )", ARG1,ARG2,ARG3,ARG4,ARG5,(ULong)ARG6);
bartf5ceec82008-04-26 07:45:10 +00001366 PRE_REG_READ6(long, "epoll_pwait",
1367 int, epfd, struct vki_epoll_event *, events,
1368 int, maxevents, int, timeout, vki_sigset_t *, sigmask,
1369 vki_size_t, sigsetsize);
1370 PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3);
1371 if (ARG4)
1372 PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
1373}
1374POST(sys_epoll_pwait)
1375{
1376 vg_assert(SUCCESS);
1377 if (RES > 0)
1378 POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ;
1379}
1380
1381PRE(sys_eventfd)
1382{
barta0b6b2c2008-07-07 06:49:24 +00001383 PRINT("sys_eventfd ( %lu )", ARG1);
bartf5ceec82008-04-26 07:45:10 +00001384 PRE_REG_READ1(long, "sys_eventfd", unsigned int, count);
1385}
1386POST(sys_eventfd)
1387{
1388 if (!ML_(fd_allowed)(RES, "eventfd", tid, True)) {
1389 VG_(close)(RES);
1390 SET_STATUS_Failure( VKI_EMFILE );
1391 } else {
1392 if (VG_(clo_track_fds))
1393 ML_(record_fd_open_nameless) (tid, RES);
1394 }
1395}
1396
tom84eb41f2008-12-10 09:28:56 +00001397PRE(sys_eventfd2)
1398{
sewardja284eb72008-12-12 08:08:58 +00001399 PRINT("sys_eventfd2 ( %lu, %ld )", ARG1,ARG2);
tom84eb41f2008-12-10 09:28:56 +00001400 PRE_REG_READ2(long, "sys_eventfd2", unsigned int, count, int, flags);
1401}
1402POST(sys_eventfd2)
1403{
1404 if (!ML_(fd_allowed)(RES, "eventfd2", tid, True)) {
1405 VG_(close)(RES);
1406 SET_STATUS_Failure( VKI_EMFILE );
1407 } else {
1408 if (VG_(clo_track_fds))
1409 ML_(record_fd_open_nameless) (tid, RES);
1410 }
1411}
1412
njn0bd71772009-07-15 03:08:35 +00001413PRE(sys_fallocate)
1414{
1415 *flags |= SfMayBlock;
tomd709b1d2009-11-25 11:51:05 +00001416#if VG_WORDSIZE == 4
1417 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1418 ARG1, ARG2, MERGE64(ARG3,ARG4), MERGE64(ARG5,ARG6));
1419 PRE_REG_READ6(long, "fallocate",
1420 int, fd, int, mode,
1421 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
1422 unsigned, MERGE64_FIRST(len), unsigned, MERGE64_SECOND(len));
1423#elif VG_WORDSIZE == 8
njn0bd71772009-07-15 03:08:35 +00001424 PRINT("sys_fallocate ( %ld, %ld, %lld, %lld )",
1425 ARG1, ARG2, (Long)ARG3, (Long)ARG4);
1426 PRE_REG_READ4(long, "fallocate",
1427 int, fd, int, mode, vki_loff_t, offset, vki_loff_t, len);
tomd709b1d2009-11-25 11:51:05 +00001428#else
1429# error Unexpected word size
1430#endif
tom93106a12009-07-15 07:47:49 +00001431 if (!ML_(fd_allowed)(ARG1, "fallocate", tid, False))
1432 SET_STATUS_Failure( VKI_EBADF );
njn0bd71772009-07-15 03:08:35 +00001433}
1434
tom46d02ab2011-06-08 09:55:54 +00001435PRE(sys_prlimit64)
1436{
1437 PRINT("sys_prlimit64 ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
1438 PRE_REG_READ4(long, "prlimit64",
1439 vki_pid_t, pid, unsigned int, resource,
1440 const struct rlimit64 *, new_rlim,
1441 struct rlimit64 *, old_rlim);
1442 if (ARG3)
1443 PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) );
1444 if (ARG4)
1445 PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) );
tomaba260b2012-03-01 13:42:18 +00001446
1447 if (ARG3 &&
1448 ((struct vki_rlimit64 *)ARG3)->rlim_cur > ((struct vki_rlimit64 *)ARG3)->rlim_max) {
1449 SET_STATUS_Failure( VKI_EINVAL );
1450 }
1451 else if (ARG1 == 0 || ARG1 == VG_(getpid)()) {
1452 switch (ARG2) {
1453 case VKI_RLIMIT_NOFILE:
1454 SET_STATUS_Success( 0 );
1455 if (ARG4) {
1456 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(fd_soft_limit);
1457 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(fd_hard_limit);
1458 }
1459 if (ARG3) {
1460 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(fd_hard_limit) ||
1461 ((struct vki_rlimit64 *)ARG3)->rlim_max != VG_(fd_hard_limit)) {
1462 SET_STATUS_Failure( VKI_EPERM );
1463 }
1464 else {
1465 VG_(fd_soft_limit) = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1466 }
1467 }
1468 break;
1469
1470 case VKI_RLIMIT_DATA:
1471 SET_STATUS_Success( 0 );
1472 if (ARG4) {
1473 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_data).rlim_cur;
1474 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_data).rlim_max;
1475 }
1476 if (ARG3) {
1477 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
1478 ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_data).rlim_max) {
1479 SET_STATUS_Failure( VKI_EPERM );
1480 }
1481 else {
1482 VG_(client_rlimit_data).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1483 VG_(client_rlimit_data).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1484 }
1485 }
1486 break;
1487
1488 case VKI_RLIMIT_STACK:
1489 SET_STATUS_Success( 0 );
1490 if (ARG4) {
1491 ((struct vki_rlimit64 *)ARG4)->rlim_cur = VG_(client_rlimit_stack).rlim_cur;
1492 ((struct vki_rlimit64 *)ARG4)->rlim_max = VG_(client_rlimit_stack).rlim_max;
1493 }
1494 if (ARG3) {
1495 if (((struct vki_rlimit64 *)ARG3)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
1496 ((struct vki_rlimit64 *)ARG3)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
1497 SET_STATUS_Failure( VKI_EPERM );
1498 }
1499 else {
1500 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1501 VG_(client_rlimit_stack).rlim_cur = ((struct vki_rlimit64 *)ARG3)->rlim_cur;
1502 VG_(client_rlimit_stack).rlim_max = ((struct vki_rlimit64 *)ARG3)->rlim_max;
1503 }
1504 }
1505 break;
1506 }
1507 }
tom46d02ab2011-06-08 09:55:54 +00001508}
1509
1510POST(sys_prlimit64)
1511{
tomaba260b2012-03-01 13:42:18 +00001512 if (ARG4)
tom46d02ab2011-06-08 09:55:54 +00001513 POST_MEM_WRITE( ARG4, sizeof(struct vki_rlimit64) );
tom46d02ab2011-06-08 09:55:54 +00001514}
1515
njn73975482005-08-30 02:45:44 +00001516/* ---------------------------------------------------------------------
1517 tid-related wrappers
1518 ------------------------------------------------------------------ */
1519
sewardj8c257322005-06-08 01:01:48 +00001520PRE(sys_gettid)
1521{
1522 PRINT("sys_gettid ()");
1523 PRE_REG_READ0(long, "gettid");
1524}
1525
njn73975482005-08-30 02:45:44 +00001526PRE(sys_set_tid_address)
1527{
barta0b6b2c2008-07-07 06:49:24 +00001528 PRINT("sys_set_tid_address ( %#lx )", ARG1);
njn73975482005-08-30 02:45:44 +00001529 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
1530}
1531
tomc8cfca62006-02-15 10:34:50 +00001532PRE(sys_tkill)
1533{
barta0b6b2c2008-07-07 06:49:24 +00001534 PRINT("sys_tgkill ( %ld, %ld )", ARG1,ARG2);
tomc8cfca62006-02-15 10:34:50 +00001535 PRE_REG_READ2(long, "tkill", int, tid, int, sig);
1536 if (!ML_(client_signal_OK)(ARG2)) {
1537 SET_STATUS_Failure( VKI_EINVAL );
1538 return;
1539 }
1540
1541 /* Check to see if this kill gave us a pending signal */
1542 *flags |= SfPollAfter;
1543
1544 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001545 VG_(message)(Vg_DebugMsg, "tkill: sending signal %ld to pid %ld\n",
tomc8cfca62006-02-15 10:34:50 +00001546 ARG2, ARG1);
1547
1548 /* If we're sending SIGKILL, check to see if the target is one of
1549 our threads and handle it specially. */
1550 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) {
1551 SET_STATUS_Success(0);
1552 return;
1553 }
1554
1555 /* Ask to handle this syscall via the slow route, since that's the
1556 only one that sets tst->status to VgTs_WaitSys. If the result
1557 of doing the syscall is an immediate run of
1558 async_signalhandler() in m_signals, then we need the thread to
1559 be properly tidied away. I have the impression the previous
1560 version of this wrapper worked on x86/amd64 only because the
1561 kernel did not immediately deliver the async signal to this
1562 thread (on ppc it did, which broke the assertion re tst->status
1563 at the top of async_signalhandler()). */
1564 *flags |= SfMayBlock;
1565}
1566POST(sys_tkill)
1567{
1568 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001569 VG_(message)(Vg_DebugMsg, "tkill: sent signal %ld to pid %ld\n",
tomc8cfca62006-02-15 10:34:50 +00001570 ARG2, ARG1);
1571}
sewardjbc22cf72005-06-08 00:02:49 +00001572
1573PRE(sys_tgkill)
1574{
barta0b6b2c2008-07-07 06:49:24 +00001575 PRINT("sys_tgkill ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
sewardjbc22cf72005-06-08 00:02:49 +00001576 PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
sewardj7eb7c582005-06-23 01:02:53 +00001577 if (!ML_(client_signal_OK)(ARG3)) {
sewardjbc22cf72005-06-08 00:02:49 +00001578 SET_STATUS_Failure( VKI_EINVAL );
1579 return;
1580 }
1581
sewardjbc22cf72005-06-08 00:02:49 +00001582 /* Check to see if this kill gave us a pending signal */
1583 *flags |= SfPollAfter;
sewardjd6e91bc2005-11-17 14:26:52 +00001584
1585 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001586 VG_(message)(Vg_DebugMsg,
1587 "tgkill: sending signal %ld to pid %ld/%ld\n",
sewardjd6e91bc2005-11-17 14:26:52 +00001588 ARG3, ARG1, ARG2);
1589
1590 /* If we're sending SIGKILL, check to see if the target is one of
1591 our threads and handle it specially. */
1592 if (ARG3 == VKI_SIGKILL && ML_(do_sigkill)(ARG2, ARG1)) {
1593 SET_STATUS_Success(0);
1594 return;
1595 }
1596
1597 /* Ask to handle this syscall via the slow route, since that's the
1598 only one that sets tst->status to VgTs_WaitSys. If the result
1599 of doing the syscall is an immediate run of
1600 async_signalhandler() in m_signals, then we need the thread to
1601 be properly tidied away. I have the impression the previous
1602 version of this wrapper worked on x86/amd64 only because the
1603 kernel did not immediately deliver the async signal to this
1604 thread (on ppc it did, which broke the assertion re tst->status
1605 at the top of async_signalhandler()). */
1606 *flags |= SfMayBlock;
sewardjbc22cf72005-06-08 00:02:49 +00001607}
sewardjbc22cf72005-06-08 00:02:49 +00001608POST(sys_tgkill)
1609{
1610 if (VG_(clo_trace_signals))
sewardj738856f2009-07-15 14:48:32 +00001611 VG_(message)(Vg_DebugMsg,
1612 "tgkill: sent signal %ld to pid %ld/%ld\n",
sewardjbc22cf72005-06-08 00:02:49 +00001613 ARG3, ARG1, ARG2);
1614}
1615
njn73975482005-08-30 02:45:44 +00001616/* ---------------------------------------------------------------------
1617 fadvise64* wrappers
1618 ------------------------------------------------------------------ */
1619
tom72440832005-06-15 10:31:10 +00001620PRE(sys_fadvise64)
1621{
barta0b6b2c2008-07-07 06:49:24 +00001622 PRINT("sys_fadvise64 ( %ld, %lld, %lu, %ld )",
tomca787242009-11-25 11:24:00 +00001623 ARG1, MERGE64(ARG2,ARG3), ARG4, ARG5);
tom20d35722005-07-27 22:57:18 +00001624 PRE_REG_READ5(long, "fadvise64",
tomca787242009-11-25 11:24:00 +00001625 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
tom20d35722005-07-27 22:57:18 +00001626 vki_size_t, len, int, advice);
tom72440832005-06-15 10:31:10 +00001627}
1628
1629PRE(sys_fadvise64_64)
1630{
barta0b6b2c2008-07-07 06:49:24 +00001631 PRINT("sys_fadvise64_64 ( %ld, %lld, %lld, %ld )",
tomca787242009-11-25 11:24:00 +00001632 ARG1, MERGE64(ARG2,ARG3), MERGE64(ARG4,ARG5), ARG6);
tom20d35722005-07-27 22:57:18 +00001633 PRE_REG_READ6(long, "fadvise64_64",
tomca787242009-11-25 11:24:00 +00001634 int, fd, vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset),
1635 vki_u32, MERGE64_FIRST(len), vki_u32, MERGE64_SECOND(len), int, advice);
tom72440832005-06-15 10:31:10 +00001636}
sewardje6d5e722005-06-10 10:27:55 +00001637
njn73975482005-08-30 02:45:44 +00001638/* ---------------------------------------------------------------------
1639 io_* wrappers
1640 ------------------------------------------------------------------ */
1641
sewardje6d5e722005-06-10 10:27:55 +00001642// Nb: this wrapper has to pad/unpad memory around the syscall itself,
1643// and this allows us to control exactly the code that gets run while
1644// the padding is in place.
sewardj45f4e7c2005-09-27 19:20:21 +00001645
sewardje6d5e722005-06-10 10:27:55 +00001646PRE(sys_io_setup)
1647{
barta0b6b2c2008-07-07 06:49:24 +00001648 PRINT("sys_io_setup ( %lu, %#lx )", ARG1,ARG2);
sewardje6d5e722005-06-10 10:27:55 +00001649 PRE_REG_READ2(long, "io_setup",
1650 unsigned, nr_events, vki_aio_context_t *, ctxp);
1651 PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
sewardj45f4e7c2005-09-27 19:20:21 +00001652}
1653
1654POST(sys_io_setup)
1655{
1656 SizeT size;
1657 struct vki_aio_ring *r;
1658
sewardje6d5e722005-06-10 10:27:55 +00001659 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1660 ARG1*sizeof(struct vki_io_event));
sewardj45f4e7c2005-09-27 19:20:21 +00001661 r = *(struct vki_aio_ring **)ARG2;
1662 vg_assert(ML_(valid_client_addr)((Addr)r, size, tid, "io_setup"));
sewardje6d5e722005-06-10 10:27:55 +00001663
njndd372582009-05-10 22:42:19 +00001664 ML_(notify_core_and_tool_of_mmap)( (Addr)r, size,
1665 VKI_PROT_READ | VKI_PROT_WRITE,
1666 VKI_MAP_ANONYMOUS, -1, 0 );
sewardje6d5e722005-06-10 10:27:55 +00001667
sewardj45f4e7c2005-09-27 19:20:21 +00001668 POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
sewardje6d5e722005-06-10 10:27:55 +00001669}
1670
1671// Nb: This wrapper is "Special" because we need 'size' to do the unmap
1672// after the syscall. We must get 'size' from the aio_ring structure,
1673// before the syscall, while the aio_ring structure still exists. (And we
1674// know that we must look at the aio_ring structure because Tom inspected the
1675// kernel and glibc sources to see what they do, yuk.)
1676//
1677// XXX This segment can be implicitly unmapped when aio
1678// file-descriptors are closed...
1679PRE(sys_io_destroy)
sewardj45f4e7c2005-09-27 19:20:21 +00001680{
sewardj5abf0f12007-11-17 01:49:06 +00001681 SizeT size = 0;
sewardje6d5e722005-06-10 10:27:55 +00001682
1683 PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
1684 PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
1685
1686 // If we are going to seg fault (due to a bogus ARG1) do it as late as
1687 // possible...
sewardj5abf0f12007-11-17 01:49:06 +00001688 if (ML_(safe_to_deref)( (void*)ARG1, sizeof(struct vki_aio_ring))) {
1689 struct vki_aio_ring *r = (struct vki_aio_ring *)ARG1;
1690 size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
1691 r->nr*sizeof(struct vki_io_event));
1692 }
sewardje6d5e722005-06-10 10:27:55 +00001693
1694 SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
1695
sewardj45f4e7c2005-09-27 19:20:21 +00001696 if (SUCCESS && RES == 0) {
1697 Bool d = VG_(am_notify_munmap)( ARG1, size );
sewardje6d5e722005-06-10 10:27:55 +00001698 VG_TRACK( die_mem_munmap, ARG1, size );
sewardj45f4e7c2005-09-27 19:20:21 +00001699 if (d)
1700 VG_(discard_translations)( (Addr64)ARG1, (ULong)size,
1701 "PRE(sys_io_destroy)" );
sewardje6d5e722005-06-10 10:27:55 +00001702 }
1703}
1704
1705PRE(sys_io_getevents)
1706{
1707 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00001708 PRINT("sys_io_getevents ( %llu, %lld, %lld, %#lx, %#lx )",
sewardje6d5e722005-06-10 10:27:55 +00001709 (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
1710 PRE_REG_READ5(long, "io_getevents",
1711 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
1712 struct io_event *, events,
1713 struct timespec *, timeout);
1714 if (ARG3 > 0)
1715 PRE_MEM_WRITE( "io_getevents(events)",
1716 ARG4, sizeof(struct vki_io_event)*ARG3 );
1717 if (ARG5 != 0)
1718 PRE_MEM_READ( "io_getevents(timeout)",
1719 ARG5, sizeof(struct vki_timespec));
1720}
1721POST(sys_io_getevents)
1722{
1723 Int i;
1724 vg_assert(SUCCESS);
1725 if (RES > 0) {
1726 POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
1727 for (i = 0; i < RES; i++) {
1728 const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
1729 const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
1730
1731 switch (cb->aio_lio_opcode) {
1732 case VKI_IOCB_CMD_PREAD:
1733 if (vev->result > 0)
1734 POST_MEM_WRITE( cb->aio_buf, vev->result );
1735 break;
tom9c85af72009-10-28 16:03:29 +00001736
sewardje6d5e722005-06-10 10:27:55 +00001737 case VKI_IOCB_CMD_PWRITE:
1738 break;
tom9c85af72009-10-28 16:03:29 +00001739
1740 case VKI_IOCB_CMD_FSYNC:
1741 break;
1742
1743 case VKI_IOCB_CMD_FDSYNC:
1744 break;
1745
1746 case VKI_IOCB_CMD_PREADV:
1747 if (vev->result > 0) {
1748 struct vki_iovec * vec = (struct vki_iovec *)(Addr)cb->aio_buf;
1749 Int remains = vev->result;
1750 Int j;
1751
1752 for (j = 0; j < cb->aio_nbytes; j++) {
1753 Int nReadThisBuf = vec[j].iov_len;
1754 if (nReadThisBuf > remains) nReadThisBuf = remains;
1755 POST_MEM_WRITE( (Addr)vec[j].iov_base, nReadThisBuf );
1756 remains -= nReadThisBuf;
1757 if (remains < 0) VG_(core_panic)("io_getevents(PREADV): remains < 0");
1758 }
1759 }
1760 break;
1761
1762 case VKI_IOCB_CMD_PWRITEV:
1763 break;
1764
sewardje6d5e722005-06-10 10:27:55 +00001765 default:
1766 VG_(message)(Vg_DebugMsg,
1767 "Warning: unhandled io_getevents opcode: %u\n",
1768 cb->aio_lio_opcode);
1769 break;
1770 }
1771 }
1772 }
1773}
1774
1775PRE(sys_io_submit)
1776{
tom9c85af72009-10-28 16:03:29 +00001777 Int i, j;
sewardje6d5e722005-06-10 10:27:55 +00001778
barta0b6b2c2008-07-07 06:49:24 +00001779 PRINT("sys_io_submit ( %llu, %ld, %#lx )", (ULong)ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +00001780 PRE_REG_READ3(long, "io_submit",
1781 vki_aio_context_t, ctx_id, long, nr,
1782 struct iocb **, iocbpp);
1783 PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
1784 if (ARG3 != 0) {
1785 for (i = 0; i < ARG2; i++) {
1786 struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
tom9c85af72009-10-28 16:03:29 +00001787 struct vki_iovec *iov;
1788
sewardje6d5e722005-06-10 10:27:55 +00001789 PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
1790 switch (cb->aio_lio_opcode) {
1791 case VKI_IOCB_CMD_PREAD:
1792 PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
1793 break;
1794
1795 case VKI_IOCB_CMD_PWRITE:
1796 PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
1797 break;
tom9c85af72009-10-28 16:03:29 +00001798
1799 case VKI_IOCB_CMD_FSYNC:
1800 break;
1801
1802 case VKI_IOCB_CMD_FDSYNC:
1803 break;
1804
1805 case VKI_IOCB_CMD_PREADV:
1806 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1807 PRE_MEM_READ( "io_submit(PREADV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1808 for (j = 0; j < cb->aio_nbytes; j++)
1809 PRE_MEM_WRITE( "io_submit(PREADV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1810 break;
1811
1812 case VKI_IOCB_CMD_PWRITEV:
1813 iov = (struct vki_iovec *)(Addr)cb->aio_buf;
1814 PRE_MEM_READ( "io_submit(PWRITEV)", cb->aio_buf, cb->aio_nbytes * sizeof(struct vki_iovec) );
1815 for (j = 0; j < cb->aio_nbytes; j++)
1816 PRE_MEM_READ( "io_submit(PWRITEV(iov[i]))", (Addr)iov[j].iov_base, iov[j].iov_len );
1817 break;
1818
sewardje6d5e722005-06-10 10:27:55 +00001819 default:
1820 VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
1821 cb->aio_lio_opcode);
1822 break;
1823 }
1824 }
1825 }
1826}
1827
1828PRE(sys_io_cancel)
1829{
barta0b6b2c2008-07-07 06:49:24 +00001830 PRINT("sys_io_cancel ( %llu, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +00001831 PRE_REG_READ3(long, "io_cancel",
1832 vki_aio_context_t, ctx_id, struct iocb *, iocb,
1833 struct io_event *, result);
1834 PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
1835 PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
1836}
sewardje6d5e722005-06-10 10:27:55 +00001837POST(sys_io_cancel)
1838{
1839 POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
1840}
1841
njn73975482005-08-30 02:45:44 +00001842/* ---------------------------------------------------------------------
1843 *_mempolicy wrappers
1844 ------------------------------------------------------------------ */
1845
tom70a5cb02005-10-20 17:00:23 +00001846PRE(sys_mbind)
1847{
barta0b6b2c2008-07-07 06:49:24 +00001848 PRINT("sys_mbind ( %#lx, %lu, %ld, %#lx, %lu, %lu )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
tom70a5cb02005-10-20 17:00:23 +00001849 PRE_REG_READ6(long, "mbind",
1850 unsigned long, start, unsigned long, len,
1851 unsigned long, policy, unsigned long *, nodemask,
1852 unsigned long, maxnode, unsigned, flags);
1853 if (ARG1 != 0)
1854 PRE_MEM_READ( "mbind(nodemask)", ARG4,
tome581bad2011-08-15 07:52:26 +00001855 VG_ROUNDUP( ARG5-1, sizeof(UWord) * 8 ) / 8 );
tom70a5cb02005-10-20 17:00:23 +00001856}
1857
tom2af58f22005-07-22 15:04:14 +00001858PRE(sys_set_mempolicy)
1859{
barta0b6b2c2008-07-07 06:49:24 +00001860 PRINT("sys_set_mempolicy ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
tom2af58f22005-07-22 15:04:14 +00001861 PRE_REG_READ3(long, "set_mempolicy",
1862 int, policy, unsigned long *, nodemask,
1863 unsigned long, maxnode);
1864 PRE_MEM_READ( "set_mempolicy(nodemask)", ARG2,
tome581bad2011-08-15 07:52:26 +00001865 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
tom2af58f22005-07-22 15:04:14 +00001866}
1867
1868PRE(sys_get_mempolicy)
1869{
barta0b6b2c2008-07-07 06:49:24 +00001870 PRINT("sys_get_mempolicy ( %#lx, %#lx, %ld, %#lx, %lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
tom2af58f22005-07-22 15:04:14 +00001871 PRE_REG_READ5(long, "get_mempolicy",
1872 int *, policy, unsigned long *, nodemask,
1873 unsigned long, maxnode, unsigned long, addr,
1874 unsigned long, flags);
1875 if (ARG1 != 0)
1876 PRE_MEM_WRITE( "get_mempolicy(policy)", ARG1, sizeof(Int) );
1877 if (ARG2 != 0)
1878 PRE_MEM_WRITE( "get_mempolicy(nodemask)", ARG2,
tome581bad2011-08-15 07:52:26 +00001879 VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
tom2af58f22005-07-22 15:04:14 +00001880}
1881POST(sys_get_mempolicy)
1882{
1883 if (ARG1 != 0)
1884 POST_MEM_WRITE( ARG1, sizeof(Int) );
1885 if (ARG2 != 0)
tome581bad2011-08-15 07:52:26 +00001886 POST_MEM_WRITE( ARG2, VG_ROUNDUP( ARG3-1, sizeof(UWord) * 8 ) / 8 );
tom2af58f22005-07-22 15:04:14 +00001887}
1888
njn73975482005-08-30 02:45:44 +00001889/* ---------------------------------------------------------------------
tomcec24b52013-07-17 13:58:59 +00001890 fanotify_* wrappers
1891 ------------------------------------------------------------------ */
1892
1893PRE(sys_fanotify_init)
1894{
1895 PRINT("sys_fanotify_init ( %lu, %lu )", ARG1,ARG2);
1896 PRE_REG_READ2(long, "fanotify_init",
1897 unsigned int, flags, unsigned int, event_f_flags);
1898}
1899
1900POST(sys_fanotify_init)
1901{
1902 vg_assert(SUCCESS);
1903 if (!ML_(fd_allowed)(RES, "fanotify_init", tid, True)) {
1904 VG_(close)(RES);
1905 SET_STATUS_Failure( VKI_EMFILE );
1906 } else {
1907 if (VG_(clo_track_fds))
1908 ML_(record_fd_open_nameless) (tid, RES);
1909 }
1910}
1911
1912PRE(sys_fanotify_mark)
1913{
1914#if VG_WORDSIZE == 4
1915 PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
1916 ARG1,ARG2,MERGE64(ARG3,ARG4),ARG5,ARG6,(char *)ARG6);
1917 PRE_REG_READ6(long, "sys_fanotify_mark",
1918 int, fanotify_fd, unsigned int, flags,
1919 __vki_u32, mask0, __vki_u32, mask1,
1920 int, dfd, const char *, pathname);
1921 if (ARG6)
1922 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG6);
1923#elif VG_WORDSIZE == 8
1924 PRINT( "sys_fanotify_mark ( %ld, %lu, %llu, %ld, %#lx(%s))",
1925 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5,(char *)ARG5);
1926 PRE_REG_READ5(long, "sys_fanotify_mark",
1927 int, fanotify_fd, unsigned int, flags,
1928 __vki_u64, mask,
1929 int, dfd, const char *, pathname);
1930 if (ARG5)
1931 PRE_MEM_RASCIIZ( "fanotify_mark(path)", ARG5);
1932#else
1933# error Unexpected word size
1934#endif
1935}
1936
1937/* ---------------------------------------------------------------------
njn73975482005-08-30 02:45:44 +00001938 inotify_* wrappers
1939 ------------------------------------------------------------------ */
1940
tom0bcaf2a2005-07-25 15:21:41 +00001941PRE(sys_inotify_init)
1942{
1943 PRINT("sys_inotify_init ( )");
1944 PRE_REG_READ0(long, "inotify_init");
1945}
1946POST(sys_inotify_init)
1947{
1948 vg_assert(SUCCESS);
1949 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
1950 VG_(close)(RES);
1951 SET_STATUS_Failure( VKI_EMFILE );
1952 } else {
1953 if (VG_(clo_track_fds))
1954 ML_(record_fd_open_nameless) (tid, RES);
1955 }
1956}
1957
tom7bb1b1c2009-10-27 14:17:27 +00001958PRE(sys_inotify_init1)
1959{
1960 PRINT("sys_inotify_init ( %ld )", ARG1);
1961 PRE_REG_READ1(long, "inotify_init", int, flag);
1962}
1963
1964POST(sys_inotify_init1)
1965{
1966 vg_assert(SUCCESS);
1967 if (!ML_(fd_allowed)(RES, "inotify_init", tid, True)) {
1968 VG_(close)(RES);
1969 SET_STATUS_Failure( VKI_EMFILE );
1970 } else {
1971 if (VG_(clo_track_fds))
1972 ML_(record_fd_open_nameless) (tid, RES);
1973 }
1974}
1975
tom0bcaf2a2005-07-25 15:21:41 +00001976PRE(sys_inotify_add_watch)
1977{
barta0b6b2c2008-07-07 06:49:24 +00001978 PRINT( "sys_inotify_add_watch ( %ld, %#lx, %lx )", ARG1,ARG2,ARG3);
tom0bcaf2a2005-07-25 15:21:41 +00001979 PRE_REG_READ3(long, "inotify_add_watch", int, fd, char *, path, int, mask);
1980 PRE_MEM_RASCIIZ( "inotify_add_watch(path)", ARG2 );
1981}
1982
1983PRE(sys_inotify_rm_watch)
1984{
barta0b6b2c2008-07-07 06:49:24 +00001985 PRINT( "sys_inotify_rm_watch ( %ld, %lx )", ARG1,ARG2);
tom0bcaf2a2005-07-25 15:21:41 +00001986 PRE_REG_READ2(long, "inotify_rm_watch", int, fd, int, wd);
1987}
1988
njn73975482005-08-30 02:45:44 +00001989/* ---------------------------------------------------------------------
1990 mq_* wrappers
1991 ------------------------------------------------------------------ */
1992
njn4279a882005-08-26 03:43:28 +00001993PRE(sys_mq_open)
1994{
barta0b6b2c2008-07-07 06:49:24 +00001995 PRINT("sys_mq_open( %#lx(%s), %ld, %lld, %#lx )",
1996 ARG1,(char*)ARG1,ARG2,(ULong)ARG3,ARG4);
njn4279a882005-08-26 03:43:28 +00001997 PRE_REG_READ4(long, "mq_open",
1998 const char *, name, int, oflag, vki_mode_t, mode,
1999 struct mq_attr *, attr);
2000 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
2001 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
2002 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
2003 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
2004 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
2005 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
2006 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
2007 }
2008}
njn4279a882005-08-26 03:43:28 +00002009POST(sys_mq_open)
2010{
2011 vg_assert(SUCCESS);
2012 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
2013 VG_(close)(RES);
2014 SET_STATUS_Failure( VKI_EMFILE );
2015 } else {
2016 if (VG_(clo_track_fds))
florian1636d332012-11-15 04:27:04 +00002017 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1);
njn4279a882005-08-26 03:43:28 +00002018 }
2019}
2020
2021PRE(sys_mq_unlink)
2022{
barta0b6b2c2008-07-07 06:49:24 +00002023 PRINT("sys_mq_unlink ( %#lx(%s) )", ARG1,(char*)ARG1);
njn4279a882005-08-26 03:43:28 +00002024 PRE_REG_READ1(long, "mq_unlink", const char *, name);
2025 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
2026}
2027
2028PRE(sys_mq_timedsend)
2029{
2030 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002031 PRINT("sys_mq_timedsend ( %ld, %#lx, %llu, %ld, %#lx )",
njn4279a882005-08-26 03:43:28 +00002032 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
2033 PRE_REG_READ5(long, "mq_timedsend",
2034 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
2035 unsigned int, msg_prio, const struct timespec *, abs_timeout);
2036 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
2037 SET_STATUS_Failure( VKI_EBADF );
2038 } else {
2039 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
2040 if (ARG5 != 0)
2041 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
2042 sizeof(struct vki_timespec) );
2043 }
2044}
2045
2046PRE(sys_mq_timedreceive)
2047{
2048 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002049 PRINT("sys_mq_timedreceive( %ld, %#lx, %llu, %#lx, %#lx )",
njn4279a882005-08-26 03:43:28 +00002050 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
2051 PRE_REG_READ5(ssize_t, "mq_timedreceive",
2052 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
2053 unsigned int *, msg_prio,
2054 const struct timespec *, abs_timeout);
2055 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
2056 SET_STATUS_Failure( VKI_EBADF );
2057 } else {
2058 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
2059 if (ARG4 != 0)
2060 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
2061 ARG4, sizeof(unsigned int) );
2062 if (ARG5 != 0)
2063 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
2064 ARG5, sizeof(struct vki_timespec) );
2065 }
2066}
njn4279a882005-08-26 03:43:28 +00002067POST(sys_mq_timedreceive)
2068{
tom44e534d2010-05-24 13:40:10 +00002069 POST_MEM_WRITE( ARG2, RES );
njn4279a882005-08-26 03:43:28 +00002070 if (ARG4 != 0)
2071 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
2072}
2073
2074PRE(sys_mq_notify)
2075{
barta0b6b2c2008-07-07 06:49:24 +00002076 PRINT("sys_mq_notify( %ld, %#lx )", ARG1,ARG2 );
njn4279a882005-08-26 03:43:28 +00002077 PRE_REG_READ2(long, "mq_notify",
2078 vki_mqd_t, mqdes, const struct sigevent *, notification);
2079 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
2080 SET_STATUS_Failure( VKI_EBADF );
2081 else if (ARG2 != 0)
2082 PRE_MEM_READ( "mq_notify(notification)",
2083 ARG2, sizeof(struct vki_sigevent) );
2084}
2085
2086PRE(sys_mq_getsetattr)
2087{
barta0b6b2c2008-07-07 06:49:24 +00002088 PRINT("sys_mq_getsetattr( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3 );
njn4279a882005-08-26 03:43:28 +00002089 PRE_REG_READ3(long, "mq_getsetattr",
2090 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
2091 struct mq_attr *, omqstat);
2092 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
2093 SET_STATUS_Failure( VKI_EBADF );
2094 } else {
2095 if (ARG2 != 0) {
2096 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
2097 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
2098 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
2099 }
2100 if (ARG3 != 0)
2101 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
2102 sizeof(struct vki_mq_attr) );
2103 }
2104}
njn4279a882005-08-26 03:43:28 +00002105POST(sys_mq_getsetattr)
2106{
2107 if (ARG3 != 0)
2108 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
2109}
2110
njn73975482005-08-30 02:45:44 +00002111/* ---------------------------------------------------------------------
2112 clock_* wrappers
2113 ------------------------------------------------------------------ */
2114
njn1588bc02005-08-26 03:49:43 +00002115PRE(sys_clock_settime)
2116{
barta0b6b2c2008-07-07 06:49:24 +00002117 PRINT("sys_clock_settime( %ld, %#lx )", ARG1,ARG2);
njn1588bc02005-08-26 03:49:43 +00002118 PRE_REG_READ2(long, "clock_settime",
2119 vki_clockid_t, clk_id, const struct timespec *, tp);
2120 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
2121}
2122
2123PRE(sys_clock_gettime)
2124{
barta0b6b2c2008-07-07 06:49:24 +00002125 PRINT("sys_clock_gettime( %ld, %#lx )" , ARG1,ARG2);
njn1588bc02005-08-26 03:49:43 +00002126 PRE_REG_READ2(long, "clock_gettime",
2127 vki_clockid_t, clk_id, struct timespec *, tp);
2128 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
2129}
2130POST(sys_clock_gettime)
2131{
2132 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2133}
2134
2135PRE(sys_clock_getres)
2136{
barta0b6b2c2008-07-07 06:49:24 +00002137 PRINT("sys_clock_getres( %ld, %#lx )" , ARG1,ARG2);
njn1588bc02005-08-26 03:49:43 +00002138 // Nb: we can't use "RES" as the param name because that's a macro
2139 // defined above!
2140 PRE_REG_READ2(long, "clock_getres",
2141 vki_clockid_t, clk_id, struct timespec *, res);
2142 if (ARG2 != 0)
2143 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
2144}
2145POST(sys_clock_getres)
2146{
2147 if (ARG2 != 0)
2148 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
2149}
2150
2151PRE(sys_clock_nanosleep)
2152{
2153 *flags |= SfMayBlock|SfPostOnFail;
barta0b6b2c2008-07-07 06:49:24 +00002154 PRINT("sys_clock_nanosleep( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
njn1588bc02005-08-26 03:49:43 +00002155 PRE_REG_READ4(int32_t, "clock_nanosleep",
2156 vki_clockid_t, clkid, int, flags,
2157 const struct timespec *, rqtp, struct timespec *, rmtp);
2158 PRE_MEM_READ( "clock_nanosleep(rqtp)", ARG3, sizeof(struct vki_timespec) );
2159 if (ARG4 != 0)
2160 PRE_MEM_WRITE( "clock_nanosleep(rmtp)", ARG4, sizeof(struct vki_timespec) );
2161}
2162POST(sys_clock_nanosleep)
2163{
sewardjef1cf8b2006-10-17 01:47:30 +00002164 if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
njn1588bc02005-08-26 03:49:43 +00002165 POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
2166}
2167
njn73975482005-08-30 02:45:44 +00002168/* ---------------------------------------------------------------------
2169 timer_* wrappers
2170 ------------------------------------------------------------------ */
2171
njn424c0562005-08-26 03:54:30 +00002172PRE(sys_timer_create)
2173{
barta0b6b2c2008-07-07 06:49:24 +00002174 PRINT("sys_timer_create( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
njn424c0562005-08-26 03:54:30 +00002175 PRE_REG_READ3(long, "timer_create",
2176 vki_clockid_t, clockid, struct sigevent *, evp,
2177 vki_timer_t *, timerid);
mjw40bb7832014-02-24 10:38:45 +00002178 if (ARG2 != 0) {
2179 struct vki_sigevent *evp = (struct vki_sigevent *) ARG2;
2180 PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
2181 sizeof(vki_sigval_t) );
2182 PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
2183 sizeof(int) );
2184 PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
2185 sizeof(int) );
mjw812e2f92014-02-24 15:09:21 +00002186 if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
2187 && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
mjw40bb7832014-02-24 10:38:45 +00002188 PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
2189 (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
2190 }
njn424c0562005-08-26 03:54:30 +00002191 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
2192}
2193POST(sys_timer_create)
2194{
2195 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
2196}
2197
2198PRE(sys_timer_settime)
2199{
barta0b6b2c2008-07-07 06:49:24 +00002200 PRINT("sys_timer_settime( %lld, %ld, %#lx, %#lx )", (ULong)ARG1,ARG2,ARG3,ARG4);
njn424c0562005-08-26 03:54:30 +00002201 PRE_REG_READ4(long, "timer_settime",
2202 vki_timer_t, timerid, int, flags,
2203 const struct itimerspec *, value,
2204 struct itimerspec *, ovalue);
2205 PRE_MEM_READ( "timer_settime(value)", ARG3,
2206 sizeof(struct vki_itimerspec) );
2207 if (ARG4 != 0)
2208 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
2209 sizeof(struct vki_itimerspec) );
2210}
2211POST(sys_timer_settime)
2212{
2213 if (ARG4 != 0)
2214 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
2215}
2216
2217PRE(sys_timer_gettime)
2218{
barta0b6b2c2008-07-07 06:49:24 +00002219 PRINT("sys_timer_gettime( %lld, %#lx )", (ULong)ARG1,ARG2);
njn424c0562005-08-26 03:54:30 +00002220 PRE_REG_READ2(long, "timer_gettime",
2221 vki_timer_t, timerid, struct itimerspec *, value);
2222 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
2223 sizeof(struct vki_itimerspec));
2224}
2225POST(sys_timer_gettime)
2226{
2227 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
2228}
2229
2230PRE(sys_timer_getoverrun)
2231{
barta0b6b2c2008-07-07 06:49:24 +00002232 PRINT("sys_timer_getoverrun( %#lx )", ARG1);
njn424c0562005-08-26 03:54:30 +00002233 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
2234}
2235
2236PRE(sys_timer_delete)
2237{
barta0b6b2c2008-07-07 06:49:24 +00002238 PRINT("sys_timer_delete( %#lx )", ARG1);
njn424c0562005-08-26 03:54:30 +00002239 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
2240}
2241
bart5fc7da22008-04-27 12:56:06 +00002242/* ---------------------------------------------------------------------
2243 timerfd* wrappers
2244 See also http://lwn.net/Articles/260172/ for an overview.
2245 See also /usr/src/linux/fs/timerfd.c for the implementation.
2246 ------------------------------------------------------------------ */
2247
sewardj212d6c92008-05-28 11:06:08 +00002248/* Returns True if running on 2.6.22, else False (or False if
2249 cannot be determined). */
2250static Bool linux_kernel_2_6_22(void)
bartf5ceec82008-04-26 07:45:10 +00002251{
sewardj212d6c92008-05-28 11:06:08 +00002252 static Int result = -1;
2253 Int fd, read;
2254 HChar release[64];
2255 SysRes res;
bart5fc7da22008-04-27 12:56:06 +00002256
sewardj212d6c92008-05-28 11:06:08 +00002257 if (result == -1) {
2258 res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
njncda2f0f2009-05-18 02:12:08 +00002259 if (sr_isError(res))
sewardj212d6c92008-05-28 11:06:08 +00002260 return False;
njncda2f0f2009-05-18 02:12:08 +00002261 fd = sr_Res(res);
sewardj212d6c92008-05-28 11:06:08 +00002262 read = VG_(read)(fd, release, sizeof(release) - 1);
2263 vg_assert(read >= 0);
2264 release[read] = 0;
2265 VG_(close)(fd);
2266 //VG_(printf)("kernel release = %s\n", release);
2267 result = (VG_(strncmp)(release, "2.6.22", 6) == 0
2268 && (release[6] < '0' || release[6] > '9'));
2269 }
2270 vg_assert(result == 0 || result == 1);
2271 return result == 1;
bartf5ceec82008-04-26 07:45:10 +00002272}
bart5fc7da22008-04-27 12:56:06 +00002273
2274PRE(sys_timerfd_create)
bartf5ceec82008-04-26 07:45:10 +00002275{
sewardj212d6c92008-05-28 11:06:08 +00002276 if (linux_kernel_2_6_22()) {
bart5fc7da22008-04-27 12:56:06 +00002277 /* 2.6.22 kernel: timerfd system call. */
barta0b6b2c2008-07-07 06:49:24 +00002278 PRINT("sys_timerfd ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
bart5fc7da22008-04-27 12:56:06 +00002279 PRE_REG_READ3(long, "sys_timerfd",
2280 int, fd, int, clockid, const struct itimerspec *, tmr);
2281 PRE_MEM_READ("timerfd(tmr)", ARG3,
2282 sizeof(struct vki_itimerspec) );
sewardj212d6c92008-05-28 11:06:08 +00002283 if ((Word)ARG1 != -1L && !ML_(fd_allowed)(ARG1, "timerfd", tid, False))
bart5fc7da22008-04-27 12:56:06 +00002284 SET_STATUS_Failure( VKI_EBADF );
sewardj212d6c92008-05-28 11:06:08 +00002285 } else {
bart5fc7da22008-04-27 12:56:06 +00002286 /* 2.6.24 and later kernels: timerfd_create system call. */
sewardj212d6c92008-05-28 11:06:08 +00002287 PRINT("sys_timerfd_create (%ld, %ld )", ARG1, ARG2);
2288 PRE_REG_READ2(long, "timerfd_create", int, clockid, int, flags);
2289 }
bart5fc7da22008-04-27 12:56:06 +00002290}
2291POST(sys_timerfd_create)
2292{
2293 if (linux_kernel_2_6_22())
2294 {
2295 /* 2.6.22 kernel: timerfd system call. */
2296 if (!ML_(fd_allowed)(RES, "timerfd", tid, True)) {
2297 VG_(close)(RES);
2298 SET_STATUS_Failure( VKI_EMFILE );
2299 } else {
2300 if (VG_(clo_track_fds))
2301 ML_(record_fd_open_nameless) (tid, RES);
2302 }
bartf5ceec82008-04-26 07:45:10 +00002303 }
bart5fc7da22008-04-27 12:56:06 +00002304 else
2305 {
2306 /* 2.6.24 and later kernels: timerfd_create system call. */
2307 if (!ML_(fd_allowed)(RES, "timerfd_create", tid, True)) {
2308 VG_(close)(RES);
2309 SET_STATUS_Failure( VKI_EMFILE );
2310 } else {
2311 if (VG_(clo_track_fds))
2312 ML_(record_fd_open_nameless) (tid, RES);
2313 }
2314 }
2315}
2316
2317PRE(sys_timerfd_gettime)
2318{
barta0b6b2c2008-07-07 06:49:24 +00002319 PRINT("sys_timerfd_gettime ( %ld, %#lx )", ARG1, ARG2);
bart5fc7da22008-04-27 12:56:06 +00002320 PRE_REG_READ2(long, "timerfd_gettime",
2321 int, ufd,
2322 struct vki_itimerspec*, otmr);
2323 if (!ML_(fd_allowed)(ARG1, "timerfd_gettime", tid, False))
2324 SET_STATUS_Failure(VKI_EBADF);
2325 else
2326 PRE_MEM_WRITE("timerfd_gettime(result)",
2327 ARG2, sizeof(struct vki_itimerspec));
2328}
2329POST(sys_timerfd_gettime)
2330{
2331 if (RES == 0)
2332 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerspec));
2333}
2334
2335PRE(sys_timerfd_settime)
2336{
barta0b6b2c2008-07-07 06:49:24 +00002337 PRINT("sys_timerfd_settime ( %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
bart5fc7da22008-04-27 12:56:06 +00002338 PRE_REG_READ4(long, "timerfd_settime",
2339 int, ufd,
2340 int, flags,
2341 const struct vki_itimerspec*, utmr,
2342 struct vki_itimerspec*, otmr);
2343 if (!ML_(fd_allowed)(ARG1, "timerfd_settime", tid, False))
2344 SET_STATUS_Failure(VKI_EBADF);
2345 else
2346 {
2347 PRE_MEM_READ("timerfd_settime(result)",
2348 ARG3, sizeof(struct vki_itimerspec));
2349 if (ARG4)
2350 {
2351 PRE_MEM_WRITE("timerfd_settime(result)",
2352 ARG4, sizeof(struct vki_itimerspec));
2353 }
2354 }
2355}
2356POST(sys_timerfd_settime)
2357{
2358 if (RES == 0 && ARG4 != 0)
2359 POST_MEM_WRITE(ARG4, sizeof(struct vki_itimerspec));
bartf5ceec82008-04-26 07:45:10 +00002360}
2361
njn73975482005-08-30 02:45:44 +00002362/* ---------------------------------------------------------------------
2363 capabilities wrappers
2364 ------------------------------------------------------------------ */
2365
njn9fe7b122005-08-26 04:03:04 +00002366PRE(sys_capget)
2367{
barta0b6b2c2008-07-07 06:49:24 +00002368 PRINT("sys_capget ( %#lx, %#lx )", ARG1, ARG2 );
njn9fe7b122005-08-26 04:03:04 +00002369 PRE_REG_READ2(long, "capget",
2370 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2371 PRE_MEM_READ( "capget(header)", ARG1,
2372 sizeof(struct __vki_user_cap_header_struct) );
tom199c15b2012-10-04 21:38:27 +00002373 if (ARG2 != (Addr)NULL)
2374 PRE_MEM_WRITE( "capget(data)", ARG2,
2375 sizeof(struct __vki_user_cap_data_struct) );
njn9fe7b122005-08-26 04:03:04 +00002376}
2377POST(sys_capget)
2378{
2379 if (ARG2 != (Addr)NULL)
2380 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2381}
2382
2383PRE(sys_capset)
2384{
barta0b6b2c2008-07-07 06:49:24 +00002385 PRINT("sys_capset ( %#lx, %#lx )", ARG1, ARG2 );
njn9fe7b122005-08-26 04:03:04 +00002386 PRE_REG_READ2(long, "capset",
2387 vki_cap_user_header_t, header,
2388 const vki_cap_user_data_t, data);
2389 PRE_MEM_READ( "capset(header)",
2390 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2391 PRE_MEM_READ( "capset(data)",
2392 ARG2, sizeof(struct __vki_user_cap_data_struct) );
2393}
2394
njn73975482005-08-30 02:45:44 +00002395/* ---------------------------------------------------------------------
2396 16-bit uid/gid/groups wrappers
2397 ------------------------------------------------------------------ */
2398
njna3b67b72005-08-26 04:27:54 +00002399PRE(sys_getuid16)
2400{
2401 PRINT("sys_getuid16 ( )");
2402 PRE_REG_READ0(long, "getuid16");
2403}
2404
2405PRE(sys_setuid16)
2406{
barta0b6b2c2008-07-07 06:49:24 +00002407 PRINT("sys_setuid16 ( %ld )", ARG1);
njna3b67b72005-08-26 04:27:54 +00002408 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
2409}
2410
2411PRE(sys_getgid16)
2412{
2413 PRINT("sys_getgid16 ( )");
2414 PRE_REG_READ0(long, "getgid16");
2415}
2416
2417PRE(sys_setgid16)
2418{
barta0b6b2c2008-07-07 06:49:24 +00002419 PRINT("sys_setgid16 ( %ld )", ARG1);
njna3b67b72005-08-26 04:27:54 +00002420 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
2421}
2422
2423PRE(sys_geteuid16)
2424{
2425 PRINT("sys_geteuid16 ( )");
2426 PRE_REG_READ0(long, "geteuid16");
2427}
2428
2429PRE(sys_getegid16)
2430{
2431 PRINT("sys_getegid16 ( )");
2432 PRE_REG_READ0(long, "getegid16");
2433}
2434
2435PRE(sys_setreuid16)
2436{
barta0b6b2c2008-07-07 06:49:24 +00002437 PRINT("setreuid16 ( 0x%lx, 0x%lx )", ARG1, ARG2);
njna3b67b72005-08-26 04:27:54 +00002438 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
2439}
2440
2441PRE(sys_setregid16)
2442{
barta0b6b2c2008-07-07 06:49:24 +00002443 PRINT("sys_setregid16 ( %ld, %ld )", ARG1, ARG2);
njna3b67b72005-08-26 04:27:54 +00002444 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2445}
2446
2447PRE(sys_getgroups16)
2448{
barta0b6b2c2008-07-07 06:49:24 +00002449 PRINT("sys_getgroups16 ( %ld, %#lx )", ARG1, ARG2);
njna3b67b72005-08-26 04:27:54 +00002450 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2451 if (ARG1 > 0)
2452 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2453}
2454POST(sys_getgroups16)
2455{
2456 vg_assert(SUCCESS);
2457 if (ARG1 > 0 && RES > 0)
2458 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2459}
2460
2461PRE(sys_setgroups16)
2462{
barta0b6b2c2008-07-07 06:49:24 +00002463 PRINT("sys_setgroups16 ( %llu, %#lx )", (ULong)ARG1, ARG2);
njna3b67b72005-08-26 04:27:54 +00002464 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
2465 if (ARG1 > 0)
2466 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2467}
2468
njn73975482005-08-30 02:45:44 +00002469/* ---------------------------------------------------------------------
2470 *chown16 wrappers
2471 ------------------------------------------------------------------ */
2472
njnefc957c2005-08-26 04:36:10 +00002473PRE(sys_chown16)
2474{
barta0b6b2c2008-07-07 06:49:24 +00002475 PRINT("sys_chown16 ( %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3);
njnefc957c2005-08-26 04:36:10 +00002476 PRE_REG_READ3(long, "chown16",
2477 const char *, path,
2478 vki_old_uid_t, owner, vki_old_gid_t, group);
2479 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
2480}
2481
2482PRE(sys_fchown16)
2483{
barta0b6b2c2008-07-07 06:49:24 +00002484 PRINT("sys_fchown16 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
njnefc957c2005-08-26 04:36:10 +00002485 PRE_REG_READ3(long, "fchown16",
2486 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
2487}
2488
njn73975482005-08-30 02:45:44 +00002489/* ---------------------------------------------------------------------
2490 *xattr wrappers
2491 ------------------------------------------------------------------ */
2492
njn65ccc502005-08-30 01:53:54 +00002493PRE(sys_setxattr)
2494{
2495 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002496 PRINT("sys_setxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
njn65ccc502005-08-30 01:53:54 +00002497 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2498 PRE_REG_READ5(long, "setxattr",
2499 char *, path, char *, name,
2500 void *, value, vki_size_t, size, int, flags);
2501 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
2502 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
2503 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
2504}
2505
2506PRE(sys_lsetxattr)
2507{
2508 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002509 PRINT("sys_lsetxattr ( %#lx, %#lx, %#lx, %llu, %ld )",
njn65ccc502005-08-30 01:53:54 +00002510 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2511 PRE_REG_READ5(long, "lsetxattr",
2512 char *, path, char *, name,
2513 void *, value, vki_size_t, size, int, flags);
2514 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
2515 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
2516 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
2517}
2518
2519PRE(sys_fsetxattr)
2520{
2521 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002522 PRINT("sys_fsetxattr ( %ld, %#lx, %#lx, %llu, %ld )",
njn65ccc502005-08-30 01:53:54 +00002523 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
2524 PRE_REG_READ5(long, "fsetxattr",
2525 int, fd, char *, name, void *, value,
2526 vki_size_t, size, int, flags);
2527 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
2528 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
2529}
2530
2531PRE(sys_getxattr)
2532{
2533 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002534 PRINT("sys_getxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
njn65ccc502005-08-30 01:53:54 +00002535 PRE_REG_READ4(ssize_t, "getxattr",
2536 char *, path, char *, name, void *, value, vki_size_t, size);
2537 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
2538 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
2539 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
2540}
2541POST(sys_getxattr)
2542{
2543 vg_assert(SUCCESS);
2544 if (RES > 0 && ARG3 != (Addr)NULL) {
2545 POST_MEM_WRITE( ARG3, RES );
2546 }
2547}
2548
2549PRE(sys_lgetxattr)
2550{
2551 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002552 PRINT("sys_lgetxattr ( %#lx, %#lx, %#lx, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
njn65ccc502005-08-30 01:53:54 +00002553 PRE_REG_READ4(ssize_t, "lgetxattr",
2554 char *, path, char *, name, void *, value, vki_size_t, size);
2555 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
2556 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
2557 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
2558}
2559POST(sys_lgetxattr)
2560{
2561 vg_assert(SUCCESS);
2562 if (RES > 0 && ARG3 != (Addr)NULL) {
2563 POST_MEM_WRITE( ARG3, RES );
2564 }
2565}
2566
2567PRE(sys_fgetxattr)
2568{
2569 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002570 PRINT("sys_fgetxattr ( %ld, %#lx, %#lx, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
njn65ccc502005-08-30 01:53:54 +00002571 PRE_REG_READ4(ssize_t, "fgetxattr",
2572 int, fd, char *, name, void *, value, vki_size_t, size);
2573 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
2574 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
2575}
2576POST(sys_fgetxattr)
2577{
2578 if (RES > 0 && ARG3 != (Addr)NULL)
2579 POST_MEM_WRITE( ARG3, RES );
2580}
2581
2582PRE(sys_listxattr)
2583{
2584 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002585 PRINT("sys_listxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
njn65ccc502005-08-30 01:53:54 +00002586 PRE_REG_READ3(ssize_t, "listxattr",
2587 char *, path, char *, list, vki_size_t, size);
2588 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
2589 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
2590}
2591POST(sys_listxattr)
2592{
2593 if (RES > 0 && ARG2 != (Addr)NULL)
2594 POST_MEM_WRITE( ARG2, RES );
2595}
2596
2597PRE(sys_llistxattr)
2598{
2599 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002600 PRINT("sys_llistxattr ( %#lx, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
njn65ccc502005-08-30 01:53:54 +00002601 PRE_REG_READ3(ssize_t, "llistxattr",
2602 char *, path, char *, list, vki_size_t, size);
2603 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
2604 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
2605}
2606POST(sys_llistxattr)
2607{
2608 if (RES > 0 && ARG2 != (Addr)NULL)
2609 POST_MEM_WRITE( ARG2, RES );
2610}
2611
2612PRE(sys_flistxattr)
2613{
2614 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002615 PRINT("sys_flistxattr ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
njn65ccc502005-08-30 01:53:54 +00002616 PRE_REG_READ3(ssize_t, "flistxattr",
2617 int, fd, char *, list, vki_size_t, size);
2618 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
2619}
2620POST(sys_flistxattr)
2621{
2622 if (RES > 0 && ARG2 != (Addr)NULL)
2623 POST_MEM_WRITE( ARG2, RES );
2624}
2625
2626PRE(sys_removexattr)
2627{
2628 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002629 PRINT("sys_removexattr ( %#lx, %#lx )", ARG1, ARG2);
njn65ccc502005-08-30 01:53:54 +00002630 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
2631 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
2632 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
2633}
2634
2635PRE(sys_lremovexattr)
2636{
2637 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002638 PRINT("sys_lremovexattr ( %#lx, %#lx )", ARG1, ARG2);
njn65ccc502005-08-30 01:53:54 +00002639 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
2640 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
2641 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
2642}
2643
2644PRE(sys_fremovexattr)
2645{
2646 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002647 PRINT("sys_fremovexattr ( %ld, %#lx )", ARG1, ARG2);
njn65ccc502005-08-30 01:53:54 +00002648 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
2649 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
2650}
2651
njn73975482005-08-30 02:45:44 +00002652/* ---------------------------------------------------------------------
2653 sched_* wrappers
2654 ------------------------------------------------------------------ */
2655
njnb2480c92005-08-30 02:17:23 +00002656PRE(sys_sched_setparam)
2657{
barta0b6b2c2008-07-07 06:49:24 +00002658 PRINT("sched_setparam ( %ld, %#lx )", ARG1, ARG2 );
njnb2480c92005-08-30 02:17:23 +00002659 PRE_REG_READ2(long, "sched_setparam",
2660 vki_pid_t, pid, struct sched_param *, p);
2661 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
2662}
2663POST(sys_sched_setparam)
2664{
2665 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2666}
2667
2668PRE(sys_sched_getparam)
2669{
barta0b6b2c2008-07-07 06:49:24 +00002670 PRINT("sched_getparam ( %ld, %#lx )", ARG1, ARG2 );
njnb2480c92005-08-30 02:17:23 +00002671 PRE_REG_READ2(long, "sched_getparam",
2672 vki_pid_t, pid, struct sched_param *, p);
2673 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
2674}
2675POST(sys_sched_getparam)
2676{
2677 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
2678}
2679
2680PRE(sys_sched_getscheduler)
2681{
barta0b6b2c2008-07-07 06:49:24 +00002682 PRINT("sys_sched_getscheduler ( %ld )", ARG1);
njnb2480c92005-08-30 02:17:23 +00002683 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
2684}
2685
2686PRE(sys_sched_setscheduler)
2687{
barta0b6b2c2008-07-07 06:49:24 +00002688 PRINT("sys_sched_setscheduler ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
njnb2480c92005-08-30 02:17:23 +00002689 PRE_REG_READ3(long, "sched_setscheduler",
2690 vki_pid_t, pid, int, policy, struct sched_param *, p);
2691 if (ARG3 != 0)
2692 PRE_MEM_READ( "sched_setscheduler(p)",
2693 ARG3, sizeof(struct vki_sched_param));
2694}
2695
2696PRE(sys_sched_yield)
2697{
2698 *flags |= SfMayBlock;
2699 PRINT("sched_yield()");
2700 PRE_REG_READ0(long, "sys_sched_yield");
2701}
2702
2703PRE(sys_sched_get_priority_max)
2704{
barta0b6b2c2008-07-07 06:49:24 +00002705 PRINT("sched_get_priority_max ( %ld )", ARG1);
njnb2480c92005-08-30 02:17:23 +00002706 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
2707}
2708
2709PRE(sys_sched_get_priority_min)
2710{
barta0b6b2c2008-07-07 06:49:24 +00002711 PRINT("sched_get_priority_min ( %ld )", ARG1);
njnb2480c92005-08-30 02:17:23 +00002712 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
2713}
2714
tomb8b48482009-11-24 16:03:19 +00002715PRE(sys_sched_rr_get_interval)
2716{
2717 PRINT("sys_sched_rr_get_interval ( %ld, %#lx )", ARG1, ARG2);
2718 PRE_REG_READ2(int, "sched_rr_get_interval",
2719 vki_pid_t, pid,
2720 struct vki_timespec *, tp);
2721 PRE_MEM_WRITE("sched_rr_get_interval(timespec)",
2722 ARG2, sizeof(struct vki_timespec));
2723}
2724
2725POST(sys_sched_rr_get_interval)
2726{
2727 POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
2728}
2729
njnb2480c92005-08-30 02:17:23 +00002730PRE(sys_sched_setaffinity)
2731{
barta0b6b2c2008-07-07 06:49:24 +00002732 PRINT("sched_setaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
njnb2480c92005-08-30 02:17:23 +00002733 PRE_REG_READ3(long, "sched_setaffinity",
2734 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2735 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
2736}
2737
2738PRE(sys_sched_getaffinity)
2739{
barta0b6b2c2008-07-07 06:49:24 +00002740 PRINT("sched_getaffinity ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
njnb2480c92005-08-30 02:17:23 +00002741 PRE_REG_READ3(long, "sched_getaffinity",
2742 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
2743 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
2744}
2745POST(sys_sched_getaffinity)
2746{
2747 POST_MEM_WRITE(ARG3, ARG2);
2748}
2749
njncd405ea2005-08-31 02:44:31 +00002750/* ---------------------------------------------------------------------
2751 miscellaneous wrappers
2752 ------------------------------------------------------------------ */
2753
2754PRE(sys_munlockall)
2755{
2756 *flags |= SfMayBlock;
2757 PRINT("sys_munlockall ( )");
2758 PRE_REG_READ0(long, "munlockall");
2759}
2760
njnf4ef1822005-09-24 19:42:41 +00002761// This has different signatures for different platforms.
2762//
2763// x86: int sys_pipe(unsigned long __user *fildes);
2764// AMD64: long sys_pipe(int *fildes);
2765// ppc32: int sys_pipe(int __user *fildes);
2766// ppc64: int sys_pipe(int __user *fildes);
2767//
2768// The type of the argument is most important, and it is an array of 32 bit
2769// values in all cases. (The return type differs across platforms, but it
2770// is not used.) So we use 'int' as its type. This fixed bug #113230 which
2771// was caused by using an array of 'unsigned long's, which didn't work on
2772// AMD64.
njncd405ea2005-08-31 02:44:31 +00002773PRE(sys_pipe)
2774{
barta0b6b2c2008-07-07 06:49:24 +00002775 PRINT("sys_pipe ( %#lx )", ARG1);
njnf4ef1822005-09-24 19:42:41 +00002776 PRE_REG_READ1(int, "pipe", int *, filedes);
2777 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
njncd405ea2005-08-31 02:44:31 +00002778}
2779POST(sys_pipe)
2780{
2781 Int *p = (Int *)ARG1;
njncd405ea2005-08-31 02:44:31 +00002782 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
2783 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
2784 VG_(close)(p[0]);
2785 VG_(close)(p[1]);
2786 SET_STATUS_Failure( VKI_EMFILE );
2787 } else {
2788 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2789 if (VG_(clo_track_fds)) {
2790 ML_(record_fd_open_nameless)(tid, p[0]);
2791 ML_(record_fd_open_nameless)(tid, p[1]);
2792 }
2793 }
2794}
2795
sewardj586c8152008-11-05 11:20:59 +00002796/* pipe2 (a kernel 2.6.twentysomething invention) is like pipe, except
2797 there's a second arg containing flags to be applied to the new file
2798 descriptors. It hardly seems worth the effort to factor out the
2799 duplicated code, hence: */
2800PRE(sys_pipe2)
2801{
2802 PRINT("sys_pipe2 ( %#lx, %#lx )", ARG1, ARG2);
2803 PRE_REG_READ2(int, "pipe", int *, filedes, long, flags);
2804 PRE_MEM_WRITE( "pipe2(filedes)", ARG1, 2*sizeof(int) );
2805}
2806POST(sys_pipe2)
2807{
2808 Int *p = (Int *)ARG1;
2809 if (!ML_(fd_allowed)(p[0], "pipe2", tid, True) ||
2810 !ML_(fd_allowed)(p[1], "pipe2", tid, True)) {
2811 VG_(close)(p[0]);
2812 VG_(close)(p[1]);
2813 SET_STATUS_Failure( VKI_EMFILE );
2814 } else {
2815 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
2816 if (VG_(clo_track_fds)) {
2817 ML_(record_fd_open_nameless)(tid, p[0]);
2818 ML_(record_fd_open_nameless)(tid, p[1]);
2819 }
2820 }
2821}
2822
tomf43793a2009-11-23 08:19:20 +00002823PRE(sys_dup3)
2824{
2825 PRINT("sys_dup3 ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
2826 PRE_REG_READ3(long, "dup3", unsigned int, oldfd, unsigned int, newfd, int, flags);
2827 if (!ML_(fd_allowed)(ARG2, "dup3", tid, True))
2828 SET_STATUS_Failure( VKI_EBADF );
2829}
2830
2831POST(sys_dup3)
2832{
2833 vg_assert(SUCCESS);
2834 if (VG_(clo_track_fds))
2835 ML_(record_fd_open_named)(tid, RES);
2836}
2837
njncd405ea2005-08-31 02:44:31 +00002838PRE(sys_quotactl)
2839{
barta0b6b2c2008-07-07 06:49:24 +00002840 PRINT("sys_quotactl (0x%lx, %#lx, 0x%lx, 0x%lx )", ARG1,ARG2,ARG3, ARG4);
njncd405ea2005-08-31 02:44:31 +00002841 PRE_REG_READ4(long, "quotactl",
2842 unsigned int, cmd, const char *, special, vki_qid_t, id,
2843 void *, addr);
2844 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
2845}
2846
2847PRE(sys_waitid)
2848{
2849 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002850 PRINT("sys_waitid( %ld, %ld, %#lx, %ld, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
njncd405ea2005-08-31 02:44:31 +00002851 PRE_REG_READ5(int32_t, "sys_waitid",
2852 int, which, vki_pid_t, pid, struct vki_siginfo *, infop,
2853 int, options, struct vki_rusage *, ru);
2854 PRE_MEM_WRITE( "waitid(infop)", ARG3, sizeof(struct vki_siginfo) );
2855 if (ARG5 != 0)
2856 PRE_MEM_WRITE( "waitid(ru)", ARG5, sizeof(struct vki_rusage) );
2857}
2858POST(sys_waitid)
2859{
2860 POST_MEM_WRITE( ARG3, sizeof(struct vki_siginfo) );
2861 if (ARG5 != 0)
2862 POST_MEM_WRITE( ARG5, sizeof(struct vki_rusage) );
2863}
2864
tomc4e466f2008-01-08 16:31:25 +00002865PRE(sys_sync_file_range)
2866{
sewardjfc2aa032008-06-04 06:49:56 +00002867 *flags |= SfMayBlock;
tomc0fe32a2009-11-25 11:29:14 +00002868#if VG_WORDSIZE == 4
2869 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2870 ARG1,MERGE64(ARG2,ARG3),MERGE64(ARG4,ARG5),ARG6);
2871 PRE_REG_READ6(long, "sync_file_range",
2872 int, fd,
2873 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2874 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes),
2875 unsigned int, flags);
2876#elif VG_WORDSIZE == 8
2877 PRINT("sys_sync_file_range ( %ld, %lld, %lld, %ld )",
2878 ARG1,(Long)ARG2,(Long)ARG3,ARG4);
sewardjfc2aa032008-06-04 06:49:56 +00002879 PRE_REG_READ4(long, "sync_file_range",
2880 int, fd, vki_loff_t, offset, vki_loff_t, nbytes,
2881 unsigned int, flags);
tomc0fe32a2009-11-25 11:29:14 +00002882#else
2883# error Unexpected word size
2884#endif
sewardjfc2aa032008-06-04 06:49:56 +00002885 if (!ML_(fd_allowed)(ARG1, "sync_file_range", tid, False))
2886 SET_STATUS_Failure( VKI_EBADF );
tomc4e466f2008-01-08 16:31:25 +00002887}
2888
tomc0fe32a2009-11-25 11:29:14 +00002889PRE(sys_sync_file_range2)
2890{
2891 *flags |= SfMayBlock;
2892#if VG_WORDSIZE == 4
2893 PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2894 ARG1,ARG2,MERGE64(ARG3,ARG4),MERGE64(ARG5,ARG6));
2895 PRE_REG_READ6(long, "sync_file_range2",
2896 int, fd, unsigned int, flags,
2897 unsigned, MERGE64_FIRST(offset), unsigned, MERGE64_SECOND(offset),
2898 unsigned, MERGE64_FIRST(nbytes), unsigned, MERGE64_SECOND(nbytes));
2899#elif VG_WORDSIZE == 8
2900 PRINT("sys_sync_file_range2 ( %ld, %ld, %lld, %lld )",
2901 ARG1,ARG2,(Long)ARG3,(Long)ARG4);
2902 PRE_REG_READ4(long, "sync_file_range2",
2903 int, fd, unsigned int, flags,
2904 vki_loff_t, offset, vki_loff_t, nbytes);
2905#else
2906# error Unexpected word size
2907#endif
2908 if (!ML_(fd_allowed)(ARG1, "sync_file_range2", tid, False))
2909 SET_STATUS_Failure( VKI_EBADF );
2910}
2911
sewardj6d652772008-11-06 23:11:42 +00002912PRE(sys_stime)
2913{
2914 PRINT("sys_stime ( %#lx )", ARG1);
2915 PRE_REG_READ1(int, "stime", vki_time_t*, t);
2916 PRE_MEM_READ( "stime(t)", ARG1, sizeof(vki_time_t) );
2917}
2918
tomc8232f92011-06-08 09:10:40 +00002919PRE(sys_perf_event_open)
tom3fbccee2009-10-27 09:19:26 +00002920{
tomc8232f92011-06-08 09:10:40 +00002921 struct vki_perf_event_attr *attr;
2922 PRINT("sys_perf_event_open ( %#lx, %ld, %ld, %ld, %ld )",
tom3fbccee2009-10-27 09:19:26 +00002923 ARG1,ARG2,ARG3,ARG4,ARG5);
tomc8232f92011-06-08 09:10:40 +00002924 PRE_REG_READ5(long, "perf_event_open",
2925 struct vki_perf_event_attr *, attr,
tom3fbccee2009-10-27 09:19:26 +00002926 vki_pid_t, pid, int, cpu, int, group_fd,
2927 unsigned long, flags);
tomc8232f92011-06-08 09:10:40 +00002928 attr = (struct vki_perf_event_attr *)ARG1;
2929 PRE_MEM_READ( "perf_event_open(attr->size)",
tom9fd3c512011-06-08 09:57:54 +00002930 (Addr)&attr->size, sizeof(attr->size) );
tomc8232f92011-06-08 09:10:40 +00002931 PRE_MEM_READ( "perf_event_open(attr)",
tom9fd3c512011-06-08 09:57:54 +00002932 (Addr)attr, attr->size );
tom3fbccee2009-10-27 09:19:26 +00002933}
2934
tomc8232f92011-06-08 09:10:40 +00002935POST(sys_perf_event_open)
tom3fbccee2009-10-27 09:19:26 +00002936{
2937 vg_assert(SUCCESS);
tomc8232f92011-06-08 09:10:40 +00002938 if (!ML_(fd_allowed)(RES, "perf_event_open", tid, True)) {
tom3fbccee2009-10-27 09:19:26 +00002939 VG_(close)(RES);
2940 SET_STATUS_Failure( VKI_EMFILE );
2941 } else {
2942 if (VG_(clo_track_fds))
2943 ML_(record_fd_open_nameless)(tid, RES);
2944 }
2945}
2946
tom472a34b2010-02-23 10:02:55 +00002947PRE(sys_getcpu)
2948{
2949 PRINT("sys_getcpu ( %#lx, %#lx, %#lx )" , ARG1,ARG2,ARG3);
2950 PRE_REG_READ3(int, "getcpu",
2951 unsigned *, cpu, unsigned *, node, struct vki_getcpu_cache *, tcache);
2952 if (ARG1 != 0)
2953 PRE_MEM_WRITE( "getcpu(cpu)", ARG1, sizeof(unsigned) );
2954 if (ARG2 != 0)
2955 PRE_MEM_WRITE( "getcpu(node)", ARG2, sizeof(unsigned) );
2956 if (ARG3 != 0)
2957 PRE_MEM_WRITE( "getcpu(tcache)", ARG3, sizeof(struct vki_getcpu_cache) );
2958}
2959
2960POST(sys_getcpu)
2961{
2962 if (ARG1 != 0)
2963 POST_MEM_WRITE( ARG1, sizeof(unsigned) );
2964 if (ARG2 != 0)
2965 POST_MEM_WRITE( ARG2, sizeof(unsigned) );
2966 if (ARG3 != 0)
2967 POST_MEM_WRITE( ARG3, sizeof(struct vki_getcpu_cache) );
2968}
2969
tomd5fb58e2012-04-03 10:51:27 +00002970PRE(sys_move_pages)
2971{
2972 PRINT("sys_move_pages ( %ld, %ld, %#lx, %#lx, %#lx, %lx )",
2973 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
2974 PRE_REG_READ6(int, "move_pages",
2975 vki_pid_t, pid, unsigned long, nr_pages, const void **, pages,
2976 const int *, nodes, int *, status, int, flags);
2977 PRE_MEM_READ("move_pages(pages)", ARG3, ARG2 * sizeof(void *));
2978 if (ARG4)
2979 PRE_MEM_READ("move_pages(nodes)", ARG4, ARG2 * sizeof(int));
2980 PRE_MEM_WRITE("move_pages(status)", ARG5, ARG2 * sizeof(int));
2981}
2982
2983POST(sys_move_pages)
2984{
2985 POST_MEM_WRITE(ARG5, ARG2 * sizeof(int));
2986}
2987
njncd405ea2005-08-31 02:44:31 +00002988/* ---------------------------------------------------------------------
2989 utime wrapper
2990 ------------------------------------------------------------------ */
2991
2992PRE(sys_utime)
2993{
2994 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00002995 PRINT("sys_utime ( %#lx, %#lx )", ARG1,ARG2);
njncd405ea2005-08-31 02:44:31 +00002996 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
2997 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
2998 if (ARG2 != 0)
2999 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
3000}
3001
3002/* ---------------------------------------------------------------------
3003 lseek wrapper
3004 ------------------------------------------------------------------ */
3005
3006PRE(sys_lseek)
3007{
barta0b6b2c2008-07-07 06:49:24 +00003008 PRINT("sys_lseek ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
njncd405ea2005-08-31 02:44:31 +00003009 PRE_REG_READ3(vki_off_t, "lseek",
3010 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
3011}
3012
3013/* ---------------------------------------------------------------------
sewardj792e00a2010-10-04 20:03:27 +00003014 readahead wrapper
3015 ------------------------------------------------------------------ */
3016
3017PRE(sys_readahead)
3018{
3019 *flags |= SfMayBlock;
3020#if VG_WORDSIZE == 4
3021 PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, MERGE64(ARG2,ARG3), ARG4);
3022 PRE_REG_READ4(vki_off_t, "readahead",
3023 int, fd, unsigned, MERGE64_FIRST(offset),
3024 unsigned, MERGE64_SECOND(offset), vki_size_t, count);
3025#elif VG_WORDSIZE == 8
3026 PRINT("sys_readahead ( %ld, %lld, %ld )", ARG1, (Long)ARG2, ARG3);
3027 PRE_REG_READ3(vki_off_t, "readahead",
3028 int, fd, vki_loff_t, offset, vki_size_t, count);
3029#else
3030# error Unexpected word size
3031#endif
3032 if (!ML_(fd_allowed)(ARG1, "readahead", tid, False))
3033 SET_STATUS_Failure( VKI_EBADF );
3034}
3035
3036/* ---------------------------------------------------------------------
njncd405ea2005-08-31 02:44:31 +00003037 sig* wrappers
3038 ------------------------------------------------------------------ */
3039
3040PRE(sys_sigpending)
3041{
barta0b6b2c2008-07-07 06:49:24 +00003042 PRINT( "sys_sigpending ( %#lx )", ARG1 );
njncd405ea2005-08-31 02:44:31 +00003043 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
3044 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
3045}
3046POST(sys_sigpending)
3047{
3048 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
3049}
3050
3051// This syscall is not used on amd64/Linux -- it only provides
3052// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
3053// This wrapper is only suitable for 32-bit architectures.
3054// (XXX: so how is it that PRE(sys_sigpending) above doesn't need
3055// conditional compilation like this?)
petarj13edb6a2012-06-21 17:33:35 +00003056#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
3057 || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
njncd405ea2005-08-31 02:44:31 +00003058PRE(sys_sigprocmask)
3059{
3060 vki_old_sigset_t* set;
3061 vki_old_sigset_t* oldset;
3062 vki_sigset_t bigger_set;
3063 vki_sigset_t bigger_oldset;
3064
barta0b6b2c2008-07-07 06:49:24 +00003065 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
njncd405ea2005-08-31 02:44:31 +00003066 PRE_REG_READ3(long, "sigprocmask",
3067 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
3068 if (ARG2 != 0)
3069 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
3070 if (ARG3 != 0)
3071 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
3072
3073 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
3074 // vki_sigset_t params.
3075 set = (vki_old_sigset_t*)ARG2;
3076 oldset = (vki_old_sigset_t*)ARG3;
3077
3078 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
3079 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
3080 if (set)
3081 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
3082
3083 SET_STATUS_from_SysRes(
3084 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3085 set ? &bigger_set : NULL,
3086 oldset ? &bigger_oldset : NULL)
3087 );
3088
3089 if (oldset)
3090 *oldset = bigger_oldset.sig[0];
3091
3092 if (SUCCESS)
3093 *flags |= SfPollAfter;
3094}
3095POST(sys_sigprocmask)
3096{
3097 vg_assert(SUCCESS);
3098 if (RES == 0 && ARG3 != 0)
3099 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
3100}
sewardjde9264c2011-07-11 17:48:24 +00003101
3102/* Convert from non-RT to RT sigset_t's */
3103static
3104void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
3105{
3106 VG_(sigemptyset)(set);
3107 set->sig[0] = *oldset;
3108}
3109PRE(sys_sigaction)
3110{
3111 vki_sigaction_toK_t new, *newp;
3112 vki_sigaction_fromK_t old, *oldp;
3113
3114 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
3115 PRE_REG_READ3(int, "sigaction",
3116 int, signum, const struct old_sigaction *, act,
3117 struct old_sigaction *, oldact);
3118
3119 newp = oldp = NULL;
3120
3121 if (ARG2 != 0) {
3122 struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
3123 PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3124 PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3125 PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3126 if (ML_(safe_to_deref)(sa,sizeof(sa))
3127 && (sa->sa_flags & VKI_SA_RESTORER))
3128 PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3129 }
3130
3131 if (ARG3 != 0) {
3132 PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
3133 oldp = &old;
3134 }
3135
3136 if (ARG2 != 0) {
3137 struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
3138
3139 new.ksa_handler = oldnew->ksa_handler;
3140 new.sa_flags = oldnew->sa_flags;
3141 new.sa_restorer = oldnew->sa_restorer;
3142 convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
3143 newp = &new;
3144 }
3145
3146 SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
3147
3148 if (ARG3 != 0 && SUCCESS && RES == 0) {
3149 struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
3150
3151 oldold->ksa_handler = oldp->ksa_handler;
3152 oldold->sa_flags = oldp->sa_flags;
3153 oldold->sa_restorer = oldp->sa_restorer;
3154 oldold->sa_mask = oldp->sa_mask.sig[0];
3155 }
3156}
3157POST(sys_sigaction)
3158{
3159 vg_assert(SUCCESS);
3160 if (RES == 0 && ARG3 != 0)
3161 POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
3162}
njncd405ea2005-08-31 02:44:31 +00003163#endif
3164
bartf5ceec82008-04-26 07:45:10 +00003165PRE(sys_signalfd)
3166{
tom6c67ef52009-01-09 16:42:51 +00003167 PRINT("sys_signalfd ( %d, %#lx, %llu )", (Int)ARG1,ARG2,(ULong)ARG3);
bartf5ceec82008-04-26 07:45:10 +00003168 PRE_REG_READ3(long, "sys_signalfd",
3169 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize);
3170 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
bart58cac552008-05-26 17:16:08 +00003171 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
bartf5ceec82008-04-26 07:45:10 +00003172 SET_STATUS_Failure( VKI_EBADF );
3173}
3174POST(sys_signalfd)
3175{
3176 if (!ML_(fd_allowed)(RES, "signalfd", tid, True)) {
3177 VG_(close)(RES);
3178 SET_STATUS_Failure( VKI_EMFILE );
3179 } else {
3180 if (VG_(clo_track_fds))
3181 ML_(record_fd_open_nameless) (tid, RES);
3182 }
3183}
3184
tom6c67ef52009-01-09 16:42:51 +00003185PRE(sys_signalfd4)
3186{
3187 PRINT("sys_signalfd4 ( %d, %#lx, %llu, %ld )", (Int)ARG1,ARG2,(ULong)ARG3,ARG4);
3188 PRE_REG_READ4(long, "sys_signalfd4",
3189 int, fd, vki_sigset_t *, sigmask, vki_size_t, sigsetsize, int, flags);
3190 PRE_MEM_READ( "signalfd(sigmask)", ARG2, sizeof(vki_sigset_t) );
3191 if ((int)ARG1 != -1 && !ML_(fd_allowed)(ARG1, "signalfd", tid, False))
3192 SET_STATUS_Failure( VKI_EBADF );
3193}
3194POST(sys_signalfd4)
3195{
3196 if (!ML_(fd_allowed)(RES, "signalfd4", tid, True)) {
3197 VG_(close)(RES);
3198 SET_STATUS_Failure( VKI_EMFILE );
3199 } else {
3200 if (VG_(clo_track_fds))
3201 ML_(record_fd_open_nameless) (tid, RES);
3202 }
3203}
3204
bartf5ceec82008-04-26 07:45:10 +00003205
njncd405ea2005-08-31 02:44:31 +00003206/* ---------------------------------------------------------------------
3207 rt_sig* wrappers
3208 ------------------------------------------------------------------ */
3209
3210PRE(sys_rt_sigaction)
3211{
barta0b6b2c2008-07-07 06:49:24 +00003212 PRINT("sys_rt_sigaction ( %ld, %#lx, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4);
njncd405ea2005-08-31 02:44:31 +00003213 PRE_REG_READ4(long, "rt_sigaction",
3214 int, signum, const struct sigaction *, act,
3215 struct sigaction *, oldact, vki_size_t, sigsetsize);
3216
3217 if (ARG2 != 0) {
njncda2f0f2009-05-18 02:12:08 +00003218 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
njncd405ea2005-08-31 02:44:31 +00003219 PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
3220 PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
3221 PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
3222 if (sa->sa_flags & VKI_SA_RESTORER)
3223 PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
3224 }
3225 if (ARG3 != 0)
njncda2f0f2009-05-18 02:12:08 +00003226 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
njncd405ea2005-08-31 02:44:31 +00003227
3228 // XXX: doesn't seem right to be calling do_sys_sigaction for
3229 // sys_rt_sigaction... perhaps this function should be renamed
3230 // VG_(do_sys_rt_sigaction)() --njn
3231
3232 SET_STATUS_from_SysRes(
njncda2f0f2009-05-18 02:12:08 +00003233 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
3234 (vki_sigaction_fromK_t *)ARG3)
njncd405ea2005-08-31 02:44:31 +00003235 );
3236}
3237POST(sys_rt_sigaction)
3238{
3239 vg_assert(SUCCESS);
3240 if (RES == 0 && ARG3 != 0)
njncda2f0f2009-05-18 02:12:08 +00003241 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
njncd405ea2005-08-31 02:44:31 +00003242}
3243
3244PRE(sys_rt_sigprocmask)
3245{
barta0b6b2c2008-07-07 06:49:24 +00003246 PRINT("sys_rt_sigprocmask ( %ld, %#lx, %#lx, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
njncd405ea2005-08-31 02:44:31 +00003247 PRE_REG_READ4(long, "rt_sigprocmask",
3248 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
3249 vki_size_t, sigsetsize);
3250 if (ARG2 != 0)
3251 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3252 if (ARG3 != 0)
3253 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3254
3255 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
3256 if (sizeof(vki_sigset_t) != ARG4)
3257 SET_STATUS_Failure( VKI_EMFILE );
3258 else {
3259 SET_STATUS_from_SysRes(
3260 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
3261 (vki_sigset_t*) ARG2,
3262 (vki_sigset_t*) ARG3 )
3263 );
3264 }
3265
3266 if (SUCCESS)
3267 *flags |= SfPollAfter;
3268}
3269POST(sys_rt_sigprocmask)
3270{
3271 vg_assert(SUCCESS);
3272 if (RES == 0 && ARG3 != 0)
3273 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3274}
3275
3276PRE(sys_rt_sigpending)
3277{
barta0b6b2c2008-07-07 06:49:24 +00003278 PRINT( "sys_rt_sigpending ( %#lx )", ARG1 );
njncd405ea2005-08-31 02:44:31 +00003279 PRE_REG_READ2(long, "rt_sigpending",
3280 vki_sigset_t *, set, vki_size_t, sigsetsize);
3281 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
3282}
3283POST(sys_rt_sigpending)
3284{
3285 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3286}
3287
3288PRE(sys_rt_sigtimedwait)
3289{
3290 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00003291 PRINT("sys_rt_sigtimedwait ( %#lx, %#lx, %#lx, %lld )",
njncd405ea2005-08-31 02:44:31 +00003292 ARG1,ARG2,ARG3,(ULong)ARG4);
3293 PRE_REG_READ4(long, "rt_sigtimedwait",
3294 const vki_sigset_t *, set, vki_siginfo_t *, info,
3295 const struct timespec *, timeout, vki_size_t, sigsetsize);
3296 if (ARG1 != 0)
3297 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
3298 if (ARG2 != 0)
3299 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
3300 if (ARG3 != 0)
3301 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
3302 ARG3, sizeof(struct vki_timespec) );
3303}
3304POST(sys_rt_sigtimedwait)
3305{
3306 if (ARG2 != 0)
3307 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
3308}
3309
3310PRE(sys_rt_sigqueueinfo)
3311{
barta0b6b2c2008-07-07 06:49:24 +00003312 PRINT("sys_rt_sigqueueinfo(%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
njncd405ea2005-08-31 02:44:31 +00003313 PRE_REG_READ3(long, "rt_sigqueueinfo",
3314 int, pid, int, sig, vki_siginfo_t *, uinfo);
3315 if (ARG2 != 0)
bart89e070c2009-10-28 10:15:06 +00003316 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, VKI_SI_MAX_SIZE );
njncd405ea2005-08-31 02:44:31 +00003317}
3318POST(sys_rt_sigqueueinfo)
3319{
3320 if (!ML_(client_signal_OK)(ARG2))
3321 SET_STATUS_Failure( VKI_EINVAL );
3322}
3323
tomd18b5412009-11-24 16:08:40 +00003324PRE(sys_rt_tgsigqueueinfo)
3325{
3326 PRINT("sys_rt_tgsigqueueinfo(%ld, %ld, %ld, %#lx)", ARG1, ARG2, ARG3, ARG4);
3327 PRE_REG_READ4(long, "rt_tgsigqueueinfo",
3328 int, tgid, int, pid, int, sig, vki_siginfo_t *, uinfo);
3329 if (ARG3 != 0)
3330 PRE_MEM_READ( "rt_tgsigqueueinfo(uinfo)", ARG4, VKI_SI_MAX_SIZE );
3331}
3332
3333POST(sys_rt_tgsigqueueinfo)
3334{
3335 if (!ML_(client_signal_OK)(ARG3))
3336 SET_STATUS_Failure( VKI_EINVAL );
3337}
3338
njncd405ea2005-08-31 02:44:31 +00003339// XXX: x86-specific? The kernel prototypes for the different archs are
3340// hard to decipher.
3341PRE(sys_rt_sigsuspend)
3342{
3343 /* The C library interface to sigsuspend just takes a pointer to
3344 a signal mask but this system call has two arguments - a pointer
3345 to the mask and the number of bytes used by it. The kernel insists
3346 on the size being equal to sizeof(sigset_t) however and will just
3347 return EINVAL if it isn't.
3348 */
3349 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00003350 PRINT("sys_rt_sigsuspend ( %#lx, %ld )", ARG1,ARG2 );
njncd405ea2005-08-31 02:44:31 +00003351 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
3352 if (ARG1 != (Addr)NULL) {
3353 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
3354 }
3355}
3356
3357/* ---------------------------------------------------------------------
3358 linux msg* wrapper helpers
3359 ------------------------------------------------------------------ */
3360
3361void
3362ML_(linux_PRE_sys_msgsnd) ( ThreadId tid,
3363 UWord arg0, UWord arg1, UWord arg2, UWord arg3 )
3364{
3365 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
3366 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3367 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3368 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3369}
3370
3371void
3372ML_(linux_PRE_sys_msgrcv) ( ThreadId tid,
3373 UWord arg0, UWord arg1, UWord arg2,
3374 UWord arg3, UWord arg4 )
3375{
3376 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
3377 long msgtyp, int msgflg); */
3378 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3379 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3380 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
3381}
3382void
3383ML_(linux_POST_sys_msgrcv) ( ThreadId tid,
3384 UWord res,
3385 UWord arg0, UWord arg1, UWord arg2,
3386 UWord arg3, UWord arg4 )
3387{
3388 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
3389 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
3390 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
3391}
3392
3393void
3394ML_(linux_PRE_sys_msgctl) ( ThreadId tid,
3395 UWord arg0, UWord arg1, UWord arg2 )
3396{
3397 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
3398 switch (arg1 /* cmd */) {
3399 case VKI_IPC_INFO:
3400 case VKI_MSG_INFO:
3401 case VKI_IPC_INFO|VKI_IPC_64:
3402 case VKI_MSG_INFO|VKI_IPC_64:
3403 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
3404 arg2, sizeof(struct vki_msginfo) );
3405 break;
3406 case VKI_IPC_STAT:
3407 case VKI_MSG_STAT:
3408 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
3409 arg2, sizeof(struct vki_msqid_ds) );
3410 break;
3411 case VKI_IPC_STAT|VKI_IPC_64:
3412 case VKI_MSG_STAT|VKI_IPC_64:
3413 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
3414 arg2, sizeof(struct vki_msqid64_ds) );
3415 break;
3416 case VKI_IPC_SET:
3417 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3418 arg2, sizeof(struct vki_msqid_ds) );
3419 break;
3420 case VKI_IPC_SET|VKI_IPC_64:
3421 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
3422 arg2, sizeof(struct vki_msqid64_ds) );
3423 break;
3424 }
3425}
3426void
3427ML_(linux_POST_sys_msgctl) ( ThreadId tid,
3428 UWord res,
3429 UWord arg0, UWord arg1, UWord arg2 )
3430{
3431 switch (arg1 /* cmd */) {
3432 case VKI_IPC_INFO:
3433 case VKI_MSG_INFO:
3434 case VKI_IPC_INFO|VKI_IPC_64:
3435 case VKI_MSG_INFO|VKI_IPC_64:
3436 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
3437 break;
3438 case VKI_IPC_STAT:
3439 case VKI_MSG_STAT:
3440 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
3441 break;
3442 case VKI_IPC_STAT|VKI_IPC_64:
3443 case VKI_MSG_STAT|VKI_IPC_64:
3444 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
3445 break;
3446 }
3447}
3448
tom363ec762006-03-21 10:58:35 +00003449/* ---------------------------------------------------------------------
philippe4eefc8c2012-10-21 20:21:17 +00003450 Generic handler for sys_ipc
3451 Depending on the platform, some syscalls (e.g. semctl, semop, ...)
3452 are either direct system calls, or are all implemented via sys_ipc.
3453 ------------------------------------------------------------------ */
3454#ifdef __NR_ipc
florian87e0a642012-11-18 22:15:22 +00003455static Addr deref_Addr ( ThreadId tid, Addr a, const HChar* s )
philippe4eefc8c2012-10-21 20:21:17 +00003456{
3457 Addr* a_p = (Addr*)a;
3458 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
3459 return *a_p;
3460}
3461
philippef2a7bbe2012-11-04 20:40:33 +00003462static Bool semctl_cmd_has_4args (UWord cmd)
philippe228552d2012-10-23 21:38:52 +00003463{
3464 switch (cmd & ~VKI_IPC_64)
3465 {
3466 case VKI_IPC_INFO:
3467 case VKI_SEM_INFO:
3468 case VKI_IPC_STAT:
3469 case VKI_SEM_STAT:
3470 case VKI_IPC_SET:
3471 case VKI_GETALL:
3472 case VKI_SETALL:
3473 return True;
3474 default:
3475 return False;
3476 }
3477}
3478
philippe4eefc8c2012-10-21 20:21:17 +00003479PRE(sys_ipc)
3480{
philippecf4a22e2012-10-21 21:49:33 +00003481 PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )",
3482 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
philippe4eefc8c2012-10-21 20:21:17 +00003483
3484 switch (ARG1 /* call */) {
3485 case VKI_SEMOP:
petarj73a0e192012-10-26 16:16:43 +00003486 PRE_REG_READ5(int, "ipc",
3487 vki_uint, call, int, first, int, second, int, third,
3488 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003489 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
3490 *flags |= SfMayBlock;
3491 break;
3492 case VKI_SEMGET:
petarj73a0e192012-10-26 16:16:43 +00003493 PRE_REG_READ4(int, "ipc",
3494 vki_uint, call, int, first, int, second, int, third);
philippe4eefc8c2012-10-21 20:21:17 +00003495 break;
3496 case VKI_SEMCTL:
3497 {
petarj73a0e192012-10-26 16:16:43 +00003498 PRE_REG_READ5(int, "ipc",
3499 vki_uint, call, int, first, int, second, int, third,
3500 void *, ptr);
philippe228552d2012-10-23 21:38:52 +00003501 UWord arg;
3502 if (semctl_cmd_has_4args(ARG4))
3503 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
3504 else
3505 arg = 0;
philippe4eefc8c2012-10-21 20:21:17 +00003506 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
3507 break;
3508 }
3509 case VKI_SEMTIMEDOP:
petarj73a0e192012-10-26 16:16:43 +00003510 PRE_REG_READ6(int, "ipc",
3511 vki_uint, call, int, first, int, second, int, third,
3512 void *, ptr, long, fifth);
philippe4eefc8c2012-10-21 20:21:17 +00003513 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
3514 *flags |= SfMayBlock;
3515 break;
3516 case VKI_MSGSND:
petarj73a0e192012-10-26 16:16:43 +00003517 PRE_REG_READ5(int, "ipc",
3518 vki_uint, call, int, first, int, second, int, third,
3519 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003520 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
3521 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3522 *flags |= SfMayBlock;
3523 break;
3524 case VKI_MSGRCV:
3525 {
petarj73a0e192012-10-26 16:16:43 +00003526 PRE_REG_READ5(int, "ipc",
3527 vki_uint, call, int, first, int, second, int, third,
3528 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003529 Addr msgp;
3530 Word msgtyp;
3531
petarj73a0e192012-10-26 16:16:43 +00003532 msgp = deref_Addr( tid, (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
3533 "msgrcv(msgp)" );
3534 msgtyp = deref_Addr( tid,
3535 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
3536 "msgrcv(msgp)" );
philippe4eefc8c2012-10-21 20:21:17 +00003537
3538 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
3539
3540 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3541 *flags |= SfMayBlock;
3542 break;
3543 }
3544 case VKI_MSGGET:
petarj73a0e192012-10-26 16:16:43 +00003545 PRE_REG_READ3(int, "ipc", vki_uint, call, int, first, int, second);
philippe4eefc8c2012-10-21 20:21:17 +00003546 break;
3547 case VKI_MSGCTL:
petarj73a0e192012-10-26 16:16:43 +00003548 PRE_REG_READ5(int, "ipc",
3549 vki_uint, call, int, first, int, second, int, third,
3550 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003551 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
3552 break;
3553 case VKI_SHMAT:
3554 {
petarj73a0e192012-10-26 16:16:43 +00003555 PRE_REG_READ5(int, "ipc",
3556 vki_uint, call, int, first, int, second, int, third,
3557 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003558 UWord w;
3559 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
3560 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
3561 if (w == 0)
3562 SET_STATUS_Failure( VKI_EINVAL );
3563 else
3564 ARG5 = w;
3565 break;
3566 }
3567 case VKI_SHMDT:
petarj73a0e192012-10-26 16:16:43 +00003568 PRE_REG_READ5(int, "ipc",
3569 vki_uint, call, int, first, int, second, int, third,
3570 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003571 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
3572 SET_STATUS_Failure( VKI_EINVAL );
3573 break;
3574 case VKI_SHMGET:
petarj73a0e192012-10-26 16:16:43 +00003575 PRE_REG_READ4(int, "ipc",
3576 vki_uint, call, int, first, int, second, int, third);
philippe4eefc8c2012-10-21 20:21:17 +00003577 break;
3578 case VKI_SHMCTL: /* IPCOP_shmctl */
petarj73a0e192012-10-26 16:16:43 +00003579 PRE_REG_READ5(int, "ipc",
3580 vki_uint, call, int, first, int, second, int, third,
3581 void *, ptr);
philippe4eefc8c2012-10-21 20:21:17 +00003582 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
3583 break;
3584 default:
3585 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
3586 VG_(core_panic)("... bye!\n");
3587 break; /*NOTREACHED*/
petarj73a0e192012-10-26 16:16:43 +00003588 }
philippe4eefc8c2012-10-21 20:21:17 +00003589}
3590
3591POST(sys_ipc)
3592{
3593 vg_assert(SUCCESS);
3594 switch (ARG1 /* call */) {
3595 case VKI_SEMOP:
3596 case VKI_SEMGET:
philippe4eefc8c2012-10-21 20:21:17 +00003597 break;
philippecf4a22e2012-10-21 21:49:33 +00003598 case VKI_SEMCTL:
3599 {
philippe228552d2012-10-23 21:38:52 +00003600 UWord arg;
3601 if (semctl_cmd_has_4args(ARG4))
3602 arg = deref_Addr( tid, ARG5, "semctl(arg)" );
3603 else
3604 arg = 0;
philippecf4a22e2012-10-21 21:49:33 +00003605 ML_(generic_POST_sys_semctl)( tid, RES, ARG2, ARG3, ARG4, arg );
3606 break;
3607 }
philippe4eefc8c2012-10-21 20:21:17 +00003608 case VKI_SEMTIMEDOP:
3609 case VKI_MSGSND:
3610 break;
3611 case VKI_MSGRCV:
3612 {
3613 Addr msgp;
3614 Word msgtyp;
3615
3616 msgp = deref_Addr( tid,
3617 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
3618 "msgrcv(msgp)" );
3619 msgtyp = deref_Addr( tid,
3620 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
3621 "msgrcv(msgp)" );
3622
3623 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
3624 break;
3625 }
3626 case VKI_MSGGET:
3627 break;
3628 case VKI_MSGCTL:
3629 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
3630 break;
3631 case VKI_SHMAT:
3632 {
3633 Addr addr;
3634
3635 /* force readability. before the syscall it is
3636 * indeed uninitialized, as can be seen in
3637 * glibc/sysdeps/unix/sysv/linux/shmat.c */
3638 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
3639
3640 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
3641 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
3642 break;
3643 }
3644 case VKI_SHMDT:
3645 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
3646 break;
3647 case VKI_SHMGET:
3648 break;
3649 case VKI_SHMCTL:
3650 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
3651 break;
3652 default:
3653 VG_(message)(Vg_DebugMsg,
3654 "FATAL: unhandled syscall(ipc) %ld\n",
3655 ARG1 );
3656 VG_(core_panic)("... bye!\n");
3657 break; /*NOTREACHED*/
3658 }
3659}
3660#endif
3661
philippe6b087762013-03-01 23:31:09 +00003662PRE(sys_semget)
3663{
3664 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3665 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
3666}
3667
3668PRE(sys_semop)
3669{
3670 *flags |= SfMayBlock;
3671 PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
3672 PRE_REG_READ3(long, "semop",
3673 int, semid, struct sembuf *, sops, unsigned, nsoops);
3674 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
3675}
3676
3677PRE(sys_semctl)
3678{
3679 switch (ARG3 & ~VKI_IPC_64) {
3680 case VKI_IPC_INFO:
3681 case VKI_SEM_INFO:
3682 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3683 PRE_REG_READ4(long, "semctl",
3684 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
3685 break;
3686 case VKI_IPC_STAT:
3687 case VKI_SEM_STAT:
3688 case VKI_IPC_SET:
3689 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3690 PRE_REG_READ4(long, "semctl",
3691 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
3692 break;
3693 case VKI_GETALL:
3694 case VKI_SETALL:
3695 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3696 PRE_REG_READ4(long, "semctl",
3697 int, semid, int, semnum, int, cmd, unsigned short *, arg);
3698 break;
3699 default:
3700 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3701 PRE_REG_READ3(long, "semctl",
3702 int, semid, int, semnum, int, cmd);
3703 break;
3704 }
3705#ifdef VGP_amd64_linux
3706 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
3707#else
3708 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
3709#endif
3710}
3711
3712POST(sys_semctl)
3713{
3714#ifdef VGP_amd64_linux
3715 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
3716#else
3717 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
3718#endif
3719}
3720
3721PRE(sys_semtimedop)
3722{
3723 *flags |= SfMayBlock;
3724 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
3725 PRE_REG_READ4(long, "semtimedop",
3726 int, semid, struct sembuf *, sops, unsigned, nsoops,
3727 struct timespec *, timeout);
3728 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
3729}
3730
3731PRE(sys_msgget)
3732{
3733 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
3734 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
3735}
3736
3737PRE(sys_msgsnd)
3738{
3739 PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
3740 PRE_REG_READ4(long, "msgsnd",
3741 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
3742 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
3743 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
3744 *flags |= SfMayBlock;
3745}
3746
3747PRE(sys_msgrcv)
3748{
3749 PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
3750 PRE_REG_READ5(long, "msgrcv",
3751 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
3752 long, msgytp, int, msgflg);
3753 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
3754 if ((ARG5 & VKI_IPC_NOWAIT) == 0)
3755 *flags |= SfMayBlock;
3756}
3757POST(sys_msgrcv)
3758{
3759 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
3760}
3761
3762PRE(sys_msgctl)
3763{
3764 PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
3765 PRE_REG_READ3(long, "msgctl",
3766 int, msqid, int, cmd, struct msqid_ds *, buf);
3767 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
3768}
3769
3770POST(sys_msgctl)
3771{
3772 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
3773}
3774
3775PRE(sys_shmget)
3776{
3777 PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
3778 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
3779}
3780
3781PRE(wrap_sys_shmat)
3782{
3783 UWord arg2tmp;
3784 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3785 PRE_REG_READ3(long, "shmat",
3786 int, shmid, const void *, shmaddr, int, shmflg);
3787#if defined(VGP_arm_linux)
3788 /* Round the attach address down to an VKI_SHMLBA boundary if the
3789 client requested rounding. See #222545. This is necessary only
3790 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
3791 other linux targets it is the same as the page size. */
3792 if (ARG3 & VKI_SHM_RND)
3793 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
3794#endif
3795 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
3796 if (arg2tmp == 0)
3797 SET_STATUS_Failure( VKI_EINVAL );
3798 else
3799 ARG2 = arg2tmp; // used in POST
3800}
3801
3802POST(wrap_sys_shmat)
3803{
3804 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
3805}
3806
3807PRE(sys_shmdt)
3808{
3809 PRINT("sys_shmdt ( %#lx )",ARG1);
3810 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
3811 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
3812 SET_STATUS_Failure( VKI_EINVAL );
3813}
3814
3815POST(sys_shmdt)
3816{
3817 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
3818}
3819
3820PRE(sys_shmctl)
3821{
3822 PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
3823 PRE_REG_READ3(long, "shmctl",
3824 int, shmid, int, cmd, struct shmid_ds *, buf);
3825#ifdef VGP_amd64_linux
3826 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
3827#else
3828 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
3829#endif
3830}
3831
3832POST(sys_shmctl)
3833{
3834#ifdef VGP_amd64_linux
3835 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
3836#else
3837 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
3838#endif
3839}
3840
3841
philippe4eefc8c2012-10-21 20:21:17 +00003842/* ---------------------------------------------------------------------
philippef2a7bbe2012-11-04 20:40:33 +00003843 Generic handler for sys_socketcall
3844 Depending on the platform, some socket related syscalls (e.g. socketpair,
3845 socket, bind, ...)
3846 are either direct system calls, or are all implemented via sys_socketcall.
3847 ------------------------------------------------------------------ */
3848#ifdef __NR_socketcall
3849PRE(sys_socketcall)
3850{
3851# define ARG2_0 (((UWord*)ARG2)[0])
3852# define ARG2_1 (((UWord*)ARG2)[1])
3853# define ARG2_2 (((UWord*)ARG2)[2])
3854# define ARG2_3 (((UWord*)ARG2)[3])
3855# define ARG2_4 (((UWord*)ARG2)[4])
3856# define ARG2_5 (((UWord*)ARG2)[5])
3857
3858// call PRE_MEM_READ and check for EFAULT result.
3859#define PRE_MEM_READ_ef(msg, arg, size) \
3860 { \
3861 PRE_MEM_READ( msg, arg, size); \
3862 if (!ML_(valid_client_addr)(arg, size, tid, NULL)) { \
3863 SET_STATUS_Failure( VKI_EFAULT ); \
3864 break; \
3865 } \
3866 }
3867
3868 *flags |= SfMayBlock;
3869 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
3870 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
3871
3872 switch (ARG1 /* request */) {
3873
3874 case VKI_SYS_SOCKETPAIR:
3875 /* int socketpair(int d, int type, int protocol, int sv[2]); */
3876 PRE_MEM_READ_ef( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
3877 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
3878 break;
3879
3880 case VKI_SYS_SOCKET:
3881 /* int socket(int domain, int type, int protocol); */
3882 PRE_MEM_READ_ef( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
3883 break;
3884
3885 case VKI_SYS_BIND:
3886 /* int bind(int sockfd, struct sockaddr *my_addr,
3887 int addrlen); */
3888 PRE_MEM_READ_ef( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
3889 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
3890 break;
3891
3892 case VKI_SYS_LISTEN:
3893 /* int listen(int s, int backlog); */
3894 PRE_MEM_READ_ef( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
3895 break;
3896
3897 case VKI_SYS_ACCEPT:
3898 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
3899 PRE_MEM_READ_ef( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
3900 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
3901 break;
3902
3903 case VKI_SYS_ACCEPT4:
3904 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
3905 PRE_MEM_READ_ef( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
3906 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
3907 break;
3908
3909 case VKI_SYS_SENDTO:
3910 /* int sendto(int s, const void *msg, int len,
3911 unsigned int flags,
3912 const struct sockaddr *to, int tolen); */
3913 PRE_MEM_READ_ef( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
3914 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
3915 ARG2_3, ARG2_4, ARG2_5 );
3916 break;
3917
3918 case VKI_SYS_SEND:
3919 /* int send(int s, const void *msg, size_t len, int flags); */
3920 PRE_MEM_READ_ef( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
3921 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
3922 break;
3923
3924 case VKI_SYS_RECVFROM:
3925 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
3926 struct sockaddr *from, int *fromlen); */
3927 PRE_MEM_READ_ef( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
3928 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
3929 ARG2_3, ARG2_4, ARG2_5 );
3930 break;
3931
3932 case VKI_SYS_RECV:
3933 /* int recv(int s, void *buf, int len, unsigned int flags); */
3934 /* man 2 recv says:
3935 The recv call is normally used only on a connected socket
3936 (see connect(2)) and is identical to recvfrom with a NULL
3937 from parameter.
3938 */
3939 PRE_MEM_READ_ef( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
3940 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
3941 break;
3942
3943 case VKI_SYS_CONNECT:
3944 /* int connect(int sockfd,
3945 struct sockaddr *serv_addr, int addrlen ); */
3946 PRE_MEM_READ_ef( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
3947 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
3948 break;
3949
3950 case VKI_SYS_SETSOCKOPT:
3951 /* int setsockopt(int s, int level, int optname,
3952 const void *optval, int optlen); */
3953 PRE_MEM_READ_ef( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
tom70f71aa2013-07-17 14:36:57 +00003954 ML_(linux_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
3955 ARG2_3, ARG2_4 );
philippef2a7bbe2012-11-04 20:40:33 +00003956 break;
3957
3958 case VKI_SYS_GETSOCKOPT:
3959 /* int getsockopt(int s, int level, int optname,
3960 void *optval, socklen_t *optlen); */
3961 PRE_MEM_READ_ef( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
3962 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
3963 ARG2_3, ARG2_4 );
3964 break;
3965
3966 case VKI_SYS_GETSOCKNAME:
3967 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
3968 PRE_MEM_READ_ef( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
3969 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
3970 break;
3971
3972 case VKI_SYS_GETPEERNAME:
3973 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
3974 PRE_MEM_READ_ef( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
3975 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
3976 break;
3977
3978 case VKI_SYS_SHUTDOWN:
3979 /* int shutdown(int s, int how); */
3980 PRE_MEM_READ_ef( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
3981 break;
3982
3983 case VKI_SYS_SENDMSG:
3984 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
3985 PRE_MEM_READ_ef( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
3986 ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
3987 break;
3988
3989 case VKI_SYS_RECVMSG:
3990 /* int recvmsg(int s, struct msghdr *msg, int flags); */
3991 PRE_MEM_READ_ef("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
3992 ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
3993 break;
3994
3995 default:
3996 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
3997 SET_STATUS_Failure( VKI_EINVAL );
3998 break;
3999 }
4000# undef ARG2_0
4001# undef ARG2_1
4002# undef ARG2_2
4003# undef ARG2_3
4004# undef ARG2_4
4005# undef ARG2_5
4006}
4007
4008POST(sys_socketcall)
4009{
4010# define ARG2_0 (((UWord*)ARG2)[0])
4011# define ARG2_1 (((UWord*)ARG2)[1])
4012# define ARG2_2 (((UWord*)ARG2)[2])
4013# define ARG2_3 (((UWord*)ARG2)[3])
4014# define ARG2_4 (((UWord*)ARG2)[4])
4015# define ARG2_5 (((UWord*)ARG2)[5])
4016
4017 SysRes r;
4018 vg_assert(SUCCESS);
4019 switch (ARG1 /* request */) {
4020
4021 case VKI_SYS_SOCKETPAIR:
4022 r = ML_(generic_POST_sys_socketpair)(
4023 tid, VG_(mk_SysRes_Success)(RES),
4024 ARG2_0, ARG2_1, ARG2_2, ARG2_3
4025 );
4026 SET_STATUS_from_SysRes(r);
4027 break;
4028
4029 case VKI_SYS_SOCKET:
4030 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
4031 SET_STATUS_from_SysRes(r);
4032 break;
4033
4034 case VKI_SYS_BIND:
4035 /* int bind(int sockfd, struct sockaddr *my_addr,
4036 int addrlen); */
4037 break;
4038
4039 case VKI_SYS_LISTEN:
4040 /* int listen(int s, int backlog); */
4041 break;
4042
4043 case VKI_SYS_ACCEPT:
4044 case VKI_SYS_ACCEPT4:
4045 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
4046 /* int accept4(int s, struct sockaddr *addr, int *addrlen, int flags); */
4047 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
4048 ARG2_0, ARG2_1, ARG2_2 );
4049 SET_STATUS_from_SysRes(r);
4050 break;
4051
4052 case VKI_SYS_SENDTO:
4053 break;
4054
4055 case VKI_SYS_SEND:
4056 break;
4057
4058 case VKI_SYS_RECVFROM:
4059 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
4060 ARG2_0, ARG2_1, ARG2_2,
4061 ARG2_3, ARG2_4, ARG2_5 );
4062 break;
4063
4064 case VKI_SYS_RECV:
4065 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
4066 break;
4067
4068 case VKI_SYS_CONNECT:
4069 break;
4070
4071 case VKI_SYS_SETSOCKOPT:
4072 break;
4073
4074 case VKI_SYS_GETSOCKOPT:
4075 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
4076 ARG2_0, ARG2_1,
4077 ARG2_2, ARG2_3, ARG2_4 );
4078 break;
4079
4080 case VKI_SYS_GETSOCKNAME:
4081 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
4082 ARG2_0, ARG2_1, ARG2_2 );
4083 break;
4084
4085 case VKI_SYS_GETPEERNAME:
4086 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
4087 ARG2_0, ARG2_1, ARG2_2 );
4088 break;
4089
4090 case VKI_SYS_SHUTDOWN:
4091 break;
4092
4093 case VKI_SYS_SENDMSG:
4094 break;
4095
4096 case VKI_SYS_RECVMSG:
4097 ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
4098 break;
4099
4100 default:
4101 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
4102 VG_(core_panic)("... bye!\n");
4103 break; /*NOTREACHED*/
4104 }
4105# undef ARG2_0
4106# undef ARG2_1
4107# undef ARG2_2
4108# undef ARG2_3
4109# undef ARG2_4
4110# undef ARG2_5
4111}
4112#endif
4113
philippe6b087762013-03-01 23:31:09 +00004114PRE(sys_socket)
4115{
4116 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
4117 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
4118}
4119POST(sys_socket)
4120{
4121 SysRes r;
4122 vg_assert(SUCCESS);
4123 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
4124 SET_STATUS_from_SysRes(r);
4125}
4126
4127PRE(sys_setsockopt)
4128{
4129 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
4130 PRE_REG_READ5(long, "setsockopt",
4131 int, s, int, level, int, optname,
4132 const void *, optval, int, optlen);
tom70f71aa2013-07-17 14:36:57 +00004133 ML_(linux_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
philippe6b087762013-03-01 23:31:09 +00004134}
4135
4136PRE(sys_getsockopt)
4137{
4138 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
4139 PRE_REG_READ5(long, "getsockopt",
4140 int, s, int, level, int, optname,
4141 void *, optval, int, *optlen);
4142 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
4143}
4144POST(sys_getsockopt)
4145{
4146 vg_assert(SUCCESS);
4147 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
4148 ARG1,ARG2,ARG3,ARG4,ARG5);
4149}
4150
4151PRE(sys_connect)
4152{
4153 *flags |= SfMayBlock;
4154 PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4155 PRE_REG_READ3(long, "connect",
4156 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
4157 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
4158}
4159
4160PRE(sys_accept)
4161{
4162 *flags |= SfMayBlock;
4163 PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4164 PRE_REG_READ3(long, "accept",
4165 int, s, struct sockaddr *, addr, int, *addrlen);
4166 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4167}
4168POST(sys_accept)
4169{
4170 SysRes r;
4171 vg_assert(SUCCESS);
4172 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4173 ARG1,ARG2,ARG3);
4174 SET_STATUS_from_SysRes(r);
4175}
4176
4177PRE(sys_accept4)
4178{
4179 *flags |= SfMayBlock;
4180 PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
4181 PRE_REG_READ4(long, "accept4",
4182 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
4183 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
4184}
4185POST(sys_accept4)
4186{
4187 SysRes r;
4188 vg_assert(SUCCESS);
4189 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
4190 ARG1,ARG2,ARG3);
4191 SET_STATUS_from_SysRes(r);
4192}
4193
4194PRE(sys_send)
4195{
4196 *flags |= SfMayBlock;
4197 PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
4198 PRE_REG_READ4(long, "send",
4199 int, s, const void *, msg, int, len,
4200 unsigned int, flags);
4201
4202 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
4203}
4204
4205PRE(sys_sendto)
4206{
4207 *flags |= SfMayBlock;
4208 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4209 PRE_REG_READ6(long, "sendto",
4210 int, s, const void *, msg, int, len,
4211 unsigned int, flags,
4212 const struct sockaddr *, to, int, tolen);
4213 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4214}
4215
4216PRE (sys_recv)
4217{
4218 *flags |= SfMayBlock;
4219 PRINT ("sys_recv ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4);
4220 PRE_REG_READ4 (long, "recv", int, s, void *, buf, int, len,
4221 unsigned int, flags);
4222 ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
4223}
4224
4225POST (sys_recv)
4226{
4227 ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
4228}
4229
4230PRE(sys_recvfrom)
4231{
4232 *flags |= SfMayBlock;
4233 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4234 PRE_REG_READ6(long, "recvfrom",
4235 int, s, void *, buf, int, len, unsigned int, flags,
4236 struct sockaddr *, from, int *, fromlen);
4237 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4238}
4239POST(sys_recvfrom)
4240{
4241 vg_assert(SUCCESS);
4242 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
4243 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
4244}
4245
4246PRE(sys_sendmsg)
4247{
4248 *flags |= SfMayBlock;
4249 PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4250 PRE_REG_READ3(long, "sendmsg",
4251 int, s, const struct msghdr *, msg, int, flags);
4252 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4253}
4254
4255PRE(sys_recvmsg)
4256{
4257 *flags |= SfMayBlock;
4258 PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4259 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
4260 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
4261}
4262POST(sys_recvmsg)
4263{
4264 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
4265}
4266
4267PRE(sys_shutdown)
4268{
4269 *flags |= SfMayBlock;
4270 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
4271 PRE_REG_READ2(int, "shutdown", int, s, int, how);
4272}
4273
4274PRE(sys_bind)
4275{
4276 PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
4277 PRE_REG_READ3(long, "bind",
4278 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
4279 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
4280}
4281
4282PRE(sys_listen)
4283{
4284 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
4285 PRE_REG_READ2(long, "listen", int, s, int, backlog);
4286}
4287
4288PRE(sys_getsockname)
4289{
4290 PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
4291 PRE_REG_READ3(long, "getsockname",
4292 int, s, struct sockaddr *, name, int *, namelen);
4293 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
4294}
4295POST(sys_getsockname)
4296{
4297 vg_assert(SUCCESS);
4298 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
4299 ARG1,ARG2,ARG3);
4300}
4301
4302PRE(sys_getpeername)
4303{
4304 PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
4305 PRE_REG_READ3(long, "getpeername",
4306 int, s, struct sockaddr *, name, int *, namelen);
4307 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
4308}
4309POST(sys_getpeername)
4310{
4311 vg_assert(SUCCESS);
4312 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
4313 ARG1,ARG2,ARG3);
4314}
4315
4316PRE(sys_socketpair)
4317{
4318 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
4319 PRE_REG_READ4(long, "socketpair",
4320 int, d, int, type, int, protocol, int*, sv);
4321 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
4322}
4323POST(sys_socketpair)
4324{
4325 vg_assert(SUCCESS);
4326 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
4327 ARG1,ARG2,ARG3,ARG4);
4328}
4329
4330
philippef2a7bbe2012-11-04 20:40:33 +00004331/* ---------------------------------------------------------------------
tom363ec762006-03-21 10:58:35 +00004332 *at wrappers
4333 ------------------------------------------------------------------ */
4334
4335PRE(sys_openat)
4336{
4337 HChar name[30];
4338 SysRes sres;
4339
4340 if (ARG3 & VKI_O_CREAT) {
4341 // 4-arg version
barta0b6b2c2008-07-07 06:49:24 +00004342 PRINT("sys_openat ( %ld, %#lx(%s), %ld, %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
tom363ec762006-03-21 10:58:35 +00004343 PRE_REG_READ4(long, "openat",
4344 int, dfd, const char *, filename, int, flags, int, mode);
4345 } else {
4346 // 3-arg version
barta0b6b2c2008-07-07 06:49:24 +00004347 PRINT("sys_openat ( %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004348 PRE_REG_READ3(long, "openat",
4349 int, dfd, const char *, filename, int, flags);
4350 }
4351
sewardjf73de262012-12-06 16:05:18 +00004352 PRE_MEM_RASCIIZ( "openat(filename)", ARG2 );
4353
4354 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
4355 filename is relative to cwd. */
4356 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
4357 && *(Char *)ARG2 != '/'
4358 && ARG1 != VKI_AT_FDCWD
4359 && !ML_(fd_allowed)(ARG1, "openat", tid, False))
tom363ec762006-03-21 10:58:35 +00004360 SET_STATUS_Failure( VKI_EBADF );
tom363ec762006-03-21 10:58:35 +00004361
4362 /* Handle the case where the open is of /proc/self/cmdline or
4363 /proc/<pid>/cmdline, and just give it a copy of the fd for the
4364 fake file we cooked up at startup (in m_main). Also, seek the
4365 cloned fd back to the start. */
4366
4367 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4368 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
florian1636d332012-11-15 04:27:04 +00004369 && (VG_(strcmp)((HChar *)ARG2, name) == 0
4370 || VG_(strcmp)((HChar *)ARG2, "/proc/self/cmdline") == 0)) {
tom363ec762006-03-21 10:58:35 +00004371 sres = VG_(dup)( VG_(cl_cmdline_fd) );
4372 SET_STATUS_from_SysRes( sres );
njncda2f0f2009-05-18 02:12:08 +00004373 if (!sr_isError(sres)) {
4374 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
tom363ec762006-03-21 10:58:35 +00004375 if (off < 0)
4376 SET_STATUS_Failure( VKI_EMFILE );
4377 }
4378 return;
4379 }
4380
tom41ad7e72012-10-04 20:27:38 +00004381 /* Do the same for /proc/self/auxv or /proc/<pid>/auxv case. */
4382
4383 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
4384 if (ML_(safe_to_deref)( (void*)ARG2, 1 )
florian1636d332012-11-15 04:27:04 +00004385 && (VG_(strcmp)((HChar *)ARG2, name) == 0
4386 || VG_(strcmp)((HChar *)ARG2, "/proc/self/auxv") == 0)) {
tom41ad7e72012-10-04 20:27:38 +00004387 sres = VG_(dup)( VG_(cl_auxv_fd) );
4388 SET_STATUS_from_SysRes( sres );
4389 if (!sr_isError(sres)) {
4390 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4391 if (off < 0)
4392 SET_STATUS_Failure( VKI_EMFILE );
4393 }
4394 return;
4395 }
4396
tom363ec762006-03-21 10:58:35 +00004397 /* Otherwise handle normally */
4398 *flags |= SfMayBlock;
4399}
4400
4401POST(sys_openat)
4402{
4403 vg_assert(SUCCESS);
4404 if (!ML_(fd_allowed)(RES, "openat", tid, True)) {
4405 VG_(close)(RES);
4406 SET_STATUS_Failure( VKI_EMFILE );
4407 } else {
4408 if (VG_(clo_track_fds))
florian1636d332012-11-15 04:27:04 +00004409 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
tom363ec762006-03-21 10:58:35 +00004410 }
4411}
4412
4413PRE(sys_mkdirat)
4414{
4415 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00004416 PRINT("sys_mkdirat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004417 PRE_REG_READ3(long, "mkdirat",
4418 int, dfd, const char *, pathname, int, mode);
4419 PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 );
4420}
4421
4422PRE(sys_mknodat)
4423{
barta0b6b2c2008-07-07 06:49:24 +00004424 PRINT("sys_mknodat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 );
tom363ec762006-03-21 10:58:35 +00004425 PRE_REG_READ4(long, "mknodat",
4426 int, dfd, const char *, pathname, int, mode, unsigned, dev);
4427 PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 );
4428}
4429
4430PRE(sys_fchownat)
4431{
barta0b6b2c2008-07-07 06:49:24 +00004432 PRINT("sys_fchownat ( %ld, %#lx(%s), 0x%lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
tom363ec762006-03-21 10:58:35 +00004433 PRE_REG_READ4(long, "fchownat",
4434 int, dfd, const char *, path,
4435 vki_uid_t, owner, vki_gid_t, group);
4436 PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 );
4437}
4438
4439PRE(sys_futimesat)
4440{
barta0b6b2c2008-07-07 06:49:24 +00004441 PRINT("sys_futimesat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004442 PRE_REG_READ3(long, "futimesat",
4443 int, dfd, char *, filename, struct timeval *, tvp);
sewardjf4ef2ea2008-05-12 14:29:23 +00004444 if (ARG2 != 0)
4445 PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 );
tom363ec762006-03-21 10:58:35 +00004446 if (ARG3 != 0)
bartf5ceec82008-04-26 07:45:10 +00004447 PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) );
4448}
4449
4450PRE(sys_utimensat)
4451{
barta0b6b2c2008-07-07 06:49:24 +00004452 PRINT("sys_utimensat ( %ld, %#lx(%s), %#lx, 0x%lx )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4);
bartf5ceec82008-04-26 07:45:10 +00004453 PRE_REG_READ4(long, "utimensat",
4454 int, dfd, char *, filename, struct timespec *, utimes, int, flags);
sewardjf4ef2ea2008-05-12 14:29:23 +00004455 if (ARG2 != 0)
4456 PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 );
bartf5ceec82008-04-26 07:45:10 +00004457 if (ARG3 != 0)
4458 PRE_MEM_READ( "utimensat(tvp)", ARG3, 2 * sizeof(struct vki_timespec) );
tom363ec762006-03-21 10:58:35 +00004459}
4460
4461PRE(sys_newfstatat)
4462{
sewardjcc3de2d2011-08-18 15:08:20 +00004463 FUSE_COMPATIBLE_MAY_BLOCK();
barta0b6b2c2008-07-07 06:49:24 +00004464 PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004465 PRE_REG_READ3(long, "fstatat",
4466 int, dfd, char *, file_name, struct stat *, buf);
4467 PRE_MEM_RASCIIZ( "fstatat(file_name)", ARG2 );
4468 PRE_MEM_WRITE( "fstatat(buf)", ARG3, sizeof(struct vki_stat) );
4469}
4470
4471POST(sys_newfstatat)
4472{
4473 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat) );
4474}
4475
4476PRE(sys_unlinkat)
4477{
4478 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00004479 PRINT("sys_unlinkat ( %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2);
tom363ec762006-03-21 10:58:35 +00004480 PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname);
4481 PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 );
4482}
4483
4484PRE(sys_renameat)
4485{
barta0b6b2c2008-07-07 06:49:24 +00004486 PRINT("sys_renameat ( %ld, %#lx(%s), %ld, %#lx(%s) )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4);
toma43717f2006-05-08 11:19:47 +00004487 PRE_REG_READ4(long, "renameat",
4488 int, olddfd, const char *, oldpath,
4489 int, newdfd, const char *, newpath);
tom363ec762006-03-21 10:58:35 +00004490 PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 );
toma43717f2006-05-08 11:19:47 +00004491 PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 );
tom363ec762006-03-21 10:58:35 +00004492}
4493
4494PRE(sys_linkat)
4495{
4496 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00004497 PRINT("sys_linkat ( %ld, %#lx(%s), %ld, %#lx(%s), %ld )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4,ARG5);
toma43717f2006-05-08 11:19:47 +00004498 PRE_REG_READ5(long, "linkat",
4499 int, olddfd, const char *, oldpath,
4500 int, newdfd, const char *, newpath,
4501 int, flags);
tom363ec762006-03-21 10:58:35 +00004502 PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2);
toma43717f2006-05-08 11:19:47 +00004503 PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4);
tom363ec762006-03-21 10:58:35 +00004504}
4505
4506PRE(sys_symlinkat)
4507{
4508 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00004509 PRINT("sys_symlinkat ( %#lx(%s), %ld, %#lx(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3);
tom363ec762006-03-21 10:58:35 +00004510 PRE_REG_READ3(long, "symlinkat",
toma43717f2006-05-08 11:19:47 +00004511 const char *, oldpath, int, newdfd, const char *, newpath);
4512 PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 );
tom363ec762006-03-21 10:58:35 +00004513 PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 );
4514}
4515
4516PRE(sys_readlinkat)
4517{
4518 HChar name[25];
4519 Word saved = SYSNO;
4520
barta0b6b2c2008-07-07 06:49:24 +00004521 PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
tom363ec762006-03-21 10:58:35 +00004522 PRE_REG_READ4(long, "readlinkat",
4523 int, dfd, const char *, path, char *, buf, int, bufsiz);
4524 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
4525 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
4526
4527 /*
4528 * Handle the case where readlinkat is looking at /proc/self/exe or
4529 * /proc/<pid>/exe.
4530 */
4531 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
4532 if (ML_(safe_to_deref)((void*)ARG2, 1)
florian1636d332012-11-15 04:27:04 +00004533 && (VG_(strcmp)((HChar *)ARG2, name) == 0
4534 || VG_(strcmp)((HChar *)ARG2, "/proc/self/exe") == 0)) {
tom363ec762006-03-21 10:58:35 +00004535 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
4536 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
4537 ARG3, ARG4));
4538 } else {
4539 /* Normal case */
4540 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
4541 }
4542
4543 if (SUCCESS && RES > 0)
4544 POST_MEM_WRITE( ARG3, RES );
4545}
4546
4547PRE(sys_fchmodat)
4548{
barta0b6b2c2008-07-07 06:49:24 +00004549 PRINT("sys_fchmodat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004550 PRE_REG_READ3(long, "fchmodat",
4551 int, dfd, const char *, path, vki_mode_t, mode);
4552 PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
4553}
4554
4555PRE(sys_faccessat)
4556{
barta0b6b2c2008-07-07 06:49:24 +00004557 PRINT("sys_faccessat ( %ld, %#lx(%s), %ld )", ARG1,ARG2,(char*)ARG2,ARG3);
tom363ec762006-03-21 10:58:35 +00004558 PRE_REG_READ3(long, "faccessat",
4559 int, dfd, const char *, pathname, int, mode);
4560 PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 );
4561}
4562
tomf9e5b5e2013-03-03 12:57:20 +00004563PRE(sys_name_to_handle_at)
4564{
4565 PRINT("sys_name_to_handle_at ( %ld, %#lx(%s), %#lx, %#lx, %ld )", ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5);
4566 PRE_REG_READ5(int, "name_to_handle_at",
4567 int, dfd, const char *, name,
tom43ca0972013-07-17 13:25:08 +00004568 struct vki_file_handle *, handle,
tomf9e5b5e2013-03-03 12:57:20 +00004569 int *, mnt_id, int, flag);
4570 PRE_MEM_RASCIIZ( "name_to_handle_at(name)", ARG2 );
tom43ca0972013-07-17 13:25:08 +00004571 if (ML_(safe_to_deref)( (void*)ARG3, sizeof(struct vki_file_handle))) {
4572 struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
4573 PRE_MEM_READ( "name_to_handle_at(handle)", (Addr)&fh->handle_bytes, sizeof(fh->handle_bytes) );
4574 PRE_MEM_WRITE( "name_to_handle_at(handle)", (Addr)fh, sizeof(struct vki_file_handle) + fh->handle_bytes );
4575 }
tomf9e5b5e2013-03-03 12:57:20 +00004576 PRE_MEM_WRITE( "name_to_handle_at(mnt_id)", ARG4, sizeof(int) );
4577}
4578
4579POST(sys_name_to_handle_at)
4580{
tom43ca0972013-07-17 13:25:08 +00004581 struct vki_file_handle *fh = (struct vki_file_handle *)ARG3;
4582 POST_MEM_WRITE( ARG3, sizeof(struct vki_file_handle) + fh->handle_bytes );
tomf9e5b5e2013-03-03 12:57:20 +00004583 POST_MEM_WRITE( ARG4, sizeof(int) );
4584}
4585
tom43ca0972013-07-17 13:25:08 +00004586PRE(sys_open_by_handle_at)
4587{
4588 *flags |= SfMayBlock;
4589 PRINT("sys_open_by_handle_at ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
4590 PRE_REG_READ3(int, "open_by_handle_at",
4591 int, mountdirfd,
4592 struct vki_file_handle *, handle,
4593 int, flags);
4594 PRE_MEM_READ( "open_by_handle_at(handle)", ARG2, sizeof(struct vki_file_handle) + ((struct vki_file_handle*)ARG2)->handle_bytes );
4595}
4596
4597POST(sys_open_by_handle_at)
4598{
4599 vg_assert(SUCCESS);
4600 if (!ML_(fd_allowed)(RES, "open_by_handle_at", tid, True)) {
4601 VG_(close)(RES);
4602 SET_STATUS_Failure( VKI_EMFILE );
4603 } else {
4604 if (VG_(clo_track_fds))
4605 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2);
4606 }
4607}
4608
tom7f4d7e42007-03-07 11:12:13 +00004609/* ---------------------------------------------------------------------
tomd8feb702009-10-28 10:04:11 +00004610 p{read,write}v wrappers
4611 ------------------------------------------------------------------ */
4612
4613PRE(sys_preadv)
4614{
4615 Int i;
4616 struct vki_iovec * vec;
4617 *flags |= SfMayBlock;
4618#if VG_WORDSIZE == 4
tom41f4c852009-12-02 16:19:12 +00004619 /* Note that the offset argument here is in lo+hi order on both
4620 big and little endian platforms... */
4621 PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
tomd8feb702009-10-28 10:04:11 +00004622 PRE_REG_READ5(ssize_t, "preadv",
4623 unsigned long, fd, const struct iovec *, vector,
tom41f4c852009-12-02 16:19:12 +00004624 unsigned long, count, vki_u32, offset_low,
4625 vki_u32, offset_high);
tomd8feb702009-10-28 10:04:11 +00004626#elif VG_WORDSIZE == 8
4627 PRINT("sys_preadv ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
4628 PRE_REG_READ4(ssize_t, "preadv",
4629 unsigned long, fd, const struct iovec *, vector,
4630 unsigned long, count, Word, offset);
4631#else
4632# error Unexpected word size
4633#endif
4634 if (!ML_(fd_allowed)(ARG1, "preadv", tid, False)) {
4635 SET_STATUS_Failure( VKI_EBADF );
4636 } else {
4637 PRE_MEM_READ( "preadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
4638
4639 if (ARG2 != 0) {
4640 /* ToDo: don't do any of the following if the vector is invalid */
4641 vec = (struct vki_iovec *)ARG2;
4642 for (i = 0; i < (Int)ARG3; i++)
4643 PRE_MEM_WRITE( "preadv(vector[...])",
4644 (Addr)vec[i].iov_base, vec[i].iov_len );
4645 }
4646 }
4647}
4648
4649POST(sys_preadv)
4650{
4651 vg_assert(SUCCESS);
4652 if (RES > 0) {
4653 Int i;
4654 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4655 Int remains = RES;
4656
4657 /* RES holds the number of bytes read. */
4658 for (i = 0; i < (Int)ARG3; i++) {
4659 Int nReadThisBuf = vec[i].iov_len;
4660 if (nReadThisBuf > remains) nReadThisBuf = remains;
4661 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4662 remains -= nReadThisBuf;
4663 if (remains < 0) VG_(core_panic)("preadv: remains < 0");
4664 }
4665 }
4666}
4667
4668PRE(sys_pwritev)
4669{
4670 Int i;
4671 struct vki_iovec * vec;
4672 *flags |= SfMayBlock;
4673#if VG_WORDSIZE == 4
tom41f4c852009-12-02 16:19:12 +00004674 /* Note that the offset argument here is in lo+hi order on both
4675 big and little endian platforms... */
4676 PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,LOHI64(ARG4,ARG5));
tomd8feb702009-10-28 10:04:11 +00004677 PRE_REG_READ5(ssize_t, "pwritev",
4678 unsigned long, fd, const struct iovec *, vector,
tom41f4c852009-12-02 16:19:12 +00004679 unsigned long, count, vki_u32, offset_low,
4680 vki_u32, offset_high);
tomd8feb702009-10-28 10:04:11 +00004681#elif VG_WORDSIZE == 8
4682 PRINT("sys_pwritev ( %ld, %#lx, %llu, %lld )",ARG1,ARG2,(ULong)ARG3,(Long)ARG4);
4683 PRE_REG_READ4(ssize_t, "pwritev",
4684 unsigned long, fd, const struct iovec *, vector,
4685 unsigned long, count, Word, offset);
4686#else
4687# error Unexpected word size
4688#endif
4689 if (!ML_(fd_allowed)(ARG1, "pwritev", tid, False)) {
4690 SET_STATUS_Failure( VKI_EBADF );
4691 } else {
4692 PRE_MEM_READ( "pwritev(vector)",
4693 ARG2, ARG3 * sizeof(struct vki_iovec) );
4694 if (ARG2 != 0) {
4695 /* ToDo: don't do any of the following if the vector is invalid */
4696 vec = (struct vki_iovec *)ARG2;
4697 for (i = 0; i < (Int)ARG3; i++)
4698 PRE_MEM_READ( "pwritev(vector[...])",
4699 (Addr)vec[i].iov_base, vec[i].iov_len );
4700 }
4701 }
4702}
4703
4704/* ---------------------------------------------------------------------
tom9e4b6362012-02-10 09:39:37 +00004705 process_vm_{read,write}v wrappers
4706 ------------------------------------------------------------------ */
4707
4708PRE(sys_process_vm_readv)
4709{
4710 PRINT("sys_process_vm_readv ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
4711 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4712 PRE_REG_READ6(ssize_t, "process_vm_readv",
4713 vki_pid_t, pid,
4714 const struct iovec *, lvec,
4715 unsigned long, liovcnt,
4716 const struct iovec *, rvec,
4717 unsigned long, riovcnt,
4718 unsigned long, flags);
4719 PRE_MEM_READ( "process_vm_readv(lvec)",
4720 ARG2, ARG3 * sizeof(struct vki_iovec) );
4721 PRE_MEM_READ( "process_vm_readv(rvec)",
4722 ARG4, ARG5 * sizeof(struct vki_iovec) );
4723 if (ARG2 != 0) {
4724 /* TODO: Don't do any of the following if lvec is invalid */
4725 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4726 UInt i;
4727 for (i = 0; i < ARG3; i++)
4728 PRE_MEM_WRITE( "process_vm_readv(lvec[...])",
4729 (Addr)vec[i].iov_base, vec[i].iov_len );
4730 }
4731}
4732
4733POST(sys_process_vm_readv)
4734{
4735 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4736 UInt remains = RES;
4737 UInt i;
4738 for (i = 0; i < ARG3; i++) {
4739 UInt nReadThisBuf = vec[i].iov_len <= remains ?
4740 vec[i].iov_len : remains;
4741 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4742 remains -= nReadThisBuf;
4743 }
4744}
4745
4746PRE(sys_process_vm_writev)
4747{
4748 PRINT("sys_process_vm_writev ( %lu, %#lx, %lu, %#lx, %lu, %lu )",
4749 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
4750 PRE_REG_READ6(ssize_t, "process_vm_writev",
4751 vki_pid_t, pid,
4752 const struct iovec *, lvec,
4753 unsigned long, liovcnt,
4754 const struct iovec *, rvec,
4755 unsigned long, riovcnt,
4756 unsigned long, flags);
4757 PRE_MEM_READ( "process_vm_writev(lvec)",
4758 ARG2, ARG3 * sizeof(struct vki_iovec) );
4759 PRE_MEM_READ( "process_vm_writev(rvec)",
4760 ARG4, ARG5 * sizeof(struct vki_iovec) );
4761 if (ARG2 != 0) {
4762 /* TODO: Don't do any of the following if lvec is invalid */
4763 const struct vki_iovec *vec = (const struct vki_iovec *)ARG2;
4764 UInt i;
4765 for (i = 0; i < ARG3; i++)
4766 PRE_MEM_READ( "process_vm_writev(lvec[...])",
4767 (Addr)vec[i].iov_base, vec[i].iov_len );
4768 }
4769}
4770
4771/* ---------------------------------------------------------------------
toma4991232012-02-10 11:30:09 +00004772 {send,recv}mmsg wrappers
4773 ------------------------------------------------------------------ */
4774
4775PRE(sys_sendmmsg)
4776{
4777 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
floriane543f302012-10-21 19:43:43 +00004778 HChar name[32];
toma4991232012-02-10 11:30:09 +00004779 UInt i;
4780 *flags |= SfMayBlock;
4781 PRINT("sys_sendmmsg ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
4782 PRE_REG_READ4(long, "sendmmsg",
4783 int, s, const struct mmsghdr *, mmsg, int, vlen, int, flags);
4784 for (i = 0; i < ARG3; i++) {
tom200bdb32012-02-10 11:54:16 +00004785 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
toma4991232012-02-10 11:30:09 +00004786 ML_(generic_PRE_sys_sendmsg)(tid, name, &mmsg[i].msg_hdr);
tom27640002012-02-10 11:48:01 +00004787 VG_(sprintf)(name, "sendmmsg(mmsg[%u].msg_len)", i);
4788 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
4789 }
4790}
4791
4792POST(sys_sendmmsg)
4793{
4794 if (RES > 0) {
4795 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
4796 UInt i;
4797 for (i = 0; i < RES; i++) {
4798 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
4799 }
toma4991232012-02-10 11:30:09 +00004800 }
4801}
4802
4803PRE(sys_recvmmsg)
4804{
4805 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
floriane543f302012-10-21 19:43:43 +00004806 HChar name[32];
toma4991232012-02-10 11:30:09 +00004807 UInt i;
4808 *flags |= SfMayBlock;
4809 PRINT("sys_recvmmsg ( %ld, %#lx, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
4810 PRE_REG_READ5(long, "recvmmsg",
4811 int, s, struct mmsghdr *, mmsg, int, vlen,
4812 int, flags, struct timespec *, timeout);
4813 for (i = 0; i < ARG3; i++) {
tom200bdb32012-02-10 11:54:16 +00004814 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
toma4991232012-02-10 11:30:09 +00004815 ML_(generic_PRE_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr);
tom361c3bd2012-02-10 11:50:36 +00004816 VG_(sprintf)(name, "recvmmsg(mmsg[%u].msg_len)", i);
tom27640002012-02-10 11:48:01 +00004817 PRE_MEM_WRITE( name, (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
toma4991232012-02-10 11:30:09 +00004818 }
4819 if (ARG5)
4820 PRE_MEM_READ( "recvmmsg(timeout)", ARG5, sizeof(struct vki_timespec) );
4821}
4822
4823POST(sys_recvmmsg)
4824{
4825 if (RES > 0) {
4826 struct vki_mmsghdr *mmsg = (struct vki_mmsghdr *)ARG2;
floriane543f302012-10-21 19:43:43 +00004827 HChar name[32];
toma4991232012-02-10 11:30:09 +00004828 UInt i;
4829 for (i = 0; i < RES; i++) {
tom200bdb32012-02-10 11:54:16 +00004830 VG_(sprintf)(name, "mmsg[%u].msg_hdr", i);
tom8b3a6092012-02-10 16:45:01 +00004831 ML_(generic_POST_sys_recvmsg)(tid, name, &mmsg[i].msg_hdr, mmsg[i].msg_len);
toma4991232012-02-10 11:30:09 +00004832 POST_MEM_WRITE( (Addr)&mmsg[i].msg_len, sizeof(mmsg[i].msg_len) );
4833 }
4834 }
4835}
4836
4837/* ---------------------------------------------------------------------
tom7f4d7e42007-03-07 11:12:13 +00004838 key retention service wrappers
4839 ------------------------------------------------------------------ */
sewardj7acef082007-03-11 19:28:02 +00004840
tom7f4d7e42007-03-07 11:12:13 +00004841PRE(sys_request_key)
4842{
barta0b6b2c2008-07-07 06:49:24 +00004843 PRINT("sys_request_key ( %#lx(%s), %#lx(%s), %#lx(%s), %ld )",
4844 ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,(char*)ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004845 PRE_REG_READ4(long, "request_key",
4846 const char *, type, const char *, description,
4847 const char *, callout_info, vki_key_serial_t, keyring);
4848 PRE_MEM_RASCIIZ( "request_key(type)", ARG1);
4849 PRE_MEM_RASCIIZ( "request_key(description)", ARG2);
4850 if (ARG3 != (UWord)NULL)
4851 PRE_MEM_RASCIIZ( "request_key(callout_info)", ARG3);
4852}
4853
4854PRE(sys_add_key)
4855{
barta0b6b2c2008-07-07 06:49:24 +00004856 PRINT("sys_add_key ( %#lx(%s), %#lx(%s), %#lx, %ld, %ld )",
4857 ARG1,(char*)ARG1,ARG2,(char*)ARG2,ARG3,ARG4,ARG5);
tom7f4d7e42007-03-07 11:12:13 +00004858 PRE_REG_READ5(long, "add_key",
4859 const char *, type, const char *, description,
4860 const void *, payload, vki_size_t, plen,
4861 vki_key_serial_t, keyring);
4862 PRE_MEM_RASCIIZ( "add_key(type)", ARG1);
4863 PRE_MEM_RASCIIZ( "add_key(description)", ARG2);
4864 if (ARG3 != (UWord)NULL)
4865 PRE_MEM_READ( "request_key(payload)", ARG3, ARG4);
4866}
4867
4868PRE(sys_keyctl)
4869{
4870 switch (ARG1 /* option */) {
4871 case VKI_KEYCTL_GET_KEYRING_ID:
barta0b6b2c2008-07-07 06:49:24 +00004872 PRINT("sys_keyctl ( KEYCTL_GET_KEYRING_ID, %ld, %ld )", ARG2,ARG3);
tom7f4d7e42007-03-07 11:12:13 +00004873 PRE_REG_READ3(long, "keyctl(KEYCTL_GET_KEYRING_ID)",
4874 int, option, vki_key_serial_t, id, int, create);
4875 break;
4876 case VKI_KEYCTL_JOIN_SESSION_KEYRING:
barta0b6b2c2008-07-07 06:49:24 +00004877 PRINT("sys_keyctl ( KEYCTL_JOIN_SESSION_KEYRING, %#lx(%s) )", ARG2,(char*)ARG2);
tom7f4d7e42007-03-07 11:12:13 +00004878 PRE_REG_READ2(long, "keyctl(KEYCTL_JOIN_SESSION_KEYRING)",
4879 int, option, const char *, name);
4880 if (ARG2 != (UWord)NULL)
4881 PRE_MEM_RASCIIZ("keyctl(KEYCTL_JOIN_SESSION_KEYRING, name)", ARG2);
4882 break;
4883 case VKI_KEYCTL_UPDATE:
barta0b6b2c2008-07-07 06:49:24 +00004884 PRINT("sys_keyctl ( KEYCTL_UPDATE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004885 PRE_REG_READ4(long, "keyctl(KEYCTL_UPDATE)",
4886 int, option, vki_key_serial_t, key,
4887 const void *, payload, vki_size_t, plen);
4888 if (ARG3 != (UWord)NULL)
4889 PRE_MEM_READ("keyctl(KEYCTL_UPDATE, payload)", ARG3, ARG4);
4890 break;
4891 case VKI_KEYCTL_REVOKE:
barta0b6b2c2008-07-07 06:49:24 +00004892 PRINT("sys_keyctl ( KEYCTL_REVOKE, %ld )", ARG2);
tom7f4d7e42007-03-07 11:12:13 +00004893 PRE_REG_READ2(long, "keyctl(KEYCTL_REVOKE)",
4894 int, option, vki_key_serial_t, id);
4895 break;
4896 case VKI_KEYCTL_CHOWN:
barta0b6b2c2008-07-07 06:49:24 +00004897 PRINT("sys_keyctl ( KEYCTL_CHOWN, %ld, %ld, %ld )", ARG2,ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004898 PRE_REG_READ4(long, "keyctl(KEYCTL_CHOWN)",
4899 int, option, vki_key_serial_t, id,
4900 vki_uid_t, uid, vki_gid_t, gid);
4901 break;
4902 case VKI_KEYCTL_SETPERM:
barta0b6b2c2008-07-07 06:49:24 +00004903 PRINT("sys_keyctl ( KEYCTL_SETPERM, %ld, %ld )", ARG2,ARG3);
tom7f4d7e42007-03-07 11:12:13 +00004904 PRE_REG_READ3(long, "keyctl(KEYCTL_SETPERM)",
4905 int, option, vki_key_serial_t, id, vki_key_perm_t, perm);
4906 break;
4907 case VKI_KEYCTL_DESCRIBE:
barta0b6b2c2008-07-07 06:49:24 +00004908 PRINT("sys_keyctl ( KEYCTL_DESCRIBE, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004909 PRE_REG_READ4(long, "keyctl(KEYCTL_DESCRIBE)",
4910 int, option, vki_key_serial_t, id,
4911 char *, buffer, vki_size_t, buflen);
4912 if (ARG3 != (UWord)NULL)
4913 PRE_MEM_WRITE("keyctl(KEYCTL_DESCRIBE, buffer)", ARG3, ARG4);
4914 break;
4915 case VKI_KEYCTL_CLEAR:
barta0b6b2c2008-07-07 06:49:24 +00004916 PRINT("sys_keyctl ( KEYCTL_CLEAR, %ld )", ARG2);
tom7f4d7e42007-03-07 11:12:13 +00004917 PRE_REG_READ2(long, "keyctl(KEYCTL_CLEAR)",
4918 int, option, vki_key_serial_t, keyring);
4919 break;
4920 case VKI_KEYCTL_LINK:
barta0b6b2c2008-07-07 06:49:24 +00004921 PRINT("sys_keyctl ( KEYCTL_LINK, %ld, %ld )", ARG2,ARG3);
tom7f4d7e42007-03-07 11:12:13 +00004922 PRE_REG_READ3(long, "keyctl(KEYCTL_LINK)", int, option,
4923 vki_key_serial_t, keyring, vki_key_serial_t, key);
4924 break;
4925 case VKI_KEYCTL_UNLINK:
barta0b6b2c2008-07-07 06:49:24 +00004926 PRINT("sys_keyctl ( KEYCTL_UNLINK, %ld, %ld )", ARG2,ARG3);
tom7f4d7e42007-03-07 11:12:13 +00004927 PRE_REG_READ3(long, "keyctl(KEYCTL_UNLINK)", int, option,
4928 vki_key_serial_t, keyring, vki_key_serial_t, key);
4929 break;
4930 case VKI_KEYCTL_SEARCH:
barta0b6b2c2008-07-07 06:49:24 +00004931 PRINT("sys_keyctl ( KEYCTL_SEARCH, %ld, %#lx(%s), %#lx(%s), %ld )",
4932 ARG2,ARG3,(char*)ARG3,ARG4,(char*)ARG4,ARG5);
tom7f4d7e42007-03-07 11:12:13 +00004933 PRE_REG_READ5(long, "keyctl(KEYCTL_SEARCH)",
4934 int, option, vki_key_serial_t, keyring,
4935 const char *, type, const char *, description,
4936 vki_key_serial_t, destring);
4937 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, type)", ARG3);
4938 PRE_MEM_RASCIIZ("sys_keyctl(KEYCTL_SEARCH, description)", ARG4);
4939 break;
4940 case VKI_KEYCTL_READ:
barta0b6b2c2008-07-07 06:49:24 +00004941 PRINT("sys_keyctl ( KEYCTL_READ, %ld, %#lx, %ld )", ARG2,ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004942 PRE_REG_READ4(long, "keyctl(KEYCTL_READ)",
4943 int, option, vki_key_serial_t, keyring,
4944 char *, buffer, vki_size_t, buflen);
4945 if (ARG3 != (UWord)NULL)
4946 PRE_MEM_WRITE("keyctl(KEYCTL_READ, buffer)", ARG3, ARG4);
4947 break;
4948 case VKI_KEYCTL_INSTANTIATE:
barta0b6b2c2008-07-07 06:49:24 +00004949 PRINT("sys_keyctl ( KEYCTL_INSTANTIATE, %ld, %#lx, %ld, %ld )",
tom7f4d7e42007-03-07 11:12:13 +00004950 ARG2,ARG3,ARG4,ARG5);
4951 PRE_REG_READ5(long, "keyctl(KEYCTL_INSTANTIATE)",
4952 int, option, vki_key_serial_t, key,
4953 char *, payload, vki_size_t, plen,
4954 vki_key_serial_t, keyring);
4955 if (ARG3 != (UWord)NULL)
4956 PRE_MEM_READ("keyctl(KEYCTL_INSTANTIATE, payload)", ARG3, ARG4);
4957 break;
4958 case VKI_KEYCTL_NEGATE:
barta0b6b2c2008-07-07 06:49:24 +00004959 PRINT("sys_keyctl ( KEYCTL_NEGATE, %ld, %lu, %ld )", ARG2,ARG3,ARG4);
tom7f4d7e42007-03-07 11:12:13 +00004960 PRE_REG_READ4(long, "keyctl(KEYCTL_NEGATE)",
4961 int, option, vki_key_serial_t, key,
4962 unsigned, timeout, vki_key_serial_t, keyring);
4963 break;
4964 case VKI_KEYCTL_SET_REQKEY_KEYRING:
barta0b6b2c2008-07-07 06:49:24 +00004965 PRINT("sys_keyctl ( KEYCTL_SET_REQKEY_KEYRING, %ld )", ARG2);
tom7f4d7e42007-03-07 11:12:13 +00004966 PRE_REG_READ2(long, "keyctl(KEYCTL_SET_REQKEY_KEYRING)",
4967 int, option, int, reqkey_defl);
4968 break;
4969 case VKI_KEYCTL_SET_TIMEOUT:
barta0b6b2c2008-07-07 06:49:24 +00004970 PRINT("sys_keyctl ( KEYCTL_SET_TIMEOUT, %ld, %ld )", ARG2,ARG3);
tom7f4d7e42007-03-07 11:12:13 +00004971 PRE_REG_READ3(long, "keyctl(KEYCTL_SET_TIMEOUT)",
4972 int, option, vki_key_serial_t, key, unsigned, timeout);
4973 break;
4974 case VKI_KEYCTL_ASSUME_AUTHORITY:
barta0b6b2c2008-07-07 06:49:24 +00004975 PRINT("sys_keyctl ( KEYCTL_ASSUME_AUTHORITY, %ld )", ARG2);
tom7f4d7e42007-03-07 11:12:13 +00004976 PRE_REG_READ2(long, "keyctl(KEYCTL_ASSUME_AUTHORITY)",
4977 int, option, vki_key_serial_t, key);
4978 break;
4979 default:
barta0b6b2c2008-07-07 06:49:24 +00004980 PRINT("sys_keyctl ( %ld ) ", ARG1);
tom7f4d7e42007-03-07 11:12:13 +00004981 PRE_REG_READ1(long, "keyctl", int, option);
4982 break;
4983 }
4984}
4985
4986POST(sys_keyctl)
4987{
4988 vg_assert(SUCCESS);
4989 switch (ARG1 /* option */) {
4990 case VKI_KEYCTL_DESCRIBE:
4991 case VKI_KEYCTL_READ:
4992 if (RES > ARG4)
4993 POST_MEM_WRITE(ARG3, ARG4);
4994 else
4995 POST_MEM_WRITE(ARG3, RES);
4996 break;
4997 default:
4998 break;
4999 }
5000}
5001
sewardj7acef082007-03-11 19:28:02 +00005002/* ---------------------------------------------------------------------
5003 ioprio_ wrappers
5004 ------------------------------------------------------------------ */
5005
sewardj7acef082007-03-11 19:28:02 +00005006PRE(sys_ioprio_set)
5007{
5008 PRINT("sys_ioprio_set ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5009 PRE_REG_READ3(int, "ioprio_set", int, which, int, who, int, ioprio);
5010}
5011
tom16dfea42008-12-15 08:58:29 +00005012PRE(sys_ioprio_get)
5013{
5014 PRINT("sys_ioprio_get ( %ld, %ld )", ARG1,ARG2);
5015 PRE_REG_READ2(int, "ioprio_get", int, which, int, who);
5016}
5017
bart10ac1442008-06-21 16:28:24 +00005018/* ---------------------------------------------------------------------
5019 _module wrappers
5020 ------------------------------------------------------------------ */
5021
5022PRE(sys_init_module)
5023{
5024 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00005025 PRINT("sys_init_module ( %#lx, %llu, %#lx(\"%s\") )",
5026 ARG1, (ULong)ARG2, ARG3, (char*)ARG3);
bart10ac1442008-06-21 16:28:24 +00005027 PRE_REG_READ3(long, "init_module",
5028 void *, umod, unsigned long, len, const char *, uargs);
5029 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
5030 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
5031}
5032
5033PRE(sys_delete_module)
5034{
5035 *flags |= SfMayBlock;
barta0b6b2c2008-07-07 06:49:24 +00005036 PRINT("sys_delete_module ( %#lx(\"%s\"), 0x%lx )", ARG1,(char*)ARG1, ARG2);
bart10ac1442008-06-21 16:28:24 +00005037 PRE_REG_READ2(long, "delete_module",
5038 const char *, name_user, unsigned int, flags);
5039 PRE_MEM_RASCIIZ("delete_module(name_user)", ARG1);
5040}
5041
sewardjd3263e52008-11-16 21:40:54 +00005042/* ---------------------------------------------------------------------
tom110743c2010-02-23 10:49:48 +00005043 splice wrappers
5044 ------------------------------------------------------------------ */
5045
5046PRE(sys_splice)
5047{
5048 *flags |= SfMayBlock;
5049 PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %ld, %ld )",
5050 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
tom5db7a792012-08-08 08:03:44 +00005051 PRE_REG_READ6(vki_ssize_t, "splice",
tom110743c2010-02-23 10:49:48 +00005052 int, fd_in, vki_loff_t *, off_in,
5053 int, fd_out, vki_loff_t *, off_out,
5054 vki_size_t, len, unsigned int, flags);
5055 if (!ML_(fd_allowed)(ARG1, "splice(fd_in)", tid, False) ||
5056 !ML_(fd_allowed)(ARG3, "splice(fd_out)", tid, False)) {
5057 SET_STATUS_Failure( VKI_EBADF );
5058 } else {
5059 if (ARG2 != 0)
5060 PRE_MEM_READ( "splice(off_in)", ARG2, sizeof(vki_loff_t));
5061 if (ARG4 != 0)
5062 PRE_MEM_READ( "splice(off_out)", ARG4, sizeof(vki_loff_t));
5063 }
5064}
5065
tom5db7a792012-08-08 08:03:44 +00005066PRE(sys_tee)
5067{
5068 *flags |= SfMayBlock;
5069 PRINT("sys_tree ( %ld, %ld, %ld, %ld )", ARG1,ARG2,ARG3,ARG4);
5070 PRE_REG_READ4(vki_ssize_t, "tee",
5071 int, fd_in, int, fd_out,
5072 vki_size_t, len, unsigned int, flags);
5073 if (!ML_(fd_allowed)(ARG1, "tee(fd_in)", tid, False) ||
5074 !ML_(fd_allowed)(ARG2, "tee(fd_out)", tid, False)) {
5075 SET_STATUS_Failure( VKI_EBADF );
5076 }
5077}
5078
5079PRE(sys_vmsplice)
5080{
5081 Int fdfl;
5082 *flags |= SfMayBlock;
5083 PRINT("sys_vmsplice ( %ld, %#lx, %ld, %ld )",
5084 ARG1,ARG2,ARG3,ARG4);
5085 PRE_REG_READ4(vki_ssize_t, "splice",
5086 int, fd, struct vki_iovec *, iov,
5087 unsigned long, nr_segs, unsigned int, flags);
5088 if (!ML_(fd_allowed)(ARG1, "vmsplice(fd)", tid, False)) {
5089 SET_STATUS_Failure( VKI_EBADF );
5090 } else if ((fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0)) < 0) {
5091 SET_STATUS_Failure( VKI_EBADF );
5092 } else {
5093 const struct vki_iovec *iov;
5094 PRE_MEM_READ( "vmsplice(iov)", ARG2, sizeof(struct vki_iovec) * ARG3 );
5095 for (iov = (struct vki_iovec *)ARG2;
5096 iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5097 {
tom91a16b72013-01-14 22:14:21 +00005098 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
tom5db7a792012-08-08 08:03:44 +00005099 PRE_MEM_WRITE( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
tom91a16b72013-01-14 22:14:21 +00005100 else
5101 PRE_MEM_READ( "vmsplice(iov[...])", (Addr)iov->iov_base, iov->iov_len );
tom5db7a792012-08-08 08:03:44 +00005102 }
5103 }
5104}
5105
5106POST(sys_vmsplice)
5107{
5108 vg_assert(SUCCESS);
5109 if (RES > 0) {
5110 Int fdfl = VG_(fcntl)(ARG1, VKI_F_GETFL, 0);
5111 vg_assert(fdfl >= 0);
tom91a16b72013-01-14 22:14:21 +00005112 if ((fdfl & VKI_O_ACCMODE) == VKI_O_RDONLY)
tom5db7a792012-08-08 08:03:44 +00005113 {
5114 const struct vki_iovec *iov;
5115 for (iov = (struct vki_iovec *)ARG2;
5116 iov < (struct vki_iovec *)ARG2 + ARG3; iov++)
5117 {
5118 POST_MEM_WRITE( (Addr)iov->iov_base, iov->iov_len );
5119 }
5120 }
5121 }
5122}
5123
tom110743c2010-02-23 10:49:48 +00005124/* ---------------------------------------------------------------------
sewardjd3263e52008-11-16 21:40:54 +00005125 oprofile-related wrappers
5126 ------------------------------------------------------------------ */
5127
5128#if defined(VGP_x86_linux)
5129PRE(sys_lookup_dcookie)
5130{
5131 PRINT("sys_lookup_dcookie (0x%llx, %#lx, %ld)",
tomca787242009-11-25 11:24:00 +00005132 MERGE64(ARG1,ARG2), ARG3, ARG4);
sewardjd3263e52008-11-16 21:40:54 +00005133 PRE_REG_READ4(long, "lookup_dcookie",
tomca787242009-11-25 11:24:00 +00005134 vki_u32, MERGE64_FIRST(cookie), vki_u32, MERGE64_SECOND(cookie),
sewardjd3263e52008-11-16 21:40:54 +00005135 char *, buf, vki_size_t, len);
5136 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
5137}
5138POST(sys_lookup_dcookie)
5139{
5140 vg_assert(SUCCESS);
5141 if (ARG3 != (Addr)NULL)
5142 POST_MEM_WRITE( ARG3, RES);
5143}
5144#endif
5145
sewardjb5b87402011-03-07 16:05:35 +00005146#if defined(VGP_amd64_linux) || defined(VGP_s390x_linux)
sewardjd3263e52008-11-16 21:40:54 +00005147PRE(sys_lookup_dcookie)
5148{
5149 *flags |= SfMayBlock;
5150 PRINT("sys_lookup_dcookie ( %llu, %#lx, %llu )",
5151 (ULong)ARG1, ARG2, (ULong)ARG3);
5152 PRE_REG_READ3(int, "lookup_dcookie",
5153 unsigned long long, cookie, char *, buf, vki_size_t, len);
5154
5155 PRE_MEM_WRITE( "sys_lookup_dcookie(buf)", ARG2, ARG3 );
5156}
5157
5158POST(sys_lookup_dcookie)
5159{
5160 vg_assert(SUCCESS);
5161 if (ARG2 != (Addr)NULL)
5162 POST_MEM_WRITE( ARG2, RES );
5163}
5164#endif
5165
njnf37a81b2009-02-17 00:23:30 +00005166/* ---------------------------------------------------------------------
njn096ccdd2009-02-22 23:00:30 +00005167 fcntl wrappers
5168 ------------------------------------------------------------------ */
5169
5170PRE(sys_fcntl)
5171{
5172 switch (ARG2) {
5173 // These ones ignore ARG3.
5174 case VKI_F_GETFD:
5175 case VKI_F_GETFL:
5176 case VKI_F_GETOWN:
5177 case VKI_F_GETSIG:
5178 case VKI_F_GETLEASE:
tom5d770102011-08-10 10:11:14 +00005179 case VKI_F_GETPIPE_SZ:
njn096ccdd2009-02-22 23:00:30 +00005180 PRINT("sys_fcntl ( %ld, %ld )", ARG1,ARG2);
5181 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
5182 break;
5183
5184 // These ones use ARG3 as "arg".
5185 case VKI_F_DUPFD:
tomb23d5052010-09-02 08:23:35 +00005186 case VKI_F_DUPFD_CLOEXEC:
njn096ccdd2009-02-22 23:00:30 +00005187 case VKI_F_SETFD:
5188 case VKI_F_SETFL:
5189 case VKI_F_SETLEASE:
5190 case VKI_F_NOTIFY:
5191 case VKI_F_SETOWN:
5192 case VKI_F_SETSIG:
tom5d770102011-08-10 10:11:14 +00005193 case VKI_F_SETPIPE_SZ:
njn096ccdd2009-02-22 23:00:30 +00005194 PRINT("sys_fcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5195 PRE_REG_READ3(long, "fcntl",
5196 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5197 break;
5198
5199 // These ones use ARG3 as "lock".
5200 case VKI_F_GETLK:
5201 case VKI_F_SETLK:
5202 case VKI_F_SETLKW:
petarj4ab0a792013-04-03 23:43:11 +00005203# if defined(VGP_x86_linux) || defined(VGP_mips64_linux)
njn096ccdd2009-02-22 23:00:30 +00005204 case VKI_F_GETLK64:
5205 case VKI_F_SETLK64:
5206 case VKI_F_SETLKW64:
5207# endif
5208 PRINT("sys_fcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
5209 PRE_REG_READ3(long, "fcntl",
5210 unsigned int, fd, unsigned int, cmd,
5211 struct flock64 *, lock);
5212 break;
njn223bd2b2009-05-22 00:38:15 +00005213
tom835a7142012-02-09 12:21:47 +00005214 case VKI_F_SETOWN_EX:
5215 PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5216 PRE_REG_READ3(long, "fcntl",
5217 unsigned int, fd, unsigned int, cmd,
5218 struct vki_f_owner_ex *, arg);
5219 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5220 break;
5221
5222 case VKI_F_GETOWN_EX:
5223 PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5224 PRE_REG_READ3(long, "fcntl",
5225 unsigned int, fd, unsigned int, cmd,
5226 struct vki_f_owner_ex *, arg);
5227 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5228 break;
5229
sewardj25b18082013-08-08 08:09:29 +00005230 case VKI_DRM_IOCTL_VERSION:
5231 if (ARG3) {
5232 struct vki_drm_version *data = (struct vki_drm_version *)ARG3;
5233 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_major", (Addr)&data->version_major, sizeof(data->version_major));
5234 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_minor", (Addr)&data->version_minor, sizeof(data->version_minor));
5235 PRE_MEM_WRITE("ioctl(DRM_VERSION).version_patchlevel", (Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
5236 PRE_MEM_READ("ioctl(DRM_VERSION).name_len", (Addr)&data->name_len, sizeof(data->name_len));
5237 PRE_MEM_READ("ioctl(DRM_VERSION).name", (Addr)&data->name, sizeof(data->name));
5238 PRE_MEM_WRITE("ioctl(DRM_VERSION).name", (Addr)data->name, data->name_len);
5239 PRE_MEM_READ("ioctl(DRM_VERSION).date_len", (Addr)&data->date_len, sizeof(data->date_len));
5240 PRE_MEM_READ("ioctl(DRM_VERSION).date", (Addr)&data->date, sizeof(data->date));
5241 PRE_MEM_WRITE("ioctl(DRM_VERSION).date", (Addr)data->date, data->date_len);
5242 PRE_MEM_READ("ioctl(DRM_VERSION).desc_len", (Addr)&data->desc_len, sizeof(data->desc_len));
5243 PRE_MEM_READ("ioctl(DRM_VERSION).desc", (Addr)&data->desc, sizeof(data->desc));
5244 PRE_MEM_WRITE("ioctl(DRM_VERSION).desc", (Addr)data->desc, data->desc_len);
5245 }
5246 break;
5247 case VKI_DRM_IOCTL_GET_UNIQUE:
5248 if (ARG3) {
5249 struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
5250 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique_len", (Addr)&data->unique_len, sizeof(data->unique_len));
5251 PRE_MEM_READ("ioctl(DRM_GET_UNIQUE).unique", (Addr)&data->unique, sizeof(data->unique));
5252 PRE_MEM_WRITE("ioctl(DRM_GET_UNIQUE).unique", (Addr)data->unique, data->unique_len);
5253 }
5254 break;
5255 case VKI_DRM_IOCTL_GET_MAGIC:
5256 if (ARG3) {
5257 struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
5258 PRE_MEM_WRITE("ioctl(DRM_GET_MAGIC).magic", (Addr)&data->magic, sizeof(data->magic));
5259 }
5260 break;
5261 case VKI_DRM_IOCTL_WAIT_VBLANK:
5262 if (ARG3) {
5263 union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
5264 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.type", (Addr)&data->request.type, sizeof(data->request.type));
5265 PRE_MEM_READ("ioctl(DRM_WAIT_VBLANK).request.sequence", (Addr)&data->request.sequence, sizeof(data->request.sequence));
5266 /* XXX: It seems request.signal isn't used */
5267 PRE_MEM_WRITE("ioctl(DRM_WAIT_VBLANK).reply", (Addr)&data->reply, sizeof(data->reply));
5268 }
5269 break;
5270 case VKI_DRM_IOCTL_GEM_CLOSE:
5271 if (ARG3) {
5272 struct vki_drm_gem_close *data = (struct vki_drm_gem_close *)ARG3;
5273 PRE_MEM_READ("ioctl(DRM_GEM_CLOSE).handle", (Addr)&data->handle, sizeof(data->handle));
5274 }
5275 break;
5276 case VKI_DRM_IOCTL_GEM_FLINK:
5277 if (ARG3) {
5278 struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
5279 PRE_MEM_READ("ioctl(DRM_GEM_FLINK).handle", (Addr)&data->handle, sizeof(data->handle));
5280 PRE_MEM_WRITE("ioctl(DRM_GEM_FLINK).name", (Addr)&data->name, sizeof(data->name));
5281 }
5282 break;
5283 case VKI_DRM_IOCTL_GEM_OPEN:
5284 if (ARG3) {
5285 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
5286 PRE_MEM_READ("ioctl(DRM_GEM_OPEN).name", (Addr)&data->name, sizeof(data->name));
5287 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).handle", (Addr)&data->handle, sizeof(data->handle));
5288 PRE_MEM_WRITE("ioctl(DRM_GEM_OPEN).size", (Addr)&data->size, sizeof(data->size));
5289 }
5290 break;
5291 case VKI_DRM_IOCTL_I915_GETPARAM:
5292 if (ARG3) {
5293 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
5294 PRE_MEM_READ("ioctl(DRM_I915_GETPARAM).param", (Addr)&data->param, sizeof(data->param));
5295 PRE_MEM_WRITE("ioctl(DRM_I915_GETPARAM).value", (Addr)data->value, sizeof(int));
5296 }
5297 break;
5298 case VKI_DRM_IOCTL_I915_GEM_BUSY:
5299 if (ARG3) {
5300 struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
5301 PRE_MEM_READ("ioctl(DRM_I915_GEM_BUSY).handle", (Addr)&data->handle, sizeof(data->handle));
5302 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_BUSY).busy", (Addr)&data->busy, sizeof(data->busy));
5303 }
5304 break;
5305 case VKI_DRM_IOCTL_I915_GEM_CREATE:
5306 if (ARG3) {
5307 struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
5308 PRE_MEM_READ("ioctl(DRM_I915_GEM_CREATE).size", (Addr)&data->size, sizeof(data->size));
5309 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_CREATE).handle", (Addr)&data->handle, sizeof(data->handle));
5310 }
5311 break;
5312 case VKI_DRM_IOCTL_I915_GEM_PREAD:
5313 if (ARG3) {
5314 struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
5315 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).handle", (Addr)&data->handle, sizeof(data->handle));
5316 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).offset", (Addr)&data->offset, sizeof(data->offset));
5317 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).size", (Addr)&data->size, sizeof(data->size));
5318 PRE_MEM_READ("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
5319 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_PREAD).data_ptr", (Addr)data->data_ptr, data->size);
5320 }
5321 break;
5322 case VKI_DRM_IOCTL_I915_GEM_PWRITE:
5323 if (ARG3) {
5324 struct vki_drm_i915_gem_pwrite *data = (struct vki_drm_i915_gem_pwrite *)ARG3;
5325 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).handle", (Addr)&data->handle, sizeof(data->handle));
5326 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).offset", (Addr)&data->offset, sizeof(data->offset));
5327 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).size", (Addr)&data->size, sizeof(data->size));
5328 PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)&data->data_ptr, sizeof(data->data_ptr));
5329 /* PRE_MEM_READ("ioctl(DRM_I915_GEM_PWRITE).data_ptr", (Addr)data->data_ptr, data->size);
5330 * NB: the buffer is allowed to contain any amount of uninitialized data (e.g.
5331 * interleaved vertex attributes may have a wide stride with uninitialized data between
5332 * consecutive vertices) */
5333 }
5334 break;
5335 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
5336 if (ARG3) {
5337 struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
5338 PRE_MEM_READ("ioctl(DRM_I915_GEM_MMAP_GTT).handle", (Addr)&data->handle, sizeof(data->handle));
5339 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_MMAP_GTT).offset", (Addr)&data->offset, sizeof(data->offset));
5340 }
5341 break;
5342 case VKI_DRM_IOCTL_I915_GEM_SET_DOMAIN:
5343 if (ARG3) {
5344 struct vki_drm_i915_gem_set_domain *data = (struct vki_drm_i915_gem_set_domain *)ARG3;
5345 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).handle", (Addr)&data->handle, sizeof(data->handle));
5346 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).read_domains", (Addr)&data->read_domains, sizeof(data->read_domains));
5347 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_DOMAIN).write_domain", (Addr)&data->write_domain, sizeof(data->write_domain));
5348 }
5349 break;
5350 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
5351 if (ARG3) {
5352 struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
5353 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
5354 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
5355 PRE_MEM_READ("ioctl(DRM_I915_GEM_SET_TILING).stride", (Addr)&data->stride, sizeof(data->stride));
5356 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_SET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
5357 }
5358 break;
5359 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
5360 if (ARG3) {
5361 struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
5362 PRE_MEM_READ("ioctl(DRM_I915_GEM_GET_TILING).handle", (Addr)&data->handle, sizeof(data->handle));
5363 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).tiling_mode", (Addr)&data->tiling_mode, sizeof(data->tiling_mode));
5364 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_TILING).swizzle_mode", (Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
5365 }
5366 break;
5367 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
5368 if (ARG3) {
5369 struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
5370 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_size", (Addr)&data->aper_size, sizeof(data->aper_size));
5371 PRE_MEM_WRITE("ioctl(DRM_I915_GEM_GET_APERTURE).aper_available_size", (Addr)&data->aper_available_size, sizeof(data->aper_available_size));
5372 }
5373 break;
5374
njn223bd2b2009-05-22 00:38:15 +00005375 default:
5376 PRINT("sys_fcntl[UNKNOWN] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5377 I_die_here;
5378 break;
njn096ccdd2009-02-22 23:00:30 +00005379 }
5380
5381# if defined(VGP_x86_linux)
5382 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5383# else
5384 if (ARG2 == VKI_F_SETLKW)
5385# endif
5386 *flags |= SfMayBlock;
5387}
5388
5389POST(sys_fcntl)
5390{
5391 vg_assert(SUCCESS);
5392 if (ARG2 == VKI_F_DUPFD) {
5393 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
5394 VG_(close)(RES);
5395 SET_STATUS_Failure( VKI_EMFILE );
5396 } else {
5397 if (VG_(clo_track_fds))
5398 ML_(record_fd_open_named)(tid, RES);
5399 }
5400 }
tomb23d5052010-09-02 08:23:35 +00005401 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5402 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) {
5403 VG_(close)(RES);
5404 SET_STATUS_Failure( VKI_EMFILE );
5405 } else {
5406 if (VG_(clo_track_fds))
5407 ML_(record_fd_open_named)(tid, RES);
5408 }
tom835a7142012-02-09 12:21:47 +00005409 } else if (ARG2 == VKI_F_GETOWN_EX) {
5410 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
tomb23d5052010-09-02 08:23:35 +00005411 }
njn096ccdd2009-02-22 23:00:30 +00005412}
5413
5414// XXX: wrapper only suitable for 32-bit systems
5415PRE(sys_fcntl64)
5416{
5417 switch (ARG2) {
5418 // These ones ignore ARG3.
5419 case VKI_F_GETFD:
5420 case VKI_F_GETFL:
5421 case VKI_F_GETOWN:
5422 case VKI_F_SETOWN:
5423 case VKI_F_GETSIG:
5424 case VKI_F_SETSIG:
5425 case VKI_F_GETLEASE:
5426 PRINT("sys_fcntl64 ( %ld, %ld )", ARG1,ARG2);
5427 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
5428 break;
5429
5430 // These ones use ARG3 as "arg".
5431 case VKI_F_DUPFD:
tomb23d5052010-09-02 08:23:35 +00005432 case VKI_F_DUPFD_CLOEXEC:
njn096ccdd2009-02-22 23:00:30 +00005433 case VKI_F_SETFD:
5434 case VKI_F_SETFL:
5435 case VKI_F_SETLEASE:
5436 case VKI_F_NOTIFY:
5437 PRINT("sys_fcntl64[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5438 PRE_REG_READ3(long, "fcntl64",
5439 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
5440 break;
5441
5442 // These ones use ARG3 as "lock".
5443 case VKI_F_GETLK:
5444 case VKI_F_SETLK:
5445 case VKI_F_SETLKW:
5446# if defined(VGP_x86_linux)
5447 case VKI_F_GETLK64:
5448 case VKI_F_SETLK64:
5449 case VKI_F_SETLKW64:
5450# endif
5451 PRINT("sys_fcntl64[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
5452 PRE_REG_READ3(long, "fcntl64",
5453 unsigned int, fd, unsigned int, cmd,
5454 struct flock64 *, lock);
5455 break;
tom835a7142012-02-09 12:21:47 +00005456
5457 case VKI_F_SETOWN_EX:
5458 PRINT("sys_fcntl[F_SETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5459 PRE_REG_READ3(long, "fcntl",
5460 unsigned int, fd, unsigned int, cmd,
5461 struct vki_f_owner_ex *, arg);
5462 PRE_MEM_READ("fcntl(F_SETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5463 break;
5464
5465 case VKI_F_GETOWN_EX:
5466 PRINT("sys_fcntl[F_GETOWN_EX] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
5467 PRE_REG_READ3(long, "fcntl",
5468 unsigned int, fd, unsigned int, cmd,
5469 struct vki_f_owner_ex *, arg);
5470 PRE_MEM_WRITE("fcntl(F_GETOWN_EX)", ARG3, sizeof(struct vki_f_owner_ex));
5471 break;
njn096ccdd2009-02-22 23:00:30 +00005472 }
5473
5474# if defined(VGP_x86_linux)
5475 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
5476# else
5477 if (ARG2 == VKI_F_SETLKW)
5478# endif
5479 *flags |= SfMayBlock;
5480}
5481
5482POST(sys_fcntl64)
5483{
5484 vg_assert(SUCCESS);
5485 if (ARG2 == VKI_F_DUPFD) {
5486 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
5487 VG_(close)(RES);
5488 SET_STATUS_Failure( VKI_EMFILE );
5489 } else {
5490 if (VG_(clo_track_fds))
5491 ML_(record_fd_open_named)(tid, RES);
5492 }
5493 }
tomb23d5052010-09-02 08:23:35 +00005494 else if (ARG2 == VKI_F_DUPFD_CLOEXEC) {
5495 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD_CLOEXEC)", tid, True)) {
5496 VG_(close)(RES);
5497 SET_STATUS_Failure( VKI_EMFILE );
5498 } else {
5499 if (VG_(clo_track_fds))
5500 ML_(record_fd_open_named)(tid, RES);
5501 }
tom835a7142012-02-09 12:21:47 +00005502 } else if (ARG2 == VKI_F_GETOWN_EX) {
5503 POST_MEM_WRITE(ARG3, sizeof(struct vki_f_owner_ex));
tomb23d5052010-09-02 08:23:35 +00005504 }
njn096ccdd2009-02-22 23:00:30 +00005505}
5506
5507/* ---------------------------------------------------------------------
5508 ioctl wrappers
5509 ------------------------------------------------------------------ */
5510
5511PRE(sys_ioctl)
5512{
5513 *flags |= SfMayBlock;
njn096ccdd2009-02-22 23:00:30 +00005514
njncf3bd972009-07-14 00:06:00 +00005515 // We first handle the ones that don't use ARG3 (even as a
5516 // scalar/non-pointer argument).
5517 switch (ARG2 /* request */) {
5518
tom0c7ff332013-07-17 14:57:18 +00005519 /* asm-generic/ioctls.h */
5520 case VKI_FIOCLEX:
5521 case VKI_FIONCLEX:
5522
njncf3bd972009-07-14 00:06:00 +00005523 /* linux/soundcard interface (ALSA) */
5524 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
5525 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
5526 case VKI_SNDRV_PCM_IOCTL_PREPARE:
5527 case VKI_SNDRV_PCM_IOCTL_RESET:
5528 case VKI_SNDRV_PCM_IOCTL_START:
5529 case VKI_SNDRV_PCM_IOCTL_DROP:
5530 case VKI_SNDRV_PCM_IOCTL_DRAIN:
5531 case VKI_SNDRV_PCM_IOCTL_RESUME:
5532 case VKI_SNDRV_PCM_IOCTL_XRUN:
5533 case VKI_SNDRV_PCM_IOCTL_UNLINK:
5534 case VKI_SNDRV_TIMER_IOCTL_START:
5535 case VKI_SNDRV_TIMER_IOCTL_STOP:
5536 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
5537 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
tom8758e702012-02-10 10:41:07 +00005538
5539 /* SCSI no operand */
5540 case VKI_SCSI_IOCTL_DOORLOCK:
5541 case VKI_SCSI_IOCTL_DOORUNLOCK:
cborntra4ea8f142014-02-11 15:15:31 +00005542
cborntra65bdbe42012-05-23 15:59:40 +00005543 /* KVM ioctls that dont check for a numeric value as parameter */
5544 case VKI_KVM_S390_ENABLE_SIE:
cborntra4ea8f142014-02-11 15:15:31 +00005545 case VKI_KVM_CREATE_IRQCHIP:
cborntra65bdbe42012-05-23 15:59:40 +00005546 case VKI_KVM_S390_INITIAL_RESET:
sewardjb6bf12c2012-07-13 13:15:10 +00005547
cborntrae5a61e12013-03-01 13:17:49 +00005548 /* vhost without parameter */
5549 case VKI_VHOST_SET_OWNER:
5550 case VKI_VHOST_RESET_OWNER:
5551
sewardjb6bf12c2012-07-13 13:15:10 +00005552 /* User input device creation */
5553 case VKI_UI_DEV_CREATE:
5554 case VKI_UI_DEV_DESTROY:
bart9f2a3392013-02-14 17:10:01 +00005555
5556 /* InfiniBand */
5557 case VKI_IB_USER_MAD_ENABLE_PKEY:
bart881f2d62009-07-14 16:36:40 +00005558 PRINT("sys_ioctl ( %ld, 0x%lx )",ARG1,ARG2);
njncf3bd972009-07-14 00:06:00 +00005559 PRE_REG_READ2(long, "ioctl",
5560 unsigned int, fd, unsigned int, request);
5561 return;
5562
sewardj25b18082013-08-08 08:09:29 +00005563 case VKI_DRM_IOCTL_VERSION:
5564 if (ARG3) {
5565 struct vki_drm_version *data = (struct vki_drm_version *)ARG3;
5566 POST_MEM_WRITE((Addr)&data->version_major, sizeof(data->version_major));
5567 POST_MEM_WRITE((Addr)&data->version_minor, sizeof(data->version_minor));
5568 POST_MEM_WRITE((Addr)&data->version_patchlevel, sizeof(data->version_patchlevel));
5569 POST_MEM_WRITE((Addr)&data->name_len, sizeof(data->name_len));
5570 POST_MEM_WRITE((Addr)data->name, data->name_len);
5571 POST_MEM_WRITE((Addr)&data->date_len, sizeof(data->date_len));
5572 POST_MEM_WRITE((Addr)data->date, data->date_len);
5573 POST_MEM_WRITE((Addr)&data->desc_len, sizeof(data->desc_len));
5574 POST_MEM_WRITE((Addr)data->desc, data->desc_len);
5575 }
5576 break;
5577 case VKI_DRM_IOCTL_GET_UNIQUE:
5578 if (ARG3) {
5579 struct vki_drm_unique *data = (struct vki_drm_unique *)ARG3;
5580 POST_MEM_WRITE((Addr)data->unique, sizeof(data->unique_len));
5581 }
5582 break;
5583 case VKI_DRM_IOCTL_GET_MAGIC:
5584 if (ARG3) {
5585 struct vki_drm_auth *data = (struct vki_drm_auth *)ARG3;
5586 POST_MEM_WRITE((Addr)&data->magic, sizeof(data->magic));
5587 }
5588 break;
5589 case VKI_DRM_IOCTL_WAIT_VBLANK:
5590 if (ARG3) {
5591 union vki_drm_wait_vblank *data = (union vki_drm_wait_vblank *)ARG3;
5592 POST_MEM_WRITE((Addr)&data->reply, sizeof(data->reply));
5593 }
5594 break;
5595 case VKI_DRM_IOCTL_GEM_FLINK:
5596 if (ARG3) {
5597 struct vki_drm_gem_flink *data = (struct vki_drm_gem_flink *)ARG3;
5598 POST_MEM_WRITE((Addr)&data->name, sizeof(data->name));
5599 }
5600 break;
5601 case VKI_DRM_IOCTL_GEM_OPEN:
5602 if (ARG3) {
5603 struct vki_drm_gem_open *data = (struct vki_drm_gem_open *)ARG3;
5604 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
5605 POST_MEM_WRITE((Addr)&data->size, sizeof(data->size));
5606 }
5607 break;
5608 case VKI_DRM_IOCTL_I915_GETPARAM:
5609 if (ARG3) {
5610 vki_drm_i915_getparam_t *data = (vki_drm_i915_getparam_t *)ARG3;
5611 POST_MEM_WRITE((Addr)data->value, sizeof(int));
5612 }
5613 break;
5614 case VKI_DRM_IOCTL_I915_GEM_BUSY:
5615 if (ARG3) {
5616 struct vki_drm_i915_gem_busy *data = (struct vki_drm_i915_gem_busy *)ARG3;
5617 POST_MEM_WRITE((Addr)&data->busy, sizeof(data->busy));
5618 }
5619 break;
5620 case VKI_DRM_IOCTL_I915_GEM_CREATE:
5621 if (ARG3) {
5622 struct vki_drm_i915_gem_create *data = (struct vki_drm_i915_gem_create *)ARG3;
5623 POST_MEM_WRITE((Addr)&data->handle, sizeof(data->handle));
5624 }
5625 break;
5626 case VKI_DRM_IOCTL_I915_GEM_PREAD:
5627 if (ARG3) {
5628 struct vki_drm_i915_gem_pread *data = (struct vki_drm_i915_gem_pread *)ARG3;
5629 POST_MEM_WRITE((Addr)data->data_ptr, data->size);
5630 }
5631 break;
5632 case VKI_DRM_IOCTL_I915_GEM_MMAP_GTT:
5633 if (ARG3) {
5634 struct vki_drm_i915_gem_mmap_gtt *data = (struct vki_drm_i915_gem_mmap_gtt *)ARG3;
5635 POST_MEM_WRITE((Addr)&data->offset, sizeof(data->offset));
5636 }
5637 break;
5638 case VKI_DRM_IOCTL_I915_GEM_SET_TILING:
5639 if (ARG3) {
5640 struct vki_drm_i915_gem_set_tiling *data = (struct vki_drm_i915_gem_set_tiling *)ARG3;
5641 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
5642 POST_MEM_WRITE((Addr)&data->stride, sizeof(data->stride));
5643 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
5644 }
5645 break;
5646 case VKI_DRM_IOCTL_I915_GEM_GET_TILING:
5647 if (ARG3) {
5648 struct vki_drm_i915_gem_get_tiling *data = (struct vki_drm_i915_gem_get_tiling *)ARG3;
5649 POST_MEM_WRITE((Addr)&data->tiling_mode, sizeof(data->tiling_mode));
5650 POST_MEM_WRITE((Addr)&data->swizzle_mode, sizeof(data->swizzle_mode));
5651 }
5652 break;
5653 case VKI_DRM_IOCTL_I915_GEM_GET_APERTURE:
5654 if (ARG3) {
5655 struct vki_drm_i915_gem_get_aperture *data = (struct vki_drm_i915_gem_get_aperture *)ARG3;
5656 POST_MEM_WRITE((Addr)&data->aper_size, sizeof(data->aper_size));
5657 POST_MEM_WRITE((Addr)&data->aper_available_size, sizeof(data->aper_available_size));
5658 }
5659 break;
5660
njncf3bd972009-07-14 00:06:00 +00005661 default:
bart881f2d62009-07-14 16:36:40 +00005662 PRINT("sys_ioctl ( %ld, 0x%lx, 0x%lx )",ARG1,ARG2,ARG3);
njncf3bd972009-07-14 00:06:00 +00005663 PRE_REG_READ3(long, "ioctl",
5664 unsigned int, fd, unsigned int, request, unsigned long, arg);
5665 break;
5666 }
5667
5668 // We now handle those that do look at ARG3 (and unknown ones fall into
5669 // this category). Nb: some of these may well belong in the
5670 // doesn't-use-ARG3 switch above.
njn096ccdd2009-02-22 23:00:30 +00005671 switch (ARG2 /* request */) {
5672 case VKI_TCSETS:
5673 case VKI_TCSETSW:
5674 case VKI_TCSETSF:
5675 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
5676 break;
5677 case VKI_TCGETS:
5678 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
5679 break;
5680 case VKI_TCSETA:
5681 case VKI_TCSETAW:
5682 case VKI_TCSETAF:
5683 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
5684 break;
5685 case VKI_TCGETA:
5686 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
5687 break;
5688 case VKI_TCSBRK:
5689 case VKI_TCXONC:
5690 case VKI_TCSBRKP:
5691 case VKI_TCFLSH:
5692 /* These just take an int by value */
5693 break;
5694 case VKI_TIOCGWINSZ:
5695 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
5696 break;
5697 case VKI_TIOCSWINSZ:
5698 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
5699 break;
5700 case VKI_TIOCMBIS:
5701 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
5702 break;
5703 case VKI_TIOCMBIC:
5704 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
5705 break;
5706 case VKI_TIOCMSET:
5707 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
5708 break;
5709 case VKI_TIOCMGET:
5710 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
5711 break;
5712 case VKI_TIOCLINUX:
5713 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
5714 if (*(char *)ARG3 == 11) {
5715 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
5716 }
5717 break;
5718 case VKI_TIOCGPGRP:
5719 /* Get process group ID for foreground processing group. */
5720 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
5721 break;
5722 case VKI_TIOCSPGRP:
5723 /* Set a process group ID? */
5724 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
5725 break;
5726 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
5727 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
5728 break;
5729 case VKI_TIOCSCTTY:
5730 /* Just takes an int value. */
5731 break;
5732 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
5733 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
5734 break;
5735 case VKI_FIONBIO:
5736 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
5737 break;
5738 case VKI_FIOASYNC:
5739 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
5740 break;
5741 case VKI_FIONREAD: /* identical to SIOCINQ */
5742 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
5743 break;
tom6bf71ef2011-08-10 14:25:06 +00005744 case VKI_FIOQSIZE:
5745 PRE_MEM_WRITE( "ioctl(FIOQSIZE)", ARG3, sizeof(vki_loff_t) );
5746 break;
njn096ccdd2009-02-22 23:00:30 +00005747
5748 case VKI_TIOCSERGETLSR:
5749 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
5750 break;
5751 case VKI_TIOCGICOUNT:
5752 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
5753 sizeof(struct vki_serial_icounter_struct) );
5754 break;
5755
5756 case VKI_SG_SET_COMMAND_Q:
5757 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
5758 break;
5759 case VKI_SG_IO:
5760 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
5761 break;
5762 case VKI_SG_GET_SCSI_ID:
5763 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
5764 break;
5765 case VKI_SG_SET_RESERVED_SIZE:
5766 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
5767 break;
5768 case VKI_SG_SET_TIMEOUT:
5769 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
5770 break;
5771 case VKI_SG_GET_RESERVED_SIZE:
5772 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
5773 break;
5774 case VKI_SG_GET_TIMEOUT:
5775 break;
5776 case VKI_SG_GET_VERSION_NUM:
5777 PRE_MEM_WRITE( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
5778 break;
5779 case VKI_SG_EMULATED_HOST: /* 0x2203 */
5780 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
5781 break;
5782 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
5783 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
5784 break;
5785
5786 case VKI_IIOCGETCPS:
5787 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
5788 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
5789 break;
5790 case VKI_IIOCNETGPN:
5791 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
5792 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
5793 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
5794 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
5795 sizeof(vki_isdn_net_ioctl_phone) );
5796 break;
5797
5798 /* These all use struct ifreq AFAIK */
5799 case VKI_SIOCGIFINDEX: /* get iface index */
5800 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
5801 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5802 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
5803 break;
5804 case VKI_SIOCGIFFLAGS: /* get flags */
5805 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
5806 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5807 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
5808 break;
5809 case VKI_SIOCGIFHWADDR: /* Get hardware address */
5810 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
5811 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5812 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
5813 break;
5814 case VKI_SIOCGIFMTU: /* get MTU size */
5815 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
5816 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5817 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
5818 break;
5819 case VKI_SIOCGIFADDR: /* get PA address */
5820 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
5821 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5822 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
5823 break;
5824 case VKI_SIOCGIFNETMASK: /* get network PA mask */
5825 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
5826 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5827 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
5828 break;
5829 case VKI_SIOCGIFMETRIC: /* get metric */
5830 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
5831 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5832 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
5833 break;
5834 case VKI_SIOCGIFMAP: /* Get device parameters */
5835 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
5836 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5837 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
5838 break;
5839 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
5840 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
5841 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5842 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
5843 break;
5844 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
5845 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
5846 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5847 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
5848 break;
5849 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
5850 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
5851 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5852 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
5853 break;
5854 case VKI_SIOCGIFNAME: /* get iface name */
5855 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
5856 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
5857 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
5858 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
5859 break;
5860 case VKI_SIOCGMIIPHY: /* get hardware entry */
5861 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
5862 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5863 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
5864 break;
5865 case VKI_SIOCGMIIREG: /* get hardware entry registers */
5866 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
5867 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5868 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
5869 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
5870 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
5871 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
5872 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
5873 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
5874 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
5875 sizeof(struct vki_ifreq));
5876 break;
5877 case VKI_SIOCGIFCONF: /* get iface list */
5878 /* WAS:
5879 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
5880 KERNEL_DO_SYSCALL(tid,RES);
5881 if (!VG_(is_kerror)(RES) && RES == 0)
5882 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
5883 */
5884 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
5885 (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
5886 sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
5887 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
5888 (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
5889 sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
5890 if ( ARG3 ) {
5891 // TODO len must be readable and writable
5892 // buf pointer only needs to be readable
5893 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
5894 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
5895 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
5896 }
5897 break;
5898 case VKI_SIOCGSTAMP:
5899 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
5900 break;
toma2ec4f52009-03-31 10:36:58 +00005901 case VKI_SIOCGSTAMPNS:
5902 PRE_MEM_WRITE( "ioctl(SIOCGSTAMPNS)", ARG3, sizeof(struct vki_timespec));
5903 break;
njn096ccdd2009-02-22 23:00:30 +00005904 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
5905 the number of bytes currently in that socket's send buffer.
5906 It writes this value as an int to the memory location
5907 indicated by the third argument of ioctl(2). */
5908 case VKI_SIOCOUTQ:
5909 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
5910 break;
5911 case VKI_SIOCGRARP: /* get RARP table entry */
5912 case VKI_SIOCGARP: /* get ARP table entry */
5913 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
5914 break;
5915
5916 case VKI_SIOCSIFFLAGS: /* set flags */
5917 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
5918 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5919 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
5920 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
5921 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
5922 break;
5923 case VKI_SIOCSIFMAP: /* Set device parameters */
5924 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
5925 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5926 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
5927 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
5928 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
5929 break;
toma7b9dfc2012-07-11 14:33:10 +00005930 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
5931 PRE_MEM_RASCIIZ( "ioctl(SIOCSHWTSTAMP)",
5932 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5933 PRE_MEM_READ( "ioctl(SIOCSHWTSTAMP)",
5934 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_data,
5935 sizeof(struct vki_hwtstamp_config) );
5936 break;
njn096ccdd2009-02-22 23:00:30 +00005937 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
5938 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
5939 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5940 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
5941 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
5942 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
5943 break;
5944 case VKI_SIOCSIFADDR: /* set PA address */
5945 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
5946 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
5947 case VKI_SIOCSIFNETMASK: /* set network PA mask */
5948 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
5949 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5950 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
5951 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
5952 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
5953 break;
5954 case VKI_SIOCSIFMETRIC: /* set metric */
5955 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
5956 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5957 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
5958 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
5959 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
5960 break;
5961 case VKI_SIOCSIFMTU: /* set MTU size */
5962 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
5963 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5964 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
5965 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
5966 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
5967 break;
5968 case VKI_SIOCSIFHWADDR: /* set hardware address */
5969 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
5970 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5971 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
5972 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
5973 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
5974 break;
5975 case VKI_SIOCSMIIREG: /* set hardware entry registers */
5976 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
5977 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5978 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
5979 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
5980 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
5981 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
5982 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
5983 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
5984 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
5985 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
5986 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
5987 break;
5988 /* Routing table calls. */
5989 case VKI_SIOCADDRT: /* add routing table entry */
5990 case VKI_SIOCDELRT: /* delete routing table entry */
5991 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
5992 sizeof(struct vki_rtentry));
5993 break;
5994
cborntradfe0dae2013-03-01 12:56:07 +00005995 /* tun/tap related ioctls */
5996 case VKI_TUNSETIFF:
5997 PRE_MEM_RASCIIZ( "ioctl(TUNSETIFF)",
5998 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
5999 PRE_MEM_READ( "ioctl(TUNSETIFF)",
6000 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
6001 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
6002 PRE_MEM_WRITE( "ioctl(TUNSETIFF)", ARG3,
6003 sizeof(struct vki_ifreq));
6004 break;
6005 case VKI_TUNSETOFFLOAD:
6006 break;
6007 case VKI_TUNGETIFF:
6008 PRE_MEM_WRITE( "ioctl(TUNGETIFF)", ARG3,
6009 sizeof(struct vki_ifreq));
6010 break;
6011
njn096ccdd2009-02-22 23:00:30 +00006012 /* RARP cache control calls. */
6013 case VKI_SIOCDRARP: /* delete RARP table entry */
6014 case VKI_SIOCSRARP: /* set RARP table entry */
6015 /* ARP cache control calls. */
6016 case VKI_SIOCSARP: /* set ARP table entry */
6017 case VKI_SIOCDARP: /* delete ARP table entry */
6018 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
6019 break;
6020
6021 case VKI_SIOCGPGRP:
6022 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
6023 break;
6024 case VKI_SIOCSPGRP:
6025 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
6026 //tst->sys_flags &= ~SfMayBlock;
6027 break;
6028
6029 /* linux/soundcard interface (OSS) */
6030 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
6031 case VKI_SNDCTL_SEQ_GETINCOUNT:
6032 case VKI_SNDCTL_SEQ_PERCMODE:
6033 case VKI_SNDCTL_SEQ_TESTMIDI:
6034 case VKI_SNDCTL_SEQ_RESETSAMPLES:
6035 case VKI_SNDCTL_SEQ_NRSYNTHS:
6036 case VKI_SNDCTL_SEQ_NRMIDIS:
6037 case VKI_SNDCTL_SEQ_GETTIME:
tom55703df2010-02-18 15:54:45 +00006038 case VKI_SNDCTL_DSP_GETBLKSIZE:
njn096ccdd2009-02-22 23:00:30 +00006039 case VKI_SNDCTL_DSP_GETFMTS:
6040 case VKI_SNDCTL_DSP_GETTRIGGER:
6041 case VKI_SNDCTL_DSP_GETODELAY:
6042 case VKI_SNDCTL_DSP_GETSPDIF:
6043 case VKI_SNDCTL_DSP_GETCAPS:
6044 case VKI_SOUND_PCM_READ_RATE:
6045 case VKI_SOUND_PCM_READ_CHANNELS:
6046 case VKI_SOUND_PCM_READ_BITS:
njn096ccdd2009-02-22 23:00:30 +00006047 case VKI_SOUND_PCM_READ_FILTER:
6048 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
6049 ARG3, sizeof(int));
6050 break;
6051 case VKI_SNDCTL_SEQ_CTRLRATE:
6052 case VKI_SNDCTL_DSP_SPEED:
6053 case VKI_SNDCTL_DSP_STEREO:
njn096ccdd2009-02-22 23:00:30 +00006054 case VKI_SNDCTL_DSP_CHANNELS:
6055 case VKI_SOUND_PCM_WRITE_FILTER:
6056 case VKI_SNDCTL_DSP_SUBDIVIDE:
6057 case VKI_SNDCTL_DSP_SETFRAGMENT:
tom55703df2010-02-18 15:54:45 +00006058 case VKI_SNDCTL_DSP_SETFMT:
njn096ccdd2009-02-22 23:00:30 +00006059 case VKI_SNDCTL_DSP_GETCHANNELMASK:
6060 case VKI_SNDCTL_DSP_BIND_CHANNEL:
6061 case VKI_SNDCTL_TMR_TIMEBASE:
6062 case VKI_SNDCTL_TMR_TEMPO:
6063 case VKI_SNDCTL_TMR_SOURCE:
6064 case VKI_SNDCTL_MIDI_PRETIME:
6065 case VKI_SNDCTL_MIDI_MPUMODE:
6066 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6067 ARG3, sizeof(int));
6068 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
6069 ARG3, sizeof(int));
6070 break;
6071 case VKI_SNDCTL_DSP_GETOSPACE:
6072 case VKI_SNDCTL_DSP_GETISPACE:
6073 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
6074 ARG3, sizeof(vki_audio_buf_info));
6075 break;
njn06605672009-06-09 22:31:00 +00006076 case VKI_SNDCTL_DSP_NONBLOCK:
6077 break;
njn096ccdd2009-02-22 23:00:30 +00006078 case VKI_SNDCTL_DSP_SETTRIGGER:
6079 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
6080 ARG3, sizeof(int));
6081 break;
6082
6083 case VKI_SNDCTL_DSP_POST:
6084 case VKI_SNDCTL_DSP_RESET:
6085 case VKI_SNDCTL_DSP_SYNC:
6086 case VKI_SNDCTL_DSP_SETSYNCRO:
6087 case VKI_SNDCTL_DSP_SETDUPLEX:
6088 break;
6089
6090 /* linux/soundcard interface (ALSA) */
njncf3bd972009-07-14 00:06:00 +00006091 case VKI_SNDRV_PCM_IOCTL_PAUSE:
6092 case VKI_SNDRV_PCM_IOCTL_LINK:
6093 /* these just take an int by value */
njn096ccdd2009-02-22 23:00:30 +00006094 break;
6095
6096 /* Real Time Clock (/dev/rtc) ioctls */
6097 case VKI_RTC_UIE_ON:
6098 case VKI_RTC_UIE_OFF:
6099 case VKI_RTC_AIE_ON:
6100 case VKI_RTC_AIE_OFF:
6101 case VKI_RTC_PIE_ON:
6102 case VKI_RTC_PIE_OFF:
6103 case VKI_RTC_IRQP_SET:
6104 break;
6105 case VKI_RTC_RD_TIME:
6106 case VKI_RTC_ALM_READ:
6107 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
6108 ARG3, sizeof(struct vki_rtc_time));
6109 break;
6110 case VKI_RTC_ALM_SET:
6111 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
6112 break;
6113 case VKI_RTC_IRQP_READ:
6114 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
6115 break;
6116
6117 /* Block devices */
6118 case VKI_BLKROSET:
6119 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
6120 break;
6121 case VKI_BLKROGET:
6122 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
6123 break;
6124 case VKI_BLKGETSIZE:
6125 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
6126 break;
6127 case VKI_BLKRASET:
6128 break;
6129 case VKI_BLKRAGET:
6130 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
6131 break;
6132 case VKI_BLKFRASET:
6133 break;
6134 case VKI_BLKFRAGET:
6135 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
6136 break;
6137 case VKI_BLKSECTGET:
6138 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
6139 break;
6140 case VKI_BLKSSZGET:
6141 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
6142 break;
6143 case VKI_BLKBSZGET:
6144 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
6145 break;
6146 case VKI_BLKBSZSET:
6147 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
6148 break;
6149 case VKI_BLKGETSIZE64:
6150 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
6151 break;
cborntra0e6d05e2012-11-09 16:01:38 +00006152 case VKI_BLKPBSZGET:
6153 PRE_MEM_WRITE( "ioctl(BLKPBSZGET)", ARG3, sizeof(int));
6154 break;
njn096ccdd2009-02-22 23:00:30 +00006155
6156 /* Hard disks */
6157 case VKI_HDIO_GETGEO: /* 0x0301 */
6158 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
6159 break;
6160 case VKI_HDIO_GET_DMA: /* 0x030b */
6161 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
6162 break;
6163 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
6164 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
6165 VKI_SIZEOF_STRUCT_HD_DRIVEID );
6166 break;
6167
tom8758e702012-02-10 10:41:07 +00006168 /* SCSI */
6169 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
6170 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_IDLUN)", ARG3, sizeof(struct vki_scsi_idlun));
6171 break;
6172 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
6173 PRE_MEM_WRITE( "ioctl(SCSI_IOCTL_GET_BUS_NUMBER)", ARG3, sizeof(int));
6174 break;
6175
njn096ccdd2009-02-22 23:00:30 +00006176 /* CD ROM stuff (??) */
6177 case VKI_CDROM_GET_MCN:
6178 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
6179 sizeof(struct vki_cdrom_mcn) );
6180 break;
6181 case VKI_CDROM_SEND_PACKET:
6182 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
6183 sizeof(struct vki_cdrom_generic_command));
6184 break;
6185 case VKI_CDROMSUBCHNL:
6186 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
6187 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
6188 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
6189 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
6190 sizeof(struct vki_cdrom_subchnl));
6191 break;
6192 case VKI_CDROMREADMODE2:
6193 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
6194 break;
6195 case VKI_CDROMREADTOCHDR:
6196 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
6197 sizeof(struct vki_cdrom_tochdr));
6198 break;
6199 case VKI_CDROMREADTOCENTRY:
6200 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
6201 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
6202 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
6203 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
6204 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
6205 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
6206 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
6207 sizeof(struct vki_cdrom_tocentry));
6208 break;
6209 case VKI_CDROMMULTISESSION: /* 0x5310 */
6210 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
6211 sizeof(struct vki_cdrom_multisession));
6212 break;
6213 case VKI_CDROMVOLREAD: /* 0x5313 */
6214 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
6215 sizeof(struct vki_cdrom_volctrl));
6216 break;
6217 case VKI_CDROMREADRAW: /* 0x5314 */
6218 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
6219 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
6220 break;
6221 case VKI_CDROMREADAUDIO: /* 0x530e */
6222 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
6223 sizeof (struct vki_cdrom_read_audio));
6224 if ( ARG3 ) {
6225 /* ToDo: don't do any of the following if the structure is invalid */
6226 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
6227 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
6228 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
6229 }
6230 break;
6231 case VKI_CDROMPLAYMSF:
6232 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
6233 break;
6234 /* The following two are probably bogus (should check args
6235 for readability). JRS 20021117 */
6236 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
6237 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
6238 break;
tom3fc99292012-07-11 12:02:06 +00006239 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
6240 break;
njn096ccdd2009-02-22 23:00:30 +00006241
6242 case VKI_FIGETBSZ:
6243 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
6244 break;
6245 case VKI_FIBMAP:
tomc1cc9632010-08-25 09:13:44 +00006246 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int));
njn096ccdd2009-02-22 23:00:30 +00006247 break;
6248
6249 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
6250 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
6251 sizeof(struct vki_fb_var_screeninfo));
6252 break;
tomfca8f5f2011-08-15 08:47:29 +00006253 case VKI_FBIOPUT_VSCREENINFO:
6254 PRE_MEM_READ( "ioctl(FBIOPUT_VSCREENINFO)", ARG3,
6255 sizeof(struct vki_fb_var_screeninfo));
6256 break;
njn096ccdd2009-02-22 23:00:30 +00006257 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
6258 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
6259 sizeof(struct vki_fb_fix_screeninfo));
6260 break;
tomfca8f5f2011-08-15 08:47:29 +00006261 case VKI_FBIOPAN_DISPLAY:
6262 PRE_MEM_READ( "ioctl(FBIOPAN_DISPLAY)", ARG3,
6263 sizeof(struct vki_fb_var_screeninfo));
njn096ccdd2009-02-22 23:00:30 +00006264
tomfca8f5f2011-08-15 08:47:29 +00006265 break;
njn096ccdd2009-02-22 23:00:30 +00006266 case VKI_PPCLAIM:
6267 case VKI_PPEXCL:
6268 case VKI_PPYIELD:
6269 case VKI_PPRELEASE:
6270 break;
6271 case VKI_PPSETMODE:
6272 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
6273 break;
6274 case VKI_PPGETMODE:
6275 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
6276 break;
6277 case VKI_PPSETPHASE:
6278 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
6279 break;
6280 case VKI_PPGETPHASE:
6281 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
6282 break;
6283 case VKI_PPGETMODES:
6284 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
6285 break;
6286 case VKI_PPSETFLAGS:
6287 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
6288 break;
6289 case VKI_PPGETFLAGS:
6290 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
6291 break;
6292 case VKI_PPRSTATUS:
6293 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
6294 break;
6295 case VKI_PPRDATA:
6296 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
6297 break;
6298 case VKI_PPRCONTROL:
6299 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
6300 break;
6301 case VKI_PPWDATA:
6302 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
6303 break;
6304 case VKI_PPWCONTROL:
6305 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
6306 break;
6307 case VKI_PPFCONTROL:
6308 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
6309 break;
6310 case VKI_PPDATADIR:
6311 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
6312 break;
6313 case VKI_PPNEGOT:
6314 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
6315 break;
6316 case VKI_PPWCTLONIRQ:
6317 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
6318 break;
6319 case VKI_PPCLRIRQ:
6320 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
6321 break;
6322 case VKI_PPSETTIME:
6323 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
6324 break;
6325 case VKI_PPGETTIME:
6326 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
6327 break;
6328
6329 case VKI_GIO_FONT:
6330 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
6331 break;
6332 case VKI_PIO_FONT:
6333 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
6334 break;
6335
6336 case VKI_GIO_FONTX:
6337 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
6338 if ( ARG3 ) {
6339 /* ToDo: don't do any of the following if the structure is invalid */
6340 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
6341 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
6342 32 * cfd->charcount );
6343 }
6344 break;
6345 case VKI_PIO_FONTX:
6346 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
6347 if ( ARG3 ) {
6348 /* ToDo: don't do any of the following if the structure is invalid */
6349 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
6350 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
6351 32 * cfd->charcount );
6352 }
6353 break;
6354
6355 case VKI_PIO_FONTRESET:
6356 break;
6357
6358 case VKI_GIO_CMAP:
6359 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
6360 break;
6361 case VKI_PIO_CMAP:
6362 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
6363 break;
6364
6365 case VKI_KIOCSOUND:
6366 case VKI_KDMKTONE:
6367 break;
6368
6369 case VKI_KDGETLED:
6370 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
6371 break;
6372 case VKI_KDSETLED:
6373 break;
6374
6375 case VKI_KDGKBTYPE:
6376 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
6377 break;
6378
6379 case VKI_KDADDIO:
6380 case VKI_KDDELIO:
6381 case VKI_KDENABIO:
6382 case VKI_KDDISABIO:
6383 break;
6384
6385 case VKI_KDSETMODE:
6386 break;
6387 case VKI_KDGETMODE:
6388 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
6389 break;
6390
6391 case VKI_KDMAPDISP:
6392 case VKI_KDUNMAPDISP:
6393 break;
6394
6395 case VKI_GIO_SCRNMAP:
6396 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
6397 break;
6398 case VKI_PIO_SCRNMAP:
6399 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
6400 break;
6401 case VKI_GIO_UNISCRNMAP:
6402 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
6403 VKI_E_TABSZ * sizeof(unsigned short) );
6404 break;
6405 case VKI_PIO_UNISCRNMAP:
6406 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
6407 VKI_E_TABSZ * sizeof(unsigned short) );
6408 break;
6409
6410 case VKI_GIO_UNIMAP:
6411 if ( ARG3 ) {
6412 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6413 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
6414 sizeof(unsigned short));
6415 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
6416 sizeof(struct vki_unipair *));
6417 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
6418 desc->entry_ct * sizeof(struct vki_unipair));
6419 }
6420 break;
6421 case VKI_PIO_UNIMAP:
6422 if ( ARG3 ) {
6423 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
6424 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
6425 sizeof(unsigned short) );
6426 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
6427 sizeof(struct vki_unipair *) );
6428 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
6429 desc->entry_ct * sizeof(struct vki_unipair) );
6430 }
6431 break;
6432 case VKI_PIO_UNIMAPCLR:
6433 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
6434 break;
6435
6436 case VKI_KDGKBMODE:
6437 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
6438 break;
6439 case VKI_KDSKBMODE:
6440 break;
6441
6442 case VKI_KDGKBMETA:
6443 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
6444 break;
6445 case VKI_KDSKBMETA:
6446 break;
6447
6448 case VKI_KDGKBLED:
6449 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
6450 break;
6451 case VKI_KDSKBLED:
6452 break;
6453
6454 case VKI_KDGKBENT:
6455 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
6456 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
6457 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
6458 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
6459 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
6460 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
6461 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
6462 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6463 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6464 break;
6465 case VKI_KDSKBENT:
6466 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
6467 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
6468 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
6469 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
6470 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
6471 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
6472 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
6473 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
6474 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
6475 break;
6476
6477 case VKI_KDGKBSENT:
6478 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
6479 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
6480 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
6481 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
6482 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
6483 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
6484 break;
6485 case VKI_KDSKBSENT:
6486 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
6487 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
6488 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
6489 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
6490 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
6491 break;
6492
6493 case VKI_KDGKBDIACR:
6494 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
6495 break;
6496 case VKI_KDSKBDIACR:
6497 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
6498 break;
6499
6500 case VKI_KDGETKEYCODE:
6501 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
6502 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
6503 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
6504 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
6505 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6506 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6507 break;
6508 case VKI_KDSETKEYCODE:
6509 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
6510 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
6511 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
6512 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
6513 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
6514 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
6515 break;
6516
6517 case VKI_KDSIGACCEPT:
6518 break;
6519
6520 case VKI_KDKBDREP:
6521 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
6522 break;
6523
6524 case VKI_KDFONTOP:
6525 if ( ARG3 ) {
6526 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
6527 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
6528 sizeof(struct vki_console_font_op) );
6529 switch ( op->op ) {
6530 case VKI_KD_FONT_OP_SET:
6531 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
6532 (Addr)op->data,
6533 (op->width + 7) / 8 * 32 * op->charcount );
6534 break;
6535 case VKI_KD_FONT_OP_GET:
6536 if ( op->data )
6537 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
6538 (Addr)op->data,
6539 (op->width + 7) / 8 * 32 * op->charcount );
6540 break;
6541 case VKI_KD_FONT_OP_SET_DEFAULT:
6542 if ( op->data )
6543 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
6544 (Addr)op->data );
6545 break;
6546 case VKI_KD_FONT_OP_COPY:
6547 break;
6548 }
6549 }
6550 break;
6551
6552 case VKI_VT_OPENQRY:
6553 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
6554 break;
6555 case VKI_VT_GETMODE:
6556 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
6557 break;
6558 case VKI_VT_SETMODE:
6559 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
6560 break;
6561 case VKI_VT_GETSTATE:
njn096ccdd2009-02-22 23:00:30 +00006562 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
6563 (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
6564 sizeof(((struct vki_vt_stat*) ARG3)->v_active));
6565 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
6566 (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
6567 sizeof(((struct vki_vt_stat*) ARG3)->v_state));
6568 break;
6569 case VKI_VT_RELDISP:
6570 case VKI_VT_ACTIVATE:
6571 case VKI_VT_WAITACTIVE:
6572 case VKI_VT_DISALLOCATE:
6573 break;
6574 case VKI_VT_RESIZE:
6575 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
6576 break;
6577 case VKI_VT_RESIZEX:
6578 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
6579 break;
6580 case VKI_VT_LOCKSWITCH:
6581 case VKI_VT_UNLOCKSWITCH:
6582 break;
6583
6584 case VKI_USBDEVFS_CONTROL:
6585 if ( ARG3 ) {
6586 struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
6587 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
6588 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
6589 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
6590 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
6591 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
6592 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
6593 if (vkuc->bRequestType & 0x80)
6594 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
6595 else
6596 PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
6597 }
6598 break;
6599 case VKI_USBDEVFS_BULK:
6600 if ( ARG3 ) {
6601 struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
6602 PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
6603 if (vkub->ep & 0x80)
6604 PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
6605 else
6606 PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
njn096ccdd2009-02-22 23:00:30 +00006607 }
tom8bb4d8f2011-07-06 14:11:56 +00006608 break;
njn096ccdd2009-02-22 23:00:30 +00006609 case VKI_USBDEVFS_GETDRIVER:
6610 if ( ARG3 ) {
6611 struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
6612 PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
njn096ccdd2009-02-22 23:00:30 +00006613 }
tom8bb4d8f2011-07-06 14:11:56 +00006614 break;
njn096ccdd2009-02-22 23:00:30 +00006615 case VKI_USBDEVFS_SUBMITURB:
6616 if ( ARG3 ) {
6617 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
6618
6619 /* Not the whole struct needs to be initialized */
njn6e10c6c2009-06-09 23:03:02 +00006620 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
njn096ccdd2009-02-22 23:00:30 +00006621 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
6622 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
6623 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
njn6e10c6c2009-06-09 23:03:02 +00006624 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
6625 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
6626 if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
6627 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
6628 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
6629 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
6630 if (vkusp->bRequestType & 0x80)
6631 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
6632 else
6633 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
6634 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
6635 } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
6636 int total_length = 0;
6637 int i;
6638 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
6639 for(i=0; i<vkuu->number_of_packets; i++) {
6640 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
6641 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));
6642 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
6643 total_length += vkuu->iso_frame_desc[i].length;
6644 }
6645 if (vkuu->endpoint & 0x80)
6646 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
6647 else
6648 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
6649 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
6650 } else {
6651 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
6652 if (vkuu->endpoint & 0x80)
6653 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
6654 else
6655 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
6656 PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
6657 }
njn096ccdd2009-02-22 23:00:30 +00006658 }
tom8bb4d8f2011-07-06 14:11:56 +00006659 break;
njn6e10c6c2009-06-09 23:03:02 +00006660 case VKI_USBDEVFS_DISCARDURB:
6661 break;
njn096ccdd2009-02-22 23:00:30 +00006662 case VKI_USBDEVFS_REAPURB:
njn6e10c6c2009-06-09 23:03:02 +00006663 if ( ARG3 ) {
6664 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
njn6e10c6c2009-06-09 23:03:02 +00006665 }
tom8bb4d8f2011-07-06 14:11:56 +00006666 break;
njn096ccdd2009-02-22 23:00:30 +00006667 case VKI_USBDEVFS_REAPURBNDELAY:
6668 if ( ARG3 ) {
njn6e10c6c2009-06-09 23:03:02 +00006669 PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
njn096ccdd2009-02-22 23:00:30 +00006670 }
tom8bb4d8f2011-07-06 14:11:56 +00006671 break;
njn096ccdd2009-02-22 23:00:30 +00006672 case VKI_USBDEVFS_CONNECTINFO:
6673 PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
6674 break;
6675 case VKI_USBDEVFS_IOCTL:
6676 if ( ARG3 ) {
6677 struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
6678 UInt dir2, size2;
6679 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
6680 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
6681 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
6682 if (size2 > 0) {
6683 if (dir2 & _VKI_IOC_WRITE)
6684 PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
6685 else if (dir2 & _VKI_IOC_READ)
6686 PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
6687 }
6688 }
6689 break;
bart551fe932011-04-18 10:37:56 +00006690 case VKI_USBDEVFS_RESET:
6691 break;
njn096ccdd2009-02-22 23:00:30 +00006692
6693 /* I2C (/dev/i2c-*) ioctls */
6694 case VKI_I2C_SLAVE:
6695 case VKI_I2C_SLAVE_FORCE:
6696 case VKI_I2C_TENBIT:
6697 case VKI_I2C_PEC:
6698 break;
6699 case VKI_I2C_FUNCS:
6700 PRE_MEM_WRITE( "ioctl(I2C_FUNCS)", ARG3, sizeof(unsigned long) );
6701 break;
tomd543d742012-03-07 10:21:33 +00006702 case VKI_I2C_RDWR:
6703 if ( ARG3 ) {
6704 struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
6705 UInt i;
6706 PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
6707 for (i=0; i < vkui->nmsgs; i++) {
6708 struct vki_i2c_msg *msg = vkui->msgs + i;
6709 PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
6710 if (msg->flags & VKI_I2C_M_RD)
6711 PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
6712 else
6713 PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
6714 }
6715 }
6716 break;
njn096ccdd2009-02-22 23:00:30 +00006717
6718 /* Wireless extensions ioctls */
6719 case VKI_SIOCSIWCOMMIT:
6720 case VKI_SIOCSIWNWID:
6721 case VKI_SIOCSIWFREQ:
6722 case VKI_SIOCSIWMODE:
6723 case VKI_SIOCSIWSENS:
6724 case VKI_SIOCSIWRANGE:
6725 case VKI_SIOCSIWPRIV:
6726 case VKI_SIOCSIWSTATS:
6727 case VKI_SIOCSIWSPY:
6728 case VKI_SIOCSIWTHRSPY:
6729 case VKI_SIOCSIWAP:
6730 case VKI_SIOCSIWSCAN:
6731 case VKI_SIOCSIWESSID:
6732 case VKI_SIOCSIWRATE:
6733 case VKI_SIOCSIWNICKN:
6734 case VKI_SIOCSIWRTS:
6735 case VKI_SIOCSIWFRAG:
6736 case VKI_SIOCSIWTXPOW:
6737 case VKI_SIOCSIWRETRY:
6738 case VKI_SIOCSIWENCODE:
6739 case VKI_SIOCSIWPOWER:
6740 case VKI_SIOCSIWGENIE:
6741 case VKI_SIOCSIWMLME:
6742 case VKI_SIOCSIWAUTH:
6743 case VKI_SIOCSIWENCODEEXT:
6744 case VKI_SIOCSIWPMKSA:
6745 break;
6746 case VKI_SIOCGIWNAME:
6747 if (ARG3) {
6748 PRE_MEM_WRITE("ioctl(SIOCGIWNAME)",
6749 (Addr)((struct vki_iwreq *)ARG3)->u.name,
6750 sizeof(((struct vki_iwreq *)ARG3)->u.name));
6751 }
6752 break;
6753 case VKI_SIOCGIWNWID:
6754 case VKI_SIOCGIWSENS:
6755 case VKI_SIOCGIWRATE:
6756 case VKI_SIOCGIWRTS:
6757 case VKI_SIOCGIWFRAG:
6758 case VKI_SIOCGIWTXPOW:
6759 case VKI_SIOCGIWRETRY:
6760 case VKI_SIOCGIWPOWER:
6761 case VKI_SIOCGIWAUTH:
6762 if (ARG3) {
6763 PRE_MEM_WRITE("ioctl(SIOCGIW[NWID|SENS|RATE|RTS|FRAG|TXPOW|"
6764 "RETRY|PARAM|AUTH])",
6765 (Addr)&((struct vki_iwreq *)ARG3)->u.nwid,
6766 sizeof(struct vki_iw_param));
6767 }
6768 break;
6769 case VKI_SIOCGIWFREQ:
6770 if (ARG3) {
6771 PRE_MEM_WRITE("ioctl(SIOCGIWFREQ",
6772 (Addr)&((struct vki_iwreq *)ARG3)->u.freq,
6773 sizeof(struct vki_iw_freq));
6774 }
6775 break;
6776 case VKI_SIOCGIWMODE:
6777 if (ARG3) {
6778 PRE_MEM_WRITE("ioctl(SIOCGIWMODE",
6779 (Addr)&((struct vki_iwreq *)ARG3)->u.mode,
6780 sizeof(__vki_u32));
6781 }
6782 break;
6783 case VKI_SIOCGIWRANGE:
6784 case VKI_SIOCGIWPRIV:
6785 case VKI_SIOCGIWSTATS:
6786 case VKI_SIOCGIWSPY:
6787 case VKI_SIOCGIWTHRSPY:
6788 case VKI_SIOCGIWAPLIST:
6789 case VKI_SIOCGIWSCAN:
6790 case VKI_SIOCGIWESSID:
6791 case VKI_SIOCGIWNICKN:
6792 case VKI_SIOCGIWENCODE:
6793 case VKI_SIOCGIWGENIE:
6794 case VKI_SIOCGIWENCODEEXT:
6795 if (ARG3) {
6796 struct vki_iw_point* point;
6797 point = &((struct vki_iwreq *)ARG3)->u.data;
6798 PRE_MEM_WRITE("ioctl(SIOCGIW[RANGE|PRIV|STATS|SPY|THRSPY|"
6799 "APLIST|SCAN|ESSID|NICKN|ENCODE|GENIE|ENCODEEXT])",
6800 (Addr)point->pointer, point->length);
6801 }
6802 break;
6803 case VKI_SIOCGIWAP:
6804 if (ARG3) {
6805 PRE_MEM_WRITE("ioctl(SIOCGIWAP)",
6806 (Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
6807 sizeof(struct vki_sockaddr));
6808 }
6809 break;
6810
sewardjb6bf12c2012-07-13 13:15:10 +00006811 /* User input device creation */
6812 case VKI_UI_SET_EVBIT:
6813 case VKI_UI_SET_KEYBIT:
6814 case VKI_UI_SET_RELBIT:
6815 case VKI_UI_SET_ABSBIT:
6816 case VKI_UI_SET_MSCBIT:
6817 case VKI_UI_SET_LEDBIT:
6818 case VKI_UI_SET_SNDBIT:
6819 case VKI_UI_SET_FFBIT:
6820 case VKI_UI_SET_SWBIT:
6821 case VKI_UI_SET_PROPBIT:
6822 /* These just take an int by value */
6823 break;
6824
dejanj9c6b05d2013-12-27 09:06:55 +00006825# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
6826 || defined(VGPV_mips32_linux_android)
sewardja3e7a482011-09-27 10:26:52 +00006827 /* ashmem */
6828 case VKI_ASHMEM_GET_SIZE:
6829 case VKI_ASHMEM_SET_SIZE:
6830 case VKI_ASHMEM_GET_PROT_MASK:
6831 case VKI_ASHMEM_SET_PROT_MASK:
6832 case VKI_ASHMEM_GET_PIN_STATUS:
6833 case VKI_ASHMEM_PURGE_ALL_CACHES:
6834 break;
6835 case VKI_ASHMEM_GET_NAME:
6836 PRE_MEM_WRITE( "ioctl(ASHMEM_SET_NAME)", ARG3, VKI_ASHMEM_NAME_LEN );
6837 break;
6838 case VKI_ASHMEM_SET_NAME:
6839 PRE_MEM_RASCIIZ( "ioctl(ASHMEM_SET_NAME)", ARG3);
6840 break;
6841 case VKI_ASHMEM_PIN:
6842 case VKI_ASHMEM_UNPIN:
6843 PRE_MEM_READ( "ioctl(ASHMEM_PIN|ASHMEM_UNPIN)",
6844 ARG3, sizeof(struct vki_ashmem_pin) );
6845 break;
6846
6847 /* binder */
6848 case VKI_BINDER_WRITE_READ:
6849 if (ARG3) {
6850 struct vki_binder_write_read* bwr
6851 = (struct vki_binder_write_read*)ARG3;
6852
6853 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_buffer",
6854 bwr->write_buffer);
6855 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_size",
6856 bwr->write_size);
6857 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).write_consumed",
6858 bwr->write_consumed);
6859 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_buffer",
6860 bwr->read_buffer);
6861 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_size",
6862 bwr->read_size);
6863 PRE_FIELD_READ("ioctl(BINDER_WRITE_READ).read_consumed",
6864 bwr->read_consumed);
6865
6866 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).write_consumed",
6867 bwr->write_consumed);
6868 PRE_FIELD_WRITE("ioctl(BINDER_WRITE_READ).read_consumed",
6869 bwr->read_consumed);
6870
6871 if (bwr->read_size)
6872 PRE_MEM_WRITE("ioctl(BINDER_WRITE_READ).read_buffer[]",
6873 (Addr)bwr->read_buffer, bwr->read_size);
6874 if (bwr->write_size)
6875 PRE_MEM_READ("ioctl(BINDER_WRITE_READ).write_buffer[]",
6876 (Addr)bwr->write_buffer, bwr->write_size);
6877 }
6878 break;
6879
6880 case VKI_BINDER_SET_IDLE_TIMEOUT:
6881 case VKI_BINDER_SET_MAX_THREADS:
6882 case VKI_BINDER_SET_IDLE_PRIORITY:
6883 case VKI_BINDER_SET_CONTEXT_MGR:
6884 case VKI_BINDER_THREAD_EXIT:
6885 break;
6886 case VKI_BINDER_VERSION:
6887 if (ARG3) {
6888 struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
6889 PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
6890 }
6891 break;
philippe5d5dd8e2012-08-05 00:08:25 +00006892# endif /* defined(VGPV_*_linux_android) */
sewardja3e7a482011-09-27 10:26:52 +00006893
tom8236fe62012-03-07 11:22:42 +00006894 case VKI_HCIINQUIRY:
6895 if (ARG3) {
6896 struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
6897 PRE_MEM_READ("ioctl(HCIINQUIRY)",
6898 (Addr)ARG3, sizeof(struct vki_hci_inquiry_req));
6899 PRE_MEM_WRITE("ioctl(HCIINQUIRY)",
6900 (Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
6901 ir->num_rsp * sizeof(struct vki_inquiry_info));
6902 }
6903 break;
cborntra4ea8f142014-02-11 15:15:31 +00006904
cborntra65bdbe42012-05-23 15:59:40 +00006905 /* KVM ioctls that check for a numeric value as parameter */
6906 case VKI_KVM_GET_API_VERSION:
6907 case VKI_KVM_CREATE_VM:
6908 case VKI_KVM_GET_VCPU_MMAP_SIZE:
6909 case VKI_KVM_CHECK_EXTENSION:
6910 case VKI_KVM_CREATE_VCPU:
6911 case VKI_KVM_RUN:
6912 break;
tom8236fe62012-03-07 11:22:42 +00006913
bart0ab84fe2012-09-09 18:30:17 +00006914#ifdef ENABLE_XEN
6915 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
6916 SyscallArgs harrghs;
6917 struct vki_xen_privcmd_hypercall *args =
6918 (struct vki_xen_privcmd_hypercall *)(ARG3);
6919
6920 if (!args)
6921 break;
6922
6923 VG_(memset)(&harrghs, 0, sizeof(harrghs));
6924 harrghs.sysno = args->op;
6925 harrghs.arg1 = args->arg[0];
6926 harrghs.arg2 = args->arg[1];
6927 harrghs.arg3 = args->arg[2];
6928 harrghs.arg4 = args->arg[3];
6929 harrghs.arg5 = args->arg[4];
6930 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
6931
6932 WRAPPER_PRE_NAME(xen, hypercall) (tid, layout, &harrghs, status, flags);
6933
6934 /* HACK. arg8 is used to return the number of hypercall
6935 * arguments actually consumed! */
6936 PRE_MEM_READ("hypercall", ARG3, sizeof(args->op) +
6937 ( sizeof(args->arg[0]) * harrghs.arg8 ) );
6938
6939 break;
6940 }
6941
6942 case VKI_XEN_IOCTL_PRIVCMD_MMAP: {
6943 struct vki_xen_privcmd_mmap *args =
6944 (struct vki_xen_privcmd_mmap *)(ARG3);
bart77addcd2013-06-30 07:57:35 +00006945 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(num)",
bart0ab84fe2012-09-09 18:30:17 +00006946 (Addr)&args->num, sizeof(args->num));
bart77addcd2013-06-30 07:57:35 +00006947 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(dom)",
bart0ab84fe2012-09-09 18:30:17 +00006948 (Addr)&args->dom, sizeof(args->dom));
bart77addcd2013-06-30 07:57:35 +00006949 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAP(entry)",
bart0ab84fe2012-09-09 18:30:17 +00006950 (Addr)args->entry, sizeof(*(args->entry)) * args->num);
6951 break;
6952 }
6953 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
6954 struct vki_xen_privcmd_mmapbatch *args =
6955 (struct vki_xen_privcmd_mmapbatch *)(ARG3);
bart77addcd2013-06-30 07:57:35 +00006956 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(num)",
bart0ab84fe2012-09-09 18:30:17 +00006957 (Addr)&args->num, sizeof(args->num));
bart77addcd2013-06-30 07:57:35 +00006958 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(dom)",
bart0ab84fe2012-09-09 18:30:17 +00006959 (Addr)&args->dom, sizeof(args->dom));
bart77addcd2013-06-30 07:57:35 +00006960 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(addr)",
bart0ab84fe2012-09-09 18:30:17 +00006961 (Addr)&args->addr, sizeof(args->addr));
bart77addcd2013-06-30 07:57:35 +00006962 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH(arr)",
bart0ab84fe2012-09-09 18:30:17 +00006963 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
6964 break;
6965 }
6966 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
6967 struct vki_xen_privcmd_mmapbatch_v2 *args =
6968 (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
bart77addcd2013-06-30 07:57:35 +00006969 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(num)",
bart0ab84fe2012-09-09 18:30:17 +00006970 (Addr)&args->num, sizeof(args->num));
bart77addcd2013-06-30 07:57:35 +00006971 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(dom)",
bart0ab84fe2012-09-09 18:30:17 +00006972 (Addr)&args->dom, sizeof(args->dom));
bart77addcd2013-06-30 07:57:35 +00006973 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(addr)",
bart0ab84fe2012-09-09 18:30:17 +00006974 (Addr)&args->addr, sizeof(args->addr));
bart77addcd2013-06-30 07:57:35 +00006975 PRE_MEM_READ("VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2(arr)",
bart0ab84fe2012-09-09 18:30:17 +00006976 (Addr)args->arr, sizeof(*(args->arr)) * args->num);
6977 break;
6978 }
6979#endif
6980
njn1be9cf62009-05-22 00:15:06 +00006981 default:
tom0ee313e2010-05-07 15:32:04 +00006982 /* EVIOC* are variable length and return size written on success */
6983 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
6984 case VKI_EVIOCGNAME(0):
6985 case VKI_EVIOCGPHYS(0):
6986 case VKI_EVIOCGUNIQ(0):
6987 case VKI_EVIOCGKEY(0):
6988 case VKI_EVIOCGLED(0):
6989 case VKI_EVIOCGSND(0):
6990 case VKI_EVIOCGSW(0):
6991 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
6992 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
6993 case VKI_EVIOCGBIT(VKI_EV_REL,0):
6994 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
6995 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
6996 case VKI_EVIOCGBIT(VKI_EV_SW,0):
6997 case VKI_EVIOCGBIT(VKI_EV_LED,0):
6998 case VKI_EVIOCGBIT(VKI_EV_SND,0):
6999 case VKI_EVIOCGBIT(VKI_EV_REP,0):
7000 case VKI_EVIOCGBIT(VKI_EV_FF,0):
7001 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
7002 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
tomaab8c762010-06-10 15:01:02 +00007003 PRE_MEM_WRITE("ioctl(EVIO*)", ARG3, _VKI_IOC_SIZE(ARG2));
tom0ee313e2010-05-07 15:32:04 +00007004 break;
7005 default:
7006 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
7007 break;
7008 }
njn096ccdd2009-02-22 23:00:30 +00007009 break;
njn096ccdd2009-02-22 23:00:30 +00007010 }
7011}
7012
7013POST(sys_ioctl)
7014{
7015 vg_assert(SUCCESS);
sewardj889ffa42011-09-27 11:40:24 +00007016
7017 /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
7018
dejanj9c6b05d2013-12-27 09:06:55 +00007019# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7020 || defined(VGPV_mips32_linux_android)
sewardj889ffa42011-09-27 11:40:24 +00007021
7022# if defined(ANDROID_HARDWARE_nexus_s)
7023
7024 /* BEGIN undocumented ioctls for the graphics hardware (??)
7025 (libpvr) on Nexus S */
7026 if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) {
7027 /* What's going on here: there appear to be a bunch of ioctls of
7028 the form 0xC01C67xx which are undocumented, and if unhandled
7029 give rise to a vast number of false positives in Memcheck.
7030
7031 The "normal" intrepretation of an ioctl of this form would be
7032 that the 3rd arg is a pointer to an area of size 0x1C (28
7033 bytes) which is filled in by the kernel. Hence you might
7034 think that "POST_MEM_WRITE(ARG3, 28)" would fix it. But it
7035 doesn't.
7036
7037 It requires POST_MEM_WRITE(ARG3, 256) to silence them. One
7038 interpretation of this is that ARG3 really does point to a 28
7039 byte struct, but inside that are pointers to other areas also
7040 filled in by the kernel. If these happen to be allocated
7041 just back up the stack then the 256 byte paint might cover
7042 them too, somewhat indiscriminately.
7043
7044 By printing out ARG3 and also the 28 bytes that it points at,
7045 it's possible to guess that the 7 word structure has this form
7046
7047 0 1 2 3 4 5 6
7048 ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask
7049
7050 Unfortunately that doesn't seem to work for some reason, so
7051 stay with the blunt-instrument approach for the time being.
7052 */
7053 if (1) {
7054 /* blunt-instrument approach */
sewardj1b3a7a42011-10-26 15:10:49 +00007055 if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
7056 " (%08lx, %08lx)\n", ARG2, ARG3);
sewardj889ffa42011-09-27 11:40:24 +00007057 POST_MEM_WRITE(ARG3, 256);
7058 } else {
7059 /* be a bit more sophisticated */
sewardj1b3a7a42011-10-26 15:10:49 +00007060 if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned"
7061 " (%08lx, %08lx) (fancy)\n", ARG2, ARG3);
sewardj889ffa42011-09-27 11:40:24 +00007062 POST_MEM_WRITE(ARG3, 28);
7063 UInt* word = (UInt*)ARG3;
7064 if (word && word[2] && word[3] < 0x200/*stay sane*/)
7065 POST_MEM_WRITE(word[2], word[3]); // "ptr1"
7066 if (word && word[4] && word[5] < 0x200/*stay sane*/)
7067 POST_MEM_WRITE(word[4], word[5]); // "ptr2"
7068 }
7069 if (0) {
7070 Int i;
7071 VG_(printf)("QQQQQQQQQQ ");
7072 for (i = 0; i < (0x1C/4); i++) {
7073 VG_(printf)("%08x ", ((UInt*)(ARG3))[i]);
7074 }
7075 VG_(printf)("\n");
7076 }
7077 return;
7078 }
7079 /* END Nexus S specific ioctls */
7080
sewardj1b3a7a42011-10-26 15:10:49 +00007081
philippe5d5dd8e2012-08-05 00:08:25 +00007082# elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator)
sewardj1b3a7a42011-10-26 15:10:49 +00007083
philippe5d5dd8e2012-08-05 00:08:25 +00007084 /* BEGIN generic/emulator specific ioctls */
sewardj1b3a7a42011-10-26 15:10:49 +00007085 /* currently none are known */
philippe5d5dd8e2012-08-05 00:08:25 +00007086 /* END generic/emulator specific ioctls */
philippeeeb07332012-07-04 21:59:29 +00007087
7088
sewardj889ffa42011-09-27 11:40:24 +00007089# else /* no ANDROID_HARDWARE_anything defined */
7090
7091# warning ""
7092# warning "You need to define one the CPP symbols ANDROID_HARDWARE_blah"
7093# warning "at configure time, to tell Valgrind what hardware you are"
7094# warning "building for. Currently known values are"
7095# warning ""
7096# warning " ANDROID_HARDWARE_nexus_s Samsung Nexus S"
philippe5d5dd8e2012-08-05 00:08:25 +00007097# warning " ANDROID_HARDWARE_generic Generic device (eg, Pandaboard)"
7098# warning " ANDROID_HARDWARE_emulator x86 or arm emulator"
sewardj889ffa42011-09-27 11:40:24 +00007099# warning ""
7100# warning "Make sure you exactly follow the steps in README.android."
7101# warning ""
7102# error "No CPP symbol ANDROID_HARDWARE_blah defined. Giving up."
7103
7104# endif /* cases for ANDROID_HARDWARE_blah */
7105
philippe5d5dd8e2012-08-05 00:08:25 +00007106# endif /* defined(VGPV_*_linux_android) */
sewardj889ffa42011-09-27 11:40:24 +00007107
7108 /* --- END special IOCTL handlers for specific Android hardware --- */
7109
7110 /* --- normal handling --- */
njn096ccdd2009-02-22 23:00:30 +00007111 switch (ARG2 /* request */) {
7112 case VKI_TCSETS:
7113 case VKI_TCSETSW:
7114 case VKI_TCSETSF:
bart9f2a3392013-02-14 17:10:01 +00007115 case VKI_IB_USER_MAD_ENABLE_PKEY:
njn096ccdd2009-02-22 23:00:30 +00007116 break;
7117 case VKI_TCGETS:
7118 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
7119 break;
7120 case VKI_TCSETA:
7121 case VKI_TCSETAW:
7122 case VKI_TCSETAF:
7123 break;
7124 case VKI_TCGETA:
7125 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
7126 break;
7127 case VKI_TCSBRK:
7128 case VKI_TCXONC:
7129 case VKI_TCSBRKP:
7130 case VKI_TCFLSH:
7131 break;
7132 case VKI_TIOCGWINSZ:
7133 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
7134 break;
7135 case VKI_TIOCSWINSZ:
7136 case VKI_TIOCMBIS:
7137 case VKI_TIOCMBIC:
7138 case VKI_TIOCMSET:
7139 break;
7140 case VKI_TIOCMGET:
7141 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
7142 break;
7143 case VKI_TIOCLINUX:
7144 POST_MEM_WRITE( ARG3, sizeof(char *) );
7145 break;
7146 case VKI_TIOCGPGRP:
7147 /* Get process group ID for foreground processing group. */
7148 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
7149 break;
7150 case VKI_TIOCSPGRP:
7151 /* Set a process group ID? */
7152 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
7153 break;
7154 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
7155 POST_MEM_WRITE( ARG3, sizeof(int));
7156 break;
7157 case VKI_TIOCSCTTY:
7158 break;
7159 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
7160 break;
7161 case VKI_FIONBIO:
7162 break;
tom0c7ff332013-07-17 14:57:18 +00007163 case VKI_FIONCLEX:
7164 break;
7165 case VKI_FIOCLEX:
7166 break;
njn096ccdd2009-02-22 23:00:30 +00007167 case VKI_FIOASYNC:
7168 break;
7169 case VKI_FIONREAD: /* identical to SIOCINQ */
7170 POST_MEM_WRITE( ARG3, sizeof(int) );
7171 break;
tom6bf71ef2011-08-10 14:25:06 +00007172 case VKI_FIOQSIZE:
7173 POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
7174 break;
njn096ccdd2009-02-22 23:00:30 +00007175
7176 case VKI_TIOCSERGETLSR:
7177 POST_MEM_WRITE( ARG3, sizeof(int) );
7178 break;
7179 case VKI_TIOCGICOUNT:
7180 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
7181 break;
7182
7183 case VKI_SG_SET_COMMAND_Q:
7184 break;
7185 case VKI_SG_IO:
7186 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
7187 break;
7188 case VKI_SG_GET_SCSI_ID:
7189 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
7190 break;
7191 case VKI_SG_SET_RESERVED_SIZE:
7192 break;
7193 case VKI_SG_SET_TIMEOUT:
7194 break;
7195 case VKI_SG_GET_RESERVED_SIZE:
7196 POST_MEM_WRITE(ARG3, sizeof(int));
7197 break;
7198 case VKI_SG_GET_TIMEOUT:
7199 break;
7200 case VKI_SG_GET_VERSION_NUM:
7201 POST_MEM_WRITE(ARG3, sizeof(int));
7202 break;
7203 case VKI_SG_EMULATED_HOST:
7204 POST_MEM_WRITE(ARG3, sizeof(int));
7205 break;
7206 case VKI_SG_GET_SG_TABLESIZE:
7207 POST_MEM_WRITE(ARG3, sizeof(int));
7208 break;
7209
7210 case VKI_IIOCGETCPS:
7211 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
7212 break;
7213 case VKI_IIOCNETGPN:
7214 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
7215 break;
7216
7217 /* These all use struct ifreq AFAIK */
7218 case VKI_SIOCGIFINDEX: /* get iface index */
7219 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
7220 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
7221 break;
7222 case VKI_SIOCGIFFLAGS: /* get flags */
7223 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
7224 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
7225 break;
7226 case VKI_SIOCGIFHWADDR: /* Get hardware address */
7227 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
7228 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
7229 break;
7230 case VKI_SIOCGIFMTU: /* get MTU size */
7231 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
7232 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
7233 break;
7234 case VKI_SIOCGIFADDR: /* get PA address */
7235 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
7236 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
7237 case VKI_SIOCGIFNETMASK: /* get network PA mask */
7238 POST_MEM_WRITE(
7239 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
7240 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
7241 break;
7242 case VKI_SIOCGIFMETRIC: /* get metric */
7243 POST_MEM_WRITE(
7244 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
7245 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
7246 break;
7247 case VKI_SIOCGIFMAP: /* Get device parameters */
7248 POST_MEM_WRITE(
7249 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
7250 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
7251 break;
7252 break;
7253 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
7254 POST_MEM_WRITE(
7255 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
7256 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
7257 break;
7258 case VKI_SIOCGIFNAME: /* get iface name */
7259 POST_MEM_WRITE(
7260 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
7261 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
7262 break;
7263 case VKI_SIOCGMIIPHY: /* get hardware entry */
7264 POST_MEM_WRITE(
7265 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
7266 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
7267 break;
7268 case VKI_SIOCGMIIREG: /* get hardware entry registers */
7269 POST_MEM_WRITE(
7270 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
7271 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
7272 break;
cborntradfe0dae2013-03-01 12:56:07 +00007273
7274 /* tun/tap related ioctls */
7275 case VKI_TUNSETIFF:
7276 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
7277 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
7278 break;
7279 case VKI_TUNGETIFF:
7280 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
7281 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
7282 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
7283 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
7284 break;
7285
njn096ccdd2009-02-22 23:00:30 +00007286 case VKI_SIOCGIFCONF: /* get iface list */
7287 /* WAS:
7288 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
7289 KERNEL_DO_SYSCALL(tid,RES);
7290 if (!VG_(is_kerror)(RES) && RES == 0)
7291 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
7292 */
7293 if (RES == 0 && ARG3 ) {
7294 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
7295 if (ifc->vki_ifc_buf != NULL)
7296 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
7297 }
7298 break;
7299 case VKI_SIOCGSTAMP:
7300 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
7301 break;
toma2ec4f52009-03-31 10:36:58 +00007302 case VKI_SIOCGSTAMPNS:
7303 POST_MEM_WRITE( ARG3, sizeof(struct vki_timespec) );
7304 break;
njn096ccdd2009-02-22 23:00:30 +00007305 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
7306 the number of bytes currently in that socket's send buffer.
7307 It writes this value as an int to the memory location
7308 indicated by the third argument of ioctl(2). */
7309 case VKI_SIOCOUTQ:
7310 POST_MEM_WRITE(ARG3, sizeof(int));
7311 break;
7312 case VKI_SIOCGRARP: /* get RARP table entry */
7313 case VKI_SIOCGARP: /* get ARP table entry */
7314 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
7315 break;
7316
7317 case VKI_SIOCSIFFLAGS: /* set flags */
7318 case VKI_SIOCSIFMAP: /* Set device parameters */
toma7b9dfc2012-07-11 14:33:10 +00007319 case VKI_SIOCSHWTSTAMP: /* Set hardware time stamping */
njn096ccdd2009-02-22 23:00:30 +00007320 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
7321 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
7322 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
7323 case VKI_SIOCSIFNETMASK: /* set network PA mask */
7324 case VKI_SIOCSIFMETRIC: /* set metric */
7325 case VKI_SIOCSIFADDR: /* set PA address */
7326 case VKI_SIOCSIFMTU: /* set MTU size */
7327 case VKI_SIOCSIFHWADDR: /* set hardware address */
7328 case VKI_SIOCSMIIREG: /* set hardware entry registers */
7329 break;
7330 /* Routing table calls. */
7331 case VKI_SIOCADDRT: /* add routing table entry */
7332 case VKI_SIOCDELRT: /* delete routing table entry */
7333 break;
7334
7335 /* RARP cache control calls. */
7336 case VKI_SIOCDRARP: /* delete RARP table entry */
7337 case VKI_SIOCSRARP: /* set RARP table entry */
7338 /* ARP cache control calls. */
7339 case VKI_SIOCSARP: /* set ARP table entry */
7340 case VKI_SIOCDARP: /* delete ARP table entry */
7341 break;
7342
7343 case VKI_SIOCGPGRP:
7344 POST_MEM_WRITE(ARG3, sizeof(int));
7345 break;
7346 case VKI_SIOCSPGRP:
7347 break;
7348
7349 /* linux/soundcard interface (OSS) */
7350 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
7351 case VKI_SNDCTL_SEQ_GETINCOUNT:
7352 case VKI_SNDCTL_SEQ_PERCMODE:
7353 case VKI_SNDCTL_SEQ_TESTMIDI:
7354 case VKI_SNDCTL_SEQ_RESETSAMPLES:
7355 case VKI_SNDCTL_SEQ_NRSYNTHS:
7356 case VKI_SNDCTL_SEQ_NRMIDIS:
7357 case VKI_SNDCTL_SEQ_GETTIME:
tom55703df2010-02-18 15:54:45 +00007358 case VKI_SNDCTL_DSP_GETBLKSIZE:
njn096ccdd2009-02-22 23:00:30 +00007359 case VKI_SNDCTL_DSP_GETFMTS:
tom55703df2010-02-18 15:54:45 +00007360 case VKI_SNDCTL_DSP_SETFMT:
njn096ccdd2009-02-22 23:00:30 +00007361 case VKI_SNDCTL_DSP_GETTRIGGER:
7362 case VKI_SNDCTL_DSP_GETODELAY:
7363 case VKI_SNDCTL_DSP_GETSPDIF:
7364 case VKI_SNDCTL_DSP_GETCAPS:
7365 case VKI_SOUND_PCM_READ_RATE:
7366 case VKI_SOUND_PCM_READ_CHANNELS:
7367 case VKI_SOUND_PCM_READ_BITS:
njn096ccdd2009-02-22 23:00:30 +00007368 case VKI_SOUND_PCM_READ_FILTER:
7369 POST_MEM_WRITE(ARG3, sizeof(int));
7370 break;
7371 case VKI_SNDCTL_SEQ_CTRLRATE:
7372 case VKI_SNDCTL_DSP_SPEED:
7373 case VKI_SNDCTL_DSP_STEREO:
njn096ccdd2009-02-22 23:00:30 +00007374 case VKI_SNDCTL_DSP_CHANNELS:
7375 case VKI_SOUND_PCM_WRITE_FILTER:
7376 case VKI_SNDCTL_DSP_SUBDIVIDE:
7377 case VKI_SNDCTL_DSP_SETFRAGMENT:
7378 case VKI_SNDCTL_DSP_GETCHANNELMASK:
7379 case VKI_SNDCTL_DSP_BIND_CHANNEL:
7380 case VKI_SNDCTL_TMR_TIMEBASE:
7381 case VKI_SNDCTL_TMR_TEMPO:
7382 case VKI_SNDCTL_TMR_SOURCE:
7383 case VKI_SNDCTL_MIDI_PRETIME:
7384 case VKI_SNDCTL_MIDI_MPUMODE:
7385 break;
7386 case VKI_SNDCTL_DSP_GETOSPACE:
7387 case VKI_SNDCTL_DSP_GETISPACE:
7388 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
7389 break;
njn06605672009-06-09 22:31:00 +00007390 case VKI_SNDCTL_DSP_NONBLOCK:
7391 break;
njn096ccdd2009-02-22 23:00:30 +00007392 case VKI_SNDCTL_DSP_SETTRIGGER:
7393 break;
7394
7395 case VKI_SNDCTL_DSP_POST:
7396 case VKI_SNDCTL_DSP_RESET:
7397 case VKI_SNDCTL_DSP_SYNC:
7398 case VKI_SNDCTL_DSP_SETSYNCRO:
7399 case VKI_SNDCTL_DSP_SETDUPLEX:
7400 break;
7401
7402 /* linux/soundcard interface (ALSA) */
7403 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
7404 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
7405 case VKI_SNDRV_PCM_IOCTL_PREPARE:
7406 case VKI_SNDRV_PCM_IOCTL_RESET:
7407 case VKI_SNDRV_PCM_IOCTL_START:
7408 case VKI_SNDRV_PCM_IOCTL_DROP:
7409 case VKI_SNDRV_PCM_IOCTL_DRAIN:
7410 case VKI_SNDRV_PCM_IOCTL_RESUME:
7411 case VKI_SNDRV_PCM_IOCTL_XRUN:
7412 case VKI_SNDRV_PCM_IOCTL_UNLINK:
7413 case VKI_SNDRV_TIMER_IOCTL_START:
7414 case VKI_SNDRV_TIMER_IOCTL_STOP:
7415 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
7416 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
tom8758e702012-02-10 10:41:07 +00007417
7418 /* SCSI no operand */
7419 case VKI_SCSI_IOCTL_DOORLOCK:
7420 case VKI_SCSI_IOCTL_DOORUNLOCK:
njn096ccdd2009-02-22 23:00:30 +00007421 break;
7422
7423 /* Real Time Clock (/dev/rtc) ioctls */
7424 case VKI_RTC_UIE_ON:
7425 case VKI_RTC_UIE_OFF:
7426 case VKI_RTC_AIE_ON:
7427 case VKI_RTC_AIE_OFF:
7428 case VKI_RTC_PIE_ON:
7429 case VKI_RTC_PIE_OFF:
7430 case VKI_RTC_IRQP_SET:
7431 break;
7432 case VKI_RTC_RD_TIME:
7433 case VKI_RTC_ALM_READ:
7434 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
7435 break;
7436 case VKI_RTC_ALM_SET:
7437 break;
7438 case VKI_RTC_IRQP_READ:
7439 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
7440 break;
7441
7442 /* Block devices */
7443 case VKI_BLKROSET:
7444 break;
7445 case VKI_BLKROGET:
7446 POST_MEM_WRITE(ARG3, sizeof(int));
7447 break;
7448 case VKI_BLKGETSIZE:
7449 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
7450 break;
7451 case VKI_BLKRASET:
7452 break;
7453 case VKI_BLKRAGET:
7454 POST_MEM_WRITE(ARG3, sizeof(long));
7455 break;
7456 case VKI_BLKFRASET:
7457 break;
7458 case VKI_BLKFRAGET:
7459 POST_MEM_WRITE(ARG3, sizeof(long));
7460 break;
7461 case VKI_BLKSECTGET:
7462 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
7463 break;
7464 case VKI_BLKSSZGET:
7465 POST_MEM_WRITE(ARG3, sizeof(int));
7466 break;
7467 case VKI_BLKBSZGET:
7468 POST_MEM_WRITE(ARG3, sizeof(int));
7469 break;
7470 case VKI_BLKBSZSET:
7471 break;
7472 case VKI_BLKGETSIZE64:
7473 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
7474 break;
cborntra0e6d05e2012-11-09 16:01:38 +00007475 case VKI_BLKPBSZGET:
7476 POST_MEM_WRITE(ARG3, sizeof(int));
7477 break;
njn096ccdd2009-02-22 23:00:30 +00007478
7479 /* Hard disks */
7480 case VKI_HDIO_GETGEO: /* 0x0301 */
7481 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
7482 break;
7483 case VKI_HDIO_GET_DMA: /* 0x030b */
7484 POST_MEM_WRITE(ARG3, sizeof(long));
7485 break;
7486 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
7487 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
7488 break;
7489
tom8758e702012-02-10 10:41:07 +00007490 /* SCSI */
7491 case VKI_SCSI_IOCTL_GET_IDLUN: /* 0x5382 */
7492 POST_MEM_WRITE(ARG3, sizeof(struct vki_scsi_idlun));
7493 break;
7494 case VKI_SCSI_IOCTL_GET_BUS_NUMBER: /* 0x5386 */
7495 POST_MEM_WRITE(ARG3, sizeof(int));
7496 break;
7497
njn096ccdd2009-02-22 23:00:30 +00007498 /* CD ROM stuff (??) */
7499 case VKI_CDROMSUBCHNL:
7500 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
7501 break;
7502 case VKI_CDROMREADTOCHDR:
7503 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
7504 break;
7505 case VKI_CDROMREADTOCENTRY:
7506 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
7507 break;
7508 case VKI_CDROMMULTISESSION:
7509 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
7510 break;
7511 case VKI_CDROMVOLREAD:
7512 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
7513 break;
7514 case VKI_CDROMREADRAW:
7515 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
7516 break;
7517 case VKI_CDROMREADAUDIO:
7518 {
7519 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
7520 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
7521 break;
7522 }
7523
7524 case VKI_CDROMPLAYMSF:
7525 break;
7526 /* The following two are probably bogus (should check args
7527 for readability). JRS 20021117 */
7528 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
7529 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
7530 break;
tom3fc99292012-07-11 12:02:06 +00007531 case VKI_CDROM_GET_CAPABILITY: /* 0x5331 */
7532 break;
njn096ccdd2009-02-22 23:00:30 +00007533
7534 case VKI_FIGETBSZ:
7535 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
7536 break;
7537 case VKI_FIBMAP:
tomc1cc9632010-08-25 09:13:44 +00007538 POST_MEM_WRITE(ARG3, sizeof(int));
njn096ccdd2009-02-22 23:00:30 +00007539 break;
7540
7541 case VKI_FBIOGET_VSCREENINFO: //0x4600
7542 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
7543 break;
7544 case VKI_FBIOGET_FSCREENINFO: //0x4602
7545 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
7546 break;
7547
7548 case VKI_PPCLAIM:
7549 case VKI_PPEXCL:
7550 case VKI_PPYIELD:
7551 case VKI_PPRELEASE:
7552 case VKI_PPSETMODE:
7553 case VKI_PPSETPHASE:
7554 case VKI_PPSETFLAGS:
7555 case VKI_PPWDATA:
7556 case VKI_PPWCONTROL:
7557 case VKI_PPFCONTROL:
7558 case VKI_PPDATADIR:
7559 case VKI_PPNEGOT:
7560 case VKI_PPWCTLONIRQ:
7561 case VKI_PPSETTIME:
7562 break;
7563 case VKI_PPGETMODE:
7564 POST_MEM_WRITE( ARG3, sizeof(int) );
7565 break;
7566 case VKI_PPGETPHASE:
7567 POST_MEM_WRITE( ARG3, sizeof(int) );
7568 break;
7569 case VKI_PPGETMODES:
7570 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
7571 break;
7572 case VKI_PPGETFLAGS:
7573 POST_MEM_WRITE( ARG3, sizeof(int) );
7574 break;
7575 case VKI_PPRSTATUS:
7576 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
7577 break;
7578 case VKI_PPRDATA:
7579 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
7580 break;
7581 case VKI_PPRCONTROL:
7582 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
7583 break;
7584 case VKI_PPCLRIRQ:
7585 POST_MEM_WRITE( ARG3, sizeof(int) );
7586 break;
7587 case VKI_PPGETTIME:
7588 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
7589 break;
7590
7591 case VKI_GIO_FONT:
7592 POST_MEM_WRITE( ARG3, 32 * 256 );
7593 break;
7594 case VKI_PIO_FONT:
7595 break;
7596
7597 case VKI_GIO_FONTX:
7598 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
7599 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
7600 break;
7601 case VKI_PIO_FONTX:
7602 break;
7603
7604 case VKI_PIO_FONTRESET:
7605 break;
7606
7607 case VKI_GIO_CMAP:
7608 POST_MEM_WRITE( ARG3, 16 * 3 );
7609 break;
7610 case VKI_PIO_CMAP:
7611 break;
7612
7613 case VKI_KIOCSOUND:
7614 case VKI_KDMKTONE:
7615 break;
7616
7617 case VKI_KDGETLED:
7618 POST_MEM_WRITE( ARG3, sizeof(char) );
7619 break;
7620 case VKI_KDSETLED:
7621 break;
7622
7623 case VKI_KDGKBTYPE:
7624 POST_MEM_WRITE( ARG3, sizeof(char) );
7625 break;
7626
7627 case VKI_KDADDIO:
7628 case VKI_KDDELIO:
7629 case VKI_KDENABIO:
7630 case VKI_KDDISABIO:
7631 break;
7632
7633 case VKI_KDSETMODE:
7634 break;
7635 case VKI_KDGETMODE:
7636 POST_MEM_WRITE( ARG3, sizeof(int) );
7637 break;
7638
7639 case VKI_KDMAPDISP:
7640 case VKI_KDUNMAPDISP:
7641 break;
7642
7643 case VKI_GIO_SCRNMAP:
7644 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
7645 break;
7646 case VKI_PIO_SCRNMAP:
7647 break;
7648 case VKI_GIO_UNISCRNMAP:
7649 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
7650 break;
7651 case VKI_PIO_UNISCRNMAP:
7652 break;
7653
7654 case VKI_GIO_UNIMAP:
7655 if ( ARG3 ) {
7656 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
7657 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
7658 POST_MEM_WRITE( (Addr)desc->entries,
7659 desc->entry_ct * sizeof(struct vki_unipair) );
7660 }
7661 break;
7662 case VKI_PIO_UNIMAP:
7663 break;
7664 case VKI_PIO_UNIMAPCLR:
7665 break;
7666
7667 case VKI_KDGKBMODE:
7668 POST_MEM_WRITE( ARG3, sizeof(int) );
7669 break;
7670 case VKI_KDSKBMODE:
7671 break;
7672
7673 case VKI_KDGKBMETA:
7674 POST_MEM_WRITE( ARG3, sizeof(int) );
7675 break;
7676 case VKI_KDSKBMETA:
7677 break;
7678
7679 case VKI_KDGKBLED:
7680 POST_MEM_WRITE( ARG3, sizeof(char) );
7681 break;
7682 case VKI_KDSKBLED:
7683 break;
7684
7685 case VKI_KDGKBENT:
7686 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
7687 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
7688 break;
7689 case VKI_KDSKBENT:
7690 break;
7691
7692 case VKI_KDGKBSENT:
7693 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
7694 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
7695 break;
7696 case VKI_KDSKBSENT:
7697 break;
7698
7699 case VKI_KDGKBDIACR:
7700 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
7701 break;
7702 case VKI_KDSKBDIACR:
7703 break;
7704
7705 case VKI_KDGETKEYCODE:
7706 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
7707 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
7708 break;
7709 case VKI_KDSETKEYCODE:
7710 break;
7711
7712 case VKI_KDSIGACCEPT:
7713 break;
7714
7715 case VKI_KDKBDREP:
7716 break;
7717
7718 case VKI_KDFONTOP:
7719 if ( ARG3 ) {
7720 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
7721 switch ( op->op ) {
7722 case VKI_KD_FONT_OP_SET:
7723 break;
7724 case VKI_KD_FONT_OP_GET:
7725 if ( op->data )
7726 POST_MEM_WRITE( (Addr) op->data,
7727 (op->width + 7) / 8 * 32 * op->charcount );
7728 break;
7729 case VKI_KD_FONT_OP_SET_DEFAULT:
7730 break;
7731 case VKI_KD_FONT_OP_COPY:
7732 break;
7733 }
7734 POST_MEM_WRITE( (Addr) op, sizeof(*op));
7735 }
7736 break;
7737
7738 case VKI_VT_OPENQRY:
7739 POST_MEM_WRITE( ARG3, sizeof(int) );
7740 break;
7741 case VKI_VT_GETMODE:
7742 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
7743 break;
7744 case VKI_VT_SETMODE:
7745 break;
7746 case VKI_VT_GETSTATE:
7747 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
7748 sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
7749 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
7750 sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
7751 break;
7752 case VKI_VT_RELDISP:
7753 case VKI_VT_ACTIVATE:
7754 case VKI_VT_WAITACTIVE:
7755 case VKI_VT_DISALLOCATE:
7756 break;
7757 case VKI_VT_RESIZE:
7758 break;
7759 case VKI_VT_RESIZEX:
7760 break;
7761 case VKI_VT_LOCKSWITCH:
7762 case VKI_VT_UNLOCKSWITCH:
7763 break;
7764
7765 case VKI_USBDEVFS_CONTROL:
7766 if ( ARG3 ) {
7767 struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
7768 if (vkuc->bRequestType & 0x80)
7769 POST_MEM_WRITE((Addr)vkuc->data, RES);
njn096ccdd2009-02-22 23:00:30 +00007770 }
tom8bb4d8f2011-07-06 14:11:56 +00007771 break;
njn096ccdd2009-02-22 23:00:30 +00007772 case VKI_USBDEVFS_BULK:
7773 if ( ARG3 ) {
7774 struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
7775 if (vkub->ep & 0x80)
7776 POST_MEM_WRITE((Addr)vkub->data, RES);
njn096ccdd2009-02-22 23:00:30 +00007777 }
tom8bb4d8f2011-07-06 14:11:56 +00007778 break;
njn096ccdd2009-02-22 23:00:30 +00007779 case VKI_USBDEVFS_GETDRIVER:
7780 if ( ARG3 ) {
7781 struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
7782 POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
njn096ccdd2009-02-22 23:00:30 +00007783 }
tom8bb4d8f2011-07-06 14:11:56 +00007784 break;
njn096ccdd2009-02-22 23:00:30 +00007785 case VKI_USBDEVFS_REAPURB:
7786 case VKI_USBDEVFS_REAPURBNDELAY:
7787 if ( ARG3 ) {
7788 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
njn6e10c6c2009-06-09 23:03:02 +00007789 POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
njn096ccdd2009-02-22 23:00:30 +00007790 if (!*vkuu)
7791 break;
7792 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
njn6e10c6c2009-06-09 23:03:02 +00007793 if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
7794 struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
7795 if (vkusp->bRequestType & 0x80)
7796 POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
7797 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
7798 } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
7799 char *bp = (*vkuu)->buffer;
7800 int i;
7801 for(i=0; i<(*vkuu)->number_of_packets; i++) {
7802 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
7803 POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
7804 if ((*vkuu)->endpoint & 0x80)
7805 POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
7806 bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
7807 }
7808 POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
7809 } else {
7810 if ((*vkuu)->endpoint & 0x80)
7811 POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
7812 POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
7813 }
njn096ccdd2009-02-22 23:00:30 +00007814 }
tom8bb4d8f2011-07-06 14:11:56 +00007815 break;
njn096ccdd2009-02-22 23:00:30 +00007816 case VKI_USBDEVFS_CONNECTINFO:
7817 POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
7818 break;
7819 case VKI_USBDEVFS_IOCTL:
7820 if ( ARG3 ) {
7821 struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
7822 UInt dir2, size2;
7823 dir2 = _VKI_IOC_DIR(vkui->ioctl_code);
7824 size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
7825 if (size2 > 0) {
7826 if (dir2 & _VKI_IOC_READ)
7827 POST_MEM_WRITE((Addr)vkui->data, size2);
7828 }
7829 }
7830 break;
7831
7832 /* I2C (/dev/i2c-*) ioctls */
7833 case VKI_I2C_SLAVE:
7834 case VKI_I2C_SLAVE_FORCE:
7835 case VKI_I2C_TENBIT:
7836 case VKI_I2C_PEC:
7837 break;
7838 case VKI_I2C_FUNCS:
7839 POST_MEM_WRITE( ARG3, sizeof(unsigned long) );
7840 break;
tomd543d742012-03-07 10:21:33 +00007841 case VKI_I2C_RDWR:
7842 if ( ARG3 ) {
7843 struct vki_i2c_rdwr_ioctl_data *vkui = (struct vki_i2c_rdwr_ioctl_data *)ARG3;
7844 UInt i;
7845 for (i=0; i < vkui->nmsgs; i++) {
7846 struct vki_i2c_msg *msg = vkui->msgs + i;
7847 if (msg->flags & VKI_I2C_M_RD)
7848 POST_MEM_WRITE((Addr)msg->buf, msg->len);
7849 }
7850 }
7851 break;
njn096ccdd2009-02-22 23:00:30 +00007852
7853 /* Wireless extensions ioctls */
7854 case VKI_SIOCSIWCOMMIT:
7855 case VKI_SIOCSIWNWID:
7856 case VKI_SIOCSIWFREQ:
7857 case VKI_SIOCSIWMODE:
7858 case VKI_SIOCSIWSENS:
7859 case VKI_SIOCSIWRANGE:
7860 case VKI_SIOCSIWPRIV:
7861 case VKI_SIOCSIWSTATS:
7862 case VKI_SIOCSIWSPY:
7863 case VKI_SIOCSIWTHRSPY:
7864 case VKI_SIOCSIWAP:
7865 case VKI_SIOCSIWSCAN:
7866 case VKI_SIOCSIWESSID:
7867 case VKI_SIOCSIWRATE:
7868 case VKI_SIOCSIWNICKN:
7869 case VKI_SIOCSIWRTS:
7870 case VKI_SIOCSIWFRAG:
7871 case VKI_SIOCSIWTXPOW:
7872 case VKI_SIOCSIWRETRY:
7873 case VKI_SIOCSIWENCODE:
7874 case VKI_SIOCSIWPOWER:
7875 case VKI_SIOCSIWGENIE:
7876 case VKI_SIOCSIWMLME:
7877 case VKI_SIOCSIWAUTH:
7878 case VKI_SIOCSIWENCODEEXT:
7879 case VKI_SIOCSIWPMKSA:
7880 break;
7881 case VKI_SIOCGIWNAME:
7882 if (ARG3) {
7883 POST_MEM_WRITE((Addr)((struct vki_iwreq *)ARG3)->u.name,
7884 sizeof(((struct vki_iwreq *)ARG3)->u.name));
7885 }
7886 break;
7887 case VKI_SIOCGIWNWID:
7888 case VKI_SIOCGIWSENS:
7889 case VKI_SIOCGIWRATE:
7890 case VKI_SIOCGIWRTS:
7891 case VKI_SIOCGIWFRAG:
7892 case VKI_SIOCGIWTXPOW:
7893 case VKI_SIOCGIWRETRY:
7894 case VKI_SIOCGIWPOWER:
7895 case VKI_SIOCGIWAUTH:
7896 if (ARG3) {
7897 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.param,
7898 sizeof(struct vki_iw_param));
7899 }
7900 break;
7901 case VKI_SIOCGIWFREQ:
7902 if (ARG3) {
7903 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.freq,
7904 sizeof(struct vki_iw_freq));
7905 }
7906 break;
7907 case VKI_SIOCGIWMODE:
7908 if (ARG3) {
7909 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.mode,
7910 sizeof(__vki_u32));
7911 }
7912 break;
7913 case VKI_SIOCGIWRANGE:
7914 case VKI_SIOCGIWPRIV:
7915 case VKI_SIOCGIWSTATS:
7916 case VKI_SIOCGIWSPY:
7917 case VKI_SIOCGIWTHRSPY:
7918 case VKI_SIOCGIWAPLIST:
7919 case VKI_SIOCGIWSCAN:
7920 case VKI_SIOCGIWESSID:
7921 case VKI_SIOCGIWNICKN:
7922 case VKI_SIOCGIWENCODE:
7923 case VKI_SIOCGIWGENIE:
7924 case VKI_SIOCGIWENCODEEXT:
7925 if (ARG3) {
7926 struct vki_iw_point* point;
7927 point = &((struct vki_iwreq *)ARG3)->u.data;
7928 POST_MEM_WRITE((Addr)point->pointer, point->length);
7929 }
7930 break;
7931 case VKI_SIOCGIWAP:
7932 if (ARG3) {
7933 POST_MEM_WRITE((Addr)&((struct vki_iwreq *)ARG3)->u.ap_addr,
7934 sizeof(struct vki_sockaddr));
7935 }
7936 break;
7937
dejanj9c6b05d2013-12-27 09:06:55 +00007938# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
7939 || defined(VGPV_mips32_linux_android)
sewardja3e7a482011-09-27 10:26:52 +00007940 /* ashmem */
7941 case VKI_ASHMEM_GET_SIZE:
7942 case VKI_ASHMEM_SET_SIZE:
7943 case VKI_ASHMEM_GET_PROT_MASK:
7944 case VKI_ASHMEM_SET_PROT_MASK:
7945 case VKI_ASHMEM_GET_PIN_STATUS:
7946 case VKI_ASHMEM_PURGE_ALL_CACHES:
7947 case VKI_ASHMEM_SET_NAME:
7948 case VKI_ASHMEM_PIN:
7949 case VKI_ASHMEM_UNPIN:
7950 break;
7951 case VKI_ASHMEM_GET_NAME:
7952 POST_MEM_WRITE( ARG3, VKI_ASHMEM_NAME_LEN );
7953 break;
7954
7955 /* binder */
7956 case VKI_BINDER_WRITE_READ:
7957 if (ARG3) {
7958 struct vki_binder_write_read* bwr
7959 = (struct vki_binder_write_read*)ARG3;
7960 POST_FIELD_WRITE(bwr->write_consumed);
7961 POST_FIELD_WRITE(bwr->read_consumed);
7962
7963 if (bwr->read_size)
7964 POST_MEM_WRITE((Addr)bwr->read_buffer, bwr->read_consumed);
7965 }
7966 break;
7967
7968 case VKI_BINDER_SET_IDLE_TIMEOUT:
7969 case VKI_BINDER_SET_MAX_THREADS:
7970 case VKI_BINDER_SET_IDLE_PRIORITY:
7971 case VKI_BINDER_SET_CONTEXT_MGR:
7972 case VKI_BINDER_THREAD_EXIT:
7973 break;
7974 case VKI_BINDER_VERSION:
7975 if (ARG3) {
7976 struct vki_binder_version* bv = (struct vki_binder_version*)ARG3;
7977 POST_FIELD_WRITE(bv->protocol_version);
7978 }
7979 break;
philippe5d5dd8e2012-08-05 00:08:25 +00007980# endif /* defined(VGPV_*_linux_android) */
sewardja3e7a482011-09-27 10:26:52 +00007981
tom8236fe62012-03-07 11:22:42 +00007982 case VKI_HCIINQUIRY:
7983 if (ARG3) {
7984 struct vki_hci_inquiry_req* ir = (struct vki_hci_inquiry_req*)ARG3;
7985 POST_MEM_WRITE((Addr)ARG3 + sizeof(struct vki_hci_inquiry_req),
7986 ir->num_rsp * sizeof(struct vki_inquiry_info));
7987 }
7988 break;
7989
cborntra65bdbe42012-05-23 15:59:40 +00007990 /* KVM ioctls that only write the system call return value */
7991 case VKI_KVM_GET_API_VERSION:
7992 case VKI_KVM_CREATE_VM:
7993 case VKI_KVM_CHECK_EXTENSION:
7994 case VKI_KVM_GET_VCPU_MMAP_SIZE:
7995 case VKI_KVM_S390_ENABLE_SIE:
7996 case VKI_KVM_CREATE_VCPU:
cborntra4ea8f142014-02-11 15:15:31 +00007997 case VKI_KVM_CREATE_IRQCHIP:
cborntra65bdbe42012-05-23 15:59:40 +00007998 case VKI_KVM_RUN:
7999 case VKI_KVM_S390_INITIAL_RESET:
8000 break;
8001
bart0ab84fe2012-09-09 18:30:17 +00008002#ifdef ENABLE_XEN
8003 case VKI_XEN_IOCTL_PRIVCMD_HYPERCALL: {
8004 SyscallArgs harrghs;
8005 struct vki_xen_privcmd_hypercall *args =
8006 (struct vki_xen_privcmd_hypercall *)(ARG3);
8007
8008 if (!args)
8009 break;
8010
8011 VG_(memset)(&harrghs, 0, sizeof(harrghs));
8012 harrghs.sysno = args->op;
8013 harrghs.arg1 = args->arg[0];
8014 harrghs.arg2 = args->arg[1];
8015 harrghs.arg3 = args->arg[2];
8016 harrghs.arg4 = args->arg[3];
8017 harrghs.arg5 = args->arg[4];
8018 harrghs.arg6 = harrghs.arg7 = harrghs.arg8 = 0;
8019
8020 WRAPPER_POST_NAME(xen, hypercall) (tid, &harrghs, status);
8021 break;
8022 };
8023
8024 case VKI_XEN_IOCTL_PRIVCMD_MMAP:
8025 break;
8026 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH: {
8027 struct vki_xen_privcmd_mmapbatch *args =
8028 (struct vki_xen_privcmd_mmapbatch *)(ARG3);
8029 POST_MEM_WRITE((Addr)args->arr, sizeof(*(args->arr)) * args->num);
8030 }
8031 break;
8032 case VKI_XEN_IOCTL_PRIVCMD_MMAPBATCH_V2: {
8033 struct vki_xen_privcmd_mmapbatch_v2 *args =
8034 (struct vki_xen_privcmd_mmapbatch_v2 *)(ARG3);
8035 POST_MEM_WRITE((Addr)args->err, sizeof(*(args->err)) * args->num);
8036 }
8037 break;
8038#endif
8039
njn1be9cf62009-05-22 00:15:06 +00008040 default:
tom0ee313e2010-05-07 15:32:04 +00008041 /* EVIOC* are variable length and return size written on success */
8042 switch (ARG2 & ~(_VKI_IOC_SIZEMASK << _VKI_IOC_SIZESHIFT)) {
8043 case VKI_EVIOCGNAME(0):
8044 case VKI_EVIOCGPHYS(0):
8045 case VKI_EVIOCGUNIQ(0):
8046 case VKI_EVIOCGKEY(0):
8047 case VKI_EVIOCGLED(0):
8048 case VKI_EVIOCGSND(0):
8049 case VKI_EVIOCGSW(0):
8050 case VKI_EVIOCGBIT(VKI_EV_SYN,0):
8051 case VKI_EVIOCGBIT(VKI_EV_KEY,0):
8052 case VKI_EVIOCGBIT(VKI_EV_REL,0):
8053 case VKI_EVIOCGBIT(VKI_EV_ABS,0):
8054 case VKI_EVIOCGBIT(VKI_EV_MSC,0):
8055 case VKI_EVIOCGBIT(VKI_EV_SW,0):
8056 case VKI_EVIOCGBIT(VKI_EV_LED,0):
8057 case VKI_EVIOCGBIT(VKI_EV_SND,0):
8058 case VKI_EVIOCGBIT(VKI_EV_REP,0):
8059 case VKI_EVIOCGBIT(VKI_EV_FF,0):
8060 case VKI_EVIOCGBIT(VKI_EV_PWR,0):
8061 case VKI_EVIOCGBIT(VKI_EV_FF_STATUS,0):
8062 if (RES > 0)
8063 POST_MEM_WRITE(ARG3, RES);
8064 break;
8065 default:
8066 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
8067 break;
8068 }
njn096ccdd2009-02-22 23:00:30 +00008069 break;
8070 }
njn096ccdd2009-02-22 23:00:30 +00008071}
8072
8073/* ---------------------------------------------------------------------
njnf37a81b2009-02-17 00:23:30 +00008074 socketcall wrapper helpers
8075 ------------------------------------------------------------------ */
8076
8077void
8078ML_(linux_PRE_sys_getsockopt) ( ThreadId tid,
8079 UWord arg0, UWord arg1, UWord arg2,
8080 UWord arg3, UWord arg4 )
8081{
8082 /* int getsockopt(int s, int level, int optname,
8083 void *optval, socklen_t *optlen); */
8084 Addr optval_p = arg3;
8085 Addr optlen_p = arg4;
8086 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
8087 if (optval_p != (Addr)NULL) {
8088 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
8089 "socketcall.getsockopt(optval)",
8090 "socketcall.getsockopt(optlen)" );
8091 if (arg1 == VKI_SOL_SCTP &&
8092 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
8093 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
8094 {
8095 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
8096 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
8097 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)",
8098 (Addr)ga->addrs, address_bytes );
8099 }
8100 }
8101}
8102
8103void
8104ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
8105 SysRes res,
8106 UWord arg0, UWord arg1, UWord arg2,
8107 UWord arg3, UWord arg4 )
8108{
8109 Addr optval_p = arg3;
8110 Addr optlen_p = arg4;
njncda2f0f2009-05-18 02:12:08 +00008111 vg_assert(!sr_isError(res)); /* guaranteed by caller */
njnf37a81b2009-02-17 00:23:30 +00008112 if (optval_p != (Addr)NULL) {
8113 ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
8114 "socketcall.getsockopt(optlen_out)" );
8115 if (arg1 == VKI_SOL_SCTP &&
8116 (arg2 == VKI_SCTP_GET_PEER_ADDRS ||
8117 arg2 == VKI_SCTP_GET_LOCAL_ADDRS))
8118 {
8119 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
8120 struct vki_sockaddr *a = ga->addrs;
8121 int i;
8122 for (i = 0; i < ga->addr_num; i++) {
8123 int sl = 0;
8124 if (a->sa_family == VKI_AF_INET)
8125 sl = sizeof(struct vki_sockaddr_in);
8126 else if (a->sa_family == VKI_AF_INET6)
8127 sl = sizeof(struct vki_sockaddr_in6);
8128 else {
sewardj738856f2009-07-15 14:48:32 +00008129 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled "
8130 "address type %d\n", a->sa_family);
njnf37a81b2009-02-17 00:23:30 +00008131 }
8132 a = (struct vki_sockaddr*)((char*)a + sl);
8133 }
8134 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
8135 }
8136 }
8137}
8138
tom70f71aa2013-07-17 14:36:57 +00008139void
8140ML_(linux_PRE_sys_setsockopt) ( ThreadId tid,
8141 UWord arg0, UWord arg1, UWord arg2,
8142 UWord arg3, UWord arg4 )
8143{
8144 /* int setsockopt(int s, int level, int optname,
8145 const void *optval, socklen_t optlen); */
8146 Addr optval_p = arg3;
8147 if (optval_p != (Addr)NULL) {
8148 /*
8149 * OK, let's handle at least some setsockopt levels and options
8150 * ourselves, so we don't get false claims of references to
8151 * uninitialized memory (such as padding in structures) and *do*
8152 * check what pointers in the argument point to.
8153 */
8154 if (arg1 == VKI_SOL_SOCKET && arg2 == VKI_SO_ATTACH_FILTER)
8155 {
8156 struct vki_sock_fprog *fp = (struct vki_sock_fprog *)optval_p;
8157
8158 /*
8159 * struct sock_fprog has a 16-bit count of instructions,
8160 * followed by a pointer to an array of those instructions.
8161 * There's padding between those two elements.
8162 *
8163 * So that we don't bogusly complain about the padding bytes,
8164 * we just report that we read len and and filter.
8165 *
8166 * We then make sure that what filter points to is valid.
8167 */
8168 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.len)",
8169 (Addr)&fp->len, sizeof(fp->len) );
8170 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, &optval.filter)",
8171 (Addr)&fp->filter, sizeof(fp->filter) );
8172
8173 /* len * sizeof (*filter) */
8174 if (fp->filter != NULL)
8175 {
8176 PRE_MEM_READ( "setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, optval.filter)",
8177 (Addr)(fp->filter),
8178 fp->len * sizeof(*fp->filter) );
8179 }
8180 }
8181 else
8182 {
8183 PRE_MEM_READ( "socketcall.setsockopt(optval)",
8184 arg3, /* optval */
8185 arg4 /* optlen */ );
8186 }
8187 }
8188}
8189
cborntrae48a4442012-11-08 20:10:10 +00008190/* ---------------------------------------------------------------------
8191 ptrace wrapper helpers
8192 ------------------------------------------------------------------ */
8193
8194void
8195ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
8196{
8197 struct vki_iovec *iov = (struct vki_iovec *) arg4;
8198
8199 PRE_MEM_READ("ptrace(getregset iovec->iov_base)",
8200 (unsigned long) &iov->iov_base, sizeof(iov->iov_base));
8201 PRE_MEM_READ("ptrace(getregset iovec->iov_len)",
8202 (unsigned long) &iov->iov_len, sizeof(iov->iov_len));
8203 PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
8204 (unsigned long) iov->iov_base, iov->iov_len);
8205}
8206
8207void
8208ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
8209{
8210 struct vki_iovec *iov = (struct vki_iovec *) arg4;
8211
8212 PRE_MEM_READ("ptrace(setregset iovec->iov_base)",
8213 (unsigned long) &iov->iov_base, sizeof(iov->iov_base));
8214 PRE_MEM_READ("ptrace(setregset iovec->iov_len)",
8215 (unsigned long) &iov->iov_len, sizeof(iov->iov_len));
8216 PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
8217 (unsigned long) iov->iov_base, iov->iov_len);
8218}
8219
8220void
8221ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
8222{
8223 struct vki_iovec *iov = (struct vki_iovec *) arg4;
8224
8225 /* XXX: The actual amount of data written by the kernel might be
8226 less than iov_len, depending on the regset (arg3). */
8227 POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
8228}
8229
sewardje6d5e722005-06-10 10:27:55 +00008230#undef PRE
8231#undef POST
nethercotefd453532004-11-17 17:21:12 +00008232
njn8b68b642009-06-24 00:37:09 +00008233#endif // defined(VGO_linux)
8234
nethercotefd453532004-11-17 17:21:12 +00008235/*--------------------------------------------------------------------*/
8236/*--- end ---*/
8237/*--------------------------------------------------------------------*/