blob: aa87149e492d0dab5aea8d569b1923aa9b6a71df [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00003/*--- Wrappers for generic Unix system calls syswrap-generic.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
njn53612422005-03-12 16:22:54 +000010 Copyright (C) 2000-2005 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +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
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
32#include "pub_core_threadstate.h"
njn899ce732005-06-21 00:28:11 +000033#include "pub_core_debuginfo.h" // Needed for pub_core_aspacemgr :(
sewardj55f9d1a2005-04-25 11:11:44 +000034#include "pub_core_aspacemgr.h"
njn899ce732005-06-21 00:28:11 +000035#include "pub_core_debuglog.h"
njn97405b22005-06-02 03:39:33 +000036#include "pub_core_libcbase.h"
sewardja8d8e232005-06-07 20:04:56 +000037#include "pub_core_libcassert.h"
njnde62cbf2005-06-10 22:08:14 +000038#include "pub_core_libcfile.h"
njnf4c50162005-06-20 14:18:12 +000039#include "pub_core_libcmman.h" // For VG_(mmap), VG_(munmap)()
njnde62cbf2005-06-10 22:08:14 +000040#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000041#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000042#include "pub_core_libcsignal.h"
njn04e16982005-05-31 00:23:43 +000043#include "pub_core_main.h"
njnaf1d7df2005-06-11 01:31:52 +000044#include "pub_core_mallocfree.h"
sewardja8d8e232005-06-07 20:04:56 +000045#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +000046#include "pub_core_scheduler.h"
sewardja8d8e232005-06-07 20:04:56 +000047#include "pub_core_signals.h"
njn419bbcb2005-06-21 03:52:49 +000048#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +000049#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +000050#include "pub_core_syswrap.h"
njn419bbcb2005-06-21 03:52:49 +000051#include "pub_core_tooliface.h"
sewardj55f9d1a2005-04-25 11:11:44 +000052
sewardja8d8e232005-06-07 20:04:56 +000053#include "priv_types_n_macros.h"
njnc1b01812005-06-17 22:19:06 +000054#include "priv_syswrap-generic.h"
sewardjde4a1d02002-03-22 01:27:54 +000055
sewardja8d8e232005-06-07 20:04:56 +000056#include "vki_unistd.h" /* for the __NR_* constants */
sewardjde4a1d02002-03-22 01:27:54 +000057
jsgf855d93d2003-10-13 22:26:55 +000058
fitzhardinge1a303042003-12-22 08:48:50 +000059/* return true if address range entirely contained within client
60 address space */
sewardj7eb7c582005-06-23 01:02:53 +000061Bool ML_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
nethercote8ff888f2004-11-17 17:11:45 +000062 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +000063{
64 Addr end = start+size;
65 Addr cl_base = VG_(client_base);
66 Bool ret;
67
68 if (size == 0)
69 return True;
70
sewardj16063e62005-03-15 23:29:13 +000071 if (0 && cl_base < 0x10000)
fitzhardinge1a303042003-12-22 08:48:50 +000072 cl_base = 0x10000;
73
74 ret =
75 (end >= start) &&
76 start >= cl_base && start < VG_(client_end) &&
77 (end <= VG_(client_end));
78
79 if (0)
80 VG_(printf)("%s: test=%p-%p client=%p-%p ret=%d\n",
nethercote1543adf2004-10-25 15:43:21 +000081 syscallname, start, end, cl_base, VG_(client_end), ret);
fitzhardinge1a303042003-12-22 08:48:50 +000082
nethercote1543adf2004-10-25 15:43:21 +000083 if (!ret && syscallname != NULL) {
sewardja8d8e232005-06-07 20:04:56 +000084 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
85 "to modify addresses %p-%p",
86 syscallname, start, end);
fitzhardinge1a303042003-12-22 08:48:50 +000087
88 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +000089 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge1a303042003-12-22 08:48:50 +000090 }
91 }
92
93 return ret;
94}
95
sewardj7eb7c582005-06-23 01:02:53 +000096Bool ML_(client_signal_OK)(Int sigNo)
njn419bbcb2005-06-21 03:52:49 +000097{
98 /* signal 0 is OK for kill */
njn351d0062005-06-21 22:23:59 +000099 Bool ret = sigNo >= 0 && sigNo <= VG_SIGVGRTUSERMAX;
njn419bbcb2005-06-21 03:52:49 +0000100
101 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
102
103 return ret;
104}
105
njn25e49d8e72002-09-23 09:36:25 +0000106/* ---------------------------------------------------------------------
nethercote27ea8bc2004-07-10 17:21:14 +0000107 Doing mmap, mremap
njn25e49d8e72002-09-23 09:36:25 +0000108 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000109
njn25e49d8e72002-09-23 09:36:25 +0000110// Nb: this isn't done as precisely as possible, but it seems that programs
111// are usually sufficiently well-behaved that the more obscure corner cases
112// aren't important. Various comments in the few functions below give more
113// details... njn 2002-Sep-17
114
115/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
116 munmap, mprotect (and mremap??) work at the page level. So addresses
117 and lengths must be adjusted for this. */
118
119/* Mash around start and length so that the area exactly covers
120 an integral number of pages. If we don't do that, memcheck's
121 idea of addressible memory diverges from that of the
122 kernel's, which causes the leak detector to crash. */
123static
nethercote928a5f72004-11-03 18:10:37 +0000124void mash_addr_and_len( Addr* a, SizeT* len)
sewardjde4a1d02002-03-22 01:27:54 +0000125{
fitzhardinge98abfc72003-12-16 02:05:15 +0000126 Addr ra;
127
njn13bfd852005-06-02 03:52:53 +0000128 ra = VG_PGROUNDDN(*a);
129 *len = VG_PGROUNDUP(*a + *len) - ra;
fitzhardinge98abfc72003-12-16 02:05:15 +0000130 *a = ra;
sewardjde4a1d02002-03-22 01:27:54 +0000131}
132
sewardj7eb7c582005-06-23 01:02:53 +0000133void ML_(mmap_segment) ( Addr a, SizeT len, UInt prot,
sewardja8d8e232005-06-07 20:04:56 +0000134 UInt mm_flags, Int fd, ULong offset )
sewardjde4a1d02002-03-22 01:27:54 +0000135{
sewardj40f8ebe2002-10-23 21:46:13 +0000136 Bool rr, ww, xx;
fitzhardinge98abfc72003-12-16 02:05:15 +0000137 UInt flags;
njn25e49d8e72002-09-23 09:36:25 +0000138
fitzhardinge98abfc72003-12-16 02:05:15 +0000139 flags = SF_MMAP;
140
fitzhardinge98abfc72003-12-16 02:05:15 +0000141 if (!(mm_flags & VKI_MAP_PRIVATE))
142 flags |= SF_SHARED;
143
144 if (fd != -1)
145 flags |= SF_FILE;
146
147 VG_(map_fd_segment)(a, len, prot, flags, fd, offset, NULL);
njn25e49d8e72002-09-23 09:36:25 +0000148
fitzhardinge1a303042003-12-22 08:48:50 +0000149 rr = prot & VKI_PROT_READ;
150 ww = prot & VKI_PROT_WRITE;
151 xx = prot & VKI_PROT_EXEC;
njn25e49d8e72002-09-23 09:36:25 +0000152
sewardj40f8ebe2002-10-23 21:46:13 +0000153 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
sewardjde4a1d02002-03-22 01:27:54 +0000154}
155
njn25e49d8e72002-09-23 09:36:25 +0000156static
sewardja8d8e232005-06-07 20:04:56 +0000157SysRes mremap_segment ( Addr old_addr, SizeT old_size,
158 Addr new_addr, SizeT new_size,
159 UInt flags, ThreadId tid)
njn25e49d8e72002-09-23 09:36:25 +0000160{
sewardja8d8e232005-06-07 20:04:56 +0000161 SysRes ret;
fitzhardinge1a303042003-12-22 08:48:50 +0000162 Segment *seg, *next;
njn25e49d8e72002-09-23 09:36:25 +0000163
njn13bfd852005-06-02 03:52:53 +0000164 old_size = VG_PGROUNDUP(old_size);
165 new_size = VG_PGROUNDUP(new_size);
njn25e49d8e72002-09-23 09:36:25 +0000166
njn13bfd852005-06-02 03:52:53 +0000167 if (VG_PGROUNDDN(old_addr) != old_addr)
sewardja8d8e232005-06-07 20:04:56 +0000168 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000169
sewardj7eb7c582005-06-23 01:02:53 +0000170 if (!ML_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
sewardja8d8e232005-06-07 20:04:56 +0000171 return VG_(mk_SysRes_Error)( VKI_EFAULT );
fitzhardinge1a303042003-12-22 08:48:50 +0000172
173 /* fixed at the current address means we don't move it */
174 if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
175 flags &= ~(VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE);
176
177 if (flags & VKI_MREMAP_FIXED) {
njn13bfd852005-06-02 03:52:53 +0000178 if (VG_PGROUNDDN(new_addr) != new_addr)
sewardja8d8e232005-06-07 20:04:56 +0000179 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000180
sewardj7eb7c582005-06-23 01:02:53 +0000181 if (!ML_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
sewardja8d8e232005-06-07 20:04:56 +0000182 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000183
184 /* check for overlaps */
185 if ((old_addr < (new_addr+new_size) &&
186 (old_addr+old_size) > new_addr) ||
187 (new_addr < (old_addr+new_size) &&
188 (new_addr+new_size) > old_addr))
sewardja8d8e232005-06-07 20:04:56 +0000189 return VG_(mk_SysRes_Error)( VKI_EINVAL );
njn25e49d8e72002-09-23 09:36:25 +0000190 }
fitzhardinge1a303042003-12-22 08:48:50 +0000191
192 /* Do nothing */
193 if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
sewardja8d8e232005-06-07 20:04:56 +0000194 return VG_(mk_SysRes_Success)( old_addr );
fitzhardinge1a303042003-12-22 08:48:50 +0000195
196 seg = VG_(find_segment)(old_addr);
197
198 /* range must be contained within segment */
199 if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
sewardja8d8e232005-06-07 20:04:56 +0000200 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000201
sewardj1024cf72005-02-28 14:39:21 +0000202 next = VG_(find_segment_above_mapped)(old_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000203
204 if (0)
205 VG_(printf)("mremap: old_addr+new_size=%p next->addr=%p flags=%d\n",
206 old_addr+new_size, next->addr, flags);
207
208 if ((flags & VKI_MREMAP_FIXED) ||
209 (next != NULL && (old_addr+new_size) > next->addr)) {
210 /* we're moving the block */
211 Addr a;
212
213 if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
sewardja8d8e232005-06-07 20:04:56 +0000214 /* not allowed to move */
215 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000216
217 if ((flags & VKI_MREMAP_FIXED) == 0)
218 new_addr = 0;
219
220 a = VG_(find_map_space)(new_addr, new_size, True);
221
222 if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
sewardja8d8e232005-06-07 20:04:56 +0000223 /* didn't find the place we wanted */
224 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000225
226 new_addr = a;
fitzhardinge1a303042003-12-22 08:48:50 +0000227
228 /* we've nailed down the location */
sewardja8d8e232005-06-07 20:04:56 +0000229 flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
fitzhardinge1a303042003-12-22 08:48:50 +0000230
njnca6fef02004-11-29 16:49:18 +0000231 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
232 flags, new_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000233
sewardja8d8e232005-06-07 20:04:56 +0000234 if (ret.isError) {
fitzhardinge1a303042003-12-22 08:48:50 +0000235 return ret;
236 }
237
238 VG_TRACK(copy_mem_remap, old_addr, new_addr,
239 (old_size < new_size) ? old_size : new_size);
240
241 if (new_size > old_size)
242 VG_TRACK(new_mem_mmap, new_addr+old_size, new_size-old_size,
243 seg->prot & VKI_PROT_READ,
244 seg->prot & VKI_PROT_WRITE,
245 seg->prot & VKI_PROT_EXEC);
246 VG_TRACK(die_mem_munmap, old_addr, old_size);
247
248 VG_(map_file_segment)(new_addr, new_size,
249 seg->prot,
250 seg->flags,
251 seg->dev, seg->ino,
252 seg->offset, seg->filename);
253
254 VG_(munmap)((void *)old_addr, old_size);
255 } else {
256 /* staying in place */
sewardja8d8e232005-06-07 20:04:56 +0000257 ret = VG_(mk_SysRes_Success)( old_addr );
fitzhardinge1a303042003-12-22 08:48:50 +0000258
259 if (new_size < old_size) {
260 VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
261 VG_(munmap)((void *)(old_addr+new_size), old_size-new_size);
262 } else {
263 /* we've nailed down the location */
264 flags &= ~VKI_MREMAP_MAYMOVE;
265
266 if (0)
267 VG_(printf)("mremap: old_addr=%p old_size=%d new_size=%d flags=%d\n",
268 old_addr, old_size, new_size, flags);
269
njnca6fef02004-11-29 16:49:18 +0000270 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
271 flags, 0);
fitzhardinge1a303042003-12-22 08:48:50 +0000272
sewardja8d8e232005-06-07 20:04:56 +0000273 if (ret.isError || (!ret.isError && ret.val != old_addr))
fitzhardinge1a303042003-12-22 08:48:50 +0000274 return ret;
275
276 VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
277 seg->prot & VKI_PROT_READ,
278 seg->prot & VKI_PROT_WRITE,
279 seg->prot & VKI_PROT_EXEC);
280
281 VG_(map_file_segment)(old_addr+old_size, new_size-old_size,
282 seg->prot,
283 seg->flags,
284 seg->dev, seg->ino,
285 seg->offset, seg->filename);
286 }
287 }
288
289 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000290}
291
292
sewardja8d8e232005-06-07 20:04:56 +0000293/* ---------------------------------------------------------------------
294 File-descriptor tracking
295 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000296
rjwalshf5f536f2003-11-17 17:45:00 +0000297/* One of these is allocated for each open file descriptor. */
rjwalshf5f536f2003-11-17 17:45:00 +0000298typedef struct OpenFd
299{
300 Int fd; /* The file descriptor */
301 Char *pathname; /* NULL if not a regular file or unknown */
302 ExeContext *where; /* NULL if inherited from parent */
303 struct OpenFd *next, *prev;
304} OpenFd;
305
306/* List of allocated file descriptors. */
rjwalshf5f536f2003-11-17 17:45:00 +0000307static OpenFd *allocated_fds;
308
309/* Count of open file descriptors. */
rjwalshf5f536f2003-11-17 17:45:00 +0000310static int fd_count = 0;
311
rjwalshf5f536f2003-11-17 17:45:00 +0000312
rjwalshf5f536f2003-11-17 17:45:00 +0000313/* Note the fact that a file descriptor was just closed. */
rjwalshf5f536f2003-11-17 17:45:00 +0000314static
njnc6168192004-11-29 13:54:10 +0000315void record_fd_close(ThreadId tid, Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000316{
317 OpenFd *i = allocated_fds;
318
thughesad1c9562004-06-26 11:27:52 +0000319 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000320 return; /* Valgrind internal */
321
rjwalshf5f536f2003-11-17 17:45:00 +0000322 while(i) {
323 if(i->fd == fd) {
324 if(i->prev)
325 i->prev->next = i->next;
326 else
327 allocated_fds = i->next;
328 if(i->next)
329 i->next->prev = i->prev;
330 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000331 VG_(arena_free) (VG_AR_CORE, i->pathname);
332 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000333 fd_count--;
334 break;
335 }
336 i = i->next;
337 }
338}
339
340/* Note the fact that a file descriptor was just opened. If the
341 tid is -1, this indicates an inherited fd. If the pathname is NULL,
342 this either indicates a non-standard file (i.e. a pipe or socket or
343 some such thing) or that we don't know the filename. If the fd is
344 already open, then we're probably doing a dup2() to an existing fd,
345 so just overwrite the existing one. */
njnf845f8f2005-06-23 02:26:47 +0000346static void record_fd_open_with_given_name(ThreadId tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000347{
348 OpenFd *i;
349
thughesad1c9562004-06-26 11:27:52 +0000350 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000351 return; /* Valgrind internal */
352
rjwalshf5f536f2003-11-17 17:45:00 +0000353 /* Check to see if this fd is already open. */
354 i = allocated_fds;
355 while (i) {
356 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000357 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000358 break;
359 }
360 i = i->next;
361 }
362
363 /* Not already one: allocate an OpenFd */
364 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000365 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000366
367 i->prev = NULL;
368 i->next = allocated_fds;
369 if(allocated_fds) allocated_fds->prev = i;
370 allocated_fds = i;
371 fd_count++;
372 }
373
374 i->fd = fd;
njnf845f8f2005-06-23 02:26:47 +0000375 i->pathname = VG_(arena_strdup)(VG_AR_CORE, pathname);
njnd01fef72005-03-25 23:35:48 +0000376 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
rjwalshf5f536f2003-11-17 17:45:00 +0000377}
378
njnf845f8f2005-06-23 02:26:47 +0000379// Record opening of an fd, and find its name.
380static void record_fd_open_named(ThreadId tid, Int fd)
381{
382 static HChar buf[VKI_PATH_MAX];
383 Char* name;
384 if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
385 name = buf;
386 else
387 name = NULL;
388
389 record_fd_open_with_given_name(tid, fd, name);
390}
391
392// Record opening of a nameless fd.
393void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
394{
395 record_fd_open_with_given_name(tid, fd, NULL);
396}
397
rjwalshf5f536f2003-11-17 17:45:00 +0000398static
nethercote73b526f2004-10-31 18:48:21 +0000399Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000400{
nethercote73b526f2004-10-31 18:48:21 +0000401 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000402 VG_(sprintf)(name, "<unknown>");
403 } else {
404 VG_(sprintf)(name, "%s", sa->sun_path);
405 }
406
407 return name;
408}
409
410static
nethercote73b526f2004-10-31 18:48:21 +0000411Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000412{
nethercote73b526f2004-10-31 18:48:21 +0000413 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000414 VG_(sprintf)(name, "<unknown>");
415 } else {
416 UInt addr = sa->sin_addr.s_addr;
417
418 if (addr == 0) {
419 VG_(sprintf)(name, "<unbound>");
420 } else {
421 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
422 addr & 0xFF, (addr>>8) & 0xFF,
423 (addr>>16) & 0xFF, (addr>>24) & 0xFF,
nethercote73b526f2004-10-31 18:48:21 +0000424 vki_ntohs(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000425 }
426 }
427
428 return name;
429}
430
rjwalshf5f536f2003-11-17 17:45:00 +0000431/*
432 * Try get some details about a socket.
433 */
rjwalshf5f536f2003-11-17 17:45:00 +0000434static void
435getsockdetails(int fd)
436{
437 union u {
nethercote73b526f2004-10-31 18:48:21 +0000438 struct vki_sockaddr a;
439 struct vki_sockaddr_in in;
440 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000441 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000442 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000443
444 llen = sizeof(laddr);
445 VG_(memset)(&laddr, 0, llen);
446
447 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
448 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000449 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000450 static char lname[32];
451 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000452 struct vki_sockaddr_in paddr;
453 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000454
455 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
456 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
457 inet2name(&(laddr.in), llen, lname),
458 inet2name(&paddr, plen, pname));
459 } else {
460 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
461 fd, inet2name(&(laddr.in), llen, lname));
462 }
463 return;
464 }
nethercote73b526f2004-10-31 18:48:21 +0000465 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000466 static char lname[256];
467 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
468 unix2name(&(laddr.un), llen, lname));
469 return;
470 }
471 default:
472 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
473 laddr.a.sa_family, fd);
474 return;
475 }
476 }
477
478 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
479}
480
481
nethercote3a42fb82004-08-03 18:08:50 +0000482/* Dump out a summary, and a more detailed list, of open file descriptors. */
483void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000484{
485 OpenFd *i = allocated_fds;
486
nethercote3a42fb82004-08-03 18:08:50 +0000487 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000488
489 while(i) {
490 if(i->pathname) {
491 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
492 i->pathname);
493 } else {
494 int val;
nethercote73b526f2004-10-31 18:48:21 +0000495 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000496
nethercote73b526f2004-10-31 18:48:21 +0000497 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000498 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
499 } else {
500 getsockdetails(i->fd);
501 }
502 }
503
504 if(i->where) {
505 VG_(pp_ExeContext)(i->where);
506 VG_(message)(Vg_UserMsg, "");
507 } else {
508 VG_(message)(Vg_UserMsg, " <inherited from parent>");
509 VG_(message)(Vg_UserMsg, "");
510 }
511
512 i = i->next;
513 }
514
515 VG_(message)(Vg_UserMsg, "");
516}
517
518/* If /proc/self/fd doesn't exist for some weird reason (like you've
519 got a kernel that doesn't have /proc support compiled in), then we
520 need to find out what file descriptors we inherited from our parent
521 process the hard way - by checking each fd in turn. */
522
523static
524void do_hacky_preopened()
525{
526 struct vki_rlimit lim;
527 unsigned int count;
528 int i;
529
nethercote620154f2004-11-12 21:21:07 +0000530 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000531 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
532 an arbitrarily high number. 1024 happens to be the limit in
533 the 2.4 kernels. */
534 count = 1024;
535 } else {
536 count = lim.rlim_cur;
537 }
538
539 for (i = 0; i < count; i++)
540 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
njnf845f8f2005-06-23 02:26:47 +0000541 ML_(record_fd_open_nameless)(-1, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000542}
543
544/* Initialize the list of open file descriptors with the file descriptors
545 we inherited from out parent process. */
546
547void VG_(init_preopened_fds)()
548{
549 int f, ret;
550 struct vki_dirent d;
551
552 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
553 if(f == -1) {
554 do_hacky_preopened();
555 return;
556 }
557
558 while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
njnf845f8f2005-06-23 02:26:47 +0000559 if (ret == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000560 goto out;
561
njnf845f8f2005-06-23 02:26:47 +0000562 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
rjwalshf5f536f2003-11-17 17:45:00 +0000563 int fno = VG_(atoll)(d.d_name);
564
njnf845f8f2005-06-23 02:26:47 +0000565 if (fno != f)
566 if (VG_(clo_track_fds))
567 record_fd_open_named(-1, fno);
rjwalshf5f536f2003-11-17 17:45:00 +0000568 }
569
570 VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
571 }
572
573out:
574 VG_(close)(f);
575}
576
sewardjde4a1d02002-03-22 01:27:54 +0000577static
sewardj8c824512002-04-14 04:16:48 +0000578Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000579{
580 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000581 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000582 VG_(strcpy) ( result, s1 );
583 VG_(strcat) ( result, s2 );
584 return result;
585}
586
587static
jsgf855d93d2003-10-13 22:26:55 +0000588void pre_mem_read_sendmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000589 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000590{
njn9f46df62005-03-13 18:11:44 +0000591 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000592 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000593
njn9f46df62005-03-13 18:11:44 +0000594 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000595}
596
597static
jsgf855d93d2003-10-13 22:26:55 +0000598void pre_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000599 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000600{
njn9f46df62005-03-13 18:11:44 +0000601 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000602 PRE_MEM_WRITE( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000603 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000604}
605
606static
njn72718642003-07-24 08:45:32 +0000607void post_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000608 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000609{
nethercoteef0c7662004-11-06 15:38:43 +0000610 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000611}
612
613static
sewardj8c824512002-04-14 04:16:48 +0000614void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000615 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000616 struct vki_msghdr *msg,
nethercote928a5f72004-11-03 18:10:37 +0000617 void (*foreach_func)( ThreadId, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000618 )
sewardjde4a1d02002-03-22 01:27:54 +0000619{
620 if ( !msg )
621 return;
622
nethercote73b526f2004-10-31 18:48:21 +0000623 foreach_func ( tid, "(msg)", (Addr)msg, sizeof( struct vki_msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000624
625 if ( msg->msg_name )
njn72718642003-07-24 08:45:32 +0000626 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000627 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000628 (Addr)msg->msg_name, msg->msg_namelen );
629
630 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000631 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000632 UInt i;
633
njn72718642003-07-24 08:45:32 +0000634 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000635 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000636 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000637
638 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
njn72718642003-07-24 08:45:32 +0000639 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000640 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000641 (Addr)iov->iov_base, iov->iov_len );
642 }
643
644 if ( msg->msg_control )
njn72718642003-07-24 08:45:32 +0000645 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000646 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000647 (Addr)msg->msg_control, msg->msg_controllen );
648}
649
sewardjb5f6f512005-03-10 23:59:00 +0000650static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000651{
nethercote73b526f2004-10-31 18:48:21 +0000652 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000653
654 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000655 if (cm->cmsg_level == VKI_SOL_SOCKET &&
656 cm->cmsg_type == VKI_SCM_RIGHTS ) {
657 int *fds = (int *) VKI_CMSG_DATA(cm);
658 int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000659 / sizeof(int);
660 int i;
661
662 for (i = 0; i < fdc; i++)
663 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000664 // XXX: must we check the range on these fds with
cerion7b2c38c2005-06-23 07:52:54 +0000665 // ML_(fd_allowed)()?
njnf845f8f2005-06-23 02:26:47 +0000666 record_fd_open_named(tid, fds[i]);
rjwalshf5f536f2003-11-17 17:45:00 +0000667 }
668
nethercote73b526f2004-10-31 18:48:21 +0000669 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000670 }
671}
672
sewardjc483e8f2002-05-03 21:01:35 +0000673static
jsgf855d93d2003-10-13 22:26:55 +0000674void pre_mem_read_sockaddr ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000675 Char *description,
676 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000677{
sewardjff7c1ab2003-02-24 21:55:34 +0000678 Char *outmsg;
679
680 /* NULL/zero-length sockaddrs are legal */
681 if ( sa == NULL || salen == 0 ) return;
682
njn9f46df62005-03-13 18:11:44 +0000683 outmsg = VG_(arena_malloc) ( VG_AR_CORE,
nethercote73b526f2004-10-31 18:48:21 +0000684 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000685
686 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000687 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000688
sewardjc483e8f2002-05-03 21:01:35 +0000689 switch (sa->sa_family) {
690
nethercote73b526f2004-10-31 18:48:21 +0000691 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000692 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000693 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000694 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000695 break;
696
nethercote73b526f2004-10-31 18:48:21 +0000697 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000698 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000699 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000700 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
701 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000702 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000703 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000704 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
705 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000706 break;
707
nethercote73b526f2004-10-31 18:48:21 +0000708 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000709 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000710 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000711 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
712 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000713 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000714 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000715 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
716 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000717 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000718 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000719 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_addr,
720 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000721 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
nethercoteef0c7662004-11-06 15:38:43 +0000722 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000723 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_scope_id,
724 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000725 break;
726
727 default:
728 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000729 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000730 break;
731 }
732
njn9f46df62005-03-13 18:11:44 +0000733 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000734}
735
njn25e49d8e72002-09-23 09:36:25 +0000736/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000737static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000738{
739 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000740 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000741 if (a_p == NULL)
742 return 0;
743 else
744 return *a_p;
745}
746
njn25e49d8e72002-09-23 09:36:25 +0000747static
njn72718642003-07-24 08:45:32 +0000748void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000749 Char* buf_s, Char* buflen_s )
750{
njn51d827b2005-05-09 01:02:08 +0000751 if (VG_(tdict).track_pre_mem_write) {
njn72718642003-07-24 08:45:32 +0000752 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000753 if (buflen_in > 0) {
njn51d827b2005-05-09 01:02:08 +0000754 VG_(tdict).track_pre_mem_write( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000755 }
756 }
757}
758
759static
sewardja8d8e232005-06-07 20:04:56 +0000760void buf_and_len_post_check( ThreadId tid, SysRes res,
njn25e49d8e72002-09-23 09:36:25 +0000761 Addr buf_p, Addr buflen_p, Char* s )
762{
sewardja8d8e232005-06-07 20:04:56 +0000763 if (!res.isError && VG_(tdict).track_post_mem_write) {
njn72718642003-07-24 08:45:32 +0000764 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000765 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njn51d827b2005-05-09 01:02:08 +0000766 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000767 }
768 }
769}
770
771/* ---------------------------------------------------------------------
772 Data seg end, for brk()
773 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000774
fitzhardinge98abfc72003-12-16 02:05:15 +0000775static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000776{
fitzhardinge98abfc72003-12-16 02:05:15 +0000777 Addr ret = VG_(brk_limit);
sewardje517b802005-02-16 01:58:51 +0000778 static const Bool debug = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000779 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000780 Addr current, newaddr;
781
fitzhardinge98abfc72003-12-16 02:05:15 +0000782
783 if (debug)
sewardj548be6d2005-02-16 01:31:37 +0000784 VG_(printf)("\ndo_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
fitzhardinge98abfc72003-12-16 02:05:15 +0000785 VG_(brk_base), VG_(brk_limit), newbrk);
786
sewardj79048ce2005-02-18 08:28:32 +0000787# if 0
sewardje517b802005-02-16 01:58:51 +0000788 if (0) show_segments("in_brk");
sewardj79048ce2005-02-18 08:28:32 +0000789# endif
sewardj548be6d2005-02-16 01:31:37 +0000790
fitzhardinge98abfc72003-12-16 02:05:15 +0000791 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
792 return VG_(brk_limit);
793
794 /* brk isn't allowed to grow over anything else */
sewardj548be6d2005-02-16 01:31:37 +0000795 seg = VG_(find_segment)(VG_(brk_limit) -1);
fitzhardinge98abfc72003-12-16 02:05:15 +0000796
797 vg_assert(seg != NULL);
798
njn25e49d8e72002-09-23 09:36:25 +0000799 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000800 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
801 VG_(brk_limit), seg->addr, seg->addr+seg->len);
sewardj79048ce2005-02-18 08:28:32 +0000802 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit)
803 <= (seg->addr + seg->len));
fitzhardinge98abfc72003-12-16 02:05:15 +0000804
sewardj79048ce2005-02-18 08:28:32 +0000805 seg = VG_(find_segment_above_mapped)(VG_(brk_limit)-1);
806 if (0 && seg)
807 VG_(printf)("NEXT addr = %p\n", seg->addr);
fitzhardinge98abfc72003-12-16 02:05:15 +0000808 if (seg != NULL && newbrk > seg->addr)
809 return VG_(brk_limit);
810
njn13bfd852005-06-02 03:52:53 +0000811 current = VG_PGROUNDUP(VG_(brk_limit));
812 newaddr = VG_PGROUNDUP(newbrk);
nethercotece471262004-08-25 13:43:44 +0000813 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000814
815 /* new brk in a new page - fix the mappings */
816 if (newbrk > VG_(brk_limit)) {
817
818 if (debug)
819 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
820 current, newaddr, newaddr-current);
821
822 if (newaddr == current) {
823 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000824 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
825 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
826 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
njn0ae787c2005-06-28 22:14:53 +0000827 0, -1, 0))
nethercoteb4250ae2004-07-10 16:50:09 +0000828 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000829 ret = newbrk;
830 }
831 } else {
832 vg_assert(newbrk < VG_(brk_limit));
833
834 if (debug)
835 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
836 current, newaddr, current-newaddr);
837
838 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000839 int res = VG_(munmap)((void *)newaddr, current - newaddr);
840 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000841 }
842 ret = newbrk;
843 }
844 } else
845 ret = newbrk;
846
847 VG_(brk_limit) = ret;
848
849 return ret;
850}
851
852
njn25e49d8e72002-09-23 09:36:25 +0000853/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000854 Vet file descriptors for sanity
855 ------------------------------------------------------------------ */
856
857/* Return true if we're allowed to use or create this fd */
sewardj7eb7c582005-06-23 01:02:53 +0000858Bool ML_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000859{
thughesad1c9562004-06-26 11:27:52 +0000860 if (fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) {
jsewardd9320a42003-12-12 06:40:05 +0000861 VG_(message)(Vg_UserMsg,
862 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000863 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000864 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000865 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000866 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000867 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000868 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
jsgf855d93d2003-10-13 22:26:55 +0000869 }
870 return False;
871 }
sewardj10759312005-05-30 23:52:47 +0000872 else
873 if (soft && fd >= VG_(fd_soft_limit)) {
thughesad1c9562004-06-26 11:27:52 +0000874 return False;
875 }
sewardj10759312005-05-30 23:52:47 +0000876 else
877 if (fd == 2 && VG_(debugLog_getLevel)() > 0) {
878 return False;
879 }
880 else {
881 return True;
882 }
jsgf855d93d2003-10-13 22:26:55 +0000883}
884
885
886/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +0000887 Deal with a bunch of socket-related syscalls
888 ------------------------------------------------------------------ */
889
890/* ------ */
891
sewardj987a8eb2005-03-01 19:00:30 +0000892void
sewardj7eb7c582005-06-23 01:02:53 +0000893ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000894 UWord arg0, UWord arg1,
895 UWord arg2, UWord arg3 )
896{
897 /* int socketpair(int d, int type, int protocol, int sv[2]); */
898 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
899 arg3, 2*sizeof(int) );
900}
901
sewardja8d8e232005-06-07 20:04:56 +0000902SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000903ML_(generic_POST_sys_socketpair) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000904 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +0000905 UWord arg0, UWord arg1,
906 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +0000907{
sewardja8d8e232005-06-07 20:04:56 +0000908 SysRes r = res;
909 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +0000910 Int fd1 = ((Int*)arg3)[0];
911 Int fd2 = ((Int*)arg3)[1];
912 POST_MEM_WRITE( arg3, 2*sizeof(int) );
sewardj7eb7c582005-06-23 01:02:53 +0000913 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
914 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
sewardj9efbbef2005-03-01 16:45:23 +0000915 VG_(close)(fd1);
916 VG_(close)(fd2);
sewardja8d8e232005-06-07 20:04:56 +0000917 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000918 } else {
919 POST_MEM_WRITE( arg3, 2*sizeof(int) );
920 if (VG_(clo_track_fds)) {
njnf845f8f2005-06-23 02:26:47 +0000921 ML_(record_fd_open_nameless)(tid, fd1);
922 ML_(record_fd_open_nameless)(tid, fd2);
sewardj9efbbef2005-03-01 16:45:23 +0000923 }
924 }
925 return r;
926}
927
928/* ------ */
929
sewardja8d8e232005-06-07 20:04:56 +0000930SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000931ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
sewardj9efbbef2005-03-01 16:45:23 +0000932{
sewardja8d8e232005-06-07 20:04:56 +0000933 SysRes r = res;
934 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +0000935 if (!ML_(fd_allowed)(res.val, "socket", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +0000936 VG_(close)(res.val);
937 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000938 } else {
939 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +0000940 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +0000941 }
942 return r;
943}
944
945/* ------ */
946
sewardj987a8eb2005-03-01 19:00:30 +0000947void
sewardj7eb7c582005-06-23 01:02:53 +0000948ML_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000949 UWord arg0, UWord arg1, UWord arg2 )
950{
951 /* int bind(int sockfd, struct sockaddr *my_addr,
952 int addrlen); */
953 pre_mem_read_sockaddr(
954 tid, "socketcall.bind(my_addr.%s)",
955 (struct vki_sockaddr *) arg1, arg2
956 );
957}
958
959/* ------ */
960
sewardj987a8eb2005-03-01 19:00:30 +0000961void
sewardj7eb7c582005-06-23 01:02:53 +0000962ML_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000963 UWord arg0, UWord arg1, UWord arg2 )
964{
965 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
966 Addr addr_p = arg1;
967 Addr addrlen_p = arg2;
968 if (addr_p != (Addr)NULL)
969 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
970 "socketcall.accept(addr)",
971 "socketcall.accept(addrlen_in)" );
972}
973
sewardja8d8e232005-06-07 20:04:56 +0000974SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000975ML_(generic_POST_sys_accept) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000976 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +0000977 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +0000978{
sewardja8d8e232005-06-07 20:04:56 +0000979 SysRes r = res;
980 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +0000981 if (!ML_(fd_allowed)(res.val, "accept", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +0000982 VG_(close)(res.val);
983 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000984 } else {
985 Addr addr_p = arg1;
986 Addr addrlen_p = arg2;
987 if (addr_p != (Addr)NULL)
988 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
989 "socketcall.accept(addrlen_out)" );
990 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +0000991 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +0000992 }
993 return r;
994}
995
996/* ------ */
997
sewardj987a8eb2005-03-01 19:00:30 +0000998void
sewardj7eb7c582005-06-23 01:02:53 +0000999ML_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001000 UWord arg0, UWord arg1, UWord arg2,
1001 UWord arg3, UWord arg4, UWord arg5 )
1002{
1003 /* int sendto(int s, const void *msg, int len,
1004 unsigned int flags,
1005 const struct sockaddr *to, int tolen); */
1006 PRE_MEM_READ( "socketcall.sendto(msg)",
1007 arg1, /* msg */
1008 arg2 /* len */ );
1009 pre_mem_read_sockaddr(
1010 tid, "socketcall.sendto(to.%s)",
1011 (struct vki_sockaddr *) arg4, arg5
1012 );
1013}
1014
1015/* ------ */
1016
sewardj987a8eb2005-03-01 19:00:30 +00001017void
sewardj7eb7c582005-06-23 01:02:53 +00001018ML_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001019 UWord arg0, UWord arg1, UWord arg2 )
1020{
1021 /* int send(int s, const void *msg, size_t len, int flags); */
1022 PRE_MEM_READ( "socketcall.send(msg)",
1023 arg1, /* msg */
1024 arg2 /* len */ );
1025
1026}
1027
1028/* ------ */
1029
sewardj987a8eb2005-03-01 19:00:30 +00001030void
sewardj7eb7c582005-06-23 01:02:53 +00001031ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001032 UWord arg0, UWord arg1, UWord arg2,
1033 UWord arg3, UWord arg4, UWord arg5 )
1034{
1035 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1036 struct sockaddr *from, int *fromlen); */
1037 Addr buf_p = arg1;
1038 Int len = arg2;
1039 Addr from_p = arg4;
1040 Addr fromlen_p = arg5;
1041 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1042 if (from_p != (Addr)NULL)
1043 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1044 "socketcall.recvfrom(from)",
1045 "socketcall.recvfrom(fromlen_in)" );
1046}
1047
sewardj987a8eb2005-03-01 19:00:30 +00001048void
sewardj7eb7c582005-06-23 01:02:53 +00001049ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001050 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001051 UWord arg0, UWord arg1, UWord arg2,
1052 UWord arg3, UWord arg4, UWord arg5 )
1053{
1054 Addr buf_p = arg1;
1055 Int len = arg2;
1056 Addr from_p = arg4;
1057 Addr fromlen_p = arg5;
1058
sewardja8d8e232005-06-07 20:04:56 +00001059 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001060 if (from_p != (Addr)NULL)
1061 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1062 "socketcall.recvfrom(fromlen_out)" );
1063 POST_MEM_WRITE( buf_p, len );
1064}
1065
1066/* ------ */
1067
sewardj987a8eb2005-03-01 19:00:30 +00001068void
sewardj7eb7c582005-06-23 01:02:53 +00001069ML_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001070 UWord arg0, UWord arg1, UWord arg2 )
1071{
1072 /* int recv(int s, void *buf, int len, unsigned int flags); */
1073 /* man 2 recv says:
1074 The recv call is normally used only on a connected socket
1075 (see connect(2)) and is identical to recvfrom with a NULL
1076 from parameter.
1077 */
1078 PRE_MEM_WRITE( "socketcall.recv(buf)",
1079 arg1, /* buf */
1080 arg2 /* len */ );
1081}
1082
sewardj987a8eb2005-03-01 19:00:30 +00001083void
sewardj7eb7c582005-06-23 01:02:53 +00001084ML_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001085 UWord res,
1086 UWord arg0, UWord arg1, UWord arg2 )
1087{
1088 if (res >= 0 && arg1 != 0) {
1089 POST_MEM_WRITE( arg1, /* buf */
1090 arg2 /* len */ );
1091 }
1092}
1093
1094/* ------ */
1095
sewardj987a8eb2005-03-01 19:00:30 +00001096void
sewardj7eb7c582005-06-23 01:02:53 +00001097ML_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001098 UWord arg0, UWord arg1, UWord arg2 )
1099{
1100 /* int connect(int sockfd,
1101 struct sockaddr *serv_addr, int addrlen ); */
1102 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1103 arg1, /* serv_addr */
1104 sizeof(vki_sa_family_t));
1105 pre_mem_read_sockaddr( tid,
1106 "socketcall.connect(serv_addr.%s)",
1107 (struct vki_sockaddr *) arg1, arg2);
1108}
1109
1110/* ------ */
1111
sewardj987a8eb2005-03-01 19:00:30 +00001112void
sewardj7eb7c582005-06-23 01:02:53 +00001113ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001114 UWord arg0, UWord arg1, UWord arg2,
1115 UWord arg3, UWord arg4 )
1116{
1117 /* int setsockopt(int s, int level, int optname,
1118 const void *optval, int optlen); */
1119 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1120 arg3, /* optval */
1121 arg4 /* optlen */ );
1122}
1123
1124/* ------ */
1125
sewardj987a8eb2005-03-01 19:00:30 +00001126void
sewardj7eb7c582005-06-23 01:02:53 +00001127ML_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001128 UWord arg0, UWord arg1, UWord arg2,
1129 UWord arg3, UWord arg4 )
1130{
1131 /* int getsockopt(int s, int level, int optname,
1132 void *optval, socklen_t *optlen); */
1133 Addr optval_p = arg3;
1134 Addr optlen_p = arg4;
1135 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
1136 if (optval_p != (Addr)NULL)
1137 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1138 "socketcall.getsockopt(optval)",
1139 "socketcall.getsockopt(optlen)" );
1140}
1141
sewardj987a8eb2005-03-01 19:00:30 +00001142void
sewardj7eb7c582005-06-23 01:02:53 +00001143ML_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001144 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001145 UWord arg0, UWord arg1, UWord arg2,
1146 UWord arg3, UWord arg4 )
1147{
1148 Addr optval_p = arg3;
1149 Addr optlen_p = arg4;
sewardja8d8e232005-06-07 20:04:56 +00001150 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001151 if (optval_p != (Addr)NULL)
1152 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1153 "socketcall.getsockopt(optlen_out)" );
1154}
1155
1156/* ------ */
1157
sewardj987a8eb2005-03-01 19:00:30 +00001158void
sewardj7eb7c582005-06-23 01:02:53 +00001159ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001160 UWord arg0, UWord arg1, UWord arg2 )
1161{
1162 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1163 Addr name_p = arg1;
1164 Addr namelen_p = arg2;
1165 /* Nb: name_p cannot be NULL */
1166 buf_and_len_pre_check ( tid, name_p, namelen_p,
1167 "socketcall.getsockname(name)",
1168 "socketcall.getsockname(namelen_in)" );
1169}
1170
sewardj987a8eb2005-03-01 19:00:30 +00001171void
sewardj7eb7c582005-06-23 01:02:53 +00001172ML_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001173 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001174 UWord arg0, UWord arg1, UWord arg2 )
1175{
1176 Addr name_p = arg1;
1177 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001178 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001179 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1180 "socketcall.getsockname(namelen_out)" );
1181}
1182
1183/* ------ */
1184
sewardj987a8eb2005-03-01 19:00:30 +00001185void
sewardj7eb7c582005-06-23 01:02:53 +00001186ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001187 UWord arg0, UWord arg1, UWord arg2 )
1188{
1189 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1190 Addr name_p = arg1;
1191 Addr namelen_p = arg2;
1192 /* Nb: name_p cannot be NULL */
1193 buf_and_len_pre_check ( tid, name_p, namelen_p,
1194 "socketcall.getpeername(name)",
1195 "socketcall.getpeername(namelen_in)" );
1196}
1197
sewardj987a8eb2005-03-01 19:00:30 +00001198void
sewardj7eb7c582005-06-23 01:02:53 +00001199ML_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001200 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001201 UWord arg0, UWord arg1, UWord arg2 )
1202{
1203 Addr name_p = arg1;
1204 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001205 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001206 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1207 "socketcall.getpeername(namelen_out)" );
1208}
1209
1210/* ------ */
1211
sewardj987a8eb2005-03-01 19:00:30 +00001212void
sewardj7eb7c582005-06-23 01:02:53 +00001213ML_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001214 UWord arg0, UWord arg1 )
1215{
1216 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1217 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1218 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1219}
1220
1221/* ------ */
1222
sewardj987a8eb2005-03-01 19:00:30 +00001223void
sewardj7eb7c582005-06-23 01:02:53 +00001224ML_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001225 UWord arg0, UWord arg1 )
1226{
1227 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1228 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1229 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1230}
1231
sewardj987a8eb2005-03-01 19:00:30 +00001232void
sewardj7eb7c582005-06-23 01:02:53 +00001233ML_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001234 UWord arg0, UWord arg1 )
1235{
1236 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1237 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1238 check_cmsg_for_fds( tid, msg );
1239}
1240
1241
1242/* ---------------------------------------------------------------------
sewardjb369c5e2005-03-24 17:52:02 +00001243 Deal with a bunch of IPC related syscalls
1244 ------------------------------------------------------------------ */
1245
1246/* ------ */
1247
1248void
sewardj7eb7c582005-06-23 01:02:53 +00001249ML_(generic_PRE_sys_semop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001250 UWord arg0, UWord arg1, UWord arg2 )
1251{
1252 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1253 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1254}
1255
1256/* ------ */
1257
1258void
sewardj7eb7c582005-06-23 01:02:53 +00001259ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001260 UWord arg0, UWord arg1,
1261 UWord arg2, UWord arg3 )
1262{
1263 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1264 struct timespec *timeout); */
1265 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1266 if (arg3 != 0)
1267 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1268}
1269
1270/* ------ */
1271
1272static
1273UInt get_sem_count( Int semid )
1274{
sewardja8d8e232005-06-07 20:04:56 +00001275 struct vki_semid_ds buf;
1276 union vki_semun arg;
1277 SysRes res;
sewardjb369c5e2005-03-24 17:52:02 +00001278
sewardja8d8e232005-06-07 20:04:56 +00001279 arg.buf = &buf;
sewardjb369c5e2005-03-24 17:52:02 +00001280
sewardja8d8e232005-06-07 20:04:56 +00001281# ifdef __NR_semctl
1282 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1283# else
1284 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
1285 VKI_IPC_STAT, (UWord)&arg);
1286# endif
1287 if (res.isError)
1288 return 0;
sewardjb369c5e2005-03-24 17:52:02 +00001289
sewardja8d8e232005-06-07 20:04:56 +00001290 return buf.sem_nsems;
sewardjb369c5e2005-03-24 17:52:02 +00001291}
1292
1293void
sewardj7eb7c582005-06-23 01:02:53 +00001294ML_(generic_PRE_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001295 UWord arg0, UWord arg1,
1296 UWord arg2, UWord arg3 )
1297{
1298 /* int semctl(int semid, int semnum, int cmd, ...); */
1299 union vki_semun arg = *(union vki_semun *)&arg3;
1300 UInt nsems;
1301 switch (arg2 /* cmd */) {
1302 case VKI_IPC_INFO:
1303 case VKI_SEM_INFO:
1304 case VKI_IPC_INFO|VKI_IPC_64:
1305 case VKI_SEM_INFO|VKI_IPC_64:
1306 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
1307 (Addr)arg.buf, sizeof(struct vki_seminfo) );
1308 break;
1309 case VKI_IPC_STAT:
1310 case VKI_SEM_STAT:
1311 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1312 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1313 break;
1314 case VKI_IPC_STAT|VKI_IPC_64:
1315 case VKI_SEM_STAT|VKI_IPC_64:
1316 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1317 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1318 break;
1319 case VKI_IPC_SET:
1320 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1321 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1322 break;
1323 case VKI_IPC_SET|VKI_IPC_64:
1324 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1325 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1326 break;
1327 case VKI_GETALL:
1328 case VKI_GETALL|VKI_IPC_64:
1329 nsems = get_sem_count( arg0 );
1330 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
1331 (Addr)arg.array, sizeof(unsigned short) * nsems );
1332 break;
1333 case VKI_SETALL:
1334 case VKI_SETALL|VKI_IPC_64:
1335 nsems = get_sem_count( arg0 );
1336 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
1337 (Addr)arg.array, sizeof(unsigned short) * nsems );
1338 break;
1339 }
1340}
1341
1342void
sewardj7eb7c582005-06-23 01:02:53 +00001343ML_(generic_POST_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001344 UWord res,
1345 UWord arg0, UWord arg1,
1346 UWord arg2, UWord arg3 )
1347{
1348 union vki_semun arg = *(union vki_semun *)&arg3;
1349 UInt nsems;
1350 switch (arg2 /* cmd */) {
1351 case VKI_IPC_INFO:
1352 case VKI_SEM_INFO:
1353 case VKI_IPC_INFO|VKI_IPC_64:
1354 case VKI_SEM_INFO|VKI_IPC_64:
1355 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
1356 break;
1357 case VKI_IPC_STAT:
1358 case VKI_SEM_STAT:
1359 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1360 break;
1361 case VKI_IPC_STAT|VKI_IPC_64:
1362 case VKI_SEM_STAT|VKI_IPC_64:
1363 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1364 break;
1365 case VKI_GETALL:
1366 case VKI_GETALL|VKI_IPC_64:
1367 nsems = get_sem_count( arg0 );
1368 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
1369 break;
1370 }
1371}
1372
1373/* ------ */
1374
1375void
sewardj7eb7c582005-06-23 01:02:53 +00001376ML_(generic_PRE_sys_msgsnd) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001377 UWord arg0, UWord arg1,
1378 UWord arg2, UWord arg3 )
1379{
1380 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
1381 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1382 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1383 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1384}
1385
1386/* ------ */
1387
1388void
sewardj7eb7c582005-06-23 01:02:53 +00001389ML_(generic_PRE_sys_msgrcv) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001390 UWord arg0, UWord arg1, UWord arg2,
1391 UWord arg3, UWord arg4 )
1392{
1393 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
1394 long msgtyp, int msgflg); */
1395 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1396 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1397 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1398}
1399
1400void
sewardj7eb7c582005-06-23 01:02:53 +00001401ML_(generic_POST_sys_msgrcv) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001402 UWord res,
1403 UWord arg0, UWord arg1, UWord arg2,
1404 UWord arg3, UWord arg4 )
1405{
1406 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1407 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1408 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
1409}
1410
1411/* ------ */
1412
1413void
sewardj7eb7c582005-06-23 01:02:53 +00001414ML_(generic_PRE_sys_msgctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001415 UWord arg0, UWord arg1, UWord arg2 )
1416{
1417 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
1418 switch (arg1 /* cmd */) {
1419 case VKI_IPC_INFO:
1420 case VKI_MSG_INFO:
1421 case VKI_IPC_INFO|VKI_IPC_64:
1422 case VKI_MSG_INFO|VKI_IPC_64:
1423 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
1424 arg2, sizeof(struct vki_msginfo) );
1425 break;
1426 case VKI_IPC_STAT:
1427 case VKI_MSG_STAT:
1428 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
1429 arg2, sizeof(struct vki_msqid_ds) );
1430 break;
1431 case VKI_IPC_STAT|VKI_IPC_64:
1432 case VKI_MSG_STAT|VKI_IPC_64:
1433 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
1434 arg2, sizeof(struct vki_msqid64_ds) );
1435 break;
1436 case VKI_IPC_SET:
1437 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1438 arg2, sizeof(struct vki_msqid_ds) );
1439 break;
1440 case VKI_IPC_SET|VKI_IPC_64:
1441 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1442 arg2, sizeof(struct vki_msqid64_ds) );
1443 break;
1444 }
1445}
1446
1447void
sewardj7eb7c582005-06-23 01:02:53 +00001448ML_(generic_POST_sys_msgctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001449 UWord res,
1450 UWord arg0, UWord arg1, UWord arg2 )
1451{
1452 switch (arg1 /* cmd */) {
1453 case VKI_IPC_INFO:
1454 case VKI_MSG_INFO:
1455 case VKI_IPC_INFO|VKI_IPC_64:
1456 case VKI_MSG_INFO|VKI_IPC_64:
1457 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
1458 break;
1459 case VKI_IPC_STAT:
1460 case VKI_MSG_STAT:
1461 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
1462 break;
1463 case VKI_IPC_STAT|VKI_IPC_64:
1464 case VKI_MSG_STAT|VKI_IPC_64:
1465 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
1466 break;
1467 }
1468}
1469
1470/* ------ */
1471
1472static
1473UInt get_shm_size ( Int shmid )
1474{
sewardja8d8e232005-06-07 20:04:56 +00001475# ifdef __NR_shmctl
sewardjb369c5e2005-03-24 17:52:02 +00001476 struct vki_shmid64_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001477 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
1478# else
sewardjb369c5e2005-03-24 17:52:02 +00001479 struct vki_shmid_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001480 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
sewardjb369c5e2005-03-24 17:52:02 +00001481 VKI_IPC_STAT, 0, (UWord)&buf);
sewardja8d8e232005-06-07 20:04:56 +00001482# endif
1483 if (__res.isError)
sewardjb369c5e2005-03-24 17:52:02 +00001484 return 0;
1485
1486 return buf.shm_segsz;
1487}
1488
1489UWord
sewardj7eb7c582005-06-23 01:02:53 +00001490ML_(generic_PRE_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001491 UWord arg0, UWord arg1, UWord arg2 )
1492{
1493 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
1494 UInt segmentSize = get_shm_size ( arg0 );
1495 if (arg1 == 0)
1496 arg1 = VG_(find_map_space)(0, segmentSize, True);
sewardj7eb7c582005-06-23 01:02:53 +00001497 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
sewardjb369c5e2005-03-24 17:52:02 +00001498 arg1 = 0;
1499 return arg1;
1500}
1501
1502void
sewardj7eb7c582005-06-23 01:02:53 +00001503ML_(generic_POST_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001504 UWord res,
1505 UWord arg0, UWord arg1, UWord arg2 )
1506{
1507 UInt segmentSize = get_shm_size ( arg0 );
1508 if ( segmentSize > 0 ) {
1509 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
1510 /* we don't distinguish whether it's read-only or
1511 * read-write -- it doesn't matter really. */
1512 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
1513
1514 if (!(arg2 & 010000)) /* = SHM_RDONLY */
1515 prot &= ~VKI_PROT_WRITE;
1516 VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
1517 }
1518}
1519
1520/* ------ */
1521
1522Bool
sewardj7eb7c582005-06-23 01:02:53 +00001523ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001524{
1525 /* int shmdt(const void *shmaddr); */
sewardj7eb7c582005-06-23 01:02:53 +00001526 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
sewardjb369c5e2005-03-24 17:52:02 +00001527}
1528
1529void
sewardj7eb7c582005-06-23 01:02:53 +00001530ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001531{
1532 Segment *s = VG_(find_segment)(arg0);
1533
1534 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, 1)) {
1535 VG_TRACK( die_mem_munmap, s->addr, s->len );
1536 VG_(unmap_range)(s->addr, s->len);
1537 }
1538}
1539/* ------ */
1540
1541void
sewardj7eb7c582005-06-23 01:02:53 +00001542ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001543 UWord arg0, UWord arg1, UWord arg2 )
1544{
1545 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
1546 switch (arg1 /* cmd */) {
1547 case VKI_IPC_INFO:
1548 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1549 arg2, sizeof(struct vki_shminfo) );
1550 break;
1551 case VKI_IPC_INFO|VKI_IPC_64:
1552 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1553 arg2, sizeof(struct vki_shminfo64) );
1554 break;
1555 case VKI_SHM_INFO:
1556 case VKI_SHM_INFO|VKI_IPC_64:
1557 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
1558 arg2, sizeof(struct vki_shm_info) );
1559 break;
1560 case VKI_IPC_STAT:
1561 case VKI_SHM_STAT:
1562 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
1563 arg2, sizeof(struct vki_shmid_ds) );
1564 break;
1565 case VKI_IPC_STAT|VKI_IPC_64:
1566 case VKI_SHM_STAT|VKI_IPC_64:
1567 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
1568 arg2, sizeof(struct vki_shmid64_ds) );
1569 break;
1570 case VKI_IPC_SET:
1571 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1572 arg2, sizeof(struct vki_shmid_ds) );
1573 break;
1574 case VKI_IPC_SET|VKI_IPC_64:
1575 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1576 arg2, sizeof(struct vki_shmid64_ds) );
1577 break;
1578 }
1579}
1580
1581void
sewardj7eb7c582005-06-23 01:02:53 +00001582ML_(generic_POST_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001583 UWord res,
1584 UWord arg0, UWord arg1, UWord arg2 )
1585{
1586 switch (arg1 /* cmd */) {
1587 case VKI_IPC_INFO:
1588 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
1589 break;
1590 case VKI_IPC_INFO|VKI_IPC_64:
1591 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
1592 break;
1593 case VKI_SHM_INFO:
1594 case VKI_SHM_INFO|VKI_IPC_64:
1595 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
1596 break;
1597 case VKI_IPC_STAT:
1598 case VKI_SHM_STAT:
1599 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
1600 break;
1601 case VKI_IPC_STAT|VKI_IPC_64:
1602 case VKI_SHM_STAT|VKI_IPC_64:
1603 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
1604 break;
1605 }
1606}
1607
1608
1609/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001610 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001611 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001612
nethercote4fa681f2004-11-08 17:51:39 +00001613/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001614 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001615 names like sys_write(); a few have names like old_mmap(). See the
njnaf839f52005-06-23 03:27:57 +00001616 comment for ML_(syscall_table)[] for important info about the __NR_foo
nethercote8ff888f2004-11-17 17:11:45 +00001617 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001618
nethercote92b2fd52004-11-16 16:15:41 +00001619 Some notes about names used for syscalls and args:
1620 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1621 ambiguity.
1622
1623 - For error messages, we generally use a somewhat generic name
1624 for the syscall (eg. "write" rather than "sys_write"). This should be
1625 good enough for the average user to understand what is happening,
1626 without confusing them with names like "sys_write".
1627
1628 - Also, for error messages the arg names are mostly taken from the man
1629 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001630 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001631 for the same reason -- a user presented with a "bogus foo(bar)" arg
1632 will most likely look at the "foo" man page to see which is the "bar"
1633 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001634
nethercote9c311eb2004-11-12 18:20:12 +00001635 Note that we use our own vki_* types. The one exception is in
1636 PRE_REG_READn calls, where pointer types haven't been changed, because
1637 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1638 be visible.
1639
nethercote4fa681f2004-11-08 17:51:39 +00001640 XXX: some of these are arch-specific, and should be factored out.
1641*/
1642
sewardja8d8e232005-06-07 20:04:56 +00001643#define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
1644#define POST(name) DEFN_POST_TEMPLATE(generic, name)
jsgf855d93d2003-10-13 22:26:55 +00001645
sewardje7aa4ae2005-06-09 12:43:42 +00001646// Combine two 32-bit values into a 64-bit value
1647#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1648
sewardja8d8e232005-06-07 20:04:56 +00001649//zz //PRE(sys_exit_group, Special)
1650//zz //{
1651//zz // VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1652//zz //}
nethercoteef0c7662004-11-06 15:38:43 +00001653
sewardja8d8e232005-06-07 20:04:56 +00001654PRE(sys_exit)
jsgf855d93d2003-10-13 22:26:55 +00001655{
sewardja8d8e232005-06-07 20:04:56 +00001656 ThreadState* tst;
sewardja922b612005-03-11 02:47:32 +00001657 /* simple; just make this thread exit */
1658 PRINT("exit( %d )", ARG1);
1659 PRE_REG_READ1(void, "exit", int, exitcode);
sewardja8d8e232005-06-07 20:04:56 +00001660 tst = VG_(get_ThreadState)(tid);
1661 /* Set the thread's status to be exiting, then claim that the
1662 syscall succeeded. */
sewardja922b612005-03-11 02:47:32 +00001663 tst->exitreason = VgSrc_ExitSyscall;
1664 tst->os_state.exitcode = ARG1;
sewardja8d8e232005-06-07 20:04:56 +00001665 SET_STATUS_Success(0);
jsgf855d93d2003-10-13 22:26:55 +00001666}
1667
sewardj78b50e42005-06-08 01:47:28 +00001668PRE(sys_sched_yield)
1669{
1670 *flags |= SfMayBlock;
1671 PRINT("sched_yield()");
1672 PRE_REG_READ0(long, "sys_sched_yield");
1673}
nethercote5b653bc2004-11-15 14:32:12 +00001674
sewardja8d8e232005-06-07 20:04:56 +00001675PRE(sys_ni_syscall)
nethercoteeb1c7b72004-11-11 19:43:50 +00001676{
1677 PRINT("non-existent syscall! (ni_syscall)");
1678 PRE_REG_READ0(long, "ni_syscall");
sewardja8d8e232005-06-07 20:04:56 +00001679 SET_STATUS_Failure( VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001680}
1681
sewardj696c5512005-06-08 23:38:32 +00001682PRE(sys_iopl)
1683{
1684 PRINT("sys_iopl ( %d )", ARG1);
1685 PRE_REG_READ1(long, "iopl", unsigned long, level);
1686}
1687
sewardje6d5e722005-06-10 10:27:55 +00001688PRE(sys_setxattr)
1689{
1690 *flags |= SfMayBlock;
1691 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
1692 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1693 PRE_REG_READ5(long, "setxattr",
1694 char *, path, char *, name,
1695 void *, value, vki_size_t, size, int, flags);
1696 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1697 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1698 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
1699}
1700
1701PRE(sys_lsetxattr)
1702{
1703 *flags |= SfMayBlock;
1704 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
1705 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1706 PRE_REG_READ5(long, "lsetxattr",
1707 char *, path, char *, name,
1708 void *, value, vki_size_t, size, int, flags);
1709 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
1710 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
1711 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
1712}
1713
1714PRE(sys_fsetxattr)
1715{
1716 *flags |= SfMayBlock;
1717 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
1718 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1719 PRE_REG_READ5(long, "fsetxattr",
1720 int, fd, char *, name, void *, value,
1721 vki_size_t, size, int, flags);
1722 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1723 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
1724}
rjwalshcdf1cb52004-04-29 08:40:50 +00001725
sewardja8d8e232005-06-07 20:04:56 +00001726PRE(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001727{
sewardja8d8e232005-06-07 20:04:56 +00001728 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00001729 PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001730 PRE_REG_READ4(ssize_t, "getxattr",
1731 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001732 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
1733 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
1734 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001735}
nethercote85a456f2004-11-16 17:31:56 +00001736POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001737{
sewardja8d8e232005-06-07 20:04:56 +00001738 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00001739 if (RES > 0 && ARG3 != (Addr)NULL) {
1740 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001741 }
1742}
1743
sewardje6d5e722005-06-10 10:27:55 +00001744PRE(sys_lgetxattr)
1745{
1746 *flags |= SfMayBlock;
1747 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
1748 PRE_REG_READ4(ssize_t, "lgetxattr",
1749 char *, path, char *, name, void *, value, vki_size_t, size);
1750 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
1751 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
1752 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
1753}
1754POST(sys_lgetxattr)
1755{
1756 vg_assert(SUCCESS);
1757 if (RES > 0 && ARG3 != (Addr)NULL) {
1758 POST_MEM_WRITE( ARG3, RES );
1759 }
1760}
1761
1762PRE(sys_fgetxattr)
1763{
1764 *flags |= SfMayBlock;
1765 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
1766 PRE_REG_READ4(ssize_t, "fgetxattr",
1767 int, fd, char *, name, void *, value, vki_size_t, size);
1768 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
1769 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
1770}
1771POST(sys_fgetxattr)
1772{
1773 if (RES > 0 && ARG3 != (Addr)NULL)
1774 POST_MEM_WRITE( ARG3, RES );
1775}
1776
1777PRE(sys_listxattr)
1778{
1779 *flags |= SfMayBlock;
1780 PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1781 PRE_REG_READ3(ssize_t, "listxattr",
1782 char *, path, char *, list, vki_size_t, size);
1783 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1784 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
1785}
1786POST(sys_listxattr)
1787{
1788 if (RES > 0 && ARG2 != (Addr)NULL)
1789 POST_MEM_WRITE( ARG2, RES );
1790}
1791
1792PRE(sys_llistxattr)
1793{
1794 *flags |= SfMayBlock;
1795 PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1796 PRE_REG_READ3(ssize_t, "llistxattr",
1797 char *, path, char *, list, vki_size_t, size);
1798 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
1799 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
1800}
1801POST(sys_llistxattr)
1802{
1803 if (RES > 0 && ARG2 != (Addr)NULL)
1804 POST_MEM_WRITE( ARG2, RES );
1805}
1806
1807PRE(sys_flistxattr)
1808{
1809 *flags |= SfMayBlock;
1810 PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1811 PRE_REG_READ3(ssize_t, "flistxattr",
1812 int, fd, char *, list, vki_size_t, size);
1813 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
1814}
1815POST(sys_flistxattr)
1816{
1817 if (RES > 0 && ARG2 != (Addr)NULL)
1818 POST_MEM_WRITE( ARG2, RES );
1819}
1820
1821PRE(sys_removexattr)
1822{
1823 *flags |= SfMayBlock;
1824 PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
1825 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
1826 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1827 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
1828}
1829
1830PRE(sys_lremovexattr)
1831{
1832 *flags |= SfMayBlock;
1833 PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
1834 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
1835 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
1836 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
1837}
1838
1839PRE(sys_fremovexattr)
1840{
1841 *flags |= SfMayBlock;
1842 PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
1843 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
1844 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
1845}
sewardj696c5512005-06-08 23:38:32 +00001846
1847PRE(sys_quotactl)
1848{
1849 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
1850 PRE_REG_READ4(long, "quotactl",
1851 unsigned int, cmd, const char *, special, vki_qid_t, id,
1852 void *, addr);
1853 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
1854}
1855
sewardje6d5e722005-06-10 10:27:55 +00001856// XXX: this wrapper is only suitable for 32-bit platforms
1857#if defined(VGP_x86_linux)
1858PRE(sys_lookup_dcookie)
1859{
1860 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
1861 PRE_REG_READ4(long, "lookup_dcookie",
1862 vki_u32, cookie_low32, vki_u32, cookie_high32,
1863 char *, buf, vki_size_t, len);
1864 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
1865}
1866POST(sys_lookup_dcookie)
1867{
1868 vg_assert(SUCCESS);
1869 if (ARG3 != (Addr)NULL)
1870 POST_MEM_WRITE( ARG3, RES);
1871}
1872#endif
sewardj78b50e42005-06-08 01:47:28 +00001873
1874PRE(sys_fsync)
1875{
1876 *flags |= SfMayBlock;
1877 PRINT("sys_fsync ( %d )", ARG1);
1878 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1879}
1880
sewardj696c5512005-06-08 23:38:32 +00001881PRE(sys_fdatasync)
1882{
1883 *flags |= SfMayBlock;
1884 PRINT("sys_fdatasync ( %d )", ARG1);
1885 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
1886}
1887
1888PRE(sys_msync)
1889{
1890 *flags |= SfMayBlock;
1891 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
1892 PRE_REG_READ3(long, "msync",
1893 unsigned long, start, vki_size_t, length, int, flags);
1894 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
1895}
1896
sewardje6d5e722005-06-10 10:27:55 +00001897// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1898// versions of LiS (Linux Streams). They are not part of the kernel.
1899// Therefore, we have to provide this type ourself, rather than getting it
1900// from the kernel sources.
1901struct vki_pmsg_strbuf {
1902 int maxlen; /* no. of bytes in buffer */
1903 int len; /* no. of bytes returned */
1904 vki_caddr_t buf; /* pointer to data */
1905};
1906PRE(sys_getpmsg)
1907{
1908 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
1909 struct vki_pmsg_strbuf *ctrl;
1910 struct vki_pmsg_strbuf *data;
1911 *flags |= SfMayBlock;
1912 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
1913 PRE_REG_READ5(int, "getpmsg",
1914 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1915 int *, bandp, int *, flagsp);
1916 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1917 data = (struct vki_pmsg_strbuf *)ARG3;
1918 if (ctrl && ctrl->maxlen > 0)
1919 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
1920 if (data && data->maxlen > 0)
1921 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
1922 if (ARG4)
1923 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
1924 if (ARG5)
1925 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
1926}
1927POST(sys_getpmsg)
1928{
1929 struct vki_pmsg_strbuf *ctrl;
1930 struct vki_pmsg_strbuf *data;
1931 vg_assert(SUCCESS);
1932 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1933 data = (struct vki_pmsg_strbuf *)ARG3;
1934 if (RES == 0 && ctrl && ctrl->len > 0) {
1935 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
1936 }
1937 if (RES == 0 && data && data->len > 0) {
1938 POST_MEM_WRITE( (Addr)data->buf, data->len);
1939 }
1940}
1941
1942PRE(sys_putpmsg)
1943{
1944 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
1945 struct vki_pmsg_strbuf *ctrl;
1946 struct vki_pmsg_strbuf *data;
1947 *flags |= SfMayBlock;
1948 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
1949 PRE_REG_READ5(int, "putpmsg",
1950 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1951 int, band, int, flags);
1952 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1953 data = (struct vki_pmsg_strbuf *)ARG3;
1954 if (ctrl && ctrl->len > 0)
1955 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
1956 if (data && data->len > 0)
1957 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
1958}
sewardj696c5512005-06-08 23:38:32 +00001959
1960PRE(sys_getitimer)
1961{
1962 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
1963 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
1964 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
1965}
sewardj696c5512005-06-08 23:38:32 +00001966POST(sys_getitimer)
1967{
1968 if (ARG2 != (Addr)NULL) {
1969 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
1970 }
1971}
1972
1973PRE(sys_setitimer)
1974{
1975 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
1976 PRE_REG_READ3(long, "setitimer",
1977 int, which,
1978 struct itimerval *, value, struct itimerval *, ovalue);
1979 if (ARG2 != (Addr)NULL)
1980 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
1981 if (ARG3 != (Addr)NULL)
1982 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
1983}
1984
1985POST(sys_setitimer)
1986{
1987 if (ARG3 != (Addr)NULL) {
1988 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
1989 }
1990}
1991
1992PRE(sys_chroot)
1993{
1994 PRINT("sys_chroot ( %p )", ARG1);
1995 PRE_REG_READ1(long, "chroot", const char *, path);
1996 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
1997}
sewardja8d8e232005-06-07 20:04:56 +00001998
1999PRE(sys_madvise)
jsgf855d93d2003-10-13 22:26:55 +00002000{
sewardja8d8e232005-06-07 20:04:56 +00002001 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002002 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00002003 PRE_REG_READ3(long, "madvise",
2004 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00002005}
2006
sewardja8d8e232005-06-07 20:04:56 +00002007PRE(sys_mremap)
jsgf855d93d2003-10-13 22:26:55 +00002008{
nethercote27ea8bc2004-07-10 17:21:14 +00002009 // Nb: this is different to the glibc version described in the man pages,
2010 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00002011 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
njn22cfccb2004-11-27 16:10:23 +00002012 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
nethercote06c7bd72004-11-14 19:11:56 +00002013 PRE_REG_READ5(unsigned long, "mremap",
2014 unsigned long, old_addr, unsigned long, old_size,
2015 unsigned long, new_size, unsigned long, flags,
2016 unsigned long, new_addr);
sewardja8d8e232005-06-07 20:04:56 +00002017 SET_STATUS_from_SysRes(
2018 mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
2019 );
jsgf855d93d2003-10-13 22:26:55 +00002020}
2021
sewardj8c9ea4e2005-06-08 10:46:56 +00002022PRE(sys_nice)
2023{
2024 PRINT("sys_nice ( %d )", ARG1);
2025 PRE_REG_READ1(long, "nice", int, inc);
2026}
sewardj78b50e42005-06-08 01:47:28 +00002027
2028PRE(sys_sched_getscheduler)
2029{
2030 PRINT("sys_sched_getscheduler ( %d )", ARG1);
2031 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
2032}
2033
2034PRE(sys_sched_setscheduler)
2035{
2036 PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
2037 PRE_REG_READ3(long, "sched_setscheduler",
2038 vki_pid_t, pid, int, policy, struct sched_param *, p);
2039 if (ARG3 != 0)
2040 PRE_MEM_READ( "sched_setscheduler(p)",
2041 ARG3, sizeof(struct vki_sched_param));
2042}
2043
sewardj696c5512005-06-08 23:38:32 +00002044PRE(sys_mlock)
2045{
2046 *flags |= SfMayBlock;
2047 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
2048 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
2049}
2050
2051PRE(sys_munlock)
2052{
2053 *flags |= SfMayBlock;
2054 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
2055 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
2056}
2057
2058PRE(sys_mlockall)
2059{
2060 *flags |= SfMayBlock;
2061 PRINT("sys_mlockall ( %x )", ARG1);
2062 PRE_REG_READ1(long, "mlockall", int, flags);
2063}
2064
2065PRE(sys_munlockall)
2066{
2067 *flags |= SfMayBlock;
2068 PRINT("sys_munlockall ( )");
2069 PRE_REG_READ0(long, "munlockall");
2070}
sewardj78b50e42005-06-08 01:47:28 +00002071
2072PRE(sys_sched_get_priority_max)
2073{
2074 PRINT("sched_get_priority_max ( %d )", ARG1);
2075 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
2076}
2077
2078PRE(sys_sched_get_priority_min)
2079{
2080 PRINT("sched_get_priority_min ( %d )", ARG1);
2081 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
2082}
2083
sewardj696c5512005-06-08 23:38:32 +00002084PRE(sys_setpriority)
2085{
2086 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
2087 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
2088}
2089
2090PRE(sys_getpriority)
2091{
2092 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
2093 PRE_REG_READ2(long, "getpriority", int, which, int, who);
2094}
2095
2096PRE(sys_setregid16)
2097{
2098 PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
2099 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2100}
2101
sewardje6d5e722005-06-10 10:27:55 +00002102// XXX: only for 32-bit archs
2103#if defined(VGP_x86_linux)
2104PRE(sys_pwrite64)
2105{
2106 *flags |= SfMayBlock;
2107 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
2108 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2109 PRE_REG_READ5(ssize_t, "pwrite64",
2110 unsigned int, fd, const char *, buf, vki_size_t, count,
2111 vki_u32, offset_low32, vki_u32, offset_high32);
2112 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
2113}
2114#endif
sewardj8c9ea4e2005-06-08 10:46:56 +00002115
2116PRE(sys_sync)
2117{
2118 *flags |= SfMayBlock;
2119 PRINT("sys_sync ( )");
2120 PRE_REG_READ0(long, "sync");
2121}
2122
sewardj696c5512005-06-08 23:38:32 +00002123PRE(sys_fstatfs)
2124{
2125 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
2126 PRE_REG_READ2(long, "fstatfs",
2127 unsigned int, fd, struct statfs *, buf);
2128 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
2129}
2130
2131POST(sys_fstatfs)
2132{
2133 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
2134}
2135
sewardje6d5e722005-06-10 10:27:55 +00002136PRE(sys_fstatfs64)
2137{
2138 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
2139 PRE_REG_READ3(long, "fstatfs64",
2140 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
2141 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
2142}
2143POST(sys_fstatfs64)
2144{
2145 POST_MEM_WRITE( ARG3, ARG2 );
2146}
sewardj696c5512005-06-08 23:38:32 +00002147
2148PRE(sys_getsid)
2149{
2150 PRINT("sys_getsid ( %d )", ARG1);
2151 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
2152}
2153
sewardje7aa4ae2005-06-09 12:43:42 +00002154// XXX: only for 32-bit archs
2155// XXX even more: this in fact gets used by amd64-linux. Someone
2156// should look into this properly.
2157PRE(sys_pread64)
2158{
2159 *flags |= SfMayBlock;
2160 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
2161 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2162 PRE_REG_READ5(ssize_t, "pread64",
2163 unsigned int, fd, char *, buf, vki_size_t, count,
2164 vki_u32, offset_low32, vki_u32, offset_high32);
2165 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
2166}
2167POST(sys_pread64)
2168{
2169 vg_assert(SUCCESS);
2170 if (RES > 0) {
2171 POST_MEM_WRITE( ARG2, RES );
2172 }
2173}
jsgf855d93d2003-10-13 22:26:55 +00002174
sewardja8d8e232005-06-07 20:04:56 +00002175PRE(sys_mknod)
jsgf855d93d2003-10-13 22:26:55 +00002176{
njn22cfccb2004-11-27 16:10:23 +00002177 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00002178 PRE_REG_READ3(long, "mknod",
2179 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00002180 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002181}
2182
sewardj696c5512005-06-08 23:38:32 +00002183PRE(sys_flock)
2184{
2185 *flags |= SfMayBlock;
2186 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
2187 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
2188}
2189
2190/* This surely isn't remotely generic -- move to linux-specifics? */
2191PRE(sys_init_module)
2192{
2193 *flags |= SfMayBlock;
2194 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
2195 PRE_REG_READ3(long, "init_module",
2196 void *, umod, unsigned long, len, const char *, uargs);
2197 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
2198 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
2199}
2200
sewardje6d5e722005-06-10 10:27:55 +00002201PRE(sys_capget)
2202{
2203 PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
2204 PRE_REG_READ2(long, "capget",
2205 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2206 PRE_MEM_READ( "capget(header)", ARG1,
2207 sizeof(struct __vki_user_cap_header_struct) );
2208 PRE_MEM_WRITE( "capget(data)", ARG2,
2209 sizeof(struct __vki_user_cap_data_struct) );
2210}
2211POST(sys_capget)
2212{
2213 if (ARG2 != (Addr)NULL)
2214 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2215}
2216
2217PRE(sys_capset)
2218{
2219 PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
2220 PRE_REG_READ2(long, "capset",
2221 vki_cap_user_header_t, header,
2222 const vki_cap_user_data_t, data);
2223 PRE_MEM_READ( "capset(header)",
2224 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2225 PRE_MEM_READ( "capset(data)",
2226 ARG2, sizeof(struct __vki_user_cap_data_struct) );
2227}
jsgf855d93d2003-10-13 22:26:55 +00002228
nethercotea81e9162004-02-12 14:34:14 +00002229// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00002230static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00002231{
2232 while (True) {
njnb249fd72004-11-29 14:24:57 +00002233 Addr a_deref;
2234 Addr* a_p = (Addr*)a;
2235 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2236 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00002237 if (0 == a_deref)
2238 break;
nethercoteef0c7662004-11-06 15:38:43 +00002239 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00002240 a += sizeof(char*);
2241 }
2242}
2243
njn7b85dd52005-06-12 17:26:29 +00002244static Bool i_am_the_only_thread ( void )
2245{
2246 Int c = VG_(count_living_threads)();
2247 vg_assert(c >= 1); /* stay sane */
2248 return c == 1;
2249}
2250
2251/* Wait until all other threads disappear. */
2252void VG_(reap_threads)(ThreadId self)
2253{
2254 while (!i_am_the_only_thread()) {
2255 /* Let other thread(s) run */
2256 VG_(vg_yield)();
2257 VG_(poll_signals)(self);
2258 }
2259 vg_assert(i_am_the_only_thread());
2260}
2261
nethercote7310afb2004-11-12 15:41:06 +00002262// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
2263// but it seems to work nonetheless...
sewardja8d8e232005-06-07 20:04:56 +00002264PRE(sys_execve)
jsgf855d93d2003-10-13 22:26:55 +00002265{
sewardja8d8e232005-06-07 20:04:56 +00002266 Char* path; /* path to executable */
2267 ThreadState* tst;
sewardjb5f6f512005-03-10 23:59:00 +00002268
njn22cfccb2004-11-27 16:10:23 +00002269 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00002270 PRE_REG_READ3(vki_off_t, "execve",
2271 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00002272 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
2273 if (ARG2 != 0)
2274 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
2275 if (ARG3 != 0)
2276 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00002277
sewardjb5f6f512005-03-10 23:59:00 +00002278 path = (Char *)ARG1;
2279
sewardja8d8e232005-06-07 20:04:56 +00002280 vg_assert(VG_(is_valid_tid)(tid));
2281 tst = VG_(get_ThreadState)(tid);
2282
fitzhardingee1c06d82003-10-30 07:21:44 +00002283 /* Erk. If the exec fails, then the following will have made a
2284 mess of things which makes it hard for us to continue. The
2285 right thing to do is piece everything together again in
2286 POST(execve), but that's hard work. Instead, we make an effort
2287 to check that the execve will work before actually calling
2288 exec. */
2289 {
2290 struct vki_stat st;
sewardja8d8e232005-06-07 20:04:56 +00002291 Int i = VG_(stat)((Char *)ARG1, &st);
fitzhardingee1c06d82003-10-30 07:21:44 +00002292
sewardja8d8e232005-06-07 20:04:56 +00002293 if (i == -1) {
2294 /* stat failed */
2295 SET_STATUS_Failure( VKI_EACCES/*really, we should copy stat's result*/ );
fitzhardingee1c06d82003-10-30 07:21:44 +00002296 return;
2297 }
thughes90efa302004-09-25 16:13:55 +00002298 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00002299 XXX do proper permissions check?
2300 */
thughes90efa302004-09-25 16:13:55 +00002301 if ((st.st_mode & 0100111) == 0100000) {
sewardja8d8e232005-06-07 20:04:56 +00002302 SET_STATUS_Failure( VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00002303 return;
2304 }
2305 }
2306
2307 /* Resistance is futile. Nuke all other threads. POSIX mandates
2308 this. (Really, nuke them all, since the new process will make
2309 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00002310 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
njn7b85dd52005-06-12 17:26:29 +00002311 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002312
sewardj1d887112005-05-30 21:44:08 +00002313 { // Remove the valgrind-specific stuff from the environment so the
njn16eeb4e2005-06-16 03:56:58 +00002314 // child doesn't get vg_preload_core.so, vg_preload_TOOL.so, etc.
2315 // This is done unconditionally, since if we are tracing the child,
sewardj1d887112005-05-30 21:44:08 +00002316 // stage1/2 will set up the appropriate client environment.
2317 Char** envp = (Char**)ARG3;
2318 if (envp != NULL) {
2319 VG_(env_remove_valgrind_env_stuff)( envp );
2320 }
fitzhardinge5408c062004-01-04 23:52:59 +00002321 }
2322
2323 if (VG_(clo_trace_children)) {
njn22cfccb2004-11-27 16:10:23 +00002324 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)ARG1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00002325
njn22cfccb2004-11-27 16:10:23 +00002326 // Set VALGRINDCLO and VALGRINDLIB in ARG3 (the environment)
2327 VG_(env_setenv)( (Char***)&ARG3, VALGRINDCLO, optvar);
2328 VG_(env_setenv)( (Char***)&ARG3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002329
njn22cfccb2004-11-27 16:10:23 +00002330 // Create executable name: "/proc/self/fd/<vgexecfd>", update ARG1
sewardj8e332792005-03-11 12:56:56 +00002331 path = VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00002332 }
2333
njnc1b01812005-06-17 22:19:06 +00002334 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)ARG1);
sewardj10759312005-05-30 23:52:47 +00002335
fitzhardinge98abfc72003-12-16 02:05:15 +00002336 if (0) {
2337 Char **cpp;
2338
njn22cfccb2004-11-27 16:10:23 +00002339 VG_(printf)("exec: %s\n", (Char *)ARG1);
2340 for(cpp = (Char **)ARG2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002341 VG_(printf)("argv: %s\n", *cpp);
njn22cfccb2004-11-27 16:10:23 +00002342 for(cpp = (Char **)ARG3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002343 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00002344 }
jsgf855d93d2003-10-13 22:26:55 +00002345
sewardjb5f6f512005-03-10 23:59:00 +00002346 /* restore the DATA rlimit for the child */
2347 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2348
2349 /*
2350 Set the signal state up for exec.
2351
2352 We need to set the real signal state to make sure the exec'd
2353 process gets SIG_IGN properly.
2354
2355 Also set our real sigmask to match the client's sigmask so that
2356 the exec'd child will get the right mask. First we need to
2357 clear out any pending signals so they they don't get delivered,
2358 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002359
2360 XXX This is a bug - the signals should remain pending, and be
2361 delivered to the new process after exec. There's also a
2362 race-condition, since if someone delivers us a signal between
2363 the sigprocmask and the execve, we'll still get the signal. Oh
2364 well.
2365 */
2366 {
nethercote73b526f2004-10-31 18:48:21 +00002367 vki_sigset_t allsigs;
2368 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002369 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002370 Int i;
2371
2372 for(i = 1; i < VG_(max_signal); i++) {
2373 struct vki_sigaction sa;
2374 VG_(do_sys_sigaction)(i, NULL, &sa);
2375 if (sa.ksa_handler == VKI_SIG_IGN)
2376 VG_(sigaction)(i, &sa, NULL);
2377 else {
2378 sa.ksa_handler = VKI_SIG_DFL;
2379 VG_(sigaction)(i, &sa, NULL);
2380 }
2381 }
2382
nethercote73b526f2004-10-31 18:48:21 +00002383 VG_(sigfillset)(&allsigs);
2384 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002385 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002386
nethercote73b526f2004-10-31 18:48:21 +00002387 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002388 }
2389
sewardja8d8e232005-06-07 20:04:56 +00002390 SET_STATUS_from_SysRes(
2391 VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3)
2392 );
fitzhardingeb50068f2004-02-24 23:42:55 +00002393
sewardjb5f6f512005-03-10 23:59:00 +00002394 /* If we got here, then the execve failed. We've already made too
2395 much of a mess of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00002396 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
sewardjb5f6f512005-03-10 23:59:00 +00002397 ARG1, ARG1, ARG2, ARG3, -RES);
2398 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2399 "execve() failing, so I'm dying.");
sewardja8d8e232005-06-07 20:04:56 +00002400 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
sewardjb5f6f512005-03-10 23:59:00 +00002401 "or work out how to recover.");
2402 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002403}
2404
sewardja8d8e232005-06-07 20:04:56 +00002405PRE(sys_access)
jsgf855d93d2003-10-13 22:26:55 +00002406{
njn22cfccb2004-11-27 16:10:23 +00002407 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002408 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002409 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002410}
2411
sewardja8d8e232005-06-07 20:04:56 +00002412PRE(sys_alarm)
jsgf855d93d2003-10-13 22:26:55 +00002413{
njn22cfccb2004-11-27 16:10:23 +00002414 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002415 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002416}
2417
sewardja8d8e232005-06-07 20:04:56 +00002418PRE(sys_brk)
jsgf855d93d2003-10-13 22:26:55 +00002419{
fitzhardinge98abfc72003-12-16 02:05:15 +00002420 Addr brk_limit = VG_(brk_limit);
sewardja8d8e232005-06-07 20:04:56 +00002421 Addr brk_new;
fitzhardinge98abfc72003-12-16 02:05:15 +00002422
jsgf855d93d2003-10-13 22:26:55 +00002423 /* libc says: int brk(void *end_data_segment);
2424 kernel says: void* brk(void* end_data_segment); (more or less)
2425
2426 libc returns 0 on success, and -1 (and sets errno) on failure.
2427 Nb: if you ask to shrink the dataseg end below what it
2428 currently is, that always succeeds, even if the dataseg end
2429 doesn't actually change (eg. brk(0)). Unless it seg faults.
2430
2431 Kernel returns the new dataseg end. If the brk() failed, this
2432 will be unchanged from the old one. That's why calling (kernel)
2433 brk(0) gives the current dataseg end (libc brk() just returns
2434 zero in that case).
2435
2436 Both will seg fault if you shrink it back into a text segment.
2437 */
njn22cfccb2004-11-27 16:10:23 +00002438 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002439 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002440
sewardja8d8e232005-06-07 20:04:56 +00002441 brk_new = do_brk(ARG1);
2442 SET_STATUS_Success( brk_new );
fitzhardinge98abfc72003-12-16 02:05:15 +00002443
sewardja8d8e232005-06-07 20:04:56 +00002444 if (brk_new == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002445 /* brk() succeeded */
sewardja8d8e232005-06-07 20:04:56 +00002446 if (brk_new < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002447 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002448 VG_TRACK( die_mem_brk, (Addr)ARG1,
2449 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002450 } else
sewardja8d8e232005-06-07 20:04:56 +00002451 if (brk_new > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002452 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002453 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002454 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002455 }
jsgf855d93d2003-10-13 22:26:55 +00002456 } else {
2457 /* brk() failed */
sewardja8d8e232005-06-07 20:04:56 +00002458 vg_assert(brk_limit == brk_new);
jsgf855d93d2003-10-13 22:26:55 +00002459 }
2460}
2461
sewardja8d8e232005-06-07 20:04:56 +00002462PRE(sys_chdir)
jsgf855d93d2003-10-13 22:26:55 +00002463{
njn22cfccb2004-11-27 16:10:23 +00002464 PRINT("sys_chdir ( %p )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002465 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002466 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002467}
2468
sewardja8d8e232005-06-07 20:04:56 +00002469PRE(sys_chmod)
jsgf855d93d2003-10-13 22:26:55 +00002470{
njn22cfccb2004-11-27 16:10:23 +00002471 PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002472 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002473 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002474}
2475
sewardje6d5e722005-06-10 10:27:55 +00002476PRE(sys_chown16)
2477{
2478 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2479 PRE_REG_READ3(long, "chown16",
2480 const char *, path,
2481 vki_old_uid_t, owner, vki_old_gid_t, group);
2482 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
2483}
2484
2485PRE(sys_chown)
2486{
2487 /* int chown(const char *path, uid_t owner, gid_t group); */
2488 PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2489 PRE_REG_READ3(long, "chown",
2490 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2491 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
2492}
2493
2494PRE(sys_lchown)
2495{
2496 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2497 PRE_REG_READ3(long, "lchown",
2498 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2499 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
2500}
nethercote2e1c37d2004-11-13 13:57:12 +00002501
sewardja8d8e232005-06-07 20:04:56 +00002502PRE(sys_close)
jsgf855d93d2003-10-13 22:26:55 +00002503{
njn22cfccb2004-11-27 16:10:23 +00002504 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002505 PRE_REG_READ1(long, "close", unsigned int, fd);
2506
nethercotef8548672004-06-21 12:42:35 +00002507 /* Detect and negate attempts by the client to close Valgrind's log fd */
sewardj7eb7c582005-06-23 01:02:53 +00002508 if (!ML_(fd_allowed)(ARG1, "close", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00002509 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002510}
2511
nethercote85a456f2004-11-16 17:31:56 +00002512POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002513{
njn22cfccb2004-11-27 16:10:23 +00002514 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002515}
jsgf855d93d2003-10-13 22:26:55 +00002516
sewardja8d8e232005-06-07 20:04:56 +00002517PRE(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002518{
njn22cfccb2004-11-27 16:10:23 +00002519 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002520 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002521}
2522
nethercote85a456f2004-11-16 17:31:56 +00002523POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002524{
sewardja8d8e232005-06-07 20:04:56 +00002525 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00002526 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002527 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002528 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002529 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002530 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002531 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002532 }
2533}
2534
sewardja8d8e232005-06-07 20:04:56 +00002535PRE(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002536{
njn22cfccb2004-11-27 16:10:23 +00002537 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002538 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
sewardj7eb7c582005-06-23 01:02:53 +00002539 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
sewardja8d8e232005-06-07 20:04:56 +00002540 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002541}
2542
nethercote85a456f2004-11-16 17:31:56 +00002543POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002544{
sewardja8d8e232005-06-07 20:04:56 +00002545 vg_assert(SUCCESS);
nethercote71f05f32004-11-12 18:49:27 +00002546 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002547 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002548}
2549
sewardj696c5512005-06-08 23:38:32 +00002550PRE(sys_fchdir)
2551{
2552 PRINT("sys_fchdir ( %d )", ARG1);
2553 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
2554}
2555
2556PRE(sys_fchown16)
2557{
2558 PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
2559 PRE_REG_READ3(long, "fchown16",
2560 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
2561}
2562
sewardje6d5e722005-06-10 10:27:55 +00002563PRE(sys_fchown)
2564{
2565 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
2566 PRE_REG_READ3(long, "fchown",
2567 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2568}
sewardj696c5512005-06-08 23:38:32 +00002569
2570PRE(sys_fchmod)
2571{
2572 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
2573 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
2574}
2575
2576PRE(sys_fcntl)
2577{
2578 switch (ARG2) {
2579 // These ones ignore ARG3.
2580 case VKI_F_GETFD:
2581 case VKI_F_GETFL:
2582 case VKI_F_GETOWN:
2583 case VKI_F_SETOWN:
2584 case VKI_F_GETSIG:
2585 case VKI_F_SETSIG:
2586 case VKI_F_GETLEASE:
2587 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2588 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
2589 break;
2590
2591 // These ones use ARG3 as "arg".
2592 case VKI_F_DUPFD:
2593 case VKI_F_SETFD:
2594 case VKI_F_SETFL:
2595 case VKI_F_SETLEASE:
2596 case VKI_F_NOTIFY:
2597 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2598 PRE_REG_READ3(long, "fcntl",
2599 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2600 break;
2601
2602 // These ones use ARG3 as "lock".
2603 case VKI_F_GETLK:
2604 case VKI_F_SETLK:
2605 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002606# if defined(VGP_x86_linux)
sewardj696c5512005-06-08 23:38:32 +00002607 case VKI_F_GETLK64:
2608 case VKI_F_SETLK64:
2609 case VKI_F_SETLKW64:
2610# else
2611# endif
2612 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2613 PRE_REG_READ3(long, "fcntl",
2614 unsigned int, fd, unsigned int, cmd,
2615 struct flock64 *, lock);
2616 break;
2617 }
2618
2619 if (ARG2 == VKI_F_SETLKW)
2620 *flags |= SfMayBlock;
2621}
2622
2623POST(sys_fcntl)
2624{
2625 vg_assert(SUCCESS);
2626 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002627 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
sewardj696c5512005-06-08 23:38:32 +00002628 VG_(close)(RES);
2629 SET_STATUS_Failure( VKI_EMFILE );
2630 } else {
2631 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002632 record_fd_open_named(tid, RES);
sewardj696c5512005-06-08 23:38:32 +00002633 }
2634 }
2635}
njncfb8ad52004-11-23 14:57:49 +00002636
nethercote06c7bd72004-11-14 19:11:56 +00002637// XXX: wrapper only suitable for 32-bit systems
sewardja8d8e232005-06-07 20:04:56 +00002638PRE(sys_fcntl64)
jsgf855d93d2003-10-13 22:26:55 +00002639{
njnc6168192004-11-29 13:54:10 +00002640 switch (ARG2) {
2641 // These ones ignore ARG3.
2642 case VKI_F_GETFD:
2643 case VKI_F_GETFL:
2644 case VKI_F_GETOWN:
2645 case VKI_F_SETOWN:
2646 case VKI_F_GETSIG:
2647 case VKI_F_SETSIG:
2648 case VKI_F_GETLEASE:
2649 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2650 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2651 break;
2652
2653 // These ones use ARG3 as "arg".
2654 case VKI_F_DUPFD:
2655 case VKI_F_SETFD:
2656 case VKI_F_SETFL:
2657 case VKI_F_SETLEASE:
2658 case VKI_F_NOTIFY:
2659 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2660 PRE_REG_READ3(long, "fcntl64",
2661 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2662 break;
2663
2664 // These ones use ARG3 as "lock".
2665 case VKI_F_GETLK:
2666 case VKI_F_SETLK:
2667 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002668# if defined(VGP_x86_linux)
njnc6168192004-11-29 13:54:10 +00002669 case VKI_F_GETLK64:
2670 case VKI_F_SETLK64:
2671 case VKI_F_SETLKW64:
sewardja8d8e232005-06-07 20:04:56 +00002672# endif
njnc6168192004-11-29 13:54:10 +00002673 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2674 PRE_REG_READ3(long, "fcntl64",
2675 unsigned int, fd, unsigned int, cmd,
2676 struct flock64 *, lock);
2677 break;
2678 }
njncfb8ad52004-11-23 14:57:49 +00002679
sewardje7aa4ae2005-06-09 12:43:42 +00002680# if defined(VGP_x86_linux)
2681 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2682 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002683# else
sewardje7aa4ae2005-06-09 12:43:42 +00002684 if (ARG2 == VKI_F_SETLKW)
2685 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002686# endif
rjwalshf5f536f2003-11-17 17:45:00 +00002687}
2688
nethercote85a456f2004-11-16 17:31:56 +00002689POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002690{
sewardja8d8e232005-06-07 20:04:56 +00002691 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002692 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002693 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002694 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002695 SET_STATUS_Failure( VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002696 } else {
2697 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002698 record_fd_open_named(tid, RES);
nethercote493dd182004-02-24 23:57:47 +00002699 }
2700 }
jsgf855d93d2003-10-13 22:26:55 +00002701}
2702
sewardj696c5512005-06-08 23:38:32 +00002703PRE(sys_newfstat)
2704{
2705 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
2706 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
2707 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
2708}
2709
2710POST(sys_newfstat)
2711{
2712 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
2713}
jsgf855d93d2003-10-13 22:26:55 +00002714
nethercote73b526f2004-10-31 18:48:21 +00002715static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002716
nethercote75a8c982004-11-11 19:03:34 +00002717// In Linux, the sys_fork() function varies across architectures, but we
2718// ignore the various args it gets, and so it looks arch-neutral. Hmm.
sewardja8d8e232005-06-07 20:04:56 +00002719PRE(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002720{
nethercote73b526f2004-10-31 18:48:21 +00002721 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002722
nethercote75a8c982004-11-11 19:03:34 +00002723 PRINT("sys_fork ( )");
2724 PRE_REG_READ0(long, "fork");
2725
jsgf855d93d2003-10-13 22:26:55 +00002726 /* Block all signals during fork, so that we can fix things up in
2727 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002728 VG_(sigfillset)(&mask);
2729 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002730
sewardja8d8e232005-06-07 20:04:56 +00002731 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
sewardjb5f6f512005-03-10 23:59:00 +00002732
sewardja8d8e232005-06-07 20:04:56 +00002733 if (SUCCESS && RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002734 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002735
2736 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002737 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardja8d8e232005-06-07 20:04:56 +00002738 }
2739 else
2740 if (SUCCESS && RES > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002741 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002742
jsgf855d93d2003-10-13 22:26:55 +00002743 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002744 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002745 }
2746}
2747
sewardj8c257322005-06-08 01:01:48 +00002748PRE(sys_ftruncate)
2749{
2750 *flags |= SfMayBlock;
2751 PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
2752 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
2753}
2754
sewardj696c5512005-06-08 23:38:32 +00002755PRE(sys_truncate)
2756{
2757 *flags |= SfMayBlock;
2758 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
2759 PRE_REG_READ2(long, "truncate",
2760 const char *, path, unsigned long, length);
2761 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
2762}
2763
sewardje6d5e722005-06-10 10:27:55 +00002764// XXX: this wrapper is only suitable for 32-bit platforms
2765#if defined(VGP_x86_linux)
2766PRE(sys_ftruncate64)
2767{
2768 *flags |= SfMayBlock;
2769 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
2770 PRE_REG_READ3(long, "ftruncate64",
2771 unsigned int, fd,
2772 vki_u32, length_low32, vki_u32, length_high32);
2773}
2774#endif
2775
2776// XXX: this wrapper is only suitable for 32-bit platforms
2777#if defined(VGP_x86_linux)
2778PRE(sys_truncate64)
2779{
2780 *flags |= SfMayBlock;
2781 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
2782 PRE_REG_READ3(long, "truncate64",
2783 const char *, path,
2784 vki_u32, length_low32, vki_u32, length_high32);
2785 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
2786}
2787#endif
sewardj78b50e42005-06-08 01:47:28 +00002788
2789PRE(sys_getdents)
2790{
2791 *flags |= SfMayBlock;
2792 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
2793 PRE_REG_READ3(long, "getdents",
2794 unsigned int, fd, struct linux_dirent *, dirp,
2795 unsigned int, count);
2796 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
2797}
2798
2799POST(sys_getdents)
2800{
2801 vg_assert(SUCCESS);
2802 if (RES > 0)
2803 POST_MEM_WRITE( ARG2, RES );
2804}
jsgf855d93d2003-10-13 22:26:55 +00002805
sewardja8d8e232005-06-07 20:04:56 +00002806PRE(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002807{
sewardj78b50e42005-06-08 01:47:28 +00002808 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002809 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002810 PRE_REG_READ3(long, "getdents64",
2811 unsigned int, fd, struct linux_dirent64 *, dirp,
2812 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002813 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002814}
2815
nethercote85a456f2004-11-16 17:31:56 +00002816POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002817{
sewardja8d8e232005-06-07 20:04:56 +00002818 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002819 if (RES > 0)
2820 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002821}
2822
sewardj696c5512005-06-08 23:38:32 +00002823PRE(sys_getgroups16)
2824{
2825 PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
2826 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2827 if (ARG1 > 0)
2828 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2829}
2830
2831POST(sys_getgroups16)
2832{
2833 vg_assert(SUCCESS);
2834 if (ARG1 > 0 && RES > 0)
2835 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2836}
sewardj78b50e42005-06-08 01:47:28 +00002837
2838PRE(sys_getgroups)
2839{
2840 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
2841 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
2842 if (ARG1 > 0)
2843 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
2844}
2845
2846POST(sys_getgroups)
2847{
2848 vg_assert(SUCCESS);
2849 if (ARG1 > 0 && RES > 0)
2850 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
2851}
nethercote686b5db2004-11-14 13:42:51 +00002852
sewardja8d8e232005-06-07 20:04:56 +00002853PRE(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002854{
nethercoteac866b92004-11-15 20:23:15 +00002855 // Note that the kernel version of getcwd() behaves quite differently to
2856 // the glibc one.
njn22cfccb2004-11-27 16:10:23 +00002857 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002858 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002859 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002860}
2861
nethercote85a456f2004-11-16 17:31:56 +00002862POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002863{
sewardja8d8e232005-06-07 20:04:56 +00002864 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002865 if (RES != (Addr)NULL)
2866 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002867}
2868
sewardja8d8e232005-06-07 20:04:56 +00002869PRE(sys_geteuid16)
jsgf855d93d2003-10-13 22:26:55 +00002870{
nethercote0df495a2004-11-11 16:38:21 +00002871 PRINT("sys_geteuid16 ( )");
2872 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002873}
2874
sewardja8d8e232005-06-07 20:04:56 +00002875PRE(sys_geteuid)
jsgf855d93d2003-10-13 22:26:55 +00002876{
nethercote0df495a2004-11-11 16:38:21 +00002877 PRINT("sys_geteuid ( )");
2878 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002879}
2880
sewardj696c5512005-06-08 23:38:32 +00002881PRE(sys_getegid16)
2882{
2883 PRINT("sys_getegid16 ( )");
2884 PRE_REG_READ0(long, "getegid16");
2885}
sewardj78b50e42005-06-08 01:47:28 +00002886
2887PRE(sys_getegid)
2888{
2889 PRINT("sys_getegid ( )");
2890 PRE_REG_READ0(long, "getegid");
2891}
2892
sewardj8c9ea4e2005-06-08 10:46:56 +00002893PRE(sys_getgid16)
2894{
2895 PRINT("sys_getgid16 ( )");
2896 PRE_REG_READ0(long, "getgid16");
2897}
sewardj78b50e42005-06-08 01:47:28 +00002898
2899PRE(sys_getgid)
2900{
2901 PRINT("sys_getgid ( )");
2902 PRE_REG_READ0(long, "getgid");
2903}
jsgf855d93d2003-10-13 22:26:55 +00002904
sewardja8d8e232005-06-07 20:04:56 +00002905PRE(sys_getpid)
jsgf855d93d2003-10-13 22:26:55 +00002906{
nethercote4e632c22004-11-09 16:45:33 +00002907 PRINT("sys_getpid ()");
2908 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002909}
2910
sewardj696c5512005-06-08 23:38:32 +00002911PRE(sys_getpgid)
2912{
2913 PRINT("sys_getpgid ( %d )", ARG1);
2914 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
2915}
sewardj78b50e42005-06-08 01:47:28 +00002916
2917PRE(sys_getpgrp)
2918{
2919 PRINT("sys_getpgrp ()");
2920 PRE_REG_READ0(long, "getpgrp");
2921}
jsgf855d93d2003-10-13 22:26:55 +00002922
sewardja8d8e232005-06-07 20:04:56 +00002923PRE(sys_getppid)
jsgf855d93d2003-10-13 22:26:55 +00002924{
nethercote4e632c22004-11-09 16:45:33 +00002925 PRINT("sys_getppid ()");
2926 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002927}
2928
njncf45fd42004-11-24 16:30:22 +00002929static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002930{
nethercote620154f2004-11-12 21:21:07 +00002931 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002932
nethercote620154f2004-11-12 21:21:07 +00002933 switch (a1) {
2934 case VKI_RLIMIT_NOFILE:
2935 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2936 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2937 break;
nethercote535f03b2004-02-15 15:32:51 +00002938
nethercote620154f2004-11-12 21:21:07 +00002939 case VKI_RLIMIT_DATA:
2940 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2941 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002942
nethercote620154f2004-11-12 21:21:07 +00002943 case VKI_RLIMIT_STACK:
2944 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2945 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002946 }
jsgf855d93d2003-10-13 22:26:55 +00002947}
2948
sewardj696c5512005-06-08 23:38:32 +00002949PRE(sys_old_getrlimit)
2950{
2951 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
2952 PRE_REG_READ2(long, "old_getrlimit",
2953 unsigned int, resource, struct rlimit *, rlim);
2954 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
2955}
2956
2957POST(sys_old_getrlimit)
2958{
2959 common_post_getrlimit(tid, ARG1, ARG2);
2960}
nethercote620154f2004-11-12 21:21:07 +00002961
sewardja8d8e232005-06-07 20:04:56 +00002962PRE(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002963{
njn22cfccb2004-11-27 16:10:23 +00002964 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002965 PRE_REG_READ2(long, "getrlimit",
2966 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002967 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002968}
2969
nethercote85a456f2004-11-16 17:31:56 +00002970POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002971{
njn22cfccb2004-11-27 16:10:23 +00002972 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002973}
jsgf855d93d2003-10-13 22:26:55 +00002974
sewardj696c5512005-06-08 23:38:32 +00002975PRE(sys_getrusage)
2976{
2977 /* int getrusage (int who, struct rusage *usage); */
2978 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
2979 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
2980 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
2981}
2982
2983POST(sys_getrusage)
2984{
2985 vg_assert(SUCCESS);
2986 if (RES == 0)
2987 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
2988}
jsgf855d93d2003-10-13 22:26:55 +00002989
sewardja8d8e232005-06-07 20:04:56 +00002990PRE(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002991{
njn22cfccb2004-11-27 16:10:23 +00002992 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002993 PRE_REG_READ2(long, "gettimeofday",
2994 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00002995 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
2996 if (ARG2 != 0)
2997 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002998}
2999
nethercote85a456f2004-11-16 17:31:56 +00003000POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003001{
sewardja8d8e232005-06-07 20:04:56 +00003002 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00003003 if (RES == 0) {
3004 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
3005 if (ARG2 != 0)
3006 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003007 }
3008}
3009
sewardj696c5512005-06-08 23:38:32 +00003010PRE(sys_settimeofday)
3011{
3012 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
3013 PRE_REG_READ2(long, "settimeofday",
3014 struct timeval *, tv, struct timezone *, tz);
3015 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3016 if (ARG2 != 0) {
3017 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3018 /* maybe should warn if tz->tz_dsttime is non-zero? */
3019 }
3020}
nethercote686b5db2004-11-14 13:42:51 +00003021
sewardja8d8e232005-06-07 20:04:56 +00003022PRE(sys_getuid16)
jsgf855d93d2003-10-13 22:26:55 +00003023{
nethercote0df495a2004-11-11 16:38:21 +00003024 PRINT("sys_getuid16 ( )");
3025 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00003026}
3027
sewardja8d8e232005-06-07 20:04:56 +00003028PRE(sys_getuid)
jsgf855d93d2003-10-13 22:26:55 +00003029{
nethercote0df495a2004-11-11 16:38:21 +00003030 PRINT("sys_getuid ( )");
3031 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00003032}
3033
nethercote2e1c37d2004-11-13 13:57:12 +00003034// XXX: I reckon some of these cases must be x86-specific
sewardja8d8e232005-06-07 20:04:56 +00003035PRE(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003036{
sewardja8d8e232005-06-07 20:04:56 +00003037 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00003038 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00003039 PRE_REG_READ3(long, "ioctl",
3040 unsigned int, fd, unsigned int, request, unsigned long, arg);
3041
njn22cfccb2004-11-27 16:10:23 +00003042 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003043 case VKI_TCSETS:
3044 case VKI_TCSETSW:
3045 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00003046 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003047 break;
nethercote73b526f2004-10-31 18:48:21 +00003048 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003049 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003050 break;
nethercote73b526f2004-10-31 18:48:21 +00003051 case VKI_TCSETA:
3052 case VKI_TCSETAW:
3053 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00003054 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003055 break;
nethercote73b526f2004-10-31 18:48:21 +00003056 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003057 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003058 break;
nethercote73b526f2004-10-31 18:48:21 +00003059 case VKI_TCSBRK:
3060 case VKI_TCXONC:
3061 case VKI_TCSBRKP:
3062 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003063 /* These just take an int by value */
3064 break;
nethercote73b526f2004-10-31 18:48:21 +00003065 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003066 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003067 break;
nethercote73b526f2004-10-31 18:48:21 +00003068 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003069 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003070 break;
nethercote73b526f2004-10-31 18:48:21 +00003071 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00003072 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003073 break;
nethercote73b526f2004-10-31 18:48:21 +00003074 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00003075 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003076 break;
nethercote73b526f2004-10-31 18:48:21 +00003077 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00003078 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003079 break;
nethercote73b526f2004-10-31 18:48:21 +00003080 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003081 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
3082 if (*(char *)ARG3 == 11) {
3083 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003084 }
3085 break;
nethercote73b526f2004-10-31 18:48:21 +00003086 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003087 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003088 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003089 break;
nethercote73b526f2004-10-31 18:48:21 +00003090 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003091 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003092 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003093 break;
nethercote73b526f2004-10-31 18:48:21 +00003094 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003095 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003096 break;
nethercote73b526f2004-10-31 18:48:21 +00003097 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003098 /* Just takes an int value. */
3099 break;
nethercote73b526f2004-10-31 18:48:21 +00003100 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00003101 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003102 break;
nethercote73b526f2004-10-31 18:48:21 +00003103 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00003104 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003105 break;
nethercote73b526f2004-10-31 18:48:21 +00003106 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00003107 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003108 break;
nethercote73b526f2004-10-31 18:48:21 +00003109 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003110 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003111 break;
3112
nethercote73b526f2004-10-31 18:48:21 +00003113 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00003114 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003115 break;
nethercote73b526f2004-10-31 18:48:21 +00003116 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003117 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00003118 break;
nethercote73b526f2004-10-31 18:48:21 +00003119 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003120 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00003121 break;
nethercote73b526f2004-10-31 18:48:21 +00003122 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003123 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003124 break;
nethercote73b526f2004-10-31 18:48:21 +00003125 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003126 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003127 break;
nethercote73b526f2004-10-31 18:48:21 +00003128 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003129 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003130 break;
nethercote73b526f2004-10-31 18:48:21 +00003131 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003132 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003133 break;
nethercote73b526f2004-10-31 18:48:21 +00003134 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00003135 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003136 break;
nethercote73b526f2004-10-31 18:48:21 +00003137 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00003138 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003139 break;
nethercote73b526f2004-10-31 18:48:21 +00003140 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00003141 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003142 break;
jsgf855d93d2003-10-13 22:26:55 +00003143
muellera4b153a2003-11-19 22:07:14 +00003144 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003145 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00003146 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003147 break;
muellera4b153a2003-11-19 22:07:14 +00003148 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003149 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00003150 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
3151 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
3152 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003153 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003154 break;
3155
3156 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003157 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00003158 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00003159 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3160 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003161 break;
nethercote73b526f2004-10-31 18:48:21 +00003162 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00003163 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003164 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3165 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003166 break;
nethercote73b526f2004-10-31 18:48:21 +00003167 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003168 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003169 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3170 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003171 break;
nethercote73b526f2004-10-31 18:48:21 +00003172 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003173 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003174 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3175 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003176 break;
nethercote73b526f2004-10-31 18:48:21 +00003177 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003178 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00003179 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3180 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003181 break;
nethercote73b526f2004-10-31 18:48:21 +00003182 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003183 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00003184 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3185 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003186 break;
nethercote73b526f2004-10-31 18:48:21 +00003187 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00003188 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003189 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3190 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003191 break;
nethercote73b526f2004-10-31 18:48:21 +00003192 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003193 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003194 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3195 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003196 break;
nethercote73b526f2004-10-31 18:48:21 +00003197 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003198 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003199 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3200 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003201 break;
nethercote73b526f2004-10-31 18:48:21 +00003202 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003203 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00003204 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3205 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003206 break;
nethercote73b526f2004-10-31 18:48:21 +00003207 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003208 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00003209 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3210 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003211 break;
nethercote73b526f2004-10-31 18:48:21 +00003212 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003213 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
njn22cfccb2004-11-27 16:10:23 +00003214 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3215 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
3216 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003217 break;
nethercote73b526f2004-10-31 18:48:21 +00003218 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003219 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00003220 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3221 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003222 break;
nethercote73b526f2004-10-31 18:48:21 +00003223 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003224 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003225 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003226 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003227 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3228 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003229 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003230 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3231 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
3232 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003233 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003234 break;
nethercote73b526f2004-10-31 18:48:21 +00003235 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003236 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003237 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3238 KERNEL_DO_SYSCALL(tid,RES);
3239 if (!VG_(is_kerror)(RES) && RES == 0)
3240 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003241 */
njn22cfccb2004-11-27 16:10:23 +00003242 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct vki_ifconf));
3243 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00003244 // TODO len must be readable and writable
3245 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00003246 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003247 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003248 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003249 }
3250 break;
nethercote73b526f2004-10-31 18:48:21 +00003251 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003252 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003253 break;
3254 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3255 the number of bytes currently in that socket's send buffer.
3256 It writes this value as an int to the memory location
3257 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003258 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003259 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003260 break;
nethercote73b526f2004-10-31 18:48:21 +00003261 case VKI_SIOCGRARP: /* get RARP table entry */
3262 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003263 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003264 break;
3265
nethercote73b526f2004-10-31 18:48:21 +00003266 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003267 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003268 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003269 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003270 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3271 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003272 break;
nethercote73b526f2004-10-31 18:48:21 +00003273 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003274 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003275 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003276 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003277 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3278 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003279 break;
nethercote73b526f2004-10-31 18:48:21 +00003280 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003281 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003282 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003283 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003284 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3285 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003286 break;
nethercote73b526f2004-10-31 18:48:21 +00003287 case VKI_SIOCSIFADDR: /* set PA address */
3288 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3289 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3290 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003291 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003292 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003293 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003294 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3295 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003296 break;
nethercote73b526f2004-10-31 18:48:21 +00003297 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003298 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003299 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003300 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003301 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3302 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003303 break;
nethercote73b526f2004-10-31 18:48:21 +00003304 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003305 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003306 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003307 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003308 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3309 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003310 break;
nethercote73b526f2004-10-31 18:48:21 +00003311 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003312 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003313 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003314 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003315 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3316 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003317 break;
nethercote73b526f2004-10-31 18:48:21 +00003318 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003319 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003320 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003321 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003322 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3323 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003324 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003325 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3326 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003327 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003328 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
3329 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003330 break;
jsgf855d93d2003-10-13 22:26:55 +00003331 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003332 case VKI_SIOCADDRT: /* add routing table entry */
3333 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00003334 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00003335 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003336 break;
3337
3338 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003339 case VKI_SIOCDRARP: /* delete RARP table entry */
3340 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003341 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003342 case VKI_SIOCSARP: /* set ARP table entry */
3343 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003344 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003345 break;
3346
nethercote73b526f2004-10-31 18:48:21 +00003347 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003348 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003349 break;
nethercote73b526f2004-10-31 18:48:21 +00003350 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003351 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardja8d8e232005-06-07 20:04:56 +00003352 //tst->sys_flags &= ~SfMayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003353 break;
3354
3355 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003356 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3357 case VKI_SNDCTL_SEQ_GETINCOUNT:
3358 case VKI_SNDCTL_SEQ_PERCMODE:
3359 case VKI_SNDCTL_SEQ_TESTMIDI:
3360 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3361 case VKI_SNDCTL_SEQ_NRSYNTHS:
3362 case VKI_SNDCTL_SEQ_NRMIDIS:
3363 case VKI_SNDCTL_SEQ_GETTIME:
3364 case VKI_SNDCTL_DSP_GETFMTS:
3365 case VKI_SNDCTL_DSP_GETTRIGGER:
3366 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003367 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003368 case VKI_SNDCTL_DSP_GETCAPS:
3369 case VKI_SOUND_PCM_READ_RATE:
3370 case VKI_SOUND_PCM_READ_CHANNELS:
3371 case VKI_SOUND_PCM_READ_BITS:
cerion85665ca2005-06-20 15:51:07 +00003372#if !defined(VGA_ppc32)
nethercote73b526f2004-10-31 18:48:21 +00003373 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00003374#endif
nethercote73b526f2004-10-31 18:48:21 +00003375 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003376 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003377 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003378 break;
nethercote73b526f2004-10-31 18:48:21 +00003379 case VKI_SNDCTL_SEQ_CTRLRATE:
3380 case VKI_SNDCTL_DSP_SPEED:
3381 case VKI_SNDCTL_DSP_STEREO:
3382 case VKI_SNDCTL_DSP_GETBLKSIZE:
3383 case VKI_SNDCTL_DSP_CHANNELS:
3384 case VKI_SOUND_PCM_WRITE_FILTER:
3385 case VKI_SNDCTL_DSP_SUBDIVIDE:
3386 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003387 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003388 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003389 case VKI_SNDCTL_TMR_TIMEBASE:
3390 case VKI_SNDCTL_TMR_TEMPO:
3391 case VKI_SNDCTL_TMR_SOURCE:
3392 case VKI_SNDCTL_MIDI_PRETIME:
3393 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003394 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003395 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003396 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003397 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003398 break;
nethercote73b526f2004-10-31 18:48:21 +00003399 case VKI_SNDCTL_DSP_GETOSPACE:
3400 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003401 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003402 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003403 break;
nethercote73b526f2004-10-31 18:48:21 +00003404 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003405 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003406 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003407 break;
3408
nethercote73b526f2004-10-31 18:48:21 +00003409 case VKI_SNDCTL_DSP_POST:
3410 case VKI_SNDCTL_DSP_RESET:
3411 case VKI_SNDCTL_DSP_SYNC:
3412 case VKI_SNDCTL_DSP_SETSYNCRO:
3413 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003414 break;
3415
3416 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003417 case VKI_RTC_UIE_ON:
3418 case VKI_RTC_UIE_OFF:
3419 case VKI_RTC_AIE_ON:
3420 case VKI_RTC_AIE_OFF:
3421 case VKI_RTC_PIE_ON:
3422 case VKI_RTC_PIE_OFF:
3423 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003424 break;
nethercote73b526f2004-10-31 18:48:21 +00003425 case VKI_RTC_RD_TIME:
3426 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003427 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003428 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003429 break;
nethercote73b526f2004-10-31 18:48:21 +00003430 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003431 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003432 break;
nethercote73b526f2004-10-31 18:48:21 +00003433 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003434 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003435 break;
jsgf855d93d2003-10-13 22:26:55 +00003436
nethercote95a97862004-11-06 16:31:43 +00003437 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003438 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003439 break;
jsgf855d93d2003-10-13 22:26:55 +00003440
thughesacbbc322004-06-19 12:12:01 +00003441 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003442 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003443 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003444 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003445 break;
3446
jsgf855d93d2003-10-13 22:26:55 +00003447 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003448 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003449 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003450 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003451 break;
nethercote73b526f2004-10-31 18:48:21 +00003452 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003453 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003454 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003455 break;
nethercote73b526f2004-10-31 18:48:21 +00003456 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003457 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003458 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3459 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3460 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003461 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003462 break;
nethercote73b526f2004-10-31 18:48:21 +00003463 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003464 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003465 break;
nethercote73b526f2004-10-31 18:48:21 +00003466 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003467 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003468 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003469 break;
nethercote73b526f2004-10-31 18:48:21 +00003470 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003471 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003472 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3473 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003474 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003475 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3476 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3477 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003478 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003479 break;
nethercote73b526f2004-10-31 18:48:21 +00003480 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003481 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003482 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003483 break;
nethercote73b526f2004-10-31 18:48:21 +00003484 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003485 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003486 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003487 break;
nethercote73b526f2004-10-31 18:48:21 +00003488 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003489 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003490 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003491 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003492 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003493 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003494 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3495 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003496 }
3497 break;
nethercote73b526f2004-10-31 18:48:21 +00003498 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003499 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003500 break;
3501 /* The following two are probably bogus (should check args
3502 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003503 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3504 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003505 break;
thughes66d80092004-06-19 12:41:05 +00003506
nethercote73b526f2004-10-31 18:48:21 +00003507 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003508 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003509 break;
nethercote73b526f2004-10-31 18:48:21 +00003510 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003511 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003512 break;
3513
nethercote73b526f2004-10-31 18:48:21 +00003514 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003515 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003516 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003517 break;
nethercote73b526f2004-10-31 18:48:21 +00003518 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003519 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003520 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003521 break;
jsgf855d93d2003-10-13 22:26:55 +00003522
nethercote73b526f2004-10-31 18:48:21 +00003523 case VKI_PPCLAIM:
3524 case VKI_PPEXCL:
3525 case VKI_PPYIELD:
3526 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003527 break;
nethercote73b526f2004-10-31 18:48:21 +00003528 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003529 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003530 break;
nethercote73b526f2004-10-31 18:48:21 +00003531 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003532 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003533 break;
nethercote73b526f2004-10-31 18:48:21 +00003534 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003535 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003536 break;
nethercote73b526f2004-10-31 18:48:21 +00003537 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003538 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003539 break;
nethercote73b526f2004-10-31 18:48:21 +00003540 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003541 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003542 break;
nethercote73b526f2004-10-31 18:48:21 +00003543 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003544 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003545 break;
nethercote73b526f2004-10-31 18:48:21 +00003546 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003547 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003548 break;
nethercote73b526f2004-10-31 18:48:21 +00003549 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003550 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003551 break;
nethercote73b526f2004-10-31 18:48:21 +00003552 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003553 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003554 break;
nethercote73b526f2004-10-31 18:48:21 +00003555 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003556 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003557 break;
nethercote73b526f2004-10-31 18:48:21 +00003558 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003559 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003560 break;
nethercote73b526f2004-10-31 18:48:21 +00003561 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003562 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003563 break;
nethercote73b526f2004-10-31 18:48:21 +00003564 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003565 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003566 break;
nethercote73b526f2004-10-31 18:48:21 +00003567 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003568 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003569 break;
nethercote73b526f2004-10-31 18:48:21 +00003570 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003571 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003572 break;
nethercote73b526f2004-10-31 18:48:21 +00003573 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003574 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003575 break;
nethercote73b526f2004-10-31 18:48:21 +00003576 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003577 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003578 break;
nethercote73b526f2004-10-31 18:48:21 +00003579 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003580 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003581 break;
nethercote73b526f2004-10-31 18:48:21 +00003582 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003583 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003584 break;
3585
thughesb3d3bcf2004-11-13 00:36:15 +00003586 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003587 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003588 break;
3589 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003590 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003591 break;
3592
3593 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003594 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3595 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003596 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003597 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003598 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3599 32 * cfd->charcount );
3600 }
3601 break;
3602 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003603 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3604 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003605 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003606 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003607 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3608 32 * cfd->charcount );
3609 }
3610 break;
3611
3612 case VKI_PIO_FONTRESET:
3613 break;
3614
3615 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003616 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003617 break;
3618 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003619 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003620 break;
3621
3622 case VKI_KIOCSOUND:
3623 case VKI_KDMKTONE:
3624 break;
3625
3626 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003627 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003628 break;
3629 case VKI_KDSETLED:
3630 break;
3631
3632 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003633 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003634 break;
3635
3636 case VKI_KDADDIO:
3637 case VKI_KDDELIO:
3638 case VKI_KDENABIO:
3639 case VKI_KDDISABIO:
3640 break;
3641
3642 case VKI_KDSETMODE:
3643 break;
3644 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003645 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003646 break;
3647
3648 case VKI_KDMAPDISP:
3649 case VKI_KDUNMAPDISP:
3650 break;
3651
3652 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003653 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003654 break;
3655 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003656 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003657 break;
3658 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003659 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003660 VKI_E_TABSZ * sizeof(unsigned short) );
3661 break;
3662 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003663 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003664 VKI_E_TABSZ * sizeof(unsigned short) );
3665 break;
3666
3667 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003668 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003669 break;
3670 case VKI_KDSKBMODE:
3671 break;
3672
3673 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003674 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003675 break;
3676 case VKI_KDSKBMETA:
3677 break;
3678
3679 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003680 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003681 break;
3682 case VKI_KDSKBLED:
3683 break;
3684
3685 case VKI_KDGKBENT:
3686 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003687 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3688 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003689 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003690 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3691 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003692 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003693 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3694 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003695 break;
3696 case VKI_KDSKBENT:
3697 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003698 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3699 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003700 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003701 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3702 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003703 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003704 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3705 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003706 break;
3707
3708 case VKI_KDGKBSENT:
3709 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003710 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3711 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003712 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003713 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3714 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003715 break;
3716 case VKI_KDSKBSENT:
3717 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003718 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3719 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003720 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003721 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003722 break;
3723
3724 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003725 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003726 break;
3727 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003728 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003729 break;
3730
3731 case VKI_KDGETKEYCODE:
3732 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003733 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3734 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003735 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003736 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3737 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003738 break;
3739 case VKI_KDSETKEYCODE:
3740 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003741 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3742 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003743 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003744 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3745 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003746 break;
3747
3748 case VKI_KDSIGACCEPT:
3749 break;
3750
3751 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003752 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003753 break;
3754
jsgf855d93d2003-10-13 22:26:55 +00003755 /* We don't have any specific information on it, so
3756 try to do something reasonable based on direction and
3757 size bits. The encoding scheme is described in
3758 /usr/include/asm/ioctl.h.
3759
3760 According to Simon Hausmann, _IOC_READ means the kernel
3761 writes a value to the ioctl value passed from the user
3762 space and the other way around with _IOC_WRITE. */
3763 default: {
njn22cfccb2004-11-27 16:10:23 +00003764 UInt dir = _VKI_IOC_DIR(ARG2);
3765 UInt size = _VKI_IOC_SIZE(ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003766 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3767 /*
3768 * Be very lax about ioctl handling; the only
3769 * assumption is that the size is correct. Doesn't
3770 * require the full buffer to be initialized when
3771 * writing. Without this, using some device
3772 * drivers with a large number of strange ioctl
3773 * commands becomes very tiresome.
3774 */
nethercote73b526f2004-10-31 18:48:21 +00003775 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003776 static Int moans = 3;
sewardj1fa7d2c2005-06-13 18:22:17 +00003777 if (moans > 0 && !VG_(clo_xml)) {
jsgf855d93d2003-10-13 22:26:55 +00003778 moans--;
3779 VG_(message)(Vg_UserMsg,
3780 "Warning: noted but unhandled ioctl 0x%x"
3781 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00003782 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003783 VG_(message)(Vg_UserMsg,
3784 " This could cause spurious value errors"
3785 " to appear.");
3786 VG_(message)(Vg_UserMsg,
3787 " See README_MISSING_SYSCALL_OR_IOCTL for "
3788 "guidance on writing a proper wrapper." );
3789 }
3790 } else {
nethercote73b526f2004-10-31 18:48:21 +00003791 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003792 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00003793 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003794 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003795 }
3796 break;
3797 }
3798 }
3799}
3800
nethercote85a456f2004-11-16 17:31:56 +00003801POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003802{
sewardja8d8e232005-06-07 20:04:56 +00003803 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00003804 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003805 case VKI_TCSETS:
3806 case VKI_TCSETSW:
3807 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003808 break;
nethercote73b526f2004-10-31 18:48:21 +00003809 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003810 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003811 break;
nethercote73b526f2004-10-31 18:48:21 +00003812 case VKI_TCSETA:
3813 case VKI_TCSETAW:
3814 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003815 break;
nethercote73b526f2004-10-31 18:48:21 +00003816 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003817 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003818 break;
nethercote73b526f2004-10-31 18:48:21 +00003819 case VKI_TCSBRK:
3820 case VKI_TCXONC:
3821 case VKI_TCSBRKP:
3822 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003823 break;
nethercote73b526f2004-10-31 18:48:21 +00003824 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003825 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003826 break;
nethercote73b526f2004-10-31 18:48:21 +00003827 case VKI_TIOCSWINSZ:
3828 case VKI_TIOCMBIS:
3829 case VKI_TIOCMBIC:
3830 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003831 break;
nethercote73b526f2004-10-31 18:48:21 +00003832 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003833 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003834 break;
nethercote73b526f2004-10-31 18:48:21 +00003835 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003836 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003837 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003838 break;
nethercote73b526f2004-10-31 18:48:21 +00003839 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003840 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003841 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003842 break;
nethercote73b526f2004-10-31 18:48:21 +00003843 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003844 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003845 break;
nethercote73b526f2004-10-31 18:48:21 +00003846 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003847 break;
nethercote73b526f2004-10-31 18:48:21 +00003848 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003849 break;
nethercote73b526f2004-10-31 18:48:21 +00003850 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003851 break;
nethercote73b526f2004-10-31 18:48:21 +00003852 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003853 break;
nethercote73b526f2004-10-31 18:48:21 +00003854 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003855 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003856 break;
3857
nethercote73b526f2004-10-31 18:48:21 +00003858 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003859 break;
nethercote73b526f2004-10-31 18:48:21 +00003860 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003861 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003862 break;
nethercote73b526f2004-10-31 18:48:21 +00003863 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003864 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003865 break;
nethercote73b526f2004-10-31 18:48:21 +00003866 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003867 break;
nethercote73b526f2004-10-31 18:48:21 +00003868 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003869 break;
nethercote73b526f2004-10-31 18:48:21 +00003870 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003871 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003872 break;
nethercote73b526f2004-10-31 18:48:21 +00003873 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003874 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003875 break;
nethercote73b526f2004-10-31 18:48:21 +00003876 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003877 break;
nethercote73b526f2004-10-31 18:48:21 +00003878 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00003879 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003880 break;
nethercote73b526f2004-10-31 18:48:21 +00003881 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00003882 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003883 break;
jsgf855d93d2003-10-13 22:26:55 +00003884
muellera4b153a2003-11-19 22:07:14 +00003885 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003886 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003887 break;
muellera4b153a2003-11-19 22:07:14 +00003888 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00003889 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003890 break;
3891
3892 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003893 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00003894 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3895 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003896 break;
nethercote73b526f2004-10-31 18:48:21 +00003897 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00003898 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3899 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003900 break;
nethercote73b526f2004-10-31 18:48:21 +00003901 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00003902 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3903 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003904 break;
nethercote73b526f2004-10-31 18:48:21 +00003905 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00003906 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3907 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003908 break;
nethercote73b526f2004-10-31 18:48:21 +00003909 case VKI_SIOCGIFADDR: /* get PA address */
3910 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3911 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3912 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003913 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003914 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3915 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003916 break;
nethercote73b526f2004-10-31 18:48:21 +00003917 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003918 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003919 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3920 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003921 break;
nethercote73b526f2004-10-31 18:48:21 +00003922 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003923 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003924 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3925 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003926 break;
3927 break;
nethercote73b526f2004-10-31 18:48:21 +00003928 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003929 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003930 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3931 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003932 break;
nethercote73b526f2004-10-31 18:48:21 +00003933 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003934 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003935 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
3936 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003937 break;
nethercote73b526f2004-10-31 18:48:21 +00003938 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003939 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003940 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3941 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003942 break;
nethercote73b526f2004-10-31 18:48:21 +00003943 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003944 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003945 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
3946 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003947 break;
nethercote73b526f2004-10-31 18:48:21 +00003948 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003949 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003950 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3951 KERNEL_DO_SYSCALL(tid,RES);
3952 if (!VG_(is_kerror)(RES) && RES == 0)
3953 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003954 */
njn22cfccb2004-11-27 16:10:23 +00003955 if (RES == 0 && ARG3 ) {
3956 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00003957 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003958 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003959 }
3960 break;
nethercote73b526f2004-10-31 18:48:21 +00003961 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003962 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003963 break;
3964 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3965 the number of bytes currently in that socket's send buffer.
3966 It writes this value as an int to the memory location
3967 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003968 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003969 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003970 break;
nethercote73b526f2004-10-31 18:48:21 +00003971 case VKI_SIOCGRARP: /* get RARP table entry */
3972 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003973 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003974 break;
3975
nethercote73b526f2004-10-31 18:48:21 +00003976 case VKI_SIOCSIFFLAGS: /* set flags */
3977 case VKI_SIOCSIFMAP: /* Set device parameters */
3978 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3979 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3980 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3981 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3982 case VKI_SIOCSIFMETRIC: /* set metric */
3983 case VKI_SIOCSIFADDR: /* set PA address */
3984 case VKI_SIOCSIFMTU: /* set MTU size */
3985 case VKI_SIOCSIFHWADDR: /* set hardware address */
3986 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003987 break;
3988 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003989 case VKI_SIOCADDRT: /* add routing table entry */
3990 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003991 break;
3992
3993 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003994 case VKI_SIOCDRARP: /* delete RARP table entry */
3995 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003996 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003997 case VKI_SIOCSARP: /* set ARP table entry */
3998 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003999 break;
4000
nethercote73b526f2004-10-31 18:48:21 +00004001 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00004002 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00004003 break;
nethercote73b526f2004-10-31 18:48:21 +00004004 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004005 break;
4006
4007 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00004008 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4009 case VKI_SNDCTL_SEQ_GETINCOUNT:
4010 case VKI_SNDCTL_SEQ_PERCMODE:
4011 case VKI_SNDCTL_SEQ_TESTMIDI:
4012 case VKI_SNDCTL_SEQ_RESETSAMPLES:
4013 case VKI_SNDCTL_SEQ_NRSYNTHS:
4014 case VKI_SNDCTL_SEQ_NRMIDIS:
4015 case VKI_SNDCTL_SEQ_GETTIME:
4016 case VKI_SNDCTL_DSP_GETFMTS:
4017 case VKI_SNDCTL_DSP_GETTRIGGER:
4018 case VKI_SNDCTL_DSP_GETODELAY:
4019 case VKI_SNDCTL_DSP_GETSPDIF:
4020 case VKI_SNDCTL_DSP_GETCAPS:
4021 case VKI_SOUND_PCM_READ_RATE:
4022 case VKI_SOUND_PCM_READ_CHANNELS:
4023 case VKI_SOUND_PCM_READ_BITS:
cerion85665ca2005-06-20 15:51:07 +00004024#if !defined(VGA_ppc32)
nethercote73b526f2004-10-31 18:48:21 +00004025 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00004026#endif
nethercote73b526f2004-10-31 18:48:21 +00004027 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00004028 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004029 break;
nethercote73b526f2004-10-31 18:48:21 +00004030 case VKI_SNDCTL_SEQ_CTRLRATE:
4031 case VKI_SNDCTL_DSP_SPEED:
4032 case VKI_SNDCTL_DSP_STEREO:
4033 case VKI_SNDCTL_DSP_GETBLKSIZE:
4034 case VKI_SNDCTL_DSP_CHANNELS:
4035 case VKI_SOUND_PCM_WRITE_FILTER:
4036 case VKI_SNDCTL_DSP_SUBDIVIDE:
4037 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00004038 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00004039 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00004040 case VKI_SNDCTL_TMR_TIMEBASE:
4041 case VKI_SNDCTL_TMR_TEMPO:
4042 case VKI_SNDCTL_TMR_SOURCE:
4043 case VKI_SNDCTL_MIDI_PRETIME:
4044 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00004045 break;
nethercote73b526f2004-10-31 18:48:21 +00004046 case VKI_SNDCTL_DSP_GETOSPACE:
4047 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00004048 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00004049 break;
nethercote73b526f2004-10-31 18:48:21 +00004050 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00004051 break;
4052
nethercote73b526f2004-10-31 18:48:21 +00004053 case VKI_SNDCTL_DSP_POST:
4054 case VKI_SNDCTL_DSP_RESET:
4055 case VKI_SNDCTL_DSP_SYNC:
4056 case VKI_SNDCTL_DSP_SETSYNCRO:
4057 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00004058 break;
4059
4060 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00004061 case VKI_RTC_UIE_ON:
4062 case VKI_RTC_UIE_OFF:
4063 case VKI_RTC_AIE_ON:
4064 case VKI_RTC_AIE_OFF:
4065 case VKI_RTC_PIE_ON:
4066 case VKI_RTC_PIE_OFF:
4067 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00004068 break;
nethercote73b526f2004-10-31 18:48:21 +00004069 case VKI_RTC_RD_TIME:
4070 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00004071 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00004072 break;
nethercote73b526f2004-10-31 18:48:21 +00004073 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00004074 break;
nethercote73b526f2004-10-31 18:48:21 +00004075 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00004076 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004077 break;
jsgf855d93d2003-10-13 22:26:55 +00004078
nethercote95a97862004-11-06 16:31:43 +00004079 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00004080 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004081 break;
jsgf855d93d2003-10-13 22:26:55 +00004082
thughesacbbc322004-06-19 12:12:01 +00004083 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00004084 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00004085 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00004086 break;
4087
jsgf855d93d2003-10-13 22:26:55 +00004088 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00004089 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00004090 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00004091 break;
nethercote73b526f2004-10-31 18:48:21 +00004092 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00004093 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004094 break;
nethercote73b526f2004-10-31 18:48:21 +00004095 case VKI_CDROMREADTOCENTRY:
njn22cfccb2004-11-27 16:10:23 +00004096 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004097 break;
nethercote73b526f2004-10-31 18:48:21 +00004098 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00004099 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00004100 break;
nethercote73b526f2004-10-31 18:48:21 +00004101 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00004102 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00004103 break;
nethercote73b526f2004-10-31 18:48:21 +00004104 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00004105 {
njn22cfccb2004-11-27 16:10:23 +00004106 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00004107 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00004108 break;
4109 }
4110
nethercote73b526f2004-10-31 18:48:21 +00004111 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00004112 break;
4113 /* The following two are probably bogus (should check args
4114 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00004115 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4116 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00004117 break;
4118
nethercote73b526f2004-10-31 18:48:21 +00004119 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00004120 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004121 break;
nethercote73b526f2004-10-31 18:48:21 +00004122 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00004123 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004124 break;
4125
nethercote73b526f2004-10-31 18:48:21 +00004126 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00004127 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004128 break;
nethercote73b526f2004-10-31 18:48:21 +00004129 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00004130 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004131 break;
4132
nethercote73b526f2004-10-31 18:48:21 +00004133 case VKI_PPCLAIM:
4134 case VKI_PPEXCL:
4135 case VKI_PPYIELD:
4136 case VKI_PPRELEASE:
4137 case VKI_PPSETMODE:
4138 case VKI_PPSETPHASE:
4139 case VKI_PPSETFLAGS:
4140 case VKI_PPWDATA:
4141 case VKI_PPWCONTROL:
4142 case VKI_PPFCONTROL:
4143 case VKI_PPDATADIR:
4144 case VKI_PPNEGOT:
4145 case VKI_PPWCTLONIRQ:
4146 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00004147 break;
nethercote73b526f2004-10-31 18:48:21 +00004148 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004149 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004150 break;
nethercote73b526f2004-10-31 18:48:21 +00004151 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00004152 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004153 break;
nethercote73b526f2004-10-31 18:48:21 +00004154 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00004155 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00004156 break;
nethercote73b526f2004-10-31 18:48:21 +00004157 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00004158 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004159 break;
nethercote73b526f2004-10-31 18:48:21 +00004160 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00004161 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004162 break;
nethercote73b526f2004-10-31 18:48:21 +00004163 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00004164 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004165 break;
nethercote73b526f2004-10-31 18:48:21 +00004166 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00004167 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004168 break;
nethercote73b526f2004-10-31 18:48:21 +00004169 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00004170 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004171 break;
nethercote73b526f2004-10-31 18:48:21 +00004172 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00004173 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00004174 break;
4175
thughesc3b842d2004-11-13 10:38:04 +00004176 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00004177 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00004178 break;
4179 case VKI_PIO_FONT:
4180 break;
4181
4182 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00004183 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
4184 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00004185 break;
4186 case VKI_PIO_FONTX:
4187 break;
4188
4189 case VKI_PIO_FONTRESET:
4190 break;
4191
4192 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00004193 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00004194 break;
4195 case VKI_PIO_CMAP:
4196 break;
4197
4198 case VKI_KIOCSOUND:
4199 case VKI_KDMKTONE:
4200 break;
4201
4202 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00004203 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004204 break;
4205 case VKI_KDSETLED:
4206 break;
4207
4208 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00004209 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004210 break;
4211
4212 case VKI_KDADDIO:
4213 case VKI_KDDELIO:
4214 case VKI_KDENABIO:
4215 case VKI_KDDISABIO:
4216 break;
4217
4218 case VKI_KDSETMODE:
4219 break;
4220 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004221 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004222 break;
4223
4224 case VKI_KDMAPDISP:
4225 case VKI_KDUNMAPDISP:
4226 break;
4227
4228 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004229 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00004230 break;
4231 case VKI_PIO_SCRNMAP:
4232 break;
4233 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004234 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00004235 break;
4236 case VKI_PIO_UNISCRNMAP:
4237 break;
4238
4239 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00004240 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004241 break;
4242 case VKI_KDSKBMODE:
4243 break;
4244
4245 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00004246 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004247 break;
4248 case VKI_KDSKBMETA:
4249 break;
4250
4251 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00004252 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004253 break;
4254 case VKI_KDSKBLED:
4255 break;
4256
4257 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00004258 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
4259 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00004260 break;
4261 case VKI_KDSKBENT:
4262 break;
4263
4264 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00004265 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
4266 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00004267 break;
4268 case VKI_KDSKBSENT:
4269 break;
4270
4271 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00004272 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00004273 break;
4274 case VKI_KDSKBDIACR:
4275 break;
4276
4277 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00004278 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
4279 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00004280 break;
4281 case VKI_KDSETKEYCODE:
4282 break;
4283
4284 case VKI_KDSIGACCEPT:
4285 break;
4286
4287 case VKI_KDKBDREP:
4288 break;
4289
jsgf855d93d2003-10-13 22:26:55 +00004290 /* We don't have any specific information on it, so
4291 try to do something reasonable based on direction and
4292 size bits. The encoding scheme is described in
4293 /usr/include/asm/ioctl.h.
4294
4295 According to Simon Hausmann, _IOC_READ means the kernel
4296 writes a value to the ioctl value passed from the user
4297 space and the other way around with _IOC_WRITE. */
4298 default: {
njn22cfccb2004-11-27 16:10:23 +00004299 UInt dir = _VKI_IOC_DIR(ARG2);
4300 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00004301 if (size > 0 && (dir & _VKI_IOC_READ)
sewardja8d8e232005-06-07 20:04:56 +00004302 && RES == 0
njn22cfccb2004-11-27 16:10:23 +00004303 && ARG3 != (Addr)NULL)
4304 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004305 break;
4306 }
4307 }
4308}
4309
njn03f1e582005-03-26 20:08:06 +00004310/*
4311 If we're sending a SIGKILL to one of our own threads, then simulate
4312 it rather than really sending the signal, so that the target thread
4313 gets a chance to clean up. Returns True if we did the killing (or
4314 no killing is necessary), and False if the caller should use the
4315 normal kill syscall.
4316
4317 "pid" is any pid argument which can be passed to kill; group kills
4318 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4319 they'll most likely hit all the threads and we won't need to worry
4320 about cleanup. In truth, we can't fully emulate these multicast
4321 kills.
4322
4323 "tgid" is a thread group id. If it is not -1, then the target
4324 thread must be in that thread group.
4325 */
sewardj7eb7c582005-06-23 01:02:53 +00004326Bool ML_(do_sigkill)(Int pid, Int tgid)
njn03f1e582005-03-26 20:08:06 +00004327{
4328 ThreadState *tst;
4329 ThreadId tid;
4330
4331 if (pid <= 0)
4332 return False;
4333
4334 tid = VG_(get_lwp_tid)(pid);
4335 if (tid == VG_INVALID_THREADID)
4336 return False; /* none of our threads */
4337
4338 tst = VG_(get_ThreadState)(tid);
4339 if (tst == NULL || tst->status == VgTs_Empty)
4340 return False; /* hm, shouldn't happen */
4341
4342 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4343 return False; /* not the right thread group */
4344
4345 /* Check to see that the target isn't already exiting. */
4346 if (!VG_(is_exiting)(tid)) {
4347 if (VG_(clo_trace_signals))
sewardja8d8e232005-06-07 20:04:56 +00004348 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL",
4349 tst->tid);
njn03f1e582005-03-26 20:08:06 +00004350
4351 tst->exitreason = VgSrc_FatalSig;
4352 tst->os_state.fatalsig = VKI_SIGKILL;
4353
4354 if (!VG_(is_running_thread)(tid))
4355 VG_(kill_thread)(tid);
4356 }
4357
4358 return True;
4359}
4360
sewardja8d8e232005-06-07 20:04:56 +00004361PRE(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004362{
4363 /* int kill(pid_t pid, int sig); */
njn22cfccb2004-11-27 16:10:23 +00004364 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004365 PRE_REG_READ2(long, "kill", int, pid, int, sig);
sewardj7eb7c582005-06-23 01:02:53 +00004366 if (!ML_(client_signal_OK)(ARG2)) {
sewardja8d8e232005-06-07 20:04:56 +00004367 SET_STATUS_Failure( VKI_EINVAL );
njn03f1e582005-03-26 20:08:06 +00004368 return;
4369 }
jsgf855d93d2003-10-13 22:26:55 +00004370
njn03f1e582005-03-26 20:08:06 +00004371 /* If we're sending SIGKILL, check to see if the target is one of
4372 our threads and handle it specially. */
sewardj7eb7c582005-06-23 01:02:53 +00004373 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
sewardja8d8e232005-06-07 20:04:56 +00004374 SET_STATUS_Success(0);
njn03f1e582005-03-26 20:08:06 +00004375 else
sewardja8d8e232005-06-07 20:04:56 +00004376 SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
njn03f1e582005-03-26 20:08:06 +00004377
sewardjb5f6f512005-03-10 23:59:00 +00004378 if (VG_(clo_trace_signals))
4379 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
njn03f1e582005-03-26 20:08:06 +00004380 ARG2, ARG1);
sewardja8d8e232005-06-07 20:04:56 +00004381
4382 /* This kill might have given us a pending signal. Ask for a check once
4383 the syscall is done. */
4384 *flags |= SfPollAfter;
jsgf855d93d2003-10-13 22:26:55 +00004385}
4386
sewardja8d8e232005-06-07 20:04:56 +00004387PRE(sys_link)
jsgf855d93d2003-10-13 22:26:55 +00004388{
sewardja8d8e232005-06-07 20:04:56 +00004389 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004390 PRINT("sys_link ( %p, %p)", ARG1, ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004391 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004392 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4393 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004394}
4395
sewardja8d8e232005-06-07 20:04:56 +00004396PRE(sys_lseek)
jsgf855d93d2003-10-13 22:26:55 +00004397{
njn22cfccb2004-11-27 16:10:23 +00004398 PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00004399 PRE_REG_READ3(vki_off_t, "lseek",
4400 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004401}
4402
sewardj696c5512005-06-08 23:38:32 +00004403PRE(sys_newlstat)
4404{
4405 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
4406 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4407 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4408 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4409}
4410
4411POST(sys_newlstat)
4412{
4413 vg_assert(SUCCESS);
4414 if (RES == 0) {
4415 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4416 }
4417}
jsgf855d93d2003-10-13 22:26:55 +00004418
sewardja8d8e232005-06-07 20:04:56 +00004419PRE(sys_mkdir)
jsgf855d93d2003-10-13 22:26:55 +00004420{
sewardja8d8e232005-06-07 20:04:56 +00004421 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004422 PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004423 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004424 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004425}
4426
sewardja8d8e232005-06-07 20:04:56 +00004427PRE(sys_mmap2)
jsgf855d93d2003-10-13 22:26:55 +00004428{
sewardja8d8e232005-06-07 20:04:56 +00004429 // Exactly like old_mmap() in x86-linux except:
nethercote3d5e9102004-11-17 18:22:38 +00004430 // - all 6 args are passed in regs, rather than in a memory-block.
4431 // - the file offset is specified in pagesize units rather than bytes,
4432 // so that it can be used for files bigger than 2^32 bytes.
4433 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
njn22cfccb2004-11-27 16:10:23 +00004434 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
nethercote3d5e9102004-11-17 18:22:38 +00004435 PRE_REG_READ6(long, "mmap2",
4436 unsigned long, start, unsigned long, length,
4437 unsigned long, prot, unsigned long, flags,
4438 unsigned long, fd, unsigned long, offset);
4439
sewardjb5f6f512005-03-10 23:59:00 +00004440 if (ARG2 == 0) {
4441 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4442 shall be established. */
sewardja8d8e232005-06-07 20:04:56 +00004443 SET_STATUS_Failure( VKI_EINVAL );
sewardjb5f6f512005-03-10 23:59:00 +00004444 return;
4445 }
4446
sewardj565b1ed2005-03-11 14:12:38 +00004447 if (/*(ARG4 & VKI_MAP_FIXED) && */ (0 != (ARG1 & (VKI_PAGE_SIZE-1)))) {
4448 /* zap any misaligned addresses. */
sewardjd0d97312005-03-23 02:53:13 +00004449 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
4450 to fail. Here, we catch them all. */
sewardja8d8e232005-06-07 20:04:56 +00004451 SET_STATUS_Failure( VKI_EINVAL );
sewardj565b1ed2005-03-11 14:12:38 +00004452 return;
4453 }
4454
njn22cfccb2004-11-27 16:10:23 +00004455 if (ARG4 & VKI_MAP_FIXED) {
sewardj7eb7c582005-06-23 01:02:53 +00004456 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
sewardja8d8e232005-06-07 20:04:56 +00004457 SET_STATUS_Failure( VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004458 } else {
sewardjd0d97312005-03-23 02:53:13 +00004459 Addr a = VG_(find_map_space)(ARG1, ARG2, True);
4460 if (a == 0 && ARG1 != 0)
4461 ARG1 = VG_(find_map_space)(0, ARG2, True);
4462 else
4463 ARG1 = a;
njn22cfccb2004-11-27 16:10:23 +00004464 if (ARG1 == 0)
sewardja8d8e232005-06-07 20:04:56 +00004465 SET_STATUS_Failure( VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004466 else
njn22cfccb2004-11-27 16:10:23 +00004467 ARG4 |= VKI_MAP_FIXED;
nethercote3d5e9102004-11-17 18:22:38 +00004468 }
4469}
4470
4471POST(sys_mmap2)
4472{
sewardja8d8e232005-06-07 20:04:56 +00004473 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004474 vg_assert(ML_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
4475 ML_(mmap_segment)( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
sewardja8d8e232005-06-07 20:04:56 +00004476 ARG6 * (ULong)VKI_PAGE_SIZE );
nethercote3d5e9102004-11-17 18:22:38 +00004477}
4478
sewardja8d8e232005-06-07 20:04:56 +00004479PRE(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004480{
njn22cfccb2004-11-27 16:10:23 +00004481 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004482 PRE_REG_READ3(long, "mprotect",
4483 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004484
sewardj7eb7c582005-06-23 01:02:53 +00004485 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
sewardja8d8e232005-06-07 20:04:56 +00004486 SET_STATUS_Failure( VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004487}
4488
nethercote85a456f2004-11-16 17:31:56 +00004489POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004490{
njn22cfccb2004-11-27 16:10:23 +00004491 Addr a = ARG1;
4492 SizeT len = ARG2;
4493 Int prot = ARG3;
nethercote27ea8bc2004-07-10 17:21:14 +00004494 Bool rr = prot & VKI_PROT_READ;
4495 Bool ww = prot & VKI_PROT_WRITE;
4496 Bool xx = prot & VKI_PROT_EXEC;
4497
nethercote27ea8bc2004-07-10 17:21:14 +00004498 mash_addr_and_len(&a, &len);
4499 VG_(mprotect_range)(a, len, prot);
4500 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004501}
4502
sewardja8d8e232005-06-07 20:04:56 +00004503PRE(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004504{
sewardja8d8e232005-06-07 20:04:56 +00004505 if (0) VG_(printf)(" munmap( %p )\n", ARG1);
njn22cfccb2004-11-27 16:10:23 +00004506 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004507 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004508
sewardj7eb7c582005-06-23 01:02:53 +00004509 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
sewardja8d8e232005-06-07 20:04:56 +00004510 SET_STATUS_Failure( VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004511}
4512
nethercote85a456f2004-11-16 17:31:56 +00004513POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004514{
njn22cfccb2004-11-27 16:10:23 +00004515 Addr a = ARG1;
4516 SizeT len = ARG2;
nethercote27ea8bc2004-07-10 17:21:14 +00004517
4518 mash_addr_and_len(&a, &len);
4519 VG_(unmap_range)(a, len);
4520 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004521}
4522
sewardje6d5e722005-06-10 10:27:55 +00004523PRE(sys_mincore)
4524{
4525 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
4526 PRE_REG_READ3(long, "mincore",
4527 unsigned long, start, vki_size_t, length,
4528 unsigned char *, vec);
4529 PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
4530}
4531POST(sys_mincore)
4532{
4533 POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
4534}
mueller6ceb2312004-01-02 22:52:34 +00004535
sewardja8d8e232005-06-07 20:04:56 +00004536PRE(sys_nanosleep)
mueller6ceb2312004-01-02 22:52:34 +00004537{
sewardja8d8e232005-06-07 20:04:56 +00004538 *flags |= SfMayBlock|SfPostOnFail;
njn22cfccb2004-11-27 16:10:23 +00004539 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004540 PRE_REG_READ2(long, "nanosleep",
4541 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004542 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4543 if (ARG2 != 0)
4544 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004545}
4546
nethercote85a456f2004-11-16 17:31:56 +00004547POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004548{
sewardja8d8e232005-06-07 20:04:56 +00004549 vg_assert(SUCCESS || FAILURE);
4550 if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
njn22cfccb2004-11-27 16:10:23 +00004551 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004552}
4553
sewardja8d8e232005-06-07 20:04:56 +00004554PRE(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004555{
sewardja8d8e232005-06-07 20:04:56 +00004556 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004557 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004558 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004559 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004560 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004561 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004562 } else {
nethercotee824cc42004-11-09 16:20:46 +00004563 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004564 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004565 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004566 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004567 }
njn22cfccb2004-11-27 16:10:23 +00004568 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004569}
4570
nethercote85a456f2004-11-16 17:31:56 +00004571POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004572{
sewardja8d8e232005-06-07 20:04:56 +00004573 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004574 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00004575 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00004576 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004577 } else {
nethercote493dd182004-02-24 23:57:47 +00004578 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00004579 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004580 }
jsgf855d93d2003-10-13 22:26:55 +00004581}
4582
sewardja8d8e232005-06-07 20:04:56 +00004583PRE(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004584{
sewardja8d8e232005-06-07 20:04:56 +00004585 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004586 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004587 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004588 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004589
sewardj7eb7c582005-06-23 01:02:53 +00004590 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00004591 SET_STATUS_Failure( VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004592 else
njn22cfccb2004-11-27 16:10:23 +00004593 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004594}
4595
nethercote85a456f2004-11-16 17:31:56 +00004596POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004597{
sewardja8d8e232005-06-07 20:04:56 +00004598 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00004599 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004600}
4601
sewardja8d8e232005-06-07 20:04:56 +00004602PRE(sys_write)
jsgf855d93d2003-10-13 22:26:55 +00004603{
sewardja8d8e232005-06-07 20:04:56 +00004604 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004605 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004606 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004607 unsigned int, fd, const char *, buf, vki_size_t, count);
sewardj7eb7c582005-06-23 01:02:53 +00004608 if (!ML_(fd_allowed)(ARG1, "write", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00004609 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004610 else
njn22cfccb2004-11-27 16:10:23 +00004611 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004612}
4613
sewardja8d8e232005-06-07 20:04:56 +00004614PRE(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004615{
sewardja8d8e232005-06-07 20:04:56 +00004616 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004617 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004618 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004619 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004620}
4621
nethercote85a456f2004-11-16 17:31:56 +00004622POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004623{
sewardja8d8e232005-06-07 20:04:56 +00004624 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004625 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00004626 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00004627 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004628 } else {
nethercote493dd182004-02-24 23:57:47 +00004629 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00004630 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004631 }
jsgf855d93d2003-10-13 22:26:55 +00004632}
4633
nethercote9a3beb92004-11-12 17:07:26 +00004634// XXX: sort of x86-specific
sewardja8d8e232005-06-07 20:04:56 +00004635PRE(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004636{
njn22cfccb2004-11-27 16:10:23 +00004637 PRINT("sys_pipe ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004638 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
njn22cfccb2004-11-27 16:10:23 +00004639 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004640}
4641
nethercote85a456f2004-11-16 17:31:56 +00004642POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004643{
njn22cfccb2004-11-27 16:10:23 +00004644 Int *p = (Int *)ARG1;
jsgf855d93d2003-10-13 22:26:55 +00004645
sewardj7eb7c582005-06-23 01:02:53 +00004646 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
4647 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004648 VG_(close)(p[0]);
4649 VG_(close)(p[1]);
sewardja8d8e232005-06-07 20:04:56 +00004650 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004651 } else {
njn22cfccb2004-11-27 16:10:23 +00004652 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004653 if (VG_(clo_track_fds)) {
njnf845f8f2005-06-23 02:26:47 +00004654 ML_(record_fd_open_nameless)(tid, p[0]);
4655 ML_(record_fd_open_nameless)(tid, p[1]);
rjwalshf5f536f2003-11-17 17:45:00 +00004656 }
4657 }
jsgf855d93d2003-10-13 22:26:55 +00004658}
4659
nethercotef90953e2004-11-15 14:50:02 +00004660// XXX: x86-specific, due to pollfd struct
sewardja8d8e232005-06-07 20:04:56 +00004661PRE(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004662{
4663 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004664 int fd; -- file descriptor
4665 short events; -- requested events
4666 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004667 };
nethercoteeb0592d2004-11-05 12:02:27 +00004668 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004669 */
nethercoteeb0592d2004-11-05 12:02:27 +00004670 UInt i;
sewardja8d8e232005-06-07 20:04:56 +00004671 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004672 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
4673 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00004674 PRE_REG_READ3(long, "poll",
4675 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004676
njn22cfccb2004-11-27 16:10:23 +00004677 for (i = 0; i < ARG2; i++) {
nethercoteeb0592d2004-11-05 12:02:27 +00004678 // 'fd' and 'events' field are inputs; 'revents' is output.
4679 // XXX: this is x86 specific -- the pollfd struct varies across
4680 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004681 PRE_MEM_READ( "poll(ufds)",
4682 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4683 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4684 }
jsgf855d93d2003-10-13 22:26:55 +00004685}
4686
nethercote85a456f2004-11-16 17:31:56 +00004687POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004688{
njn22cfccb2004-11-27 16:10:23 +00004689 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004690 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004691 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
nethercoteeb0592d2004-11-05 12:02:27 +00004692 // XXX: again, this is x86-specific
njn22cfccb2004-11-27 16:10:23 +00004693 for (i = 0; i < ARG2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004694 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004695 }
4696}
4697
sewardja8d8e232005-06-07 20:04:56 +00004698PRE(sys_readlink)
jsgf855d93d2003-10-13 22:26:55 +00004699{
sewardja8d8e232005-06-07 20:04:56 +00004700 Word saved = SYSNO;
njn22cfccb2004-11-27 16:10:23 +00004701 PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00004702 PRE_REG_READ3(long, "readlink",
4703 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00004704 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4705 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004706
rjwalsh17d85302004-11-18 22:56:09 +00004707 /*
rjwalsh093047d2004-11-19 02:11:56 +00004708 * Handle the case where readlink is looking at /proc/self/exe or
4709 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004710 */
4711
sewardja8d8e232005-06-07 20:04:56 +00004712 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004713
sewardja8d8e232005-06-07 20:04:56 +00004714 /* jrs 20050604: where does the magic value 2 come from? It seems
4715 like it should be a kernel error value, but we don't know of any
4716 such. */
4717 if (SWHAT == SsFailure && RES_unchecked == 2) {
4718 HChar name[25];
rjwalsh093047d2004-11-19 02:11:56 +00004719 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
njn22cfccb2004-11-27 16:10:23 +00004720 if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
4721 VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
rjwalsh093047d2004-11-19 02:11:56 +00004722 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
sewardja8d8e232005-06-07 20:04:56 +00004723 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004724 }
rjwalsh17d85302004-11-18 22:56:09 +00004725 }
4726
sewardja8d8e232005-06-07 20:04:56 +00004727 if (SUCCESS && RES > 0)
njn22cfccb2004-11-27 16:10:23 +00004728 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004729}
4730
sewardja8d8e232005-06-07 20:04:56 +00004731PRE(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004732{
jsgf855d93d2003-10-13 22:26:55 +00004733 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004734 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00004735 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004736 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00004737 PRE_REG_READ3(ssize_t, "readv",
4738 unsigned long, fd, const struct iovec *, vector,
4739 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00004740 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00004741 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004742 } else {
njn22cfccb2004-11-27 16:10:23 +00004743 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004744
njn22cfccb2004-11-27 16:10:23 +00004745 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004746 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00004747 vec = (struct vki_iovec *)ARG2;
4748 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00004749 PRE_MEM_WRITE( "readv(vector[...])",
4750 (Addr)vec[i].iov_base, vec[i].iov_len );
4751 }
jsgf855d93d2003-10-13 22:26:55 +00004752 }
4753}
4754
nethercote85a456f2004-11-16 17:31:56 +00004755POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004756{
sewardja8d8e232005-06-07 20:04:56 +00004757 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00004758 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004759 Int i;
njn22cfccb2004-11-27 16:10:23 +00004760 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4761 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00004762
njn22cfccb2004-11-27 16:10:23 +00004763 /* RES holds the number of bytes read. */
4764 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00004765 Int nReadThisBuf = vec[i].iov_len;
4766 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004767 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004768 remains -= nReadThisBuf;
4769 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4770 }
4771 }
4772}
4773
sewardja8d8e232005-06-07 20:04:56 +00004774PRE(sys_rename)
jsgf855d93d2003-10-13 22:26:55 +00004775{
njn22cfccb2004-11-27 16:10:23 +00004776 PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
nethercote9a3beb92004-11-12 17:07:26 +00004777 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004778 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4779 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004780}
4781
sewardj78b50e42005-06-08 01:47:28 +00004782PRE(sys_rmdir)
4783{
4784 *flags |= SfMayBlock;
4785 PRINT("sys_rmdir ( %p )", ARG1);
4786 PRE_REG_READ1(long, "rmdir", const char *, pathname);
4787 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
4788}
4789
sewardje6d5e722005-06-10 10:27:55 +00004790PRE(sys_sched_setparam)
4791{
4792 PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
4793 PRE_REG_READ2(long, "sched_setparam",
4794 vki_pid_t, pid, struct sched_param *, p);
4795 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
4796}
4797POST(sys_sched_setparam)
4798{
4799 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
4800}
sewardj78b50e42005-06-08 01:47:28 +00004801
4802PRE(sys_sched_getparam)
4803{
4804 PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
4805 PRE_REG_READ2(long, "sched_getparam",
4806 vki_pid_t, pid, struct sched_param *, p);
4807 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
4808}
4809
4810POST(sys_sched_getparam)
4811{
4812 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
4813}
jsgf855d93d2003-10-13 22:26:55 +00004814
sewardja8d8e232005-06-07 20:04:56 +00004815PRE(sys_select)
jsgf855d93d2003-10-13 22:26:55 +00004816{
sewardja8d8e232005-06-07 20:04:56 +00004817 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004818 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00004819 PRE_REG_READ5(long, "select",
4820 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4821 vki_fd_set *, exceptfds, struct timeval *, timeout);
4822 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00004823 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004824 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00004825 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4826 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004827 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00004828 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4829 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004830 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00004831 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4832 if (ARG5 != 0)
4833 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00004834}
4835
sewardj8c9ea4e2005-06-08 10:46:56 +00004836PRE(sys_setgid16)
4837{
4838 PRINT("sys_setgid16 ( %d )", ARG1);
4839 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4840}
4841
sewardje6d5e722005-06-10 10:27:55 +00004842PRE(sys_setgid)
4843{
4844 PRINT("sys_setgid ( %d )", ARG1);
4845 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
4846}
sewardj696c5512005-06-08 23:38:32 +00004847
4848PRE(sys_setsid)
4849{
4850 PRINT("sys_setsid ( )");
4851 PRE_REG_READ0(long, "setsid");
4852}
4853
4854PRE(sys_setgroups16)
4855{
4856 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
4857 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
4858 if (ARG1 > 0)
4859 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
4860}
4861
sewardje6d5e722005-06-10 10:27:55 +00004862PRE(sys_setgroups)
4863{
4864 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
4865 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
4866 if (ARG1 > 0)
4867 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
4868}
sewardj696c5512005-06-08 23:38:32 +00004869
4870PRE(sys_setpgid)
4871{
4872 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
4873 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
4874}
4875
4876PRE(sys_setregid)
4877{
4878 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
4879 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
4880}
4881
4882PRE(sys_setreuid16)
4883{
4884 PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
4885 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4886}
4887
sewardje6d5e722005-06-10 10:27:55 +00004888PRE(sys_setreuid)
4889{
4890 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
4891 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
4892}
nethercote9c311eb2004-11-12 18:20:12 +00004893
sewardja8d8e232005-06-07 20:04:56 +00004894PRE(sys_setrlimit)
jsgf855d93d2003-10-13 22:26:55 +00004895{
njn22cfccb2004-11-27 16:10:23 +00004896 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004897 PRE_REG_READ2(long, "setrlimit",
4898 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00004899 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004900
njn22cfccb2004-11-27 16:10:23 +00004901 if (ARG1 == VKI_RLIMIT_NOFILE) {
4902 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4903 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
sewardja8d8e232005-06-07 20:04:56 +00004904 SET_STATUS_Failure( VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004905 }
4906 else {
njn22cfccb2004-11-27 16:10:23 +00004907 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
sewardja8d8e232005-06-07 20:04:56 +00004908 SET_STATUS_Success( 0 );
thughesad1c9562004-06-26 11:27:52 +00004909 }
4910 }
njn22cfccb2004-11-27 16:10:23 +00004911 else if (ARG1 == VKI_RLIMIT_DATA) {
4912 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4913 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00004914 SET_STATUS_Failure( VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004915 }
4916 else {
njn22cfccb2004-11-27 16:10:23 +00004917 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00004918 SET_STATUS_Success( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004919 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004920 }
njn22cfccb2004-11-27 16:10:23 +00004921 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
4922 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4923 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00004924 SET_STATUS_Failure( VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004925 }
4926 else {
sewardja8d8e232005-06-07 20:04:56 +00004927 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
njn22cfccb2004-11-27 16:10:23 +00004928 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00004929 SET_STATUS_Success( 0 );
thughesc37184f2004-09-11 14:16:57 +00004930 }
4931 }
jsgf855d93d2003-10-13 22:26:55 +00004932}
4933
sewardja8d8e232005-06-07 20:04:56 +00004934PRE(sys_setuid16)
jsgf855d93d2003-10-13 22:26:55 +00004935{
njn22cfccb2004-11-27 16:10:23 +00004936 PRINT("sys_setuid16 ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004937 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004938}
4939
sewardje6d5e722005-06-10 10:27:55 +00004940PRE(sys_setuid)
4941{
4942 PRINT("sys_setuid ( %d )", ARG1);
4943 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4944}
jsgf855d93d2003-10-13 22:26:55 +00004945
sewardj696c5512005-06-08 23:38:32 +00004946PRE(sys_newstat)
4947{
4948 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
4949 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
4950 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4951 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
4952}
4953
4954POST(sys_newstat)
4955{
4956 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4957}
4958
4959PRE(sys_statfs)
4960{
4961 PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
4962 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
4963 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4964 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
4965}
sewardj696c5512005-06-08 23:38:32 +00004966POST(sys_statfs)
4967{
4968 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
4969}
4970
sewardje6d5e722005-06-10 10:27:55 +00004971PRE(sys_statfs64)
4972{
4973 PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
4974 PRE_REG_READ3(long, "statfs64",
4975 const char *, path, vki_size_t, size, struct statfs64 *, buf);
4976 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4977 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
4978}
4979POST(sys_statfs64)
4980{
4981 POST_MEM_WRITE( ARG3, ARG2 );
4982}
sewardj78b50e42005-06-08 01:47:28 +00004983
4984PRE(sys_symlink)
4985{
4986 *flags |= SfMayBlock;
4987 PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
4988 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
4989 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4990 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
4991}
sewardj9efbbef2005-03-01 16:45:23 +00004992
sewardja8d8e232005-06-07 20:04:56 +00004993PRE(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00004994{
4995 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00004996 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004997 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00004998 if (ARG1 != 0) {
4999 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005000 }
5001}
5002
nethercote85a456f2004-11-16 17:31:56 +00005003POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005004{
njn22cfccb2004-11-27 16:10:23 +00005005 if (ARG1 != 0) {
5006 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005007 }
5008}
5009
sewardj78b50e42005-06-08 01:47:28 +00005010PRE(sys_times)
5011{
5012 PRINT("sys_times ( %p )", ARG1);
5013 PRE_REG_READ1(long, "times", struct tms *, buf);
5014 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
5015}
5016
5017POST(sys_times)
5018{
5019 if (ARG1 != 0) {
5020 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
5021 }
5022}
5023
5024PRE(sys_umask)
5025{
5026 PRINT("sys_umask ( %d )", ARG1);
5027 PRE_REG_READ1(long, "umask", int, mask);
5028}
jsgf855d93d2003-10-13 22:26:55 +00005029
sewardja8d8e232005-06-07 20:04:56 +00005030PRE(sys_unlink)
jsgf855d93d2003-10-13 22:26:55 +00005031{
sewardja8d8e232005-06-07 20:04:56 +00005032 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005033 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005034 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00005035 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005036}
5037
sewardja8d8e232005-06-07 20:04:56 +00005038PRE(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005039{
njn22cfccb2004-11-27 16:10:23 +00005040 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00005041 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00005042 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005043}
5044
nethercote85a456f2004-11-16 17:31:56 +00005045POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005046{
njn22cfccb2004-11-27 16:10:23 +00005047 if (ARG1 != 0) {
5048 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005049 }
5050}
5051
sewardj8c9ea4e2005-06-08 10:46:56 +00005052PRE(sys_utime)
5053{
5054 *flags |= SfMayBlock;
5055 PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
5056 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
5057 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
5058 if (ARG2 != 0)
5059 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
5060}
jsgf855d93d2003-10-13 22:26:55 +00005061
sewardja8d8e232005-06-07 20:04:56 +00005062PRE(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005063{
sewardja8d8e232005-06-07 20:04:56 +00005064 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005065 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00005066 PRE_REG_READ3(long, "waitpid",
5067 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005068
njn22cfccb2004-11-27 16:10:23 +00005069 if (ARG2 != (Addr)NULL)
5070 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005071}
5072
nethercote85a456f2004-11-16 17:31:56 +00005073POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005074{
njn22cfccb2004-11-27 16:10:23 +00005075 if (ARG2 != (Addr)NULL)
5076 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005077}
5078
sewardja8d8e232005-06-07 20:04:56 +00005079PRE(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005080{
sewardja8d8e232005-06-07 20:04:56 +00005081 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005082 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
jsgf855d93d2003-10-13 22:26:55 +00005083
nethercote7f7e4d12004-11-15 12:28:58 +00005084 PRE_REG_READ4(long, "wait4",
5085 vki_pid_t, pid, unsigned int *, status, int, options,
5086 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00005087 if (ARG2 != (Addr)NULL)
5088 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5089 if (ARG4 != (Addr)NULL)
5090 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005091}
5092
nethercote85a456f2004-11-16 17:31:56 +00005093POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005094{
njn22cfccb2004-11-27 16:10:23 +00005095 if (ARG2 != (Addr)NULL)
5096 POST_MEM_WRITE( ARG2, sizeof(int) );
5097 if (ARG4 != (Addr)NULL)
5098 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005099}
5100
sewardja8d8e232005-06-07 20:04:56 +00005101PRE(sys_writev)
jsgf855d93d2003-10-13 22:26:55 +00005102{
jsgf855d93d2003-10-13 22:26:55 +00005103 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005104 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00005105 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005106 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005107 PRE_REG_READ3(ssize_t, "writev",
5108 unsigned long, fd, const struct iovec *, vector,
5109 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00005110 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00005111 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005112 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005113 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005114 ARG2, ARG3 * sizeof(struct vki_iovec) );
5115 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005116 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005117 vec = (struct vki_iovec *)ARG2;
5118 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005119 PRE_MEM_READ( "writev(vector[...])",
5120 (Addr)vec[i].iov_base, vec[i].iov_len );
5121 }
jsgf855d93d2003-10-13 22:26:55 +00005122 }
5123}
5124
sewardje6d5e722005-06-10 10:27:55 +00005125PRE(sys_utimes)
5126{
5127 PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
5128 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
5129 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5130 if (ARG2 != 0)
5131 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
5132}
5133
5134PRE(sys_sched_setaffinity)
5135{
5136 PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
5137 PRE_REG_READ3(long, "sched_setaffinity",
5138 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
5139 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
5140}
5141
5142PRE(sys_sched_getaffinity)
5143{
5144 PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
5145 PRE_REG_READ3(long, "sched_getaffinity",
5146 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
5147 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
5148}
5149POST(sys_sched_getaffinity)
5150{
5151 POST_MEM_WRITE(ARG3, ARG2);
5152}
sewardj696c5512005-06-08 23:38:32 +00005153
5154PRE(sys_acct)
5155{
5156 PRINT("sys_acct ( %p )", ARG1);
5157 PRE_REG_READ1(long, "acct", const char *, filename);
5158 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
5159}
muellerd3502b62003-11-19 00:43:57 +00005160
sewardja8d8e232005-06-07 20:04:56 +00005161PRE(sys_pause)
thughes2f8d5f82004-09-11 14:29:19 +00005162{
sewardja8d8e232005-06-07 20:04:56 +00005163 *flags |= SfMayBlock;
nethercote0df495a2004-11-11 16:38:21 +00005164 PRINT("sys_pause ( )");
5165 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005166}
5167
sewardja8d8e232005-06-07 20:04:56 +00005168//zz // XXX: x86-specific
5169//zz PRE(sys_sigsuspend, SfMayBlock)
5170//zz {
5171//zz /* The C library interface to sigsuspend just takes a pointer to
5172//zz a signal mask but this system call has three arguments - the first
5173//zz two don't appear to be used by the kernel and are always passed as
5174//zz zero by glibc and the third is the first word of the signal mask
5175//zz so only 32 signals are supported.
5176//zz
5177//zz In fact glibc normally uses rt_sigsuspend if it is available as
5178//zz that takes a pointer to the signal mask so supports more signals.
5179//zz */
5180//zz PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
5181//zz PRE_REG_READ3(int, "sigsuspend",
5182//zz int, history0, int, history1,
5183//zz vki_old_sigset_t, mask);
5184//zz }
jsgf855d93d2003-10-13 22:26:55 +00005185
nethercotea3a2c142004-11-14 14:13:05 +00005186// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005187PRE(sys_rt_sigsuspend)
nethercotea3a2c142004-11-14 14:13:05 +00005188{
thughesc3e85df2004-11-15 09:27:24 +00005189 /* The C library interface to sigsuspend just takes a pointer to
5190 a signal mask but this system call has two arguments - a pointer
5191 to the mask and the number of bytes used by it. The kernel insists
5192 on the size being equal to sizeof(sigset_t) however and will just
5193 return EINVAL if it isn't.
5194 */
sewardja8d8e232005-06-07 20:04:56 +00005195 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005196 PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
nethercotea3a2c142004-11-14 14:13:05 +00005197 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
njn22cfccb2004-11-27 16:10:23 +00005198 if (ARG1 != (Addr)NULL) {
5199 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
nethercotea3a2c142004-11-14 14:13:05 +00005200 }
5201}
jsgf855d93d2003-10-13 22:26:55 +00005202
sewardja8d8e232005-06-07 20:04:56 +00005203PRE(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005204{
sewardja8d8e232005-06-07 20:04:56 +00005205 *flags |= SfMayBlock;
nethercoteac866b92004-11-15 20:23:15 +00005206 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
njn22cfccb2004-11-27 16:10:23 +00005207 ARG1,ARG2,ARG3,(ULong)ARG4);
nethercoteac866b92004-11-15 20:23:15 +00005208 PRE_REG_READ4(long, "rt_sigtimedwait",
5209 const vki_sigset_t *, set, vki_siginfo_t *, info,
5210 const struct timespec *, timeout, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005211 if (ARG1 != 0)
5212 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
5213 if (ARG2 != 0)
5214 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
nethercoteac866b92004-11-15 20:23:15 +00005215 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
njn22cfccb2004-11-27 16:10:23 +00005216 ARG4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005217}
5218
nethercote85a456f2004-11-16 17:31:56 +00005219POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005220{
njn22cfccb2004-11-27 16:10:23 +00005221 if (ARG2 != 0)
5222 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005223}
5224
sewardje6d5e722005-06-10 10:27:55 +00005225PRE(sys_rt_sigqueueinfo)
5226{
5227 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
5228 PRE_REG_READ3(long, "rt_sigqueueinfo",
5229 int, pid, int, sig, vki_siginfo_t *, uinfo);
5230 if (ARG2 != 0)
5231 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
5232}
5233POST(sys_rt_sigqueueinfo)
5234{
sewardj7eb7c582005-06-23 01:02:53 +00005235 if (!ML_(client_signal_OK)(ARG2))
sewardje6d5e722005-06-10 10:27:55 +00005236 SET_STATUS_Failure( VKI_EINVAL );
5237}
jsgf855d93d2003-10-13 22:26:55 +00005238
nethercoteb77dee62004-11-16 17:13:24 +00005239// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005240PRE(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005241{
5242 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
njn22cfccb2004-11-27 16:10:23 +00005243 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005244 PRE_REG_READ2(int, "sigaltstack",
5245 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005246 if (ARG1 != 0) {
5247 PRE_MEM_READ( "sigaltstack(ss)", ARG1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005248 }
njn22cfccb2004-11-27 16:10:23 +00005249 if (ARG2 != 0) {
5250 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005251 }
5252
sewardja8d8e232005-06-07 20:04:56 +00005253 SET_STATUS_from_SysRes(
5254 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1,
5255 (vki_stack_t*)ARG2)
5256 );
jsgf855d93d2003-10-13 22:26:55 +00005257}
nethercote85a456f2004-11-16 17:31:56 +00005258POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005259{
sewardja8d8e232005-06-07 20:04:56 +00005260 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005261 if (RES == 0 && ARG2 != 0)
5262 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005263}
5264
nethercote71f05f32004-11-12 18:49:27 +00005265// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005266PRE(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005267{
njn22cfccb2004-11-27 16:10:23 +00005268 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
nethercote686b5db2004-11-14 13:42:51 +00005269 PRE_REG_READ4(long, "rt_sigaction",
5270 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005271 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005272
njn22cfccb2004-11-27 16:10:23 +00005273 if (ARG2 != 0)
5274 PRE_MEM_READ( "rt_sigaction(act)", ARG2, sizeof(struct vki_sigaction));
5275 if (ARG3 != 0)
5276 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005277
njnb249fd72004-11-29 14:24:57 +00005278 // XXX: doesn't seem right to be calling do_sys_sigaction for
5279 // sys_rt_sigaction... perhaps this function should be renamed
5280 // VG_(do_sys_rt_sigaction)() --njn
sewardjb5f6f512005-03-10 23:59:00 +00005281
sewardja8d8e232005-06-07 20:04:56 +00005282 SET_STATUS_from_SysRes(
sewardjb5f6f512005-03-10 23:59:00 +00005283 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
5284 (struct vki_sigaction *)ARG3)
5285 );
nethercote686b5db2004-11-14 13:42:51 +00005286}
nethercote85a456f2004-11-16 17:31:56 +00005287POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005288{
sewardja8d8e232005-06-07 20:04:56 +00005289 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005290 if (RES == 0 && ARG3 != 0)
5291 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005292}
jsgf855d93d2003-10-13 22:26:55 +00005293
njnc6168192004-11-29 13:54:10 +00005294// XXX: This syscall is not used on amd64 -- it only provides
5295// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
5296// This wrapper is only suitable for 32-bit architectures.
sewardja8d8e232005-06-07 20:04:56 +00005297#if defined(VGP_x86_linux)
5298PRE(sys_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005299{
sewardj970ac792004-12-31 18:09:32 +00005300 vki_old_sigset_t* set;
5301 vki_old_sigset_t* oldset;
5302 vki_sigset_t bigger_set;
5303 vki_sigset_t bigger_oldset;
5304
njn22cfccb2004-11-27 16:10:23 +00005305 PRINT("sys_sigprocmask ( %d, %p, %p )",ARG1,ARG2,ARG3);
nethercote7fbe08a2004-11-15 19:03:27 +00005306 PRE_REG_READ3(long, "sigprocmask",
5307 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
njn22cfccb2004-11-27 16:10:23 +00005308 if (ARG2 != 0)
5309 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
5310 if (ARG3 != 0)
5311 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005312
njnb249fd72004-11-29 14:24:57 +00005313 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5314 // vki_sigset_t params.
sewardj970ac792004-12-31 18:09:32 +00005315 set = (vki_old_sigset_t*)ARG2;
5316 oldset = (vki_old_sigset_t*)ARG3;
nethercote7fbe08a2004-11-15 19:03:27 +00005317
sewardj1f276622004-12-06 16:18:58 +00005318 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5319 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
5320 if (set)
5321 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
nethercote7fbe08a2004-11-15 19:03:27 +00005322
sewardja8d8e232005-06-07 20:04:56 +00005323 SET_STATUS_from_SysRes(
njn4fbc86c2005-05-08 00:45:11 +00005324 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
5325 set ? &bigger_set : NULL,
5326 oldset ? &bigger_oldset : NULL)
5327 );
nethercote7fbe08a2004-11-15 19:03:27 +00005328
njnb249fd72004-11-29 14:24:57 +00005329 if (oldset)
5330 *oldset = bigger_oldset.sig[0];
sewardja8d8e232005-06-07 20:04:56 +00005331
5332 if (SUCCESS)
5333 *flags |= SfPollAfter;
nethercote7fbe08a2004-11-15 19:03:27 +00005334}
5335
nethercote85a456f2004-11-16 17:31:56 +00005336POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005337{
sewardja8d8e232005-06-07 20:04:56 +00005338 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005339 if (RES == 0 && ARG3 != 0)
5340 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005341}
njnc6168192004-11-29 13:54:10 +00005342#endif
nethercote7fbe08a2004-11-15 19:03:27 +00005343
sewardja8d8e232005-06-07 20:04:56 +00005344PRE(sys_rt_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005345{
njn22cfccb2004-11-27 16:10:23 +00005346 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
nethercote7fbe08a2004-11-15 19:03:27 +00005347 PRE_REG_READ4(long, "rt_sigprocmask",
5348 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5349 vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005350 if (ARG2 != 0)
5351 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
5352 if (ARG3 != 0)
5353 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005354
5355 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
njn22cfccb2004-11-27 16:10:23 +00005356 if (sizeof(vki_sigset_t) != ARG4)
sewardja8d8e232005-06-07 20:04:56 +00005357 SET_STATUS_Failure( VKI_EMFILE );
sewardj004e8ca2005-02-28 17:27:04 +00005358 else {
sewardja8d8e232005-06-07 20:04:56 +00005359 SET_STATUS_from_SysRes(
5360 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
njn4fbc86c2005-05-08 00:45:11 +00005361 (vki_sigset_t*) ARG2,
5362 (vki_sigset_t*) ARG3 )
5363 );
sewardj004e8ca2005-02-28 17:27:04 +00005364 }
sewardja8d8e232005-06-07 20:04:56 +00005365
5366 if (SUCCESS)
5367 *flags |= SfPollAfter;
jsgf855d93d2003-10-13 22:26:55 +00005368}
5369
nethercote85a456f2004-11-16 17:31:56 +00005370POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005371{
sewardja8d8e232005-06-07 20:04:56 +00005372 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005373 if (RES == 0 && ARG3 != 0)
5374 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005375}
5376
sewardj696c5512005-06-08 23:38:32 +00005377PRE(sys_sigpending)
5378{
5379 PRINT( "sys_sigpending ( %p )", ARG1 );
5380 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
5381 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
5382}
5383
5384POST(sys_sigpending)
5385{
5386 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
5387}
5388
sewardje6d5e722005-06-10 10:27:55 +00005389PRE(sys_rt_sigpending)
5390{
5391 PRINT( "sys_rt_sigpending ( %p )", ARG1 );
5392 PRE_REG_READ2(long, "rt_sigpending",
5393 vki_sigset_t *, set, vki_size_t, sigsetsize);
5394 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
5395}
5396POST(sys_rt_sigpending)
5397{
5398 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
5399}
sewardj8c257322005-06-08 01:01:48 +00005400
5401PRE(sys_mq_open)
5402{
5403 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
5404 ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
5405 PRE_REG_READ4(long, "mq_open",
5406 const char *, name, int, oflag, vki_mode_t, mode,
5407 struct mq_attr *, attr);
5408 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
5409 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
5410 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
5411 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
5412 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
5413 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
5414 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5415 }
5416}
5417
5418POST(sys_mq_open)
5419{
5420 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00005421 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
sewardj8c257322005-06-08 01:01:48 +00005422 VG_(close)(RES);
5423 SET_STATUS_Failure( VKI_EMFILE );
5424 } else {
5425 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00005426 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
sewardj8c257322005-06-08 01:01:48 +00005427 }
5428}
5429
5430PRE(sys_mq_unlink)
5431{
5432 PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
5433 PRE_REG_READ1(long, "mq_unlink", const char *, name);
5434 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
5435}
5436
sewardj8c9ea4e2005-06-08 10:46:56 +00005437PRE(sys_mq_timedsend)
5438{
5439 *flags |= SfMayBlock;
5440 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
5441 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
5442 PRE_REG_READ5(long, "mq_timedsend",
5443 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5444 unsigned int, msg_prio, const struct timespec *, abs_timeout);
sewardj7eb7c582005-06-23 01:02:53 +00005445 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005446 SET_STATUS_Failure( VKI_EBADF );
5447 } else {
5448 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5449 if (ARG5 != 0)
5450 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
5451 sizeof(struct vki_timespec) );
5452 }
5453}
5454
5455PRE(sys_mq_timedreceive)
5456{
5457 *flags |= SfMayBlock;
5458 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
5459 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
5460 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5461 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5462 unsigned int *, msg_prio,
5463 const struct timespec *, abs_timeout);
sewardj7eb7c582005-06-23 01:02:53 +00005464 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005465 SET_STATUS_Failure( VKI_EBADF );
5466 } else {
5467 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
5468 if (ARG4 != 0)
5469 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
5470 ARG4, sizeof(unsigned int) );
5471 if (ARG5 != 0)
5472 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
5473 ARG5, sizeof(struct vki_timespec) );
5474 }
5475}
5476
5477POST(sys_mq_timedreceive)
5478{
5479 POST_MEM_WRITE( ARG2, ARG3 );
5480 if (ARG4 != 0)
5481 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
5482}
5483
5484PRE(sys_mq_notify)
5485{
5486 PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
5487 PRE_REG_READ2(long, "mq_notify",
5488 vki_mqd_t, mqdes, const struct sigevent *, notification);
sewardj7eb7c582005-06-23 01:02:53 +00005489 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
sewardj8c9ea4e2005-06-08 10:46:56 +00005490 SET_STATUS_Failure( VKI_EBADF );
5491 else if (ARG2 != 0)
5492 PRE_MEM_READ( "mq_notify(notification)",
5493 ARG2, sizeof(struct vki_sigevent) );
5494}
5495
5496PRE(sys_mq_getsetattr)
5497{
5498 PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
5499 PRE_REG_READ3(long, "mq_getsetattr",
5500 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5501 struct mq_attr *, omqstat);
sewardj7eb7c582005-06-23 01:02:53 +00005502 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005503 SET_STATUS_Failure( VKI_EBADF );
5504 } else {
5505 if (ARG2 != 0) {
5506 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
5507 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
5508 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5509 }
5510 if (ARG3 != 0)
5511 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
5512 sizeof(struct vki_mq_attr) );
5513 }
5514}
5515
5516POST(sys_mq_getsetattr)
5517{
5518 if (ARG3 != 0)
5519 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
5520}
5521
sewardje6d5e722005-06-10 10:27:55 +00005522PRE(sys_timer_create)
5523{
5524 PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
5525 PRE_REG_READ3(long, "timer_create",
5526 vki_clockid_t, clockid, struct sigevent *, evp,
5527 vki_timer_t *, timerid);
5528 if (ARG2 != 0)
5529 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
5530 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
5531}
5532POST(sys_timer_create)
5533{
5534 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
5535}
5536
5537PRE(sys_timer_settime)
5538{
5539 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
5540 PRE_REG_READ4(long, "timer_settime",
5541 vki_timer_t, timerid, int, flags,
5542 const struct itimerspec *, value,
5543 struct itimerspec *, ovalue);
5544 PRE_MEM_READ( "timer_settime(value)", ARG3,
5545 sizeof(struct vki_itimerspec) );
5546 if (ARG4 != 0)
5547 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
5548 sizeof(struct vki_itimerspec) );
5549}
5550POST(sys_timer_settime)
5551{
5552 if (ARG4 != 0)
5553 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
5554}
5555
5556PRE(sys_timer_gettime)
5557{
5558 PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
5559 PRE_REG_READ2(long, "timer_gettime",
5560 vki_timer_t, timerid, struct itimerspec *, value);
5561 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
5562 sizeof(struct vki_itimerspec));
5563}
5564POST(sys_timer_gettime)
5565{
5566 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
5567}
5568
5569PRE(sys_timer_getoverrun)
5570{
5571 PRINT("sys_timer_getoverrun( %p )", ARG1);
5572 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
5573}
5574
5575PRE(sys_timer_delete)
5576{
5577 PRINT("sys_timer_delete( %p )", ARG1);
5578 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
5579}
5580
5581PRE(sys_clock_settime)
5582{
5583 PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
5584 PRE_REG_READ2(long, "clock_settime",
5585 vki_clockid_t, clk_id, const struct timespec *, tp);
5586 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
5587}
jsgf855d93d2003-10-13 22:26:55 +00005588
sewardja8d8e232005-06-07 20:04:56 +00005589PRE(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005590{
njn22cfccb2004-11-27 16:10:23 +00005591 PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005592 PRE_REG_READ2(long, "clock_gettime",
5593 vki_clockid_t, clk_id, struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005594 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005595}
nethercote85a456f2004-11-16 17:31:56 +00005596POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005597{
njn22cfccb2004-11-27 16:10:23 +00005598 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005599}
5600
sewardje6d5e722005-06-10 10:27:55 +00005601PRE(sys_clock_getres)
5602{
5603 PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
5604 // Nb: we can't use "RES" as the param name because that's a macro
5605 // defined above!
5606 PRE_REG_READ2(long, "clock_getres",
5607 vki_clockid_t, clk_id, struct timespec *, res);
5608 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
5609}
5610POST(sys_clock_getres)
5611{
5612 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
5613}
thughese1a925d2004-08-30 19:50:02 +00005614
sewardje6d5e722005-06-10 10:27:55 +00005615#undef PRE
5616#undef POST
sewardj2e93c502002-04-12 11:12:52 +00005617
sewardjde4a1d02002-03-22 01:27:54 +00005618/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00005619/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005620/*--------------------------------------------------------------------*/