blob: cc8548bd68e7fbd17b280a4738aba79900f777ce [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"
njn0087c502005-07-01 04:15:36 +000036#include "pub_core_errormgr.h"
njn97405b22005-06-02 03:39:33 +000037#include "pub_core_libcbase.h"
sewardja8d8e232005-06-07 20:04:56 +000038#include "pub_core_libcassert.h"
njnde62cbf2005-06-10 22:08:14 +000039#include "pub_core_libcfile.h"
njnf4c50162005-06-20 14:18:12 +000040#include "pub_core_libcmman.h" // For VG_(mmap), VG_(munmap)()
njnde62cbf2005-06-10 22:08:14 +000041#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000042#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000043#include "pub_core_libcsignal.h"
njn04e16982005-05-31 00:23:43 +000044#include "pub_core_main.h"
njnaf1d7df2005-06-11 01:31:52 +000045#include "pub_core_mallocfree.h"
sewardja8d8e232005-06-07 20:04:56 +000046#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +000047#include "pub_core_scheduler.h"
sewardja8d8e232005-06-07 20:04:56 +000048#include "pub_core_signals.h"
njn419bbcb2005-06-21 03:52:49 +000049#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +000050#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +000051#include "pub_core_syswrap.h"
njn419bbcb2005-06-21 03:52:49 +000052#include "pub_core_tooliface.h"
sewardj55f9d1a2005-04-25 11:11:44 +000053
sewardja8d8e232005-06-07 20:04:56 +000054#include "priv_types_n_macros.h"
njnc1b01812005-06-17 22:19:06 +000055#include "priv_syswrap-generic.h"
sewardjde4a1d02002-03-22 01:27:54 +000056
sewardja8d8e232005-06-07 20:04:56 +000057#include "vki_unistd.h" /* for the __NR_* constants */
sewardjde4a1d02002-03-22 01:27:54 +000058
jsgf855d93d2003-10-13 22:26:55 +000059
fitzhardinge1a303042003-12-22 08:48:50 +000060/* return true if address range entirely contained within client
61 address space */
sewardj7eb7c582005-06-23 01:02:53 +000062Bool ML_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
nethercote8ff888f2004-11-17 17:11:45 +000063 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +000064{
65 Addr end = start+size;
66 Addr cl_base = VG_(client_base);
67 Bool ret;
68
69 if (size == 0)
70 return True;
71
sewardj16063e62005-03-15 23:29:13 +000072 if (0 && cl_base < 0x10000)
fitzhardinge1a303042003-12-22 08:48:50 +000073 cl_base = 0x10000;
74
75 ret =
76 (end >= start) &&
77 start >= cl_base && start < VG_(client_end) &&
78 (end <= VG_(client_end));
79
80 if (0)
81 VG_(printf)("%s: test=%p-%p client=%p-%p ret=%d\n",
nethercote1543adf2004-10-25 15:43:21 +000082 syscallname, start, end, cl_base, VG_(client_end), ret);
fitzhardinge1a303042003-12-22 08:48:50 +000083
nethercote1543adf2004-10-25 15:43:21 +000084 if (!ret && syscallname != NULL) {
sewardja8d8e232005-06-07 20:04:56 +000085 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
86 "to modify addresses %p-%p",
87 syscallname, start, end);
fitzhardinge1a303042003-12-22 08:48:50 +000088
89 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +000090 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge1a303042003-12-22 08:48:50 +000091 }
92 }
93
94 return ret;
95}
96
sewardj7eb7c582005-06-23 01:02:53 +000097Bool ML_(client_signal_OK)(Int sigNo)
njn419bbcb2005-06-21 03:52:49 +000098{
99 /* signal 0 is OK for kill */
njn351d0062005-06-21 22:23:59 +0000100 Bool ret = sigNo >= 0 && sigNo <= VG_SIGVGRTUSERMAX;
njn419bbcb2005-06-21 03:52:49 +0000101
102 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
103
104 return ret;
105}
106
njn25e49d8e72002-09-23 09:36:25 +0000107/* ---------------------------------------------------------------------
nethercote27ea8bc2004-07-10 17:21:14 +0000108 Doing mmap, mremap
njn25e49d8e72002-09-23 09:36:25 +0000109 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000110
njn25e49d8e72002-09-23 09:36:25 +0000111// Nb: this isn't done as precisely as possible, but it seems that programs
112// are usually sufficiently well-behaved that the more obscure corner cases
113// aren't important. Various comments in the few functions below give more
114// details... njn 2002-Sep-17
115
116/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
117 munmap, mprotect (and mremap??) work at the page level. So addresses
118 and lengths must be adjusted for this. */
119
120/* Mash around start and length so that the area exactly covers
121 an integral number of pages. If we don't do that, memcheck's
122 idea of addressible memory diverges from that of the
123 kernel's, which causes the leak detector to crash. */
124static
nethercote928a5f72004-11-03 18:10:37 +0000125void mash_addr_and_len( Addr* a, SizeT* len)
sewardjde4a1d02002-03-22 01:27:54 +0000126{
fitzhardinge98abfc72003-12-16 02:05:15 +0000127 Addr ra;
128
njn13bfd852005-06-02 03:52:53 +0000129 ra = VG_PGROUNDDN(*a);
130 *len = VG_PGROUNDUP(*a + *len) - ra;
fitzhardinge98abfc72003-12-16 02:05:15 +0000131 *a = ra;
sewardjde4a1d02002-03-22 01:27:54 +0000132}
133
sewardj7eb7c582005-06-23 01:02:53 +0000134void ML_(mmap_segment) ( Addr a, SizeT len, UInt prot,
sewardja8d8e232005-06-07 20:04:56 +0000135 UInt mm_flags, Int fd, ULong offset )
sewardjde4a1d02002-03-22 01:27:54 +0000136{
sewardj40f8ebe2002-10-23 21:46:13 +0000137 Bool rr, ww, xx;
fitzhardinge98abfc72003-12-16 02:05:15 +0000138 UInt flags;
njn25e49d8e72002-09-23 09:36:25 +0000139
fitzhardinge98abfc72003-12-16 02:05:15 +0000140 flags = SF_MMAP;
141
fitzhardinge98abfc72003-12-16 02:05:15 +0000142 if (!(mm_flags & VKI_MAP_PRIVATE))
143 flags |= SF_SHARED;
144
145 if (fd != -1)
146 flags |= SF_FILE;
147
148 VG_(map_fd_segment)(a, len, prot, flags, fd, offset, NULL);
njn25e49d8e72002-09-23 09:36:25 +0000149
fitzhardinge1a303042003-12-22 08:48:50 +0000150 rr = prot & VKI_PROT_READ;
151 ww = prot & VKI_PROT_WRITE;
152 xx = prot & VKI_PROT_EXEC;
njn25e49d8e72002-09-23 09:36:25 +0000153
sewardj40f8ebe2002-10-23 21:46:13 +0000154 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
sewardjde4a1d02002-03-22 01:27:54 +0000155}
156
njn25e49d8e72002-09-23 09:36:25 +0000157static
sewardja8d8e232005-06-07 20:04:56 +0000158SysRes mremap_segment ( Addr old_addr, SizeT old_size,
159 Addr new_addr, SizeT new_size,
160 UInt flags, ThreadId tid)
njn25e49d8e72002-09-23 09:36:25 +0000161{
sewardja8d8e232005-06-07 20:04:56 +0000162 SysRes ret;
fitzhardinge1a303042003-12-22 08:48:50 +0000163 Segment *seg, *next;
njn25e49d8e72002-09-23 09:36:25 +0000164
njn13bfd852005-06-02 03:52:53 +0000165 old_size = VG_PGROUNDUP(old_size);
166 new_size = VG_PGROUNDUP(new_size);
njn25e49d8e72002-09-23 09:36:25 +0000167
njn13bfd852005-06-02 03:52:53 +0000168 if (VG_PGROUNDDN(old_addr) != old_addr)
sewardja8d8e232005-06-07 20:04:56 +0000169 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000170
sewardj7eb7c582005-06-23 01:02:53 +0000171 if (!ML_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
sewardja8d8e232005-06-07 20:04:56 +0000172 return VG_(mk_SysRes_Error)( VKI_EFAULT );
fitzhardinge1a303042003-12-22 08:48:50 +0000173
174 /* fixed at the current address means we don't move it */
175 if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
176 flags &= ~(VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE);
177
178 if (flags & VKI_MREMAP_FIXED) {
njn13bfd852005-06-02 03:52:53 +0000179 if (VG_PGROUNDDN(new_addr) != new_addr)
sewardja8d8e232005-06-07 20:04:56 +0000180 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000181
sewardj7eb7c582005-06-23 01:02:53 +0000182 if (!ML_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
sewardja8d8e232005-06-07 20:04:56 +0000183 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000184
185 /* check for overlaps */
186 if ((old_addr < (new_addr+new_size) &&
187 (old_addr+old_size) > new_addr) ||
188 (new_addr < (old_addr+new_size) &&
189 (new_addr+new_size) > old_addr))
sewardja8d8e232005-06-07 20:04:56 +0000190 return VG_(mk_SysRes_Error)( VKI_EINVAL );
njn25e49d8e72002-09-23 09:36:25 +0000191 }
fitzhardinge1a303042003-12-22 08:48:50 +0000192
193 /* Do nothing */
194 if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
sewardja8d8e232005-06-07 20:04:56 +0000195 return VG_(mk_SysRes_Success)( old_addr );
fitzhardinge1a303042003-12-22 08:48:50 +0000196
197 seg = VG_(find_segment)(old_addr);
198
199 /* range must be contained within segment */
200 if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
sewardja8d8e232005-06-07 20:04:56 +0000201 return VG_(mk_SysRes_Error)( VKI_EINVAL );
fitzhardinge1a303042003-12-22 08:48:50 +0000202
sewardj1024cf72005-02-28 14:39:21 +0000203 next = VG_(find_segment_above_mapped)(old_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000204
205 if (0)
206 VG_(printf)("mremap: old_addr+new_size=%p next->addr=%p flags=%d\n",
207 old_addr+new_size, next->addr, flags);
208
209 if ((flags & VKI_MREMAP_FIXED) ||
210 (next != NULL && (old_addr+new_size) > next->addr)) {
211 /* we're moving the block */
212 Addr a;
213
214 if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
sewardja8d8e232005-06-07 20:04:56 +0000215 /* not allowed to move */
216 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000217
218 if ((flags & VKI_MREMAP_FIXED) == 0)
219 new_addr = 0;
220
221 a = VG_(find_map_space)(new_addr, new_size, True);
222
223 if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
sewardja8d8e232005-06-07 20:04:56 +0000224 /* didn't find the place we wanted */
225 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
fitzhardinge1a303042003-12-22 08:48:50 +0000226
227 new_addr = a;
fitzhardinge1a303042003-12-22 08:48:50 +0000228
229 /* we've nailed down the location */
sewardja8d8e232005-06-07 20:04:56 +0000230 flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
fitzhardinge1a303042003-12-22 08:48:50 +0000231
njnca6fef02004-11-29 16:49:18 +0000232 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
233 flags, new_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000234
sewardja8d8e232005-06-07 20:04:56 +0000235 if (ret.isError) {
fitzhardinge1a303042003-12-22 08:48:50 +0000236 return ret;
237 }
238
239 VG_TRACK(copy_mem_remap, old_addr, new_addr,
240 (old_size < new_size) ? old_size : new_size);
241
242 if (new_size > old_size)
243 VG_TRACK(new_mem_mmap, new_addr+old_size, new_size-old_size,
244 seg->prot & VKI_PROT_READ,
245 seg->prot & VKI_PROT_WRITE,
246 seg->prot & VKI_PROT_EXEC);
247 VG_TRACK(die_mem_munmap, old_addr, old_size);
248
249 VG_(map_file_segment)(new_addr, new_size,
250 seg->prot,
251 seg->flags,
252 seg->dev, seg->ino,
253 seg->offset, seg->filename);
254
255 VG_(munmap)((void *)old_addr, old_size);
256 } else {
257 /* staying in place */
sewardja8d8e232005-06-07 20:04:56 +0000258 ret = VG_(mk_SysRes_Success)( old_addr );
fitzhardinge1a303042003-12-22 08:48:50 +0000259
260 if (new_size < old_size) {
261 VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
262 VG_(munmap)((void *)(old_addr+new_size), old_size-new_size);
263 } else {
264 /* we've nailed down the location */
265 flags &= ~VKI_MREMAP_MAYMOVE;
266
267 if (0)
268 VG_(printf)("mremap: old_addr=%p old_size=%d new_size=%d flags=%d\n",
269 old_addr, old_size, new_size, flags);
270
njnca6fef02004-11-29 16:49:18 +0000271 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
272 flags, 0);
fitzhardinge1a303042003-12-22 08:48:50 +0000273
sewardja8d8e232005-06-07 20:04:56 +0000274 if (ret.isError || (!ret.isError && ret.val != old_addr))
fitzhardinge1a303042003-12-22 08:48:50 +0000275 return ret;
276
277 VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
278 seg->prot & VKI_PROT_READ,
279 seg->prot & VKI_PROT_WRITE,
280 seg->prot & VKI_PROT_EXEC);
281
282 VG_(map_file_segment)(old_addr+old_size, new_size-old_size,
283 seg->prot,
284 seg->flags,
285 seg->dev, seg->ino,
286 seg->offset, seg->filename);
287 }
288 }
289
290 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000291}
292
293
sewardja8d8e232005-06-07 20:04:56 +0000294/* ---------------------------------------------------------------------
295 File-descriptor tracking
296 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000297
rjwalshf5f536f2003-11-17 17:45:00 +0000298/* One of these is allocated for each open file descriptor. */
rjwalshf5f536f2003-11-17 17:45:00 +0000299typedef struct OpenFd
300{
301 Int fd; /* The file descriptor */
302 Char *pathname; /* NULL if not a regular file or unknown */
303 ExeContext *where; /* NULL if inherited from parent */
304 struct OpenFd *next, *prev;
305} OpenFd;
306
307/* List of allocated file descriptors. */
rjwalshf5f536f2003-11-17 17:45:00 +0000308static OpenFd *allocated_fds;
309
310/* Count of open file descriptors. */
rjwalshf5f536f2003-11-17 17:45:00 +0000311static int fd_count = 0;
312
rjwalshf5f536f2003-11-17 17:45:00 +0000313
rjwalshf5f536f2003-11-17 17:45:00 +0000314/* Note the fact that a file descriptor was just closed. */
rjwalshf5f536f2003-11-17 17:45:00 +0000315static
njnc6168192004-11-29 13:54:10 +0000316void record_fd_close(ThreadId tid, Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000317{
318 OpenFd *i = allocated_fds;
319
thughesad1c9562004-06-26 11:27:52 +0000320 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000321 return; /* Valgrind internal */
322
rjwalshf5f536f2003-11-17 17:45:00 +0000323 while(i) {
324 if(i->fd == fd) {
325 if(i->prev)
326 i->prev->next = i->next;
327 else
328 allocated_fds = i->next;
329 if(i->next)
330 i->next->prev = i->prev;
331 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000332 VG_(arena_free) (VG_AR_CORE, i->pathname);
333 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000334 fd_count--;
335 break;
336 }
337 i = i->next;
338 }
339}
340
341/* Note the fact that a file descriptor was just opened. If the
342 tid is -1, this indicates an inherited fd. If the pathname is NULL,
343 this either indicates a non-standard file (i.e. a pipe or socket or
344 some such thing) or that we don't know the filename. If the fd is
345 already open, then we're probably doing a dup2() to an existing fd,
346 so just overwrite the existing one. */
njnf845f8f2005-06-23 02:26:47 +0000347static void record_fd_open_with_given_name(ThreadId tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000348{
349 OpenFd *i;
350
thughesad1c9562004-06-26 11:27:52 +0000351 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000352 return; /* Valgrind internal */
353
rjwalshf5f536f2003-11-17 17:45:00 +0000354 /* Check to see if this fd is already open. */
355 i = allocated_fds;
356 while (i) {
357 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000358 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000359 break;
360 }
361 i = i->next;
362 }
363
364 /* Not already one: allocate an OpenFd */
365 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000366 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000367
368 i->prev = NULL;
369 i->next = allocated_fds;
370 if(allocated_fds) allocated_fds->prev = i;
371 allocated_fds = i;
372 fd_count++;
373 }
374
375 i->fd = fd;
njnf845f8f2005-06-23 02:26:47 +0000376 i->pathname = VG_(arena_strdup)(VG_AR_CORE, pathname);
njnd01fef72005-03-25 23:35:48 +0000377 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
rjwalshf5f536f2003-11-17 17:45:00 +0000378}
379
njnf845f8f2005-06-23 02:26:47 +0000380// Record opening of an fd, and find its name.
381static void record_fd_open_named(ThreadId tid, Int fd)
382{
383 static HChar buf[VKI_PATH_MAX];
384 Char* name;
385 if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
386 name = buf;
387 else
388 name = NULL;
389
390 record_fd_open_with_given_name(tid, fd, name);
391}
392
393// Record opening of a nameless fd.
394void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
395{
396 record_fd_open_with_given_name(tid, fd, NULL);
397}
398
rjwalshf5f536f2003-11-17 17:45:00 +0000399static
nethercote73b526f2004-10-31 18:48:21 +0000400Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000401{
nethercote73b526f2004-10-31 18:48:21 +0000402 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000403 VG_(sprintf)(name, "<unknown>");
404 } else {
405 VG_(sprintf)(name, "%s", sa->sun_path);
406 }
407
408 return name;
409}
410
411static
nethercote73b526f2004-10-31 18:48:21 +0000412Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000413{
nethercote73b526f2004-10-31 18:48:21 +0000414 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000415 VG_(sprintf)(name, "<unknown>");
416 } else {
417 UInt addr = sa->sin_addr.s_addr;
418
419 if (addr == 0) {
420 VG_(sprintf)(name, "<unbound>");
421 } else {
422 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
423 addr & 0xFF, (addr>>8) & 0xFF,
424 (addr>>16) & 0xFF, (addr>>24) & 0xFF,
nethercote73b526f2004-10-31 18:48:21 +0000425 vki_ntohs(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000426 }
427 }
428
429 return name;
430}
431
rjwalshf5f536f2003-11-17 17:45:00 +0000432/*
433 * Try get some details about a socket.
434 */
rjwalshf5f536f2003-11-17 17:45:00 +0000435static void
436getsockdetails(int fd)
437{
438 union u {
nethercote73b526f2004-10-31 18:48:21 +0000439 struct vki_sockaddr a;
440 struct vki_sockaddr_in in;
441 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000442 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000443 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000444
445 llen = sizeof(laddr);
446 VG_(memset)(&laddr, 0, llen);
447
448 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
449 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000450 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000451 static char lname[32];
452 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000453 struct vki_sockaddr_in paddr;
454 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000455
456 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
457 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
458 inet2name(&(laddr.in), llen, lname),
459 inet2name(&paddr, plen, pname));
460 } else {
461 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
462 fd, inet2name(&(laddr.in), llen, lname));
463 }
464 return;
465 }
nethercote73b526f2004-10-31 18:48:21 +0000466 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000467 static char lname[256];
468 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
469 unix2name(&(laddr.un), llen, lname));
470 return;
471 }
472 default:
473 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
474 laddr.a.sa_family, fd);
475 return;
476 }
477 }
478
479 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
480}
481
482
nethercote3a42fb82004-08-03 18:08:50 +0000483/* Dump out a summary, and a more detailed list, of open file descriptors. */
484void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000485{
486 OpenFd *i = allocated_fds;
487
nethercote3a42fb82004-08-03 18:08:50 +0000488 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000489
490 while(i) {
491 if(i->pathname) {
492 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
493 i->pathname);
494 } else {
495 int val;
nethercote73b526f2004-10-31 18:48:21 +0000496 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000497
nethercote73b526f2004-10-31 18:48:21 +0000498 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000499 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
500 } else {
501 getsockdetails(i->fd);
502 }
503 }
504
505 if(i->where) {
506 VG_(pp_ExeContext)(i->where);
507 VG_(message)(Vg_UserMsg, "");
508 } else {
509 VG_(message)(Vg_UserMsg, " <inherited from parent>");
510 VG_(message)(Vg_UserMsg, "");
511 }
512
513 i = i->next;
514 }
515
516 VG_(message)(Vg_UserMsg, "");
517}
518
519/* If /proc/self/fd doesn't exist for some weird reason (like you've
520 got a kernel that doesn't have /proc support compiled in), then we
521 need to find out what file descriptors we inherited from our parent
522 process the hard way - by checking each fd in turn. */
523
524static
525void do_hacky_preopened()
526{
527 struct vki_rlimit lim;
528 unsigned int count;
529 int i;
530
nethercote620154f2004-11-12 21:21:07 +0000531 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000532 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
533 an arbitrarily high number. 1024 happens to be the limit in
534 the 2.4 kernels. */
535 count = 1024;
536 } else {
537 count = lim.rlim_cur;
538 }
539
540 for (i = 0; i < count; i++)
541 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
njnf845f8f2005-06-23 02:26:47 +0000542 ML_(record_fd_open_nameless)(-1, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000543}
544
545/* Initialize the list of open file descriptors with the file descriptors
546 we inherited from out parent process. */
547
548void VG_(init_preopened_fds)()
549{
550 int f, ret;
551 struct vki_dirent d;
552
553 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
554 if(f == -1) {
555 do_hacky_preopened();
556 return;
557 }
558
559 while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
njnf845f8f2005-06-23 02:26:47 +0000560 if (ret == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000561 goto out;
562
njnf845f8f2005-06-23 02:26:47 +0000563 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
rjwalshf5f536f2003-11-17 17:45:00 +0000564 int fno = VG_(atoll)(d.d_name);
565
njnf845f8f2005-06-23 02:26:47 +0000566 if (fno != f)
567 if (VG_(clo_track_fds))
568 record_fd_open_named(-1, fno);
rjwalshf5f536f2003-11-17 17:45:00 +0000569 }
570
571 VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
572 }
573
574out:
575 VG_(close)(f);
576}
577
sewardjde4a1d02002-03-22 01:27:54 +0000578static
sewardj8c824512002-04-14 04:16:48 +0000579Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000580{
581 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000582 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000583 VG_(strcpy) ( result, s1 );
584 VG_(strcat) ( result, s2 );
585 return result;
586}
587
588static
jsgf855d93d2003-10-13 22:26:55 +0000589void pre_mem_read_sendmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000590 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000591{
njn9f46df62005-03-13 18:11:44 +0000592 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000593 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000594
njn9f46df62005-03-13 18:11:44 +0000595 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000596}
597
598static
jsgf855d93d2003-10-13 22:26:55 +0000599void pre_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000600 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000601{
njn9f46df62005-03-13 18:11:44 +0000602 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000603 PRE_MEM_WRITE( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000604 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000605}
606
607static
njn72718642003-07-24 08:45:32 +0000608void post_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000609 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000610{
nethercoteef0c7662004-11-06 15:38:43 +0000611 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000612}
613
614static
sewardj8c824512002-04-14 04:16:48 +0000615void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000616 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000617 struct vki_msghdr *msg,
nethercote928a5f72004-11-03 18:10:37 +0000618 void (*foreach_func)( ThreadId, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000619 )
sewardjde4a1d02002-03-22 01:27:54 +0000620{
621 if ( !msg )
622 return;
623
nethercote73b526f2004-10-31 18:48:21 +0000624 foreach_func ( tid, "(msg)", (Addr)msg, sizeof( struct vki_msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000625
626 if ( msg->msg_name )
njn72718642003-07-24 08:45:32 +0000627 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000628 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000629 (Addr)msg->msg_name, msg->msg_namelen );
630
631 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000632 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000633 UInt i;
634
njn72718642003-07-24 08:45:32 +0000635 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000636 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000637 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000638
639 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
njn72718642003-07-24 08:45:32 +0000640 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000641 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000642 (Addr)iov->iov_base, iov->iov_len );
643 }
644
645 if ( msg->msg_control )
njn72718642003-07-24 08:45:32 +0000646 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000647 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000648 (Addr)msg->msg_control, msg->msg_controllen );
649}
650
sewardjb5f6f512005-03-10 23:59:00 +0000651static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000652{
nethercote73b526f2004-10-31 18:48:21 +0000653 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000654
655 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000656 if (cm->cmsg_level == VKI_SOL_SOCKET &&
657 cm->cmsg_type == VKI_SCM_RIGHTS ) {
658 int *fds = (int *) VKI_CMSG_DATA(cm);
659 int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000660 / sizeof(int);
661 int i;
662
663 for (i = 0; i < fdc; i++)
664 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000665 // XXX: must we check the range on these fds with
cerion7b2c38c2005-06-23 07:52:54 +0000666 // ML_(fd_allowed)()?
njnf845f8f2005-06-23 02:26:47 +0000667 record_fd_open_named(tid, fds[i]);
rjwalshf5f536f2003-11-17 17:45:00 +0000668 }
669
nethercote73b526f2004-10-31 18:48:21 +0000670 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000671 }
672}
673
sewardjc483e8f2002-05-03 21:01:35 +0000674static
jsgf855d93d2003-10-13 22:26:55 +0000675void pre_mem_read_sockaddr ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000676 Char *description,
677 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000678{
sewardjff7c1ab2003-02-24 21:55:34 +0000679 Char *outmsg;
680
681 /* NULL/zero-length sockaddrs are legal */
682 if ( sa == NULL || salen == 0 ) return;
683
njn9f46df62005-03-13 18:11:44 +0000684 outmsg = VG_(arena_malloc) ( VG_AR_CORE,
nethercote73b526f2004-10-31 18:48:21 +0000685 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000686
687 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000688 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000689
sewardjc483e8f2002-05-03 21:01:35 +0000690 switch (sa->sa_family) {
691
nethercote73b526f2004-10-31 18:48:21 +0000692 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000693 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000694 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000695 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000696 break;
697
nethercote73b526f2004-10-31 18:48:21 +0000698 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000699 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000700 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000701 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
702 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000703 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000704 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000705 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
706 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000707 break;
708
nethercote73b526f2004-10-31 18:48:21 +0000709 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000710 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000711 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000712 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
713 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000714 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000715 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000716 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
717 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000718 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000719 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000720 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_addr,
721 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000722 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
nethercoteef0c7662004-11-06 15:38:43 +0000723 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000724 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_scope_id,
725 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000726 break;
727
728 default:
729 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000730 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000731 break;
732 }
733
njn9f46df62005-03-13 18:11:44 +0000734 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000735}
736
njn25e49d8e72002-09-23 09:36:25 +0000737/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000738static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000739{
740 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000741 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000742 if (a_p == NULL)
743 return 0;
744 else
745 return *a_p;
746}
747
njn25e49d8e72002-09-23 09:36:25 +0000748static
njn72718642003-07-24 08:45:32 +0000749void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000750 Char* buf_s, Char* buflen_s )
751{
njn51d827b2005-05-09 01:02:08 +0000752 if (VG_(tdict).track_pre_mem_write) {
njn72718642003-07-24 08:45:32 +0000753 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000754 if (buflen_in > 0) {
njn51d827b2005-05-09 01:02:08 +0000755 VG_(tdict).track_pre_mem_write( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000756 }
757 }
758}
759
760static
sewardja8d8e232005-06-07 20:04:56 +0000761void buf_and_len_post_check( ThreadId tid, SysRes res,
njn25e49d8e72002-09-23 09:36:25 +0000762 Addr buf_p, Addr buflen_p, Char* s )
763{
sewardja8d8e232005-06-07 20:04:56 +0000764 if (!res.isError && VG_(tdict).track_post_mem_write) {
njn72718642003-07-24 08:45:32 +0000765 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000766 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njn51d827b2005-05-09 01:02:08 +0000767 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000768 }
769 }
770}
771
772/* ---------------------------------------------------------------------
773 Data seg end, for brk()
774 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000775
fitzhardinge98abfc72003-12-16 02:05:15 +0000776static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000777{
fitzhardinge98abfc72003-12-16 02:05:15 +0000778 Addr ret = VG_(brk_limit);
sewardje517b802005-02-16 01:58:51 +0000779 static const Bool debug = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000780 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000781 Addr current, newaddr;
782
fitzhardinge98abfc72003-12-16 02:05:15 +0000783
784 if (debug)
sewardj548be6d2005-02-16 01:31:37 +0000785 VG_(printf)("\ndo_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
fitzhardinge98abfc72003-12-16 02:05:15 +0000786 VG_(brk_base), VG_(brk_limit), newbrk);
787
sewardj79048ce2005-02-18 08:28:32 +0000788# if 0
sewardje517b802005-02-16 01:58:51 +0000789 if (0) show_segments("in_brk");
sewardj79048ce2005-02-18 08:28:32 +0000790# endif
sewardj548be6d2005-02-16 01:31:37 +0000791
fitzhardinge98abfc72003-12-16 02:05:15 +0000792 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
793 return VG_(brk_limit);
794
795 /* brk isn't allowed to grow over anything else */
sewardj548be6d2005-02-16 01:31:37 +0000796 seg = VG_(find_segment)(VG_(brk_limit) -1);
fitzhardinge98abfc72003-12-16 02:05:15 +0000797
798 vg_assert(seg != NULL);
799
njn25e49d8e72002-09-23 09:36:25 +0000800 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000801 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
802 VG_(brk_limit), seg->addr, seg->addr+seg->len);
sewardj79048ce2005-02-18 08:28:32 +0000803 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit)
804 <= (seg->addr + seg->len));
fitzhardinge98abfc72003-12-16 02:05:15 +0000805
sewardj79048ce2005-02-18 08:28:32 +0000806 seg = VG_(find_segment_above_mapped)(VG_(brk_limit)-1);
807 if (0 && seg)
808 VG_(printf)("NEXT addr = %p\n", seg->addr);
fitzhardinge98abfc72003-12-16 02:05:15 +0000809 if (seg != NULL && newbrk > seg->addr)
810 return VG_(brk_limit);
811
njn13bfd852005-06-02 03:52:53 +0000812 current = VG_PGROUNDUP(VG_(brk_limit));
813 newaddr = VG_PGROUNDUP(newbrk);
nethercotece471262004-08-25 13:43:44 +0000814 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000815
816 /* new brk in a new page - fix the mappings */
817 if (newbrk > VG_(brk_limit)) {
818
819 if (debug)
820 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
821 current, newaddr, newaddr-current);
822
823 if (newaddr == current) {
824 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000825 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
826 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
827 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
njn0ae787c2005-06-28 22:14:53 +0000828 0, -1, 0))
nethercoteb4250ae2004-07-10 16:50:09 +0000829 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000830 ret = newbrk;
831 }
832 } else {
833 vg_assert(newbrk < VG_(brk_limit));
834
835 if (debug)
836 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
837 current, newaddr, current-newaddr);
838
839 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000840 int res = VG_(munmap)((void *)newaddr, current - newaddr);
841 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000842 }
843 ret = newbrk;
844 }
845 } else
846 ret = newbrk;
847
848 VG_(brk_limit) = ret;
849
850 return ret;
851}
852
853
njn25e49d8e72002-09-23 09:36:25 +0000854/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000855 Vet file descriptors for sanity
856 ------------------------------------------------------------------ */
857
858/* Return true if we're allowed to use or create this fd */
sewardj7eb7c582005-06-23 01:02:53 +0000859Bool ML_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000860{
njn0087c502005-07-01 04:15:36 +0000861 if ((fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) &&
862 VG_(showing_core_errors)())
863 {
jsewardd9320a42003-12-12 06:40:05 +0000864 VG_(message)(Vg_UserMsg,
865 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000866 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000867 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000868 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000869 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000870 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000871 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
jsgf855d93d2003-10-13 22:26:55 +0000872 }
873 return False;
874 }
sewardj10759312005-05-30 23:52:47 +0000875 else
876 if (soft && fd >= VG_(fd_soft_limit)) {
thughesad1c9562004-06-26 11:27:52 +0000877 return False;
878 }
sewardj10759312005-05-30 23:52:47 +0000879 else
880 if (fd == 2 && VG_(debugLog_getLevel)() > 0) {
881 return False;
882 }
883 else {
884 return True;
885 }
jsgf855d93d2003-10-13 22:26:55 +0000886}
887
888
889/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +0000890 Deal with a bunch of socket-related syscalls
891 ------------------------------------------------------------------ */
892
893/* ------ */
894
sewardj987a8eb2005-03-01 19:00:30 +0000895void
sewardj7eb7c582005-06-23 01:02:53 +0000896ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000897 UWord arg0, UWord arg1,
898 UWord arg2, UWord arg3 )
899{
900 /* int socketpair(int d, int type, int protocol, int sv[2]); */
901 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
902 arg3, 2*sizeof(int) );
903}
904
sewardja8d8e232005-06-07 20:04:56 +0000905SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000906ML_(generic_POST_sys_socketpair) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000907 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +0000908 UWord arg0, UWord arg1,
909 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +0000910{
sewardja8d8e232005-06-07 20:04:56 +0000911 SysRes r = res;
912 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +0000913 Int fd1 = ((Int*)arg3)[0];
914 Int fd2 = ((Int*)arg3)[1];
915 POST_MEM_WRITE( arg3, 2*sizeof(int) );
sewardj7eb7c582005-06-23 01:02:53 +0000916 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
917 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
sewardj9efbbef2005-03-01 16:45:23 +0000918 VG_(close)(fd1);
919 VG_(close)(fd2);
sewardja8d8e232005-06-07 20:04:56 +0000920 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000921 } else {
922 POST_MEM_WRITE( arg3, 2*sizeof(int) );
923 if (VG_(clo_track_fds)) {
njnf845f8f2005-06-23 02:26:47 +0000924 ML_(record_fd_open_nameless)(tid, fd1);
925 ML_(record_fd_open_nameless)(tid, fd2);
sewardj9efbbef2005-03-01 16:45:23 +0000926 }
927 }
928 return r;
929}
930
931/* ------ */
932
sewardja8d8e232005-06-07 20:04:56 +0000933SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000934ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
sewardj9efbbef2005-03-01 16:45:23 +0000935{
sewardja8d8e232005-06-07 20:04:56 +0000936 SysRes r = res;
937 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +0000938 if (!ML_(fd_allowed)(res.val, "socket", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +0000939 VG_(close)(res.val);
940 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000941 } else {
942 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +0000943 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +0000944 }
945 return r;
946}
947
948/* ------ */
949
sewardj987a8eb2005-03-01 19:00:30 +0000950void
sewardj7eb7c582005-06-23 01:02:53 +0000951ML_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000952 UWord arg0, UWord arg1, UWord arg2 )
953{
954 /* int bind(int sockfd, struct sockaddr *my_addr,
955 int addrlen); */
956 pre_mem_read_sockaddr(
957 tid, "socketcall.bind(my_addr.%s)",
958 (struct vki_sockaddr *) arg1, arg2
959 );
960}
961
962/* ------ */
963
sewardj987a8eb2005-03-01 19:00:30 +0000964void
sewardj7eb7c582005-06-23 01:02:53 +0000965ML_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000966 UWord arg0, UWord arg1, UWord arg2 )
967{
968 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
969 Addr addr_p = arg1;
970 Addr addrlen_p = arg2;
971 if (addr_p != (Addr)NULL)
972 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
973 "socketcall.accept(addr)",
974 "socketcall.accept(addrlen_in)" );
975}
976
sewardja8d8e232005-06-07 20:04:56 +0000977SysRes
sewardj7eb7c582005-06-23 01:02:53 +0000978ML_(generic_POST_sys_accept) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000979 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +0000980 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +0000981{
sewardja8d8e232005-06-07 20:04:56 +0000982 SysRes r = res;
983 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +0000984 if (!ML_(fd_allowed)(res.val, "accept", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +0000985 VG_(close)(res.val);
986 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +0000987 } else {
988 Addr addr_p = arg1;
989 Addr addrlen_p = arg2;
990 if (addr_p != (Addr)NULL)
991 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
992 "socketcall.accept(addrlen_out)" );
993 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +0000994 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +0000995 }
996 return r;
997}
998
999/* ------ */
1000
sewardj987a8eb2005-03-01 19:00:30 +00001001void
sewardj7eb7c582005-06-23 01:02:53 +00001002ML_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001003 UWord arg0, UWord arg1, UWord arg2,
1004 UWord arg3, UWord arg4, UWord arg5 )
1005{
1006 /* int sendto(int s, const void *msg, int len,
1007 unsigned int flags,
1008 const struct sockaddr *to, int tolen); */
1009 PRE_MEM_READ( "socketcall.sendto(msg)",
1010 arg1, /* msg */
1011 arg2 /* len */ );
1012 pre_mem_read_sockaddr(
1013 tid, "socketcall.sendto(to.%s)",
1014 (struct vki_sockaddr *) arg4, arg5
1015 );
1016}
1017
1018/* ------ */
1019
sewardj987a8eb2005-03-01 19:00:30 +00001020void
sewardj7eb7c582005-06-23 01:02:53 +00001021ML_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001022 UWord arg0, UWord arg1, UWord arg2 )
1023{
1024 /* int send(int s, const void *msg, size_t len, int flags); */
1025 PRE_MEM_READ( "socketcall.send(msg)",
1026 arg1, /* msg */
1027 arg2 /* len */ );
1028
1029}
1030
1031/* ------ */
1032
sewardj987a8eb2005-03-01 19:00:30 +00001033void
sewardj7eb7c582005-06-23 01:02:53 +00001034ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001035 UWord arg0, UWord arg1, UWord arg2,
1036 UWord arg3, UWord arg4, UWord arg5 )
1037{
1038 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1039 struct sockaddr *from, int *fromlen); */
1040 Addr buf_p = arg1;
1041 Int len = arg2;
1042 Addr from_p = arg4;
1043 Addr fromlen_p = arg5;
1044 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1045 if (from_p != (Addr)NULL)
1046 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1047 "socketcall.recvfrom(from)",
1048 "socketcall.recvfrom(fromlen_in)" );
1049}
1050
sewardj987a8eb2005-03-01 19:00:30 +00001051void
sewardj7eb7c582005-06-23 01:02:53 +00001052ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001053 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001054 UWord arg0, UWord arg1, UWord arg2,
1055 UWord arg3, UWord arg4, UWord arg5 )
1056{
1057 Addr buf_p = arg1;
1058 Int len = arg2;
1059 Addr from_p = arg4;
1060 Addr fromlen_p = arg5;
1061
sewardja8d8e232005-06-07 20:04:56 +00001062 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001063 if (from_p != (Addr)NULL)
1064 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1065 "socketcall.recvfrom(fromlen_out)" );
1066 POST_MEM_WRITE( buf_p, len );
1067}
1068
1069/* ------ */
1070
sewardj987a8eb2005-03-01 19:00:30 +00001071void
sewardj7eb7c582005-06-23 01:02:53 +00001072ML_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001073 UWord arg0, UWord arg1, UWord arg2 )
1074{
1075 /* int recv(int s, void *buf, int len, unsigned int flags); */
1076 /* man 2 recv says:
1077 The recv call is normally used only on a connected socket
1078 (see connect(2)) and is identical to recvfrom with a NULL
1079 from parameter.
1080 */
1081 PRE_MEM_WRITE( "socketcall.recv(buf)",
1082 arg1, /* buf */
1083 arg2 /* len */ );
1084}
1085
sewardj987a8eb2005-03-01 19:00:30 +00001086void
sewardj7eb7c582005-06-23 01:02:53 +00001087ML_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001088 UWord res,
1089 UWord arg0, UWord arg1, UWord arg2 )
1090{
1091 if (res >= 0 && arg1 != 0) {
1092 POST_MEM_WRITE( arg1, /* buf */
1093 arg2 /* len */ );
1094 }
1095}
1096
1097/* ------ */
1098
sewardj987a8eb2005-03-01 19:00:30 +00001099void
sewardj7eb7c582005-06-23 01:02:53 +00001100ML_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001101 UWord arg0, UWord arg1, UWord arg2 )
1102{
1103 /* int connect(int sockfd,
1104 struct sockaddr *serv_addr, int addrlen ); */
1105 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1106 arg1, /* serv_addr */
1107 sizeof(vki_sa_family_t));
1108 pre_mem_read_sockaddr( tid,
1109 "socketcall.connect(serv_addr.%s)",
1110 (struct vki_sockaddr *) arg1, arg2);
1111}
1112
1113/* ------ */
1114
sewardj987a8eb2005-03-01 19:00:30 +00001115void
sewardj7eb7c582005-06-23 01:02:53 +00001116ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001117 UWord arg0, UWord arg1, UWord arg2,
1118 UWord arg3, UWord arg4 )
1119{
1120 /* int setsockopt(int s, int level, int optname,
1121 const void *optval, int optlen); */
1122 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1123 arg3, /* optval */
1124 arg4 /* optlen */ );
1125}
1126
1127/* ------ */
1128
sewardj987a8eb2005-03-01 19:00:30 +00001129void
sewardj7eb7c582005-06-23 01:02:53 +00001130ML_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001131 UWord arg0, UWord arg1, UWord arg2,
1132 UWord arg3, UWord arg4 )
1133{
1134 /* int getsockopt(int s, int level, int optname,
1135 void *optval, socklen_t *optlen); */
1136 Addr optval_p = arg3;
1137 Addr optlen_p = arg4;
1138 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
1139 if (optval_p != (Addr)NULL)
1140 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1141 "socketcall.getsockopt(optval)",
1142 "socketcall.getsockopt(optlen)" );
1143}
1144
sewardj987a8eb2005-03-01 19:00:30 +00001145void
sewardj7eb7c582005-06-23 01:02:53 +00001146ML_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001147 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001148 UWord arg0, UWord arg1, UWord arg2,
1149 UWord arg3, UWord arg4 )
1150{
1151 Addr optval_p = arg3;
1152 Addr optlen_p = arg4;
sewardja8d8e232005-06-07 20:04:56 +00001153 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001154 if (optval_p != (Addr)NULL)
1155 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1156 "socketcall.getsockopt(optlen_out)" );
1157}
1158
1159/* ------ */
1160
sewardj987a8eb2005-03-01 19:00:30 +00001161void
sewardj7eb7c582005-06-23 01:02:53 +00001162ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001163 UWord arg0, UWord arg1, UWord arg2 )
1164{
1165 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1166 Addr name_p = arg1;
1167 Addr namelen_p = arg2;
1168 /* Nb: name_p cannot be NULL */
1169 buf_and_len_pre_check ( tid, name_p, namelen_p,
1170 "socketcall.getsockname(name)",
1171 "socketcall.getsockname(namelen_in)" );
1172}
1173
sewardj987a8eb2005-03-01 19:00:30 +00001174void
sewardj7eb7c582005-06-23 01:02:53 +00001175ML_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001176 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001177 UWord arg0, UWord arg1, UWord arg2 )
1178{
1179 Addr name_p = arg1;
1180 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001181 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001182 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1183 "socketcall.getsockname(namelen_out)" );
1184}
1185
1186/* ------ */
1187
sewardj987a8eb2005-03-01 19:00:30 +00001188void
sewardj7eb7c582005-06-23 01:02:53 +00001189ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001190 UWord arg0, UWord arg1, UWord arg2 )
1191{
1192 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1193 Addr name_p = arg1;
1194 Addr namelen_p = arg2;
1195 /* Nb: name_p cannot be NULL */
1196 buf_and_len_pre_check ( tid, name_p, namelen_p,
1197 "socketcall.getpeername(name)",
1198 "socketcall.getpeername(namelen_in)" );
1199}
1200
sewardj987a8eb2005-03-01 19:00:30 +00001201void
sewardj7eb7c582005-06-23 01:02:53 +00001202ML_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001203 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001204 UWord arg0, UWord arg1, UWord arg2 )
1205{
1206 Addr name_p = arg1;
1207 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001208 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001209 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1210 "socketcall.getpeername(namelen_out)" );
1211}
1212
1213/* ------ */
1214
sewardj987a8eb2005-03-01 19:00:30 +00001215void
sewardj7eb7c582005-06-23 01:02:53 +00001216ML_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001217 UWord arg0, UWord arg1 )
1218{
1219 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1220 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1221 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1222}
1223
1224/* ------ */
1225
sewardj987a8eb2005-03-01 19:00:30 +00001226void
sewardj7eb7c582005-06-23 01:02:53 +00001227ML_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001228 UWord arg0, UWord arg1 )
1229{
1230 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1231 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1232 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1233}
1234
sewardj987a8eb2005-03-01 19:00:30 +00001235void
sewardj7eb7c582005-06-23 01:02:53 +00001236ML_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001237 UWord arg0, UWord arg1 )
1238{
1239 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1240 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1241 check_cmsg_for_fds( tid, msg );
1242}
1243
1244
1245/* ---------------------------------------------------------------------
sewardjb369c5e2005-03-24 17:52:02 +00001246 Deal with a bunch of IPC related syscalls
1247 ------------------------------------------------------------------ */
1248
1249/* ------ */
1250
1251void
sewardj7eb7c582005-06-23 01:02:53 +00001252ML_(generic_PRE_sys_semop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001253 UWord arg0, UWord arg1, UWord arg2 )
1254{
1255 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1256 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1257}
1258
1259/* ------ */
1260
1261void
sewardj7eb7c582005-06-23 01:02:53 +00001262ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001263 UWord arg0, UWord arg1,
1264 UWord arg2, UWord arg3 )
1265{
1266 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1267 struct timespec *timeout); */
1268 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1269 if (arg3 != 0)
1270 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1271}
1272
1273/* ------ */
1274
1275static
1276UInt get_sem_count( Int semid )
1277{
sewardja8d8e232005-06-07 20:04:56 +00001278 struct vki_semid_ds buf;
1279 union vki_semun arg;
1280 SysRes res;
sewardjb369c5e2005-03-24 17:52:02 +00001281
sewardja8d8e232005-06-07 20:04:56 +00001282 arg.buf = &buf;
sewardjb369c5e2005-03-24 17:52:02 +00001283
sewardja8d8e232005-06-07 20:04:56 +00001284# ifdef __NR_semctl
1285 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1286# else
1287 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
1288 VKI_IPC_STAT, (UWord)&arg);
1289# endif
1290 if (res.isError)
1291 return 0;
sewardjb369c5e2005-03-24 17:52:02 +00001292
sewardja8d8e232005-06-07 20:04:56 +00001293 return buf.sem_nsems;
sewardjb369c5e2005-03-24 17:52:02 +00001294}
1295
1296void
sewardj7eb7c582005-06-23 01:02:53 +00001297ML_(generic_PRE_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001298 UWord arg0, UWord arg1,
1299 UWord arg2, UWord arg3 )
1300{
1301 /* int semctl(int semid, int semnum, int cmd, ...); */
1302 union vki_semun arg = *(union vki_semun *)&arg3;
1303 UInt nsems;
1304 switch (arg2 /* cmd */) {
1305 case VKI_IPC_INFO:
1306 case VKI_SEM_INFO:
1307 case VKI_IPC_INFO|VKI_IPC_64:
1308 case VKI_SEM_INFO|VKI_IPC_64:
1309 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
1310 (Addr)arg.buf, sizeof(struct vki_seminfo) );
1311 break;
1312 case VKI_IPC_STAT:
1313 case VKI_SEM_STAT:
1314 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1315 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1316 break;
1317 case VKI_IPC_STAT|VKI_IPC_64:
1318 case VKI_SEM_STAT|VKI_IPC_64:
1319 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1320 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1321 break;
1322 case VKI_IPC_SET:
1323 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1324 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1325 break;
1326 case VKI_IPC_SET|VKI_IPC_64:
1327 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1328 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1329 break;
1330 case VKI_GETALL:
1331 case VKI_GETALL|VKI_IPC_64:
1332 nsems = get_sem_count( arg0 );
1333 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
1334 (Addr)arg.array, sizeof(unsigned short) * nsems );
1335 break;
1336 case VKI_SETALL:
1337 case VKI_SETALL|VKI_IPC_64:
1338 nsems = get_sem_count( arg0 );
1339 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
1340 (Addr)arg.array, sizeof(unsigned short) * nsems );
1341 break;
1342 }
1343}
1344
1345void
sewardj7eb7c582005-06-23 01:02:53 +00001346ML_(generic_POST_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001347 UWord res,
1348 UWord arg0, UWord arg1,
1349 UWord arg2, UWord arg3 )
1350{
1351 union vki_semun arg = *(union vki_semun *)&arg3;
1352 UInt nsems;
1353 switch (arg2 /* cmd */) {
1354 case VKI_IPC_INFO:
1355 case VKI_SEM_INFO:
1356 case VKI_IPC_INFO|VKI_IPC_64:
1357 case VKI_SEM_INFO|VKI_IPC_64:
1358 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
1359 break;
1360 case VKI_IPC_STAT:
1361 case VKI_SEM_STAT:
1362 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1363 break;
1364 case VKI_IPC_STAT|VKI_IPC_64:
1365 case VKI_SEM_STAT|VKI_IPC_64:
1366 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1367 break;
1368 case VKI_GETALL:
1369 case VKI_GETALL|VKI_IPC_64:
1370 nsems = get_sem_count( arg0 );
1371 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
1372 break;
1373 }
1374}
1375
1376/* ------ */
1377
1378void
sewardj7eb7c582005-06-23 01:02:53 +00001379ML_(generic_PRE_sys_msgsnd) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001380 UWord arg0, UWord arg1,
1381 UWord arg2, UWord arg3 )
1382{
1383 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
1384 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1385 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1386 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1387}
1388
1389/* ------ */
1390
1391void
sewardj7eb7c582005-06-23 01:02:53 +00001392ML_(generic_PRE_sys_msgrcv) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001393 UWord arg0, UWord arg1, UWord arg2,
1394 UWord arg3, UWord arg4 )
1395{
1396 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
1397 long msgtyp, int msgflg); */
1398 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1399 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1400 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1401}
1402
1403void
sewardj7eb7c582005-06-23 01:02:53 +00001404ML_(generic_POST_sys_msgrcv) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001405 UWord res,
1406 UWord arg0, UWord arg1, UWord arg2,
1407 UWord arg3, UWord arg4 )
1408{
1409 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1410 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1411 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
1412}
1413
1414/* ------ */
1415
1416void
sewardj7eb7c582005-06-23 01:02:53 +00001417ML_(generic_PRE_sys_msgctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001418 UWord arg0, UWord arg1, UWord arg2 )
1419{
1420 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
1421 switch (arg1 /* cmd */) {
1422 case VKI_IPC_INFO:
1423 case VKI_MSG_INFO:
1424 case VKI_IPC_INFO|VKI_IPC_64:
1425 case VKI_MSG_INFO|VKI_IPC_64:
1426 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
1427 arg2, sizeof(struct vki_msginfo) );
1428 break;
1429 case VKI_IPC_STAT:
1430 case VKI_MSG_STAT:
1431 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
1432 arg2, sizeof(struct vki_msqid_ds) );
1433 break;
1434 case VKI_IPC_STAT|VKI_IPC_64:
1435 case VKI_MSG_STAT|VKI_IPC_64:
1436 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
1437 arg2, sizeof(struct vki_msqid64_ds) );
1438 break;
1439 case VKI_IPC_SET:
1440 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1441 arg2, sizeof(struct vki_msqid_ds) );
1442 break;
1443 case VKI_IPC_SET|VKI_IPC_64:
1444 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1445 arg2, sizeof(struct vki_msqid64_ds) );
1446 break;
1447 }
1448}
1449
1450void
sewardj7eb7c582005-06-23 01:02:53 +00001451ML_(generic_POST_sys_msgctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001452 UWord res,
1453 UWord arg0, UWord arg1, UWord arg2 )
1454{
1455 switch (arg1 /* cmd */) {
1456 case VKI_IPC_INFO:
1457 case VKI_MSG_INFO:
1458 case VKI_IPC_INFO|VKI_IPC_64:
1459 case VKI_MSG_INFO|VKI_IPC_64:
1460 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
1461 break;
1462 case VKI_IPC_STAT:
1463 case VKI_MSG_STAT:
1464 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
1465 break;
1466 case VKI_IPC_STAT|VKI_IPC_64:
1467 case VKI_MSG_STAT|VKI_IPC_64:
1468 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
1469 break;
1470 }
1471}
1472
1473/* ------ */
1474
1475static
1476UInt get_shm_size ( Int shmid )
1477{
sewardja8d8e232005-06-07 20:04:56 +00001478# ifdef __NR_shmctl
sewardjb369c5e2005-03-24 17:52:02 +00001479 struct vki_shmid64_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001480 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
1481# else
sewardjb369c5e2005-03-24 17:52:02 +00001482 struct vki_shmid_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001483 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
sewardjb369c5e2005-03-24 17:52:02 +00001484 VKI_IPC_STAT, 0, (UWord)&buf);
sewardja8d8e232005-06-07 20:04:56 +00001485# endif
1486 if (__res.isError)
sewardjb369c5e2005-03-24 17:52:02 +00001487 return 0;
1488
1489 return buf.shm_segsz;
1490}
1491
1492UWord
sewardj7eb7c582005-06-23 01:02:53 +00001493ML_(generic_PRE_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001494 UWord arg0, UWord arg1, UWord arg2 )
1495{
1496 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
1497 UInt segmentSize = get_shm_size ( arg0 );
1498 if (arg1 == 0)
1499 arg1 = VG_(find_map_space)(0, segmentSize, True);
sewardj7eb7c582005-06-23 01:02:53 +00001500 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
sewardjb369c5e2005-03-24 17:52:02 +00001501 arg1 = 0;
1502 return arg1;
1503}
1504
1505void
sewardj7eb7c582005-06-23 01:02:53 +00001506ML_(generic_POST_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001507 UWord res,
1508 UWord arg0, UWord arg1, UWord arg2 )
1509{
1510 UInt segmentSize = get_shm_size ( arg0 );
1511 if ( segmentSize > 0 ) {
1512 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
1513 /* we don't distinguish whether it's read-only or
1514 * read-write -- it doesn't matter really. */
1515 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
1516
1517 if (!(arg2 & 010000)) /* = SHM_RDONLY */
1518 prot &= ~VKI_PROT_WRITE;
1519 VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
1520 }
1521}
1522
1523/* ------ */
1524
1525Bool
sewardj7eb7c582005-06-23 01:02:53 +00001526ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001527{
1528 /* int shmdt(const void *shmaddr); */
sewardj7eb7c582005-06-23 01:02:53 +00001529 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
sewardjb369c5e2005-03-24 17:52:02 +00001530}
1531
1532void
sewardj7eb7c582005-06-23 01:02:53 +00001533ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001534{
1535 Segment *s = VG_(find_segment)(arg0);
1536
1537 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, 1)) {
1538 VG_TRACK( die_mem_munmap, s->addr, s->len );
1539 VG_(unmap_range)(s->addr, s->len);
1540 }
1541}
1542/* ------ */
1543
1544void
sewardj7eb7c582005-06-23 01:02:53 +00001545ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001546 UWord arg0, UWord arg1, UWord arg2 )
1547{
1548 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
1549 switch (arg1 /* cmd */) {
1550 case VKI_IPC_INFO:
1551 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1552 arg2, sizeof(struct vki_shminfo) );
1553 break;
1554 case VKI_IPC_INFO|VKI_IPC_64:
1555 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1556 arg2, sizeof(struct vki_shminfo64) );
1557 break;
1558 case VKI_SHM_INFO:
1559 case VKI_SHM_INFO|VKI_IPC_64:
1560 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
1561 arg2, sizeof(struct vki_shm_info) );
1562 break;
1563 case VKI_IPC_STAT:
1564 case VKI_SHM_STAT:
1565 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
1566 arg2, sizeof(struct vki_shmid_ds) );
1567 break;
1568 case VKI_IPC_STAT|VKI_IPC_64:
1569 case VKI_SHM_STAT|VKI_IPC_64:
1570 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
1571 arg2, sizeof(struct vki_shmid64_ds) );
1572 break;
1573 case VKI_IPC_SET:
1574 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1575 arg2, sizeof(struct vki_shmid_ds) );
1576 break;
1577 case VKI_IPC_SET|VKI_IPC_64:
1578 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1579 arg2, sizeof(struct vki_shmid64_ds) );
1580 break;
1581 }
1582}
1583
1584void
sewardj7eb7c582005-06-23 01:02:53 +00001585ML_(generic_POST_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001586 UWord res,
1587 UWord arg0, UWord arg1, UWord arg2 )
1588{
1589 switch (arg1 /* cmd */) {
1590 case VKI_IPC_INFO:
1591 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
1592 break;
1593 case VKI_IPC_INFO|VKI_IPC_64:
1594 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
1595 break;
1596 case VKI_SHM_INFO:
1597 case VKI_SHM_INFO|VKI_IPC_64:
1598 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
1599 break;
1600 case VKI_IPC_STAT:
1601 case VKI_SHM_STAT:
1602 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
1603 break;
1604 case VKI_IPC_STAT|VKI_IPC_64:
1605 case VKI_SHM_STAT|VKI_IPC_64:
1606 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
1607 break;
1608 }
1609}
1610
1611
1612/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001613 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001614 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001615
nethercote4fa681f2004-11-08 17:51:39 +00001616/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001617 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001618 names like sys_write(); a few have names like old_mmap(). See the
njnaf839f52005-06-23 03:27:57 +00001619 comment for ML_(syscall_table)[] for important info about the __NR_foo
nethercote8ff888f2004-11-17 17:11:45 +00001620 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001621
nethercote92b2fd52004-11-16 16:15:41 +00001622 Some notes about names used for syscalls and args:
1623 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1624 ambiguity.
1625
1626 - For error messages, we generally use a somewhat generic name
1627 for the syscall (eg. "write" rather than "sys_write"). This should be
1628 good enough for the average user to understand what is happening,
1629 without confusing them with names like "sys_write".
1630
1631 - Also, for error messages the arg names are mostly taken from the man
1632 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001633 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001634 for the same reason -- a user presented with a "bogus foo(bar)" arg
1635 will most likely look at the "foo" man page to see which is the "bar"
1636 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001637
nethercote9c311eb2004-11-12 18:20:12 +00001638 Note that we use our own vki_* types. The one exception is in
1639 PRE_REG_READn calls, where pointer types haven't been changed, because
1640 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1641 be visible.
1642
nethercote4fa681f2004-11-08 17:51:39 +00001643 XXX: some of these are arch-specific, and should be factored out.
1644*/
1645
sewardja8d8e232005-06-07 20:04:56 +00001646#define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
1647#define POST(name) DEFN_POST_TEMPLATE(generic, name)
jsgf855d93d2003-10-13 22:26:55 +00001648
sewardje7aa4ae2005-06-09 12:43:42 +00001649// Combine two 32-bit values into a 64-bit value
1650#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1651
sewardja8d8e232005-06-07 20:04:56 +00001652//zz //PRE(sys_exit_group, Special)
1653//zz //{
1654//zz // VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1655//zz //}
nethercoteef0c7662004-11-06 15:38:43 +00001656
sewardja8d8e232005-06-07 20:04:56 +00001657PRE(sys_exit)
jsgf855d93d2003-10-13 22:26:55 +00001658{
sewardja8d8e232005-06-07 20:04:56 +00001659 ThreadState* tst;
sewardja922b612005-03-11 02:47:32 +00001660 /* simple; just make this thread exit */
1661 PRINT("exit( %d )", ARG1);
1662 PRE_REG_READ1(void, "exit", int, exitcode);
sewardja8d8e232005-06-07 20:04:56 +00001663 tst = VG_(get_ThreadState)(tid);
1664 /* Set the thread's status to be exiting, then claim that the
1665 syscall succeeded. */
sewardja922b612005-03-11 02:47:32 +00001666 tst->exitreason = VgSrc_ExitSyscall;
1667 tst->os_state.exitcode = ARG1;
sewardja8d8e232005-06-07 20:04:56 +00001668 SET_STATUS_Success(0);
jsgf855d93d2003-10-13 22:26:55 +00001669}
1670
sewardj78b50e42005-06-08 01:47:28 +00001671PRE(sys_sched_yield)
1672{
1673 *flags |= SfMayBlock;
1674 PRINT("sched_yield()");
1675 PRE_REG_READ0(long, "sys_sched_yield");
1676}
nethercote5b653bc2004-11-15 14:32:12 +00001677
sewardja8d8e232005-06-07 20:04:56 +00001678PRE(sys_ni_syscall)
nethercoteeb1c7b72004-11-11 19:43:50 +00001679{
1680 PRINT("non-existent syscall! (ni_syscall)");
1681 PRE_REG_READ0(long, "ni_syscall");
sewardja8d8e232005-06-07 20:04:56 +00001682 SET_STATUS_Failure( VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001683}
1684
sewardj696c5512005-06-08 23:38:32 +00001685PRE(sys_iopl)
1686{
1687 PRINT("sys_iopl ( %d )", ARG1);
1688 PRE_REG_READ1(long, "iopl", unsigned long, level);
1689}
1690
sewardje6d5e722005-06-10 10:27:55 +00001691PRE(sys_setxattr)
1692{
1693 *flags |= SfMayBlock;
1694 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
1695 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1696 PRE_REG_READ5(long, "setxattr",
1697 char *, path, char *, name,
1698 void *, value, vki_size_t, size, int, flags);
1699 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1700 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1701 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
1702}
1703
1704PRE(sys_lsetxattr)
1705{
1706 *flags |= SfMayBlock;
1707 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
1708 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1709 PRE_REG_READ5(long, "lsetxattr",
1710 char *, path, char *, name,
1711 void *, value, vki_size_t, size, int, flags);
1712 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
1713 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
1714 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
1715}
1716
1717PRE(sys_fsetxattr)
1718{
1719 *flags |= SfMayBlock;
1720 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
1721 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
1722 PRE_REG_READ5(long, "fsetxattr",
1723 int, fd, char *, name, void *, value,
1724 vki_size_t, size, int, flags);
1725 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1726 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
1727}
rjwalshcdf1cb52004-04-29 08:40:50 +00001728
sewardja8d8e232005-06-07 20:04:56 +00001729PRE(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001730{
sewardja8d8e232005-06-07 20:04:56 +00001731 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00001732 PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001733 PRE_REG_READ4(ssize_t, "getxattr",
1734 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001735 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
1736 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
1737 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001738}
nethercote85a456f2004-11-16 17:31:56 +00001739POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001740{
sewardja8d8e232005-06-07 20:04:56 +00001741 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00001742 if (RES > 0 && ARG3 != (Addr)NULL) {
1743 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001744 }
1745}
1746
sewardje6d5e722005-06-10 10:27:55 +00001747PRE(sys_lgetxattr)
1748{
1749 *flags |= SfMayBlock;
1750 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
1751 PRE_REG_READ4(ssize_t, "lgetxattr",
1752 char *, path, char *, name, void *, value, vki_size_t, size);
1753 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
1754 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
1755 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
1756}
1757POST(sys_lgetxattr)
1758{
1759 vg_assert(SUCCESS);
1760 if (RES > 0 && ARG3 != (Addr)NULL) {
1761 POST_MEM_WRITE( ARG3, RES );
1762 }
1763}
1764
1765PRE(sys_fgetxattr)
1766{
1767 *flags |= SfMayBlock;
1768 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
1769 PRE_REG_READ4(ssize_t, "fgetxattr",
1770 int, fd, char *, name, void *, value, vki_size_t, size);
1771 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
1772 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
1773}
1774POST(sys_fgetxattr)
1775{
1776 if (RES > 0 && ARG3 != (Addr)NULL)
1777 POST_MEM_WRITE( ARG3, RES );
1778}
1779
1780PRE(sys_listxattr)
1781{
1782 *flags |= SfMayBlock;
1783 PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1784 PRE_REG_READ3(ssize_t, "listxattr",
1785 char *, path, char *, list, vki_size_t, size);
1786 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1787 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
1788}
1789POST(sys_listxattr)
1790{
1791 if (RES > 0 && ARG2 != (Addr)NULL)
1792 POST_MEM_WRITE( ARG2, RES );
1793}
1794
1795PRE(sys_llistxattr)
1796{
1797 *flags |= SfMayBlock;
1798 PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1799 PRE_REG_READ3(ssize_t, "llistxattr",
1800 char *, path, char *, list, vki_size_t, size);
1801 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
1802 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
1803}
1804POST(sys_llistxattr)
1805{
1806 if (RES > 0 && ARG2 != (Addr)NULL)
1807 POST_MEM_WRITE( ARG2, RES );
1808}
1809
1810PRE(sys_flistxattr)
1811{
1812 *flags |= SfMayBlock;
1813 PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
1814 PRE_REG_READ3(ssize_t, "flistxattr",
1815 int, fd, char *, list, vki_size_t, size);
1816 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
1817}
1818POST(sys_flistxattr)
1819{
1820 if (RES > 0 && ARG2 != (Addr)NULL)
1821 POST_MEM_WRITE( ARG2, RES );
1822}
1823
1824PRE(sys_removexattr)
1825{
1826 *flags |= SfMayBlock;
1827 PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
1828 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
1829 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1830 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
1831}
1832
1833PRE(sys_lremovexattr)
1834{
1835 *flags |= SfMayBlock;
1836 PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
1837 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
1838 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
1839 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
1840}
1841
1842PRE(sys_fremovexattr)
1843{
1844 *flags |= SfMayBlock;
1845 PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
1846 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
1847 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
1848}
sewardj696c5512005-06-08 23:38:32 +00001849
1850PRE(sys_quotactl)
1851{
1852 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
1853 PRE_REG_READ4(long, "quotactl",
1854 unsigned int, cmd, const char *, special, vki_qid_t, id,
1855 void *, addr);
1856 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
1857}
1858
sewardje6d5e722005-06-10 10:27:55 +00001859// XXX: this wrapper is only suitable for 32-bit platforms
1860#if defined(VGP_x86_linux)
1861PRE(sys_lookup_dcookie)
1862{
1863 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
1864 PRE_REG_READ4(long, "lookup_dcookie",
1865 vki_u32, cookie_low32, vki_u32, cookie_high32,
1866 char *, buf, vki_size_t, len);
1867 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
1868}
1869POST(sys_lookup_dcookie)
1870{
1871 vg_assert(SUCCESS);
1872 if (ARG3 != (Addr)NULL)
1873 POST_MEM_WRITE( ARG3, RES);
1874}
1875#endif
sewardj78b50e42005-06-08 01:47:28 +00001876
1877PRE(sys_fsync)
1878{
1879 *flags |= SfMayBlock;
1880 PRINT("sys_fsync ( %d )", ARG1);
1881 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1882}
1883
sewardj696c5512005-06-08 23:38:32 +00001884PRE(sys_fdatasync)
1885{
1886 *flags |= SfMayBlock;
1887 PRINT("sys_fdatasync ( %d )", ARG1);
1888 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
1889}
1890
1891PRE(sys_msync)
1892{
1893 *flags |= SfMayBlock;
1894 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
1895 PRE_REG_READ3(long, "msync",
1896 unsigned long, start, vki_size_t, length, int, flags);
1897 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
1898}
1899
sewardje6d5e722005-06-10 10:27:55 +00001900// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1901// versions of LiS (Linux Streams). They are not part of the kernel.
1902// Therefore, we have to provide this type ourself, rather than getting it
1903// from the kernel sources.
1904struct vki_pmsg_strbuf {
1905 int maxlen; /* no. of bytes in buffer */
1906 int len; /* no. of bytes returned */
1907 vki_caddr_t buf; /* pointer to data */
1908};
1909PRE(sys_getpmsg)
1910{
1911 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
1912 struct vki_pmsg_strbuf *ctrl;
1913 struct vki_pmsg_strbuf *data;
1914 *flags |= SfMayBlock;
1915 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
1916 PRE_REG_READ5(int, "getpmsg",
1917 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1918 int *, bandp, int *, flagsp);
1919 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1920 data = (struct vki_pmsg_strbuf *)ARG3;
1921 if (ctrl && ctrl->maxlen > 0)
1922 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
1923 if (data && data->maxlen > 0)
1924 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
1925 if (ARG4)
1926 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
1927 if (ARG5)
1928 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
1929}
1930POST(sys_getpmsg)
1931{
1932 struct vki_pmsg_strbuf *ctrl;
1933 struct vki_pmsg_strbuf *data;
1934 vg_assert(SUCCESS);
1935 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1936 data = (struct vki_pmsg_strbuf *)ARG3;
1937 if (RES == 0 && ctrl && ctrl->len > 0) {
1938 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
1939 }
1940 if (RES == 0 && data && data->len > 0) {
1941 POST_MEM_WRITE( (Addr)data->buf, data->len);
1942 }
1943}
1944
1945PRE(sys_putpmsg)
1946{
1947 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
1948 struct vki_pmsg_strbuf *ctrl;
1949 struct vki_pmsg_strbuf *data;
1950 *flags |= SfMayBlock;
1951 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
1952 PRE_REG_READ5(int, "putpmsg",
1953 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1954 int, band, int, flags);
1955 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1956 data = (struct vki_pmsg_strbuf *)ARG3;
1957 if (ctrl && ctrl->len > 0)
1958 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
1959 if (data && data->len > 0)
1960 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
1961}
sewardj696c5512005-06-08 23:38:32 +00001962
1963PRE(sys_getitimer)
1964{
1965 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
1966 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
1967 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
1968}
sewardj696c5512005-06-08 23:38:32 +00001969POST(sys_getitimer)
1970{
1971 if (ARG2 != (Addr)NULL) {
1972 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
1973 }
1974}
1975
1976PRE(sys_setitimer)
1977{
1978 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
1979 PRE_REG_READ3(long, "setitimer",
1980 int, which,
1981 struct itimerval *, value, struct itimerval *, ovalue);
1982 if (ARG2 != (Addr)NULL)
1983 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
1984 if (ARG3 != (Addr)NULL)
1985 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
1986}
1987
1988POST(sys_setitimer)
1989{
1990 if (ARG3 != (Addr)NULL) {
1991 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
1992 }
1993}
1994
1995PRE(sys_chroot)
1996{
1997 PRINT("sys_chroot ( %p )", ARG1);
1998 PRE_REG_READ1(long, "chroot", const char *, path);
1999 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
2000}
sewardja8d8e232005-06-07 20:04:56 +00002001
2002PRE(sys_madvise)
jsgf855d93d2003-10-13 22:26:55 +00002003{
sewardja8d8e232005-06-07 20:04:56 +00002004 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002005 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00002006 PRE_REG_READ3(long, "madvise",
2007 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00002008}
2009
sewardja8d8e232005-06-07 20:04:56 +00002010PRE(sys_mremap)
jsgf855d93d2003-10-13 22:26:55 +00002011{
nethercote27ea8bc2004-07-10 17:21:14 +00002012 // Nb: this is different to the glibc version described in the man pages,
2013 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00002014 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
njn22cfccb2004-11-27 16:10:23 +00002015 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
nethercote06c7bd72004-11-14 19:11:56 +00002016 PRE_REG_READ5(unsigned long, "mremap",
2017 unsigned long, old_addr, unsigned long, old_size,
2018 unsigned long, new_size, unsigned long, flags,
2019 unsigned long, new_addr);
sewardja8d8e232005-06-07 20:04:56 +00002020 SET_STATUS_from_SysRes(
2021 mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
2022 );
jsgf855d93d2003-10-13 22:26:55 +00002023}
2024
sewardj8c9ea4e2005-06-08 10:46:56 +00002025PRE(sys_nice)
2026{
2027 PRINT("sys_nice ( %d )", ARG1);
2028 PRE_REG_READ1(long, "nice", int, inc);
2029}
sewardj78b50e42005-06-08 01:47:28 +00002030
2031PRE(sys_sched_getscheduler)
2032{
2033 PRINT("sys_sched_getscheduler ( %d )", ARG1);
2034 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
2035}
2036
2037PRE(sys_sched_setscheduler)
2038{
2039 PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
2040 PRE_REG_READ3(long, "sched_setscheduler",
2041 vki_pid_t, pid, int, policy, struct sched_param *, p);
2042 if (ARG3 != 0)
2043 PRE_MEM_READ( "sched_setscheduler(p)",
2044 ARG3, sizeof(struct vki_sched_param));
2045}
2046
sewardj696c5512005-06-08 23:38:32 +00002047PRE(sys_mlock)
2048{
2049 *flags |= SfMayBlock;
2050 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
2051 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
2052}
2053
2054PRE(sys_munlock)
2055{
2056 *flags |= SfMayBlock;
2057 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
2058 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
2059}
2060
2061PRE(sys_mlockall)
2062{
2063 *flags |= SfMayBlock;
2064 PRINT("sys_mlockall ( %x )", ARG1);
2065 PRE_REG_READ1(long, "mlockall", int, flags);
2066}
2067
2068PRE(sys_munlockall)
2069{
2070 *flags |= SfMayBlock;
2071 PRINT("sys_munlockall ( )");
2072 PRE_REG_READ0(long, "munlockall");
2073}
sewardj78b50e42005-06-08 01:47:28 +00002074
2075PRE(sys_sched_get_priority_max)
2076{
2077 PRINT("sched_get_priority_max ( %d )", ARG1);
2078 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
2079}
2080
2081PRE(sys_sched_get_priority_min)
2082{
2083 PRINT("sched_get_priority_min ( %d )", ARG1);
2084 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
2085}
2086
sewardj696c5512005-06-08 23:38:32 +00002087PRE(sys_setpriority)
2088{
2089 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
2090 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
2091}
2092
2093PRE(sys_getpriority)
2094{
2095 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
2096 PRE_REG_READ2(long, "getpriority", int, which, int, who);
2097}
2098
2099PRE(sys_setregid16)
2100{
2101 PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
2102 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
2103}
2104
tom4f08a652005-07-05 23:25:17 +00002105// The actual kernel definition of this routine takes a
2106// single 64 bit offset argument. This version is for 32 bit
2107// platforms only and treats the offset as two values - the
2108// kernel relies on stack based argument passing conventions
2109// to merge the two together.
sewardje6d5e722005-06-10 10:27:55 +00002110PRE(sys_pwrite64)
2111{
2112 *flags |= SfMayBlock;
2113 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
2114 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2115 PRE_REG_READ5(ssize_t, "pwrite64",
2116 unsigned int, fd, const char *, buf, vki_size_t, count,
2117 vki_u32, offset_low32, vki_u32, offset_high32);
2118 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
2119}
sewardj8c9ea4e2005-06-08 10:46:56 +00002120
2121PRE(sys_sync)
2122{
2123 *flags |= SfMayBlock;
2124 PRINT("sys_sync ( )");
2125 PRE_REG_READ0(long, "sync");
2126}
2127
sewardj696c5512005-06-08 23:38:32 +00002128PRE(sys_fstatfs)
2129{
2130 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
2131 PRE_REG_READ2(long, "fstatfs",
2132 unsigned int, fd, struct statfs *, buf);
2133 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
2134}
2135
2136POST(sys_fstatfs)
2137{
2138 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
2139}
2140
sewardje6d5e722005-06-10 10:27:55 +00002141PRE(sys_fstatfs64)
2142{
2143 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
2144 PRE_REG_READ3(long, "fstatfs64",
2145 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
2146 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
2147}
2148POST(sys_fstatfs64)
2149{
2150 POST_MEM_WRITE( ARG3, ARG2 );
2151}
sewardj696c5512005-06-08 23:38:32 +00002152
2153PRE(sys_getsid)
2154{
2155 PRINT("sys_getsid ( %d )", ARG1);
2156 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
2157}
2158
tom4f08a652005-07-05 23:25:17 +00002159// The actual kernel definition of this routine takes a
2160// single 64 bit offset argument. This version is for 32 bit
2161// platforms only and treats the offset as two values - the
2162// kernel relies on stack based argument passing conventions
2163// to merge the two together.
sewardje7aa4ae2005-06-09 12:43:42 +00002164PRE(sys_pread64)
2165{
2166 *flags |= SfMayBlock;
2167 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
2168 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2169 PRE_REG_READ5(ssize_t, "pread64",
2170 unsigned int, fd, char *, buf, vki_size_t, count,
2171 vki_u32, offset_low32, vki_u32, offset_high32);
2172 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
2173}
2174POST(sys_pread64)
2175{
2176 vg_assert(SUCCESS);
2177 if (RES > 0) {
2178 POST_MEM_WRITE( ARG2, RES );
2179 }
2180}
jsgf855d93d2003-10-13 22:26:55 +00002181
sewardja8d8e232005-06-07 20:04:56 +00002182PRE(sys_mknod)
jsgf855d93d2003-10-13 22:26:55 +00002183{
njn22cfccb2004-11-27 16:10:23 +00002184 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00002185 PRE_REG_READ3(long, "mknod",
2186 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00002187 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002188}
2189
sewardj696c5512005-06-08 23:38:32 +00002190PRE(sys_flock)
2191{
2192 *flags |= SfMayBlock;
2193 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
2194 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
2195}
2196
2197/* This surely isn't remotely generic -- move to linux-specifics? */
2198PRE(sys_init_module)
2199{
2200 *flags |= SfMayBlock;
2201 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
2202 PRE_REG_READ3(long, "init_module",
2203 void *, umod, unsigned long, len, const char *, uargs);
2204 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
2205 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
2206}
2207
sewardje6d5e722005-06-10 10:27:55 +00002208PRE(sys_capget)
2209{
2210 PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
2211 PRE_REG_READ2(long, "capget",
2212 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
2213 PRE_MEM_READ( "capget(header)", ARG1,
2214 sizeof(struct __vki_user_cap_header_struct) );
2215 PRE_MEM_WRITE( "capget(data)", ARG2,
2216 sizeof(struct __vki_user_cap_data_struct) );
2217}
2218POST(sys_capget)
2219{
2220 if (ARG2 != (Addr)NULL)
2221 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
2222}
2223
2224PRE(sys_capset)
2225{
2226 PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
2227 PRE_REG_READ2(long, "capset",
2228 vki_cap_user_header_t, header,
2229 const vki_cap_user_data_t, data);
2230 PRE_MEM_READ( "capset(header)",
2231 ARG1, sizeof(struct __vki_user_cap_header_struct) );
2232 PRE_MEM_READ( "capset(data)",
2233 ARG2, sizeof(struct __vki_user_cap_data_struct) );
2234}
jsgf855d93d2003-10-13 22:26:55 +00002235
nethercotea81e9162004-02-12 14:34:14 +00002236// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00002237static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00002238{
2239 while (True) {
njnb249fd72004-11-29 14:24:57 +00002240 Addr a_deref;
2241 Addr* a_p = (Addr*)a;
2242 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2243 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00002244 if (0 == a_deref)
2245 break;
nethercoteef0c7662004-11-06 15:38:43 +00002246 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00002247 a += sizeof(char*);
2248 }
2249}
2250
njn7b85dd52005-06-12 17:26:29 +00002251static Bool i_am_the_only_thread ( void )
2252{
2253 Int c = VG_(count_living_threads)();
2254 vg_assert(c >= 1); /* stay sane */
2255 return c == 1;
2256}
2257
2258/* Wait until all other threads disappear. */
2259void VG_(reap_threads)(ThreadId self)
2260{
2261 while (!i_am_the_only_thread()) {
2262 /* Let other thread(s) run */
2263 VG_(vg_yield)();
2264 VG_(poll_signals)(self);
2265 }
2266 vg_assert(i_am_the_only_thread());
2267}
2268
nethercote7310afb2004-11-12 15:41:06 +00002269// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
2270// but it seems to work nonetheless...
sewardja8d8e232005-06-07 20:04:56 +00002271PRE(sys_execve)
jsgf855d93d2003-10-13 22:26:55 +00002272{
sewardja8d8e232005-06-07 20:04:56 +00002273 Char* path; /* path to executable */
2274 ThreadState* tst;
sewardjb5f6f512005-03-10 23:59:00 +00002275
njn22cfccb2004-11-27 16:10:23 +00002276 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00002277 PRE_REG_READ3(vki_off_t, "execve",
2278 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00002279 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
2280 if (ARG2 != 0)
2281 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
2282 if (ARG3 != 0)
2283 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00002284
sewardjb5f6f512005-03-10 23:59:00 +00002285 path = (Char *)ARG1;
2286
sewardja8d8e232005-06-07 20:04:56 +00002287 vg_assert(VG_(is_valid_tid)(tid));
2288 tst = VG_(get_ThreadState)(tid);
2289
fitzhardingee1c06d82003-10-30 07:21:44 +00002290 /* Erk. If the exec fails, then the following will have made a
2291 mess of things which makes it hard for us to continue. The
2292 right thing to do is piece everything together again in
2293 POST(execve), but that's hard work. Instead, we make an effort
2294 to check that the execve will work before actually calling
2295 exec. */
2296 {
2297 struct vki_stat st;
sewardja8d8e232005-06-07 20:04:56 +00002298 Int i = VG_(stat)((Char *)ARG1, &st);
fitzhardingee1c06d82003-10-30 07:21:44 +00002299
sewardja8d8e232005-06-07 20:04:56 +00002300 if (i == -1) {
2301 /* stat failed */
2302 SET_STATUS_Failure( VKI_EACCES/*really, we should copy stat's result*/ );
fitzhardingee1c06d82003-10-30 07:21:44 +00002303 return;
2304 }
thughes90efa302004-09-25 16:13:55 +00002305 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00002306 XXX do proper permissions check?
2307 */
thughes90efa302004-09-25 16:13:55 +00002308 if ((st.st_mode & 0100111) == 0100000) {
sewardja8d8e232005-06-07 20:04:56 +00002309 SET_STATUS_Failure( VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00002310 return;
2311 }
2312 }
2313
2314 /* Resistance is futile. Nuke all other threads. POSIX mandates
2315 this. (Really, nuke them all, since the new process will make
2316 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00002317 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
njn7b85dd52005-06-12 17:26:29 +00002318 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002319
sewardj1d887112005-05-30 21:44:08 +00002320 { // Remove the valgrind-specific stuff from the environment so the
njn16eeb4e2005-06-16 03:56:58 +00002321 // child doesn't get vg_preload_core.so, vg_preload_TOOL.so, etc.
2322 // This is done unconditionally, since if we are tracing the child,
sewardj1d887112005-05-30 21:44:08 +00002323 // stage1/2 will set up the appropriate client environment.
2324 Char** envp = (Char**)ARG3;
2325 if (envp != NULL) {
2326 VG_(env_remove_valgrind_env_stuff)( envp );
2327 }
fitzhardinge5408c062004-01-04 23:52:59 +00002328 }
2329
2330 if (VG_(clo_trace_children)) {
njn22cfccb2004-11-27 16:10:23 +00002331 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)ARG1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00002332
njn22cfccb2004-11-27 16:10:23 +00002333 // Set VALGRINDCLO and VALGRINDLIB in ARG3 (the environment)
2334 VG_(env_setenv)( (Char***)&ARG3, VALGRINDCLO, optvar);
2335 VG_(env_setenv)( (Char***)&ARG3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002336
njn22cfccb2004-11-27 16:10:23 +00002337 // Create executable name: "/proc/self/fd/<vgexecfd>", update ARG1
sewardj8e332792005-03-11 12:56:56 +00002338 path = VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00002339 }
2340
njnc1b01812005-06-17 22:19:06 +00002341 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)ARG1);
sewardj10759312005-05-30 23:52:47 +00002342
fitzhardinge98abfc72003-12-16 02:05:15 +00002343 if (0) {
2344 Char **cpp;
2345
njn22cfccb2004-11-27 16:10:23 +00002346 VG_(printf)("exec: %s\n", (Char *)ARG1);
2347 for(cpp = (Char **)ARG2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002348 VG_(printf)("argv: %s\n", *cpp);
njn22cfccb2004-11-27 16:10:23 +00002349 for(cpp = (Char **)ARG3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002350 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00002351 }
jsgf855d93d2003-10-13 22:26:55 +00002352
sewardjb5f6f512005-03-10 23:59:00 +00002353 /* restore the DATA rlimit for the child */
2354 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2355
2356 /*
2357 Set the signal state up for exec.
2358
2359 We need to set the real signal state to make sure the exec'd
2360 process gets SIG_IGN properly.
2361
2362 Also set our real sigmask to match the client's sigmask so that
2363 the exec'd child will get the right mask. First we need to
2364 clear out any pending signals so they they don't get delivered,
2365 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002366
2367 XXX This is a bug - the signals should remain pending, and be
2368 delivered to the new process after exec. There's also a
2369 race-condition, since if someone delivers us a signal between
2370 the sigprocmask and the execve, we'll still get the signal. Oh
2371 well.
2372 */
2373 {
nethercote73b526f2004-10-31 18:48:21 +00002374 vki_sigset_t allsigs;
2375 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002376 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002377 Int i;
2378
2379 for(i = 1; i < VG_(max_signal); i++) {
2380 struct vki_sigaction sa;
2381 VG_(do_sys_sigaction)(i, NULL, &sa);
2382 if (sa.ksa_handler == VKI_SIG_IGN)
2383 VG_(sigaction)(i, &sa, NULL);
2384 else {
2385 sa.ksa_handler = VKI_SIG_DFL;
2386 VG_(sigaction)(i, &sa, NULL);
2387 }
2388 }
2389
nethercote73b526f2004-10-31 18:48:21 +00002390 VG_(sigfillset)(&allsigs);
2391 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002392 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002393
nethercote73b526f2004-10-31 18:48:21 +00002394 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002395 }
2396
sewardja8d8e232005-06-07 20:04:56 +00002397 SET_STATUS_from_SysRes(
2398 VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3)
2399 );
fitzhardingeb50068f2004-02-24 23:42:55 +00002400
sewardjb5f6f512005-03-10 23:59:00 +00002401 /* If we got here, then the execve failed. We've already made too
2402 much of a mess of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00002403 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
sewardjb5f6f512005-03-10 23:59:00 +00002404 ARG1, ARG1, ARG2, ARG3, -RES);
2405 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2406 "execve() failing, so I'm dying.");
sewardja8d8e232005-06-07 20:04:56 +00002407 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
sewardjb5f6f512005-03-10 23:59:00 +00002408 "or work out how to recover.");
2409 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002410}
2411
sewardja8d8e232005-06-07 20:04:56 +00002412PRE(sys_access)
jsgf855d93d2003-10-13 22:26:55 +00002413{
njn22cfccb2004-11-27 16:10:23 +00002414 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002415 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002416 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002417}
2418
sewardja8d8e232005-06-07 20:04:56 +00002419PRE(sys_alarm)
jsgf855d93d2003-10-13 22:26:55 +00002420{
njn22cfccb2004-11-27 16:10:23 +00002421 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002422 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002423}
2424
sewardja8d8e232005-06-07 20:04:56 +00002425PRE(sys_brk)
jsgf855d93d2003-10-13 22:26:55 +00002426{
fitzhardinge98abfc72003-12-16 02:05:15 +00002427 Addr brk_limit = VG_(brk_limit);
sewardja8d8e232005-06-07 20:04:56 +00002428 Addr brk_new;
fitzhardinge98abfc72003-12-16 02:05:15 +00002429
jsgf855d93d2003-10-13 22:26:55 +00002430 /* libc says: int brk(void *end_data_segment);
2431 kernel says: void* brk(void* end_data_segment); (more or less)
2432
2433 libc returns 0 on success, and -1 (and sets errno) on failure.
2434 Nb: if you ask to shrink the dataseg end below what it
2435 currently is, that always succeeds, even if the dataseg end
2436 doesn't actually change (eg. brk(0)). Unless it seg faults.
2437
2438 Kernel returns the new dataseg end. If the brk() failed, this
2439 will be unchanged from the old one. That's why calling (kernel)
2440 brk(0) gives the current dataseg end (libc brk() just returns
2441 zero in that case).
2442
2443 Both will seg fault if you shrink it back into a text segment.
2444 */
njn22cfccb2004-11-27 16:10:23 +00002445 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002446 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002447
sewardja8d8e232005-06-07 20:04:56 +00002448 brk_new = do_brk(ARG1);
2449 SET_STATUS_Success( brk_new );
fitzhardinge98abfc72003-12-16 02:05:15 +00002450
sewardja8d8e232005-06-07 20:04:56 +00002451 if (brk_new == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002452 /* brk() succeeded */
sewardja8d8e232005-06-07 20:04:56 +00002453 if (brk_new < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002454 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002455 VG_TRACK( die_mem_brk, (Addr)ARG1,
2456 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002457 } else
sewardja8d8e232005-06-07 20:04:56 +00002458 if (brk_new > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002459 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002460 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002461 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002462 }
jsgf855d93d2003-10-13 22:26:55 +00002463 } else {
2464 /* brk() failed */
sewardja8d8e232005-06-07 20:04:56 +00002465 vg_assert(brk_limit == brk_new);
jsgf855d93d2003-10-13 22:26:55 +00002466 }
2467}
2468
sewardja8d8e232005-06-07 20:04:56 +00002469PRE(sys_chdir)
jsgf855d93d2003-10-13 22:26:55 +00002470{
njn22cfccb2004-11-27 16:10:23 +00002471 PRINT("sys_chdir ( %p )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002472 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002473 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002474}
2475
sewardja8d8e232005-06-07 20:04:56 +00002476PRE(sys_chmod)
jsgf855d93d2003-10-13 22:26:55 +00002477{
njn22cfccb2004-11-27 16:10:23 +00002478 PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002479 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002480 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002481}
2482
sewardje6d5e722005-06-10 10:27:55 +00002483PRE(sys_chown16)
2484{
2485 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2486 PRE_REG_READ3(long, "chown16",
2487 const char *, path,
2488 vki_old_uid_t, owner, vki_old_gid_t, group);
2489 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
2490}
2491
2492PRE(sys_chown)
2493{
2494 /* int chown(const char *path, uid_t owner, gid_t group); */
2495 PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2496 PRE_REG_READ3(long, "chown",
2497 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2498 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
2499}
2500
2501PRE(sys_lchown)
2502{
2503 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
2504 PRE_REG_READ3(long, "lchown",
2505 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2506 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
2507}
nethercote2e1c37d2004-11-13 13:57:12 +00002508
sewardja8d8e232005-06-07 20:04:56 +00002509PRE(sys_close)
jsgf855d93d2003-10-13 22:26:55 +00002510{
njn22cfccb2004-11-27 16:10:23 +00002511 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002512 PRE_REG_READ1(long, "close", unsigned int, fd);
2513
nethercotef8548672004-06-21 12:42:35 +00002514 /* Detect and negate attempts by the client to close Valgrind's log fd */
sewardj7eb7c582005-06-23 01:02:53 +00002515 if (!ML_(fd_allowed)(ARG1, "close", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00002516 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002517}
2518
nethercote85a456f2004-11-16 17:31:56 +00002519POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002520{
njn22cfccb2004-11-27 16:10:23 +00002521 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002522}
jsgf855d93d2003-10-13 22:26:55 +00002523
sewardja8d8e232005-06-07 20:04:56 +00002524PRE(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002525{
njn22cfccb2004-11-27 16:10:23 +00002526 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002527 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002528}
2529
nethercote85a456f2004-11-16 17:31:56 +00002530POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002531{
sewardja8d8e232005-06-07 20:04:56 +00002532 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00002533 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002534 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002535 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002536 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002537 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002538 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002539 }
2540}
2541
sewardja8d8e232005-06-07 20:04:56 +00002542PRE(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002543{
njn22cfccb2004-11-27 16:10:23 +00002544 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002545 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
sewardj7eb7c582005-06-23 01:02:53 +00002546 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
sewardja8d8e232005-06-07 20:04:56 +00002547 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002548}
2549
nethercote85a456f2004-11-16 17:31:56 +00002550POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002551{
sewardja8d8e232005-06-07 20:04:56 +00002552 vg_assert(SUCCESS);
nethercote71f05f32004-11-12 18:49:27 +00002553 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002554 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002555}
2556
sewardj696c5512005-06-08 23:38:32 +00002557PRE(sys_fchdir)
2558{
2559 PRINT("sys_fchdir ( %d )", ARG1);
2560 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
2561}
2562
2563PRE(sys_fchown16)
2564{
2565 PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
2566 PRE_REG_READ3(long, "fchown16",
2567 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
2568}
2569
sewardje6d5e722005-06-10 10:27:55 +00002570PRE(sys_fchown)
2571{
2572 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
2573 PRE_REG_READ3(long, "fchown",
2574 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2575}
sewardj696c5512005-06-08 23:38:32 +00002576
2577PRE(sys_fchmod)
2578{
2579 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
2580 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
2581}
2582
2583PRE(sys_fcntl)
2584{
2585 switch (ARG2) {
2586 // These ones ignore ARG3.
2587 case VKI_F_GETFD:
2588 case VKI_F_GETFL:
2589 case VKI_F_GETOWN:
2590 case VKI_F_SETOWN:
2591 case VKI_F_GETSIG:
2592 case VKI_F_SETSIG:
2593 case VKI_F_GETLEASE:
2594 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2595 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
2596 break;
2597
2598 // These ones use ARG3 as "arg".
2599 case VKI_F_DUPFD:
2600 case VKI_F_SETFD:
2601 case VKI_F_SETFL:
2602 case VKI_F_SETLEASE:
2603 case VKI_F_NOTIFY:
2604 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2605 PRE_REG_READ3(long, "fcntl",
2606 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2607 break;
2608
2609 // These ones use ARG3 as "lock".
2610 case VKI_F_GETLK:
2611 case VKI_F_SETLK:
2612 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002613# if defined(VGP_x86_linux)
sewardj696c5512005-06-08 23:38:32 +00002614 case VKI_F_GETLK64:
2615 case VKI_F_SETLK64:
2616 case VKI_F_SETLKW64:
2617# else
2618# endif
2619 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2620 PRE_REG_READ3(long, "fcntl",
2621 unsigned int, fd, unsigned int, cmd,
2622 struct flock64 *, lock);
2623 break;
2624 }
2625
2626 if (ARG2 == VKI_F_SETLKW)
2627 *flags |= SfMayBlock;
2628}
2629
2630POST(sys_fcntl)
2631{
2632 vg_assert(SUCCESS);
2633 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002634 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
sewardj696c5512005-06-08 23:38:32 +00002635 VG_(close)(RES);
2636 SET_STATUS_Failure( VKI_EMFILE );
2637 } else {
2638 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002639 record_fd_open_named(tid, RES);
sewardj696c5512005-06-08 23:38:32 +00002640 }
2641 }
2642}
njncfb8ad52004-11-23 14:57:49 +00002643
nethercote06c7bd72004-11-14 19:11:56 +00002644// XXX: wrapper only suitable for 32-bit systems
sewardja8d8e232005-06-07 20:04:56 +00002645PRE(sys_fcntl64)
jsgf855d93d2003-10-13 22:26:55 +00002646{
njnc6168192004-11-29 13:54:10 +00002647 switch (ARG2) {
2648 // These ones ignore ARG3.
2649 case VKI_F_GETFD:
2650 case VKI_F_GETFL:
2651 case VKI_F_GETOWN:
2652 case VKI_F_SETOWN:
2653 case VKI_F_GETSIG:
2654 case VKI_F_SETSIG:
2655 case VKI_F_GETLEASE:
2656 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2657 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2658 break;
2659
2660 // These ones use ARG3 as "arg".
2661 case VKI_F_DUPFD:
2662 case VKI_F_SETFD:
2663 case VKI_F_SETFL:
2664 case VKI_F_SETLEASE:
2665 case VKI_F_NOTIFY:
2666 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2667 PRE_REG_READ3(long, "fcntl64",
2668 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2669 break;
2670
2671 // These ones use ARG3 as "lock".
2672 case VKI_F_GETLK:
2673 case VKI_F_SETLK:
2674 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002675# if defined(VGP_x86_linux)
njnc6168192004-11-29 13:54:10 +00002676 case VKI_F_GETLK64:
2677 case VKI_F_SETLK64:
2678 case VKI_F_SETLKW64:
sewardja8d8e232005-06-07 20:04:56 +00002679# endif
njnc6168192004-11-29 13:54:10 +00002680 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2681 PRE_REG_READ3(long, "fcntl64",
2682 unsigned int, fd, unsigned int, cmd,
2683 struct flock64 *, lock);
2684 break;
2685 }
njncfb8ad52004-11-23 14:57:49 +00002686
sewardje7aa4ae2005-06-09 12:43:42 +00002687# if defined(VGP_x86_linux)
2688 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2689 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002690# else
sewardje7aa4ae2005-06-09 12:43:42 +00002691 if (ARG2 == VKI_F_SETLKW)
2692 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002693# endif
rjwalshf5f536f2003-11-17 17:45:00 +00002694}
2695
nethercote85a456f2004-11-16 17:31:56 +00002696POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002697{
sewardja8d8e232005-06-07 20:04:56 +00002698 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002699 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002700 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002701 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002702 SET_STATUS_Failure( VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002703 } else {
2704 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002705 record_fd_open_named(tid, RES);
nethercote493dd182004-02-24 23:57:47 +00002706 }
2707 }
jsgf855d93d2003-10-13 22:26:55 +00002708}
2709
sewardj696c5512005-06-08 23:38:32 +00002710PRE(sys_newfstat)
2711{
2712 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
2713 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
2714 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
2715}
2716
2717POST(sys_newfstat)
2718{
2719 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
2720}
jsgf855d93d2003-10-13 22:26:55 +00002721
nethercote73b526f2004-10-31 18:48:21 +00002722static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002723
nethercote75a8c982004-11-11 19:03:34 +00002724// In Linux, the sys_fork() function varies across architectures, but we
2725// ignore the various args it gets, and so it looks arch-neutral. Hmm.
sewardja8d8e232005-06-07 20:04:56 +00002726PRE(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002727{
nethercote73b526f2004-10-31 18:48:21 +00002728 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002729
nethercote75a8c982004-11-11 19:03:34 +00002730 PRINT("sys_fork ( )");
2731 PRE_REG_READ0(long, "fork");
2732
jsgf855d93d2003-10-13 22:26:55 +00002733 /* Block all signals during fork, so that we can fix things up in
2734 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002735 VG_(sigfillset)(&mask);
2736 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002737
sewardja8d8e232005-06-07 20:04:56 +00002738 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
sewardjb5f6f512005-03-10 23:59:00 +00002739
sewardja8d8e232005-06-07 20:04:56 +00002740 if (SUCCESS && RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002741 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002742
2743 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002744 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardja8d8e232005-06-07 20:04:56 +00002745 }
2746 else
2747 if (SUCCESS && RES > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002748 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002749
jsgf855d93d2003-10-13 22:26:55 +00002750 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002751 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002752 }
2753}
2754
sewardj8c257322005-06-08 01:01:48 +00002755PRE(sys_ftruncate)
2756{
2757 *flags |= SfMayBlock;
2758 PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
2759 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
2760}
2761
sewardj696c5512005-06-08 23:38:32 +00002762PRE(sys_truncate)
2763{
2764 *flags |= SfMayBlock;
2765 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
2766 PRE_REG_READ2(long, "truncate",
2767 const char *, path, unsigned long, length);
2768 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
2769}
2770
sewardje6d5e722005-06-10 10:27:55 +00002771// XXX: this wrapper is only suitable for 32-bit platforms
2772#if defined(VGP_x86_linux)
2773PRE(sys_ftruncate64)
2774{
2775 *flags |= SfMayBlock;
2776 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
2777 PRE_REG_READ3(long, "ftruncate64",
2778 unsigned int, fd,
2779 vki_u32, length_low32, vki_u32, length_high32);
2780}
2781#endif
2782
2783// XXX: this wrapper is only suitable for 32-bit platforms
2784#if defined(VGP_x86_linux)
2785PRE(sys_truncate64)
2786{
2787 *flags |= SfMayBlock;
2788 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
2789 PRE_REG_READ3(long, "truncate64",
2790 const char *, path,
2791 vki_u32, length_low32, vki_u32, length_high32);
2792 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
2793}
2794#endif
sewardj78b50e42005-06-08 01:47:28 +00002795
2796PRE(sys_getdents)
2797{
2798 *flags |= SfMayBlock;
2799 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
2800 PRE_REG_READ3(long, "getdents",
2801 unsigned int, fd, struct linux_dirent *, dirp,
2802 unsigned int, count);
2803 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
2804}
2805
2806POST(sys_getdents)
2807{
2808 vg_assert(SUCCESS);
2809 if (RES > 0)
2810 POST_MEM_WRITE( ARG2, RES );
2811}
jsgf855d93d2003-10-13 22:26:55 +00002812
sewardja8d8e232005-06-07 20:04:56 +00002813PRE(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002814{
sewardj78b50e42005-06-08 01:47:28 +00002815 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002816 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002817 PRE_REG_READ3(long, "getdents64",
2818 unsigned int, fd, struct linux_dirent64 *, dirp,
2819 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002820 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002821}
2822
nethercote85a456f2004-11-16 17:31:56 +00002823POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002824{
sewardja8d8e232005-06-07 20:04:56 +00002825 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002826 if (RES > 0)
2827 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002828}
2829
sewardj696c5512005-06-08 23:38:32 +00002830PRE(sys_getgroups16)
2831{
2832 PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
2833 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2834 if (ARG1 > 0)
2835 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
2836}
2837
2838POST(sys_getgroups16)
2839{
2840 vg_assert(SUCCESS);
2841 if (ARG1 > 0 && RES > 0)
2842 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
2843}
sewardj78b50e42005-06-08 01:47:28 +00002844
2845PRE(sys_getgroups)
2846{
2847 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
2848 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
2849 if (ARG1 > 0)
2850 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
2851}
2852
2853POST(sys_getgroups)
2854{
2855 vg_assert(SUCCESS);
2856 if (ARG1 > 0 && RES > 0)
2857 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
2858}
nethercote686b5db2004-11-14 13:42:51 +00002859
sewardja8d8e232005-06-07 20:04:56 +00002860PRE(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002861{
nethercoteac866b92004-11-15 20:23:15 +00002862 // Note that the kernel version of getcwd() behaves quite differently to
2863 // the glibc one.
njn22cfccb2004-11-27 16:10:23 +00002864 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002865 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002866 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002867}
2868
nethercote85a456f2004-11-16 17:31:56 +00002869POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002870{
sewardja8d8e232005-06-07 20:04:56 +00002871 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002872 if (RES != (Addr)NULL)
2873 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002874}
2875
sewardja8d8e232005-06-07 20:04:56 +00002876PRE(sys_geteuid16)
jsgf855d93d2003-10-13 22:26:55 +00002877{
nethercote0df495a2004-11-11 16:38:21 +00002878 PRINT("sys_geteuid16 ( )");
2879 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002880}
2881
sewardja8d8e232005-06-07 20:04:56 +00002882PRE(sys_geteuid)
jsgf855d93d2003-10-13 22:26:55 +00002883{
nethercote0df495a2004-11-11 16:38:21 +00002884 PRINT("sys_geteuid ( )");
2885 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002886}
2887
sewardj696c5512005-06-08 23:38:32 +00002888PRE(sys_getegid16)
2889{
2890 PRINT("sys_getegid16 ( )");
2891 PRE_REG_READ0(long, "getegid16");
2892}
sewardj78b50e42005-06-08 01:47:28 +00002893
2894PRE(sys_getegid)
2895{
2896 PRINT("sys_getegid ( )");
2897 PRE_REG_READ0(long, "getegid");
2898}
2899
sewardj8c9ea4e2005-06-08 10:46:56 +00002900PRE(sys_getgid16)
2901{
2902 PRINT("sys_getgid16 ( )");
2903 PRE_REG_READ0(long, "getgid16");
2904}
sewardj78b50e42005-06-08 01:47:28 +00002905
2906PRE(sys_getgid)
2907{
2908 PRINT("sys_getgid ( )");
2909 PRE_REG_READ0(long, "getgid");
2910}
jsgf855d93d2003-10-13 22:26:55 +00002911
sewardja8d8e232005-06-07 20:04:56 +00002912PRE(sys_getpid)
jsgf855d93d2003-10-13 22:26:55 +00002913{
nethercote4e632c22004-11-09 16:45:33 +00002914 PRINT("sys_getpid ()");
2915 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002916}
2917
sewardj696c5512005-06-08 23:38:32 +00002918PRE(sys_getpgid)
2919{
2920 PRINT("sys_getpgid ( %d )", ARG1);
2921 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
2922}
sewardj78b50e42005-06-08 01:47:28 +00002923
2924PRE(sys_getpgrp)
2925{
2926 PRINT("sys_getpgrp ()");
2927 PRE_REG_READ0(long, "getpgrp");
2928}
jsgf855d93d2003-10-13 22:26:55 +00002929
sewardja8d8e232005-06-07 20:04:56 +00002930PRE(sys_getppid)
jsgf855d93d2003-10-13 22:26:55 +00002931{
nethercote4e632c22004-11-09 16:45:33 +00002932 PRINT("sys_getppid ()");
2933 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002934}
2935
njncf45fd42004-11-24 16:30:22 +00002936static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002937{
nethercote620154f2004-11-12 21:21:07 +00002938 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002939
nethercote620154f2004-11-12 21:21:07 +00002940 switch (a1) {
2941 case VKI_RLIMIT_NOFILE:
2942 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2943 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2944 break;
nethercote535f03b2004-02-15 15:32:51 +00002945
nethercote620154f2004-11-12 21:21:07 +00002946 case VKI_RLIMIT_DATA:
2947 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2948 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002949
nethercote620154f2004-11-12 21:21:07 +00002950 case VKI_RLIMIT_STACK:
2951 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2952 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002953 }
jsgf855d93d2003-10-13 22:26:55 +00002954}
2955
sewardj696c5512005-06-08 23:38:32 +00002956PRE(sys_old_getrlimit)
2957{
2958 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
2959 PRE_REG_READ2(long, "old_getrlimit",
2960 unsigned int, resource, struct rlimit *, rlim);
2961 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
2962}
2963
2964POST(sys_old_getrlimit)
2965{
2966 common_post_getrlimit(tid, ARG1, ARG2);
2967}
nethercote620154f2004-11-12 21:21:07 +00002968
sewardja8d8e232005-06-07 20:04:56 +00002969PRE(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002970{
njn22cfccb2004-11-27 16:10:23 +00002971 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002972 PRE_REG_READ2(long, "getrlimit",
2973 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002974 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002975}
2976
nethercote85a456f2004-11-16 17:31:56 +00002977POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002978{
njn22cfccb2004-11-27 16:10:23 +00002979 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002980}
jsgf855d93d2003-10-13 22:26:55 +00002981
sewardj696c5512005-06-08 23:38:32 +00002982PRE(sys_getrusage)
2983{
2984 /* int getrusage (int who, struct rusage *usage); */
2985 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
2986 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
2987 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
2988}
2989
2990POST(sys_getrusage)
2991{
2992 vg_assert(SUCCESS);
2993 if (RES == 0)
2994 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
2995}
jsgf855d93d2003-10-13 22:26:55 +00002996
sewardja8d8e232005-06-07 20:04:56 +00002997PRE(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002998{
njn22cfccb2004-11-27 16:10:23 +00002999 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003000 PRE_REG_READ2(long, "gettimeofday",
3001 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003002 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3003 if (ARG2 != 0)
3004 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003005}
3006
nethercote85a456f2004-11-16 17:31:56 +00003007POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003008{
sewardja8d8e232005-06-07 20:04:56 +00003009 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00003010 if (RES == 0) {
3011 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
3012 if (ARG2 != 0)
3013 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003014 }
3015}
3016
sewardj696c5512005-06-08 23:38:32 +00003017PRE(sys_settimeofday)
3018{
3019 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
3020 PRE_REG_READ2(long, "settimeofday",
3021 struct timeval *, tv, struct timezone *, tz);
3022 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3023 if (ARG2 != 0) {
3024 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3025 /* maybe should warn if tz->tz_dsttime is non-zero? */
3026 }
3027}
nethercote686b5db2004-11-14 13:42:51 +00003028
sewardja8d8e232005-06-07 20:04:56 +00003029PRE(sys_getuid16)
jsgf855d93d2003-10-13 22:26:55 +00003030{
nethercote0df495a2004-11-11 16:38:21 +00003031 PRINT("sys_getuid16 ( )");
3032 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00003033}
3034
sewardja8d8e232005-06-07 20:04:56 +00003035PRE(sys_getuid)
jsgf855d93d2003-10-13 22:26:55 +00003036{
nethercote0df495a2004-11-11 16:38:21 +00003037 PRINT("sys_getuid ( )");
3038 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00003039}
3040
nethercote2e1c37d2004-11-13 13:57:12 +00003041// XXX: I reckon some of these cases must be x86-specific
sewardja8d8e232005-06-07 20:04:56 +00003042PRE(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003043{
sewardja8d8e232005-06-07 20:04:56 +00003044 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00003045 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00003046 PRE_REG_READ3(long, "ioctl",
3047 unsigned int, fd, unsigned int, request, unsigned long, arg);
3048
njn22cfccb2004-11-27 16:10:23 +00003049 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003050 case VKI_TCSETS:
3051 case VKI_TCSETSW:
3052 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00003053 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003054 break;
nethercote73b526f2004-10-31 18:48:21 +00003055 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003056 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003057 break;
nethercote73b526f2004-10-31 18:48:21 +00003058 case VKI_TCSETA:
3059 case VKI_TCSETAW:
3060 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00003061 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003062 break;
nethercote73b526f2004-10-31 18:48:21 +00003063 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003064 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003065 break;
nethercote73b526f2004-10-31 18:48:21 +00003066 case VKI_TCSBRK:
3067 case VKI_TCXONC:
3068 case VKI_TCSBRKP:
3069 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003070 /* These just take an int by value */
3071 break;
nethercote73b526f2004-10-31 18:48:21 +00003072 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003073 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003074 break;
nethercote73b526f2004-10-31 18:48:21 +00003075 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003076 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003077 break;
nethercote73b526f2004-10-31 18:48:21 +00003078 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00003079 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003080 break;
nethercote73b526f2004-10-31 18:48:21 +00003081 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00003082 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003083 break;
nethercote73b526f2004-10-31 18:48:21 +00003084 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00003085 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003086 break;
nethercote73b526f2004-10-31 18:48:21 +00003087 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003088 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
3089 if (*(char *)ARG3 == 11) {
3090 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003091 }
3092 break;
nethercote73b526f2004-10-31 18:48:21 +00003093 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003094 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003095 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003096 break;
nethercote73b526f2004-10-31 18:48:21 +00003097 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003098 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003099 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003100 break;
nethercote73b526f2004-10-31 18:48:21 +00003101 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003102 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003103 break;
nethercote73b526f2004-10-31 18:48:21 +00003104 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003105 /* Just takes an int value. */
3106 break;
nethercote73b526f2004-10-31 18:48:21 +00003107 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00003108 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003109 break;
nethercote73b526f2004-10-31 18:48:21 +00003110 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00003111 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003112 break;
nethercote73b526f2004-10-31 18:48:21 +00003113 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00003114 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003115 break;
nethercote73b526f2004-10-31 18:48:21 +00003116 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003117 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003118 break;
3119
nethercote73b526f2004-10-31 18:48:21 +00003120 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00003121 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003122 break;
nethercote73b526f2004-10-31 18:48:21 +00003123 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003124 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00003125 break;
nethercote73b526f2004-10-31 18:48:21 +00003126 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003127 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00003128 break;
nethercote73b526f2004-10-31 18:48:21 +00003129 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003130 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003131 break;
nethercote73b526f2004-10-31 18:48:21 +00003132 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003133 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003134 break;
nethercote73b526f2004-10-31 18:48:21 +00003135 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003136 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003137 break;
nethercote73b526f2004-10-31 18:48:21 +00003138 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003139 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003140 break;
nethercote73b526f2004-10-31 18:48:21 +00003141 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00003142 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003143 break;
nethercote73b526f2004-10-31 18:48:21 +00003144 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00003145 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003146 break;
nethercote73b526f2004-10-31 18:48:21 +00003147 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00003148 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003149 break;
jsgf855d93d2003-10-13 22:26:55 +00003150
muellera4b153a2003-11-19 22:07:14 +00003151 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003152 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00003153 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003154 break;
muellera4b153a2003-11-19 22:07:14 +00003155 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003156 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00003157 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
3158 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
3159 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003160 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003161 break;
3162
3163 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003164 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00003165 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00003166 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3167 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003168 break;
nethercote73b526f2004-10-31 18:48:21 +00003169 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00003170 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003171 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3172 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003173 break;
nethercote73b526f2004-10-31 18:48:21 +00003174 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003175 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003176 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3177 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003178 break;
nethercote73b526f2004-10-31 18:48:21 +00003179 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003180 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003181 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3182 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003183 break;
nethercote73b526f2004-10-31 18:48:21 +00003184 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003185 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00003186 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3187 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003188 break;
nethercote73b526f2004-10-31 18:48:21 +00003189 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003190 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00003191 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3192 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003193 break;
nethercote73b526f2004-10-31 18:48:21 +00003194 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00003195 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003196 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3197 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003198 break;
nethercote73b526f2004-10-31 18:48:21 +00003199 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003200 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003201 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3202 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003203 break;
nethercote73b526f2004-10-31 18:48:21 +00003204 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003205 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003206 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3207 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003208 break;
nethercote73b526f2004-10-31 18:48:21 +00003209 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003210 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00003211 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3212 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003213 break;
nethercote73b526f2004-10-31 18:48:21 +00003214 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003215 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00003216 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3217 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003218 break;
nethercote73b526f2004-10-31 18:48:21 +00003219 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003220 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
njn22cfccb2004-11-27 16:10:23 +00003221 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3222 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
3223 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003224 break;
nethercote73b526f2004-10-31 18:48:21 +00003225 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003226 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00003227 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3228 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003229 break;
nethercote73b526f2004-10-31 18:48:21 +00003230 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003231 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003232 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003233 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003234 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3235 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003236 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003237 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3238 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
3239 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003240 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003241 break;
nethercote73b526f2004-10-31 18:48:21 +00003242 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003243 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003244 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3245 KERNEL_DO_SYSCALL(tid,RES);
3246 if (!VG_(is_kerror)(RES) && RES == 0)
3247 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003248 */
njn22cfccb2004-11-27 16:10:23 +00003249 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct vki_ifconf));
3250 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00003251 // TODO len must be readable and writable
3252 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00003253 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003254 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003255 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003256 }
3257 break;
nethercote73b526f2004-10-31 18:48:21 +00003258 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003259 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003260 break;
3261 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3262 the number of bytes currently in that socket's send buffer.
3263 It writes this value as an int to the memory location
3264 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003265 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003266 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003267 break;
nethercote73b526f2004-10-31 18:48:21 +00003268 case VKI_SIOCGRARP: /* get RARP table entry */
3269 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003270 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003271 break;
3272
nethercote73b526f2004-10-31 18:48:21 +00003273 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003274 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
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(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003277 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3278 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003279 break;
nethercote73b526f2004-10-31 18:48:21 +00003280 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003281 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
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(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003284 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3285 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003286 break;
nethercote73b526f2004-10-31 18:48:21 +00003287 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003288 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003289 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003290 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003291 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3292 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003293 break;
nethercote73b526f2004-10-31 18:48:21 +00003294 case VKI_SIOCSIFADDR: /* set PA address */
3295 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3296 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3297 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003298 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
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(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003301 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3302 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003303 break;
nethercote73b526f2004-10-31 18:48:21 +00003304 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003305 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
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(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003308 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3309 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003310 break;
nethercote73b526f2004-10-31 18:48:21 +00003311 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003312 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
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(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003315 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3316 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003317 break;
nethercote73b526f2004-10-31 18:48:21 +00003318 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003319 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
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(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003322 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3323 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003324 break;
nethercote73b526f2004-10-31 18:48:21 +00003325 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003326 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003327 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003328 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003329 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3330 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003331 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003332 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3333 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003334 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003335 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
3336 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003337 break;
jsgf855d93d2003-10-13 22:26:55 +00003338 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003339 case VKI_SIOCADDRT: /* add routing table entry */
3340 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00003341 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00003342 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003343 break;
3344
3345 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003346 case VKI_SIOCDRARP: /* delete RARP table entry */
3347 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003348 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003349 case VKI_SIOCSARP: /* set ARP table entry */
3350 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003351 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003352 break;
3353
nethercote73b526f2004-10-31 18:48:21 +00003354 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003355 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003356 break;
nethercote73b526f2004-10-31 18:48:21 +00003357 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003358 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardja8d8e232005-06-07 20:04:56 +00003359 //tst->sys_flags &= ~SfMayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003360 break;
3361
3362 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003363 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3364 case VKI_SNDCTL_SEQ_GETINCOUNT:
3365 case VKI_SNDCTL_SEQ_PERCMODE:
3366 case VKI_SNDCTL_SEQ_TESTMIDI:
3367 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3368 case VKI_SNDCTL_SEQ_NRSYNTHS:
3369 case VKI_SNDCTL_SEQ_NRMIDIS:
3370 case VKI_SNDCTL_SEQ_GETTIME:
3371 case VKI_SNDCTL_DSP_GETFMTS:
3372 case VKI_SNDCTL_DSP_GETTRIGGER:
3373 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003374 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003375 case VKI_SNDCTL_DSP_GETCAPS:
3376 case VKI_SOUND_PCM_READ_RATE:
3377 case VKI_SOUND_PCM_READ_CHANNELS:
3378 case VKI_SOUND_PCM_READ_BITS:
cerion85665ca2005-06-20 15:51:07 +00003379#if !defined(VGA_ppc32)
nethercote73b526f2004-10-31 18:48:21 +00003380 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00003381#endif
nethercote73b526f2004-10-31 18:48:21 +00003382 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003383 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003384 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003385 break;
nethercote73b526f2004-10-31 18:48:21 +00003386 case VKI_SNDCTL_SEQ_CTRLRATE:
3387 case VKI_SNDCTL_DSP_SPEED:
3388 case VKI_SNDCTL_DSP_STEREO:
3389 case VKI_SNDCTL_DSP_GETBLKSIZE:
3390 case VKI_SNDCTL_DSP_CHANNELS:
3391 case VKI_SOUND_PCM_WRITE_FILTER:
3392 case VKI_SNDCTL_DSP_SUBDIVIDE:
3393 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003394 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003395 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003396 case VKI_SNDCTL_TMR_TIMEBASE:
3397 case VKI_SNDCTL_TMR_TEMPO:
3398 case VKI_SNDCTL_TMR_SOURCE:
3399 case VKI_SNDCTL_MIDI_PRETIME:
3400 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003401 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003402 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003403 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003404 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003405 break;
nethercote73b526f2004-10-31 18:48:21 +00003406 case VKI_SNDCTL_DSP_GETOSPACE:
3407 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003408 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003409 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003410 break;
nethercote73b526f2004-10-31 18:48:21 +00003411 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003412 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003413 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003414 break;
3415
nethercote73b526f2004-10-31 18:48:21 +00003416 case VKI_SNDCTL_DSP_POST:
3417 case VKI_SNDCTL_DSP_RESET:
3418 case VKI_SNDCTL_DSP_SYNC:
3419 case VKI_SNDCTL_DSP_SETSYNCRO:
3420 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003421 break;
3422
3423 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003424 case VKI_RTC_UIE_ON:
3425 case VKI_RTC_UIE_OFF:
3426 case VKI_RTC_AIE_ON:
3427 case VKI_RTC_AIE_OFF:
3428 case VKI_RTC_PIE_ON:
3429 case VKI_RTC_PIE_OFF:
3430 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003431 break;
nethercote73b526f2004-10-31 18:48:21 +00003432 case VKI_RTC_RD_TIME:
3433 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003434 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003435 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003436 break;
nethercote73b526f2004-10-31 18:48:21 +00003437 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003438 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003439 break;
nethercote73b526f2004-10-31 18:48:21 +00003440 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003441 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003442 break;
jsgf855d93d2003-10-13 22:26:55 +00003443
nethercote95a97862004-11-06 16:31:43 +00003444 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003445 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003446 break;
jsgf855d93d2003-10-13 22:26:55 +00003447
thughesacbbc322004-06-19 12:12:01 +00003448 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003449 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003450 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003451 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003452 break;
3453
jsgf855d93d2003-10-13 22:26:55 +00003454 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003455 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003456 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003457 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003458 break;
nethercote73b526f2004-10-31 18:48:21 +00003459 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003460 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003461 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003462 break;
nethercote73b526f2004-10-31 18:48:21 +00003463 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003464 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003465 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3466 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3467 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003468 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003469 break;
nethercote73b526f2004-10-31 18:48:21 +00003470 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003471 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003472 break;
nethercote73b526f2004-10-31 18:48:21 +00003473 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003474 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003475 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003476 break;
nethercote73b526f2004-10-31 18:48:21 +00003477 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003478 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003479 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3480 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003481 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003482 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3483 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3484 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003485 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003486 break;
nethercote73b526f2004-10-31 18:48:21 +00003487 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003488 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003489 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003490 break;
nethercote73b526f2004-10-31 18:48:21 +00003491 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003492 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003493 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003494 break;
nethercote73b526f2004-10-31 18:48:21 +00003495 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003496 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003497 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003498 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003499 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003500 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003501 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3502 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003503 }
3504 break;
nethercote73b526f2004-10-31 18:48:21 +00003505 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003506 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003507 break;
3508 /* The following two are probably bogus (should check args
3509 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003510 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3511 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003512 break;
thughes66d80092004-06-19 12:41:05 +00003513
nethercote73b526f2004-10-31 18:48:21 +00003514 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003515 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003516 break;
nethercote73b526f2004-10-31 18:48:21 +00003517 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003518 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003519 break;
3520
nethercote73b526f2004-10-31 18:48:21 +00003521 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003522 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003523 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003524 break;
nethercote73b526f2004-10-31 18:48:21 +00003525 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003526 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003527 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003528 break;
jsgf855d93d2003-10-13 22:26:55 +00003529
nethercote73b526f2004-10-31 18:48:21 +00003530 case VKI_PPCLAIM:
3531 case VKI_PPEXCL:
3532 case VKI_PPYIELD:
3533 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003534 break;
nethercote73b526f2004-10-31 18:48:21 +00003535 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003536 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003537 break;
nethercote73b526f2004-10-31 18:48:21 +00003538 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003539 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003540 break;
nethercote73b526f2004-10-31 18:48:21 +00003541 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003542 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003543 break;
nethercote73b526f2004-10-31 18:48:21 +00003544 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003545 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003546 break;
nethercote73b526f2004-10-31 18:48:21 +00003547 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003548 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003549 break;
nethercote73b526f2004-10-31 18:48:21 +00003550 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003551 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003552 break;
nethercote73b526f2004-10-31 18:48:21 +00003553 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003554 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003555 break;
nethercote73b526f2004-10-31 18:48:21 +00003556 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003557 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003558 break;
nethercote73b526f2004-10-31 18:48:21 +00003559 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003560 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003561 break;
nethercote73b526f2004-10-31 18:48:21 +00003562 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003563 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003564 break;
nethercote73b526f2004-10-31 18:48:21 +00003565 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003566 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003567 break;
nethercote73b526f2004-10-31 18:48:21 +00003568 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003569 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003570 break;
nethercote73b526f2004-10-31 18:48:21 +00003571 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003572 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003573 break;
nethercote73b526f2004-10-31 18:48:21 +00003574 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003575 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003576 break;
nethercote73b526f2004-10-31 18:48:21 +00003577 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003578 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003579 break;
nethercote73b526f2004-10-31 18:48:21 +00003580 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003581 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003582 break;
nethercote73b526f2004-10-31 18:48:21 +00003583 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003584 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003585 break;
nethercote73b526f2004-10-31 18:48:21 +00003586 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003587 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003588 break;
nethercote73b526f2004-10-31 18:48:21 +00003589 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003590 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003591 break;
3592
thughesb3d3bcf2004-11-13 00:36:15 +00003593 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003594 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003595 break;
3596 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003597 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003598 break;
3599
3600 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003601 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3602 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003603 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003604 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003605 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3606 32 * cfd->charcount );
3607 }
3608 break;
3609 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003610 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3611 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003612 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003613 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003614 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3615 32 * cfd->charcount );
3616 }
3617 break;
3618
3619 case VKI_PIO_FONTRESET:
3620 break;
3621
3622 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003623 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003624 break;
3625 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003626 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003627 break;
3628
3629 case VKI_KIOCSOUND:
3630 case VKI_KDMKTONE:
3631 break;
3632
3633 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003634 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003635 break;
3636 case VKI_KDSETLED:
3637 break;
3638
3639 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003640 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003641 break;
3642
3643 case VKI_KDADDIO:
3644 case VKI_KDDELIO:
3645 case VKI_KDENABIO:
3646 case VKI_KDDISABIO:
3647 break;
3648
3649 case VKI_KDSETMODE:
3650 break;
3651 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003652 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003653 break;
3654
3655 case VKI_KDMAPDISP:
3656 case VKI_KDUNMAPDISP:
3657 break;
3658
3659 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003660 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003661 break;
3662 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003663 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003664 break;
3665 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003666 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003667 VKI_E_TABSZ * sizeof(unsigned short) );
3668 break;
3669 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003670 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003671 VKI_E_TABSZ * sizeof(unsigned short) );
3672 break;
3673
3674 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003675 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003676 break;
3677 case VKI_KDSKBMODE:
3678 break;
3679
3680 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003681 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003682 break;
3683 case VKI_KDSKBMETA:
3684 break;
3685
3686 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003687 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003688 break;
3689 case VKI_KDSKBLED:
3690 break;
3691
3692 case VKI_KDGKBENT:
3693 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003694 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3695 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003696 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003697 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3698 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003699 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003700 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3701 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003702 break;
3703 case VKI_KDSKBENT:
3704 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003705 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3706 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003707 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003708 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3709 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003710 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003711 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3712 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003713 break;
3714
3715 case VKI_KDGKBSENT:
3716 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003717 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3718 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003719 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003720 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3721 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003722 break;
3723 case VKI_KDSKBSENT:
3724 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003725 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3726 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003727 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003728 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003729 break;
3730
3731 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003732 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003733 break;
3734 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003735 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003736 break;
3737
3738 case VKI_KDGETKEYCODE:
3739 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003740 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3741 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003742 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003743 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3744 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003745 break;
3746 case VKI_KDSETKEYCODE:
3747 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003748 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3749 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003750 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003751 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3752 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003753 break;
3754
3755 case VKI_KDSIGACCEPT:
3756 break;
3757
3758 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003759 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003760 break;
3761
jsgf855d93d2003-10-13 22:26:55 +00003762 /* We don't have any specific information on it, so
3763 try to do something reasonable based on direction and
3764 size bits. The encoding scheme is described in
3765 /usr/include/asm/ioctl.h.
3766
3767 According to Simon Hausmann, _IOC_READ means the kernel
3768 writes a value to the ioctl value passed from the user
3769 space and the other way around with _IOC_WRITE. */
3770 default: {
njn22cfccb2004-11-27 16:10:23 +00003771 UInt dir = _VKI_IOC_DIR(ARG2);
3772 UInt size = _VKI_IOC_SIZE(ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003773 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3774 /*
3775 * Be very lax about ioctl handling; the only
3776 * assumption is that the size is correct. Doesn't
3777 * require the full buffer to be initialized when
3778 * writing. Without this, using some device
3779 * drivers with a large number of strange ioctl
3780 * commands becomes very tiresome.
3781 */
nethercote73b526f2004-10-31 18:48:21 +00003782 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003783 static Int moans = 3;
sewardj1fa7d2c2005-06-13 18:22:17 +00003784 if (moans > 0 && !VG_(clo_xml)) {
jsgf855d93d2003-10-13 22:26:55 +00003785 moans--;
3786 VG_(message)(Vg_UserMsg,
3787 "Warning: noted but unhandled ioctl 0x%x"
3788 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00003789 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003790 VG_(message)(Vg_UserMsg,
3791 " This could cause spurious value errors"
3792 " to appear.");
3793 VG_(message)(Vg_UserMsg,
3794 " See README_MISSING_SYSCALL_OR_IOCTL for "
3795 "guidance on writing a proper wrapper." );
3796 }
3797 } else {
nethercote73b526f2004-10-31 18:48:21 +00003798 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003799 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00003800 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003801 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003802 }
3803 break;
3804 }
3805 }
3806}
3807
nethercote85a456f2004-11-16 17:31:56 +00003808POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003809{
sewardja8d8e232005-06-07 20:04:56 +00003810 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00003811 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003812 case VKI_TCSETS:
3813 case VKI_TCSETSW:
3814 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003815 break;
nethercote73b526f2004-10-31 18:48:21 +00003816 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003817 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003818 break;
nethercote73b526f2004-10-31 18:48:21 +00003819 case VKI_TCSETA:
3820 case VKI_TCSETAW:
3821 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003822 break;
nethercote73b526f2004-10-31 18:48:21 +00003823 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003824 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003825 break;
nethercote73b526f2004-10-31 18:48:21 +00003826 case VKI_TCSBRK:
3827 case VKI_TCXONC:
3828 case VKI_TCSBRKP:
3829 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003830 break;
nethercote73b526f2004-10-31 18:48:21 +00003831 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003832 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003833 break;
nethercote73b526f2004-10-31 18:48:21 +00003834 case VKI_TIOCSWINSZ:
3835 case VKI_TIOCMBIS:
3836 case VKI_TIOCMBIC:
3837 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003838 break;
nethercote73b526f2004-10-31 18:48:21 +00003839 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003840 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003841 break;
nethercote73b526f2004-10-31 18:48:21 +00003842 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003843 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003844 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003845 break;
nethercote73b526f2004-10-31 18:48:21 +00003846 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003847 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003848 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003849 break;
nethercote73b526f2004-10-31 18:48:21 +00003850 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003851 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003852 break;
nethercote73b526f2004-10-31 18:48:21 +00003853 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003854 break;
nethercote73b526f2004-10-31 18:48:21 +00003855 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003856 break;
nethercote73b526f2004-10-31 18:48:21 +00003857 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003858 break;
nethercote73b526f2004-10-31 18:48:21 +00003859 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003860 break;
nethercote73b526f2004-10-31 18:48:21 +00003861 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003862 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003863 break;
3864
nethercote73b526f2004-10-31 18:48:21 +00003865 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003866 break;
nethercote73b526f2004-10-31 18:48:21 +00003867 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003868 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003869 break;
nethercote73b526f2004-10-31 18:48:21 +00003870 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003871 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003872 break;
nethercote73b526f2004-10-31 18:48:21 +00003873 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003874 break;
nethercote73b526f2004-10-31 18:48:21 +00003875 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003876 break;
nethercote73b526f2004-10-31 18:48:21 +00003877 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003878 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003879 break;
nethercote73b526f2004-10-31 18:48:21 +00003880 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003881 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003882 break;
nethercote73b526f2004-10-31 18:48:21 +00003883 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003884 break;
nethercote73b526f2004-10-31 18:48:21 +00003885 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00003886 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003887 break;
nethercote73b526f2004-10-31 18:48:21 +00003888 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00003889 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003890 break;
jsgf855d93d2003-10-13 22:26:55 +00003891
muellera4b153a2003-11-19 22:07:14 +00003892 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003893 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003894 break;
muellera4b153a2003-11-19 22:07:14 +00003895 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00003896 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003897 break;
3898
3899 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003900 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00003901 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3902 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003903 break;
nethercote73b526f2004-10-31 18:48:21 +00003904 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00003905 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3906 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003907 break;
nethercote73b526f2004-10-31 18:48:21 +00003908 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00003909 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3910 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003911 break;
nethercote73b526f2004-10-31 18:48:21 +00003912 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00003913 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3914 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003915 break;
nethercote73b526f2004-10-31 18:48:21 +00003916 case VKI_SIOCGIFADDR: /* get PA address */
3917 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3918 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3919 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003920 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003921 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3922 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003923 break;
nethercote73b526f2004-10-31 18:48:21 +00003924 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003925 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003926 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3927 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003928 break;
nethercote73b526f2004-10-31 18:48:21 +00003929 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003930 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003931 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3932 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003933 break;
3934 break;
nethercote73b526f2004-10-31 18:48:21 +00003935 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003936 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003937 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3938 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003939 break;
nethercote73b526f2004-10-31 18:48:21 +00003940 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003941 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003942 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
3943 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003944 break;
nethercote73b526f2004-10-31 18:48:21 +00003945 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003946 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003947 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3948 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003949 break;
nethercote73b526f2004-10-31 18:48:21 +00003950 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003951 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003952 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
3953 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003954 break;
nethercote73b526f2004-10-31 18:48:21 +00003955 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003956 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003957 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3958 KERNEL_DO_SYSCALL(tid,RES);
3959 if (!VG_(is_kerror)(RES) && RES == 0)
3960 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003961 */
njn22cfccb2004-11-27 16:10:23 +00003962 if (RES == 0 && ARG3 ) {
3963 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00003964 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003965 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003966 }
3967 break;
nethercote73b526f2004-10-31 18:48:21 +00003968 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003969 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003970 break;
3971 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3972 the number of bytes currently in that socket's send buffer.
3973 It writes this value as an int to the memory location
3974 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003975 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003976 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003977 break;
nethercote73b526f2004-10-31 18:48:21 +00003978 case VKI_SIOCGRARP: /* get RARP table entry */
3979 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003980 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003981 break;
3982
nethercote73b526f2004-10-31 18:48:21 +00003983 case VKI_SIOCSIFFLAGS: /* set flags */
3984 case VKI_SIOCSIFMAP: /* Set device parameters */
3985 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3986 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3987 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3988 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3989 case VKI_SIOCSIFMETRIC: /* set metric */
3990 case VKI_SIOCSIFADDR: /* set PA address */
3991 case VKI_SIOCSIFMTU: /* set MTU size */
3992 case VKI_SIOCSIFHWADDR: /* set hardware address */
3993 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003994 break;
3995 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003996 case VKI_SIOCADDRT: /* add routing table entry */
3997 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003998 break;
3999
4000 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004001 case VKI_SIOCDRARP: /* delete RARP table entry */
4002 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004003 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004004 case VKI_SIOCSARP: /* set ARP table entry */
4005 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004006 break;
4007
nethercote73b526f2004-10-31 18:48:21 +00004008 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00004009 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00004010 break;
nethercote73b526f2004-10-31 18:48:21 +00004011 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004012 break;
4013
4014 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00004015 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4016 case VKI_SNDCTL_SEQ_GETINCOUNT:
4017 case VKI_SNDCTL_SEQ_PERCMODE:
4018 case VKI_SNDCTL_SEQ_TESTMIDI:
4019 case VKI_SNDCTL_SEQ_RESETSAMPLES:
4020 case VKI_SNDCTL_SEQ_NRSYNTHS:
4021 case VKI_SNDCTL_SEQ_NRMIDIS:
4022 case VKI_SNDCTL_SEQ_GETTIME:
4023 case VKI_SNDCTL_DSP_GETFMTS:
4024 case VKI_SNDCTL_DSP_GETTRIGGER:
4025 case VKI_SNDCTL_DSP_GETODELAY:
4026 case VKI_SNDCTL_DSP_GETSPDIF:
4027 case VKI_SNDCTL_DSP_GETCAPS:
4028 case VKI_SOUND_PCM_READ_RATE:
4029 case VKI_SOUND_PCM_READ_CHANNELS:
4030 case VKI_SOUND_PCM_READ_BITS:
cerion85665ca2005-06-20 15:51:07 +00004031#if !defined(VGA_ppc32)
nethercote73b526f2004-10-31 18:48:21 +00004032 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00004033#endif
nethercote73b526f2004-10-31 18:48:21 +00004034 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00004035 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004036 break;
nethercote73b526f2004-10-31 18:48:21 +00004037 case VKI_SNDCTL_SEQ_CTRLRATE:
4038 case VKI_SNDCTL_DSP_SPEED:
4039 case VKI_SNDCTL_DSP_STEREO:
4040 case VKI_SNDCTL_DSP_GETBLKSIZE:
4041 case VKI_SNDCTL_DSP_CHANNELS:
4042 case VKI_SOUND_PCM_WRITE_FILTER:
4043 case VKI_SNDCTL_DSP_SUBDIVIDE:
4044 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00004045 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00004046 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00004047 case VKI_SNDCTL_TMR_TIMEBASE:
4048 case VKI_SNDCTL_TMR_TEMPO:
4049 case VKI_SNDCTL_TMR_SOURCE:
4050 case VKI_SNDCTL_MIDI_PRETIME:
4051 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00004052 break;
nethercote73b526f2004-10-31 18:48:21 +00004053 case VKI_SNDCTL_DSP_GETOSPACE:
4054 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00004055 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00004056 break;
nethercote73b526f2004-10-31 18:48:21 +00004057 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00004058 break;
4059
nethercote73b526f2004-10-31 18:48:21 +00004060 case VKI_SNDCTL_DSP_POST:
4061 case VKI_SNDCTL_DSP_RESET:
4062 case VKI_SNDCTL_DSP_SYNC:
4063 case VKI_SNDCTL_DSP_SETSYNCRO:
4064 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00004065 break;
4066
4067 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00004068 case VKI_RTC_UIE_ON:
4069 case VKI_RTC_UIE_OFF:
4070 case VKI_RTC_AIE_ON:
4071 case VKI_RTC_AIE_OFF:
4072 case VKI_RTC_PIE_ON:
4073 case VKI_RTC_PIE_OFF:
4074 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00004075 break;
nethercote73b526f2004-10-31 18:48:21 +00004076 case VKI_RTC_RD_TIME:
4077 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00004078 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00004079 break;
nethercote73b526f2004-10-31 18:48:21 +00004080 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00004081 break;
nethercote73b526f2004-10-31 18:48:21 +00004082 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00004083 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004084 break;
jsgf855d93d2003-10-13 22:26:55 +00004085
nethercote95a97862004-11-06 16:31:43 +00004086 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00004087 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004088 break;
jsgf855d93d2003-10-13 22:26:55 +00004089
thughesacbbc322004-06-19 12:12:01 +00004090 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00004091 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00004092 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00004093 break;
4094
jsgf855d93d2003-10-13 22:26:55 +00004095 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00004096 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00004097 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00004098 break;
nethercote73b526f2004-10-31 18:48:21 +00004099 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00004100 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004101 break;
nethercote73b526f2004-10-31 18:48:21 +00004102 case VKI_CDROMREADTOCENTRY:
njn22cfccb2004-11-27 16:10:23 +00004103 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004104 break;
nethercote73b526f2004-10-31 18:48:21 +00004105 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00004106 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00004107 break;
nethercote73b526f2004-10-31 18:48:21 +00004108 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00004109 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00004110 break;
nethercote73b526f2004-10-31 18:48:21 +00004111 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00004112 {
njn22cfccb2004-11-27 16:10:23 +00004113 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00004114 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00004115 break;
4116 }
4117
nethercote73b526f2004-10-31 18:48:21 +00004118 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00004119 break;
4120 /* The following two are probably bogus (should check args
4121 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00004122 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4123 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00004124 break;
4125
nethercote73b526f2004-10-31 18:48:21 +00004126 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00004127 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004128 break;
nethercote73b526f2004-10-31 18:48:21 +00004129 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00004130 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004131 break;
4132
nethercote73b526f2004-10-31 18:48:21 +00004133 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00004134 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004135 break;
nethercote73b526f2004-10-31 18:48:21 +00004136 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00004137 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004138 break;
4139
nethercote73b526f2004-10-31 18:48:21 +00004140 case VKI_PPCLAIM:
4141 case VKI_PPEXCL:
4142 case VKI_PPYIELD:
4143 case VKI_PPRELEASE:
4144 case VKI_PPSETMODE:
4145 case VKI_PPSETPHASE:
4146 case VKI_PPSETFLAGS:
4147 case VKI_PPWDATA:
4148 case VKI_PPWCONTROL:
4149 case VKI_PPFCONTROL:
4150 case VKI_PPDATADIR:
4151 case VKI_PPNEGOT:
4152 case VKI_PPWCTLONIRQ:
4153 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00004154 break;
nethercote73b526f2004-10-31 18:48:21 +00004155 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004156 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004157 break;
nethercote73b526f2004-10-31 18:48:21 +00004158 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00004159 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004160 break;
nethercote73b526f2004-10-31 18:48:21 +00004161 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00004162 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00004163 break;
nethercote73b526f2004-10-31 18:48:21 +00004164 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00004165 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004166 break;
nethercote73b526f2004-10-31 18:48:21 +00004167 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00004168 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004169 break;
nethercote73b526f2004-10-31 18:48:21 +00004170 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00004171 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004172 break;
nethercote73b526f2004-10-31 18:48:21 +00004173 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00004174 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004175 break;
nethercote73b526f2004-10-31 18:48:21 +00004176 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00004177 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004178 break;
nethercote73b526f2004-10-31 18:48:21 +00004179 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00004180 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00004181 break;
4182
thughesc3b842d2004-11-13 10:38:04 +00004183 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00004184 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00004185 break;
4186 case VKI_PIO_FONT:
4187 break;
4188
4189 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00004190 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
4191 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00004192 break;
4193 case VKI_PIO_FONTX:
4194 break;
4195
4196 case VKI_PIO_FONTRESET:
4197 break;
4198
4199 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00004200 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00004201 break;
4202 case VKI_PIO_CMAP:
4203 break;
4204
4205 case VKI_KIOCSOUND:
4206 case VKI_KDMKTONE:
4207 break;
4208
4209 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00004210 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004211 break;
4212 case VKI_KDSETLED:
4213 break;
4214
4215 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00004216 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004217 break;
4218
4219 case VKI_KDADDIO:
4220 case VKI_KDDELIO:
4221 case VKI_KDENABIO:
4222 case VKI_KDDISABIO:
4223 break;
4224
4225 case VKI_KDSETMODE:
4226 break;
4227 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004228 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004229 break;
4230
4231 case VKI_KDMAPDISP:
4232 case VKI_KDUNMAPDISP:
4233 break;
4234
4235 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004236 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00004237 break;
4238 case VKI_PIO_SCRNMAP:
4239 break;
4240 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004241 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00004242 break;
4243 case VKI_PIO_UNISCRNMAP:
4244 break;
4245
4246 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00004247 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004248 break;
4249 case VKI_KDSKBMODE:
4250 break;
4251
4252 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00004253 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004254 break;
4255 case VKI_KDSKBMETA:
4256 break;
4257
4258 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00004259 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004260 break;
4261 case VKI_KDSKBLED:
4262 break;
4263
4264 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00004265 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
4266 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00004267 break;
4268 case VKI_KDSKBENT:
4269 break;
4270
4271 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00004272 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
4273 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00004274 break;
4275 case VKI_KDSKBSENT:
4276 break;
4277
4278 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00004279 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00004280 break;
4281 case VKI_KDSKBDIACR:
4282 break;
4283
4284 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00004285 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
4286 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00004287 break;
4288 case VKI_KDSETKEYCODE:
4289 break;
4290
4291 case VKI_KDSIGACCEPT:
4292 break;
4293
4294 case VKI_KDKBDREP:
4295 break;
4296
jsgf855d93d2003-10-13 22:26:55 +00004297 /* We don't have any specific information on it, so
4298 try to do something reasonable based on direction and
4299 size bits. The encoding scheme is described in
4300 /usr/include/asm/ioctl.h.
4301
4302 According to Simon Hausmann, _IOC_READ means the kernel
4303 writes a value to the ioctl value passed from the user
4304 space and the other way around with _IOC_WRITE. */
4305 default: {
njn22cfccb2004-11-27 16:10:23 +00004306 UInt dir = _VKI_IOC_DIR(ARG2);
4307 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00004308 if (size > 0 && (dir & _VKI_IOC_READ)
sewardja8d8e232005-06-07 20:04:56 +00004309 && RES == 0
njn22cfccb2004-11-27 16:10:23 +00004310 && ARG3 != (Addr)NULL)
4311 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004312 break;
4313 }
4314 }
4315}
4316
njn03f1e582005-03-26 20:08:06 +00004317/*
4318 If we're sending a SIGKILL to one of our own threads, then simulate
4319 it rather than really sending the signal, so that the target thread
4320 gets a chance to clean up. Returns True if we did the killing (or
4321 no killing is necessary), and False if the caller should use the
4322 normal kill syscall.
4323
4324 "pid" is any pid argument which can be passed to kill; group kills
4325 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4326 they'll most likely hit all the threads and we won't need to worry
4327 about cleanup. In truth, we can't fully emulate these multicast
4328 kills.
4329
4330 "tgid" is a thread group id. If it is not -1, then the target
4331 thread must be in that thread group.
4332 */
sewardj7eb7c582005-06-23 01:02:53 +00004333Bool ML_(do_sigkill)(Int pid, Int tgid)
njn03f1e582005-03-26 20:08:06 +00004334{
4335 ThreadState *tst;
4336 ThreadId tid;
4337
4338 if (pid <= 0)
4339 return False;
4340
4341 tid = VG_(get_lwp_tid)(pid);
4342 if (tid == VG_INVALID_THREADID)
4343 return False; /* none of our threads */
4344
4345 tst = VG_(get_ThreadState)(tid);
4346 if (tst == NULL || tst->status == VgTs_Empty)
4347 return False; /* hm, shouldn't happen */
4348
4349 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4350 return False; /* not the right thread group */
4351
4352 /* Check to see that the target isn't already exiting. */
4353 if (!VG_(is_exiting)(tid)) {
4354 if (VG_(clo_trace_signals))
sewardja8d8e232005-06-07 20:04:56 +00004355 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL",
4356 tst->tid);
njn03f1e582005-03-26 20:08:06 +00004357
4358 tst->exitreason = VgSrc_FatalSig;
4359 tst->os_state.fatalsig = VKI_SIGKILL;
4360
4361 if (!VG_(is_running_thread)(tid))
4362 VG_(kill_thread)(tid);
4363 }
4364
4365 return True;
4366}
4367
sewardja8d8e232005-06-07 20:04:56 +00004368PRE(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004369{
4370 /* int kill(pid_t pid, int sig); */
njn22cfccb2004-11-27 16:10:23 +00004371 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004372 PRE_REG_READ2(long, "kill", int, pid, int, sig);
sewardj7eb7c582005-06-23 01:02:53 +00004373 if (!ML_(client_signal_OK)(ARG2)) {
sewardja8d8e232005-06-07 20:04:56 +00004374 SET_STATUS_Failure( VKI_EINVAL );
njn03f1e582005-03-26 20:08:06 +00004375 return;
4376 }
jsgf855d93d2003-10-13 22:26:55 +00004377
njn03f1e582005-03-26 20:08:06 +00004378 /* If we're sending SIGKILL, check to see if the target is one of
4379 our threads and handle it specially. */
sewardj7eb7c582005-06-23 01:02:53 +00004380 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
sewardja8d8e232005-06-07 20:04:56 +00004381 SET_STATUS_Success(0);
njn03f1e582005-03-26 20:08:06 +00004382 else
sewardja8d8e232005-06-07 20:04:56 +00004383 SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
njn03f1e582005-03-26 20:08:06 +00004384
sewardjb5f6f512005-03-10 23:59:00 +00004385 if (VG_(clo_trace_signals))
4386 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
njn03f1e582005-03-26 20:08:06 +00004387 ARG2, ARG1);
sewardja8d8e232005-06-07 20:04:56 +00004388
4389 /* This kill might have given us a pending signal. Ask for a check once
4390 the syscall is done. */
4391 *flags |= SfPollAfter;
jsgf855d93d2003-10-13 22:26:55 +00004392}
4393
sewardja8d8e232005-06-07 20:04:56 +00004394PRE(sys_link)
jsgf855d93d2003-10-13 22:26:55 +00004395{
sewardja8d8e232005-06-07 20:04:56 +00004396 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004397 PRINT("sys_link ( %p, %p)", ARG1, ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004398 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004399 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4400 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004401}
4402
sewardja8d8e232005-06-07 20:04:56 +00004403PRE(sys_lseek)
jsgf855d93d2003-10-13 22:26:55 +00004404{
njn22cfccb2004-11-27 16:10:23 +00004405 PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00004406 PRE_REG_READ3(vki_off_t, "lseek",
4407 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004408}
4409
sewardj696c5512005-06-08 23:38:32 +00004410PRE(sys_newlstat)
4411{
4412 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
4413 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4414 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4415 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4416}
4417
4418POST(sys_newlstat)
4419{
4420 vg_assert(SUCCESS);
4421 if (RES == 0) {
4422 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4423 }
4424}
jsgf855d93d2003-10-13 22:26:55 +00004425
sewardja8d8e232005-06-07 20:04:56 +00004426PRE(sys_mkdir)
jsgf855d93d2003-10-13 22:26:55 +00004427{
sewardja8d8e232005-06-07 20:04:56 +00004428 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004429 PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004430 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004431 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004432}
4433
sewardja8d8e232005-06-07 20:04:56 +00004434PRE(sys_mmap2)
jsgf855d93d2003-10-13 22:26:55 +00004435{
sewardja8d8e232005-06-07 20:04:56 +00004436 // Exactly like old_mmap() in x86-linux except:
nethercote3d5e9102004-11-17 18:22:38 +00004437 // - all 6 args are passed in regs, rather than in a memory-block.
4438 // - the file offset is specified in pagesize units rather than bytes,
4439 // so that it can be used for files bigger than 2^32 bytes.
4440 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
njn22cfccb2004-11-27 16:10:23 +00004441 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
nethercote3d5e9102004-11-17 18:22:38 +00004442 PRE_REG_READ6(long, "mmap2",
4443 unsigned long, start, unsigned long, length,
4444 unsigned long, prot, unsigned long, flags,
4445 unsigned long, fd, unsigned long, offset);
4446
sewardjb5f6f512005-03-10 23:59:00 +00004447 if (ARG2 == 0) {
4448 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4449 shall be established. */
sewardja8d8e232005-06-07 20:04:56 +00004450 SET_STATUS_Failure( VKI_EINVAL );
sewardjb5f6f512005-03-10 23:59:00 +00004451 return;
4452 }
4453
sewardj565b1ed2005-03-11 14:12:38 +00004454 if (/*(ARG4 & VKI_MAP_FIXED) && */ (0 != (ARG1 & (VKI_PAGE_SIZE-1)))) {
4455 /* zap any misaligned addresses. */
sewardjd0d97312005-03-23 02:53:13 +00004456 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
4457 to fail. Here, we catch them all. */
sewardja8d8e232005-06-07 20:04:56 +00004458 SET_STATUS_Failure( VKI_EINVAL );
sewardj565b1ed2005-03-11 14:12:38 +00004459 return;
4460 }
4461
njn22cfccb2004-11-27 16:10:23 +00004462 if (ARG4 & VKI_MAP_FIXED) {
sewardj7eb7c582005-06-23 01:02:53 +00004463 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
sewardja8d8e232005-06-07 20:04:56 +00004464 SET_STATUS_Failure( VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004465 } else {
sewardjd0d97312005-03-23 02:53:13 +00004466 Addr a = VG_(find_map_space)(ARG1, ARG2, True);
4467 if (a == 0 && ARG1 != 0)
4468 ARG1 = VG_(find_map_space)(0, ARG2, True);
4469 else
4470 ARG1 = a;
njn22cfccb2004-11-27 16:10:23 +00004471 if (ARG1 == 0)
sewardja8d8e232005-06-07 20:04:56 +00004472 SET_STATUS_Failure( VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004473 else
njn22cfccb2004-11-27 16:10:23 +00004474 ARG4 |= VKI_MAP_FIXED;
nethercote3d5e9102004-11-17 18:22:38 +00004475 }
4476}
4477
4478POST(sys_mmap2)
4479{
sewardja8d8e232005-06-07 20:04:56 +00004480 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004481 vg_assert(ML_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
4482 ML_(mmap_segment)( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
sewardja8d8e232005-06-07 20:04:56 +00004483 ARG6 * (ULong)VKI_PAGE_SIZE );
nethercote3d5e9102004-11-17 18:22:38 +00004484}
4485
sewardja8d8e232005-06-07 20:04:56 +00004486PRE(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004487{
njn22cfccb2004-11-27 16:10:23 +00004488 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004489 PRE_REG_READ3(long, "mprotect",
4490 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004491
sewardj7eb7c582005-06-23 01:02:53 +00004492 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
sewardja8d8e232005-06-07 20:04:56 +00004493 SET_STATUS_Failure( VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004494}
4495
nethercote85a456f2004-11-16 17:31:56 +00004496POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004497{
njn22cfccb2004-11-27 16:10:23 +00004498 Addr a = ARG1;
4499 SizeT len = ARG2;
4500 Int prot = ARG3;
nethercote27ea8bc2004-07-10 17:21:14 +00004501 Bool rr = prot & VKI_PROT_READ;
4502 Bool ww = prot & VKI_PROT_WRITE;
4503 Bool xx = prot & VKI_PROT_EXEC;
4504
nethercote27ea8bc2004-07-10 17:21:14 +00004505 mash_addr_and_len(&a, &len);
4506 VG_(mprotect_range)(a, len, prot);
4507 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004508}
4509
sewardja8d8e232005-06-07 20:04:56 +00004510PRE(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004511{
sewardja8d8e232005-06-07 20:04:56 +00004512 if (0) VG_(printf)(" munmap( %p )\n", ARG1);
njn22cfccb2004-11-27 16:10:23 +00004513 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004514 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004515
sewardj7eb7c582005-06-23 01:02:53 +00004516 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
sewardja8d8e232005-06-07 20:04:56 +00004517 SET_STATUS_Failure( VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004518}
4519
nethercote85a456f2004-11-16 17:31:56 +00004520POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004521{
njn22cfccb2004-11-27 16:10:23 +00004522 Addr a = ARG1;
4523 SizeT len = ARG2;
nethercote27ea8bc2004-07-10 17:21:14 +00004524
4525 mash_addr_and_len(&a, &len);
4526 VG_(unmap_range)(a, len);
4527 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004528}
4529
sewardje6d5e722005-06-10 10:27:55 +00004530PRE(sys_mincore)
4531{
4532 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
4533 PRE_REG_READ3(long, "mincore",
4534 unsigned long, start, vki_size_t, length,
4535 unsigned char *, vec);
njncdaec512005-06-30 00:16:02 +00004536 PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
sewardje6d5e722005-06-10 10:27:55 +00004537}
4538POST(sys_mincore)
4539{
njncdaec512005-06-30 00:16:02 +00004540 POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
sewardje6d5e722005-06-10 10:27:55 +00004541}
mueller6ceb2312004-01-02 22:52:34 +00004542
sewardja8d8e232005-06-07 20:04:56 +00004543PRE(sys_nanosleep)
mueller6ceb2312004-01-02 22:52:34 +00004544{
sewardja8d8e232005-06-07 20:04:56 +00004545 *flags |= SfMayBlock|SfPostOnFail;
njn22cfccb2004-11-27 16:10:23 +00004546 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004547 PRE_REG_READ2(long, "nanosleep",
4548 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004549 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4550 if (ARG2 != 0)
4551 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004552}
4553
nethercote85a456f2004-11-16 17:31:56 +00004554POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004555{
sewardja8d8e232005-06-07 20:04:56 +00004556 vg_assert(SUCCESS || FAILURE);
4557 if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
njn22cfccb2004-11-27 16:10:23 +00004558 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004559}
4560
sewardja8d8e232005-06-07 20:04:56 +00004561PRE(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004562{
sewardja8d8e232005-06-07 20:04:56 +00004563 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004564 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004565 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004566 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004567 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004568 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004569 } else {
nethercotee824cc42004-11-09 16:20:46 +00004570 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004571 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004572 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004573 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004574 }
njn22cfccb2004-11-27 16:10:23 +00004575 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004576}
4577
nethercote85a456f2004-11-16 17:31:56 +00004578POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004579{
sewardja8d8e232005-06-07 20:04:56 +00004580 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004581 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00004582 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00004583 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004584 } else {
nethercote493dd182004-02-24 23:57:47 +00004585 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00004586 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004587 }
jsgf855d93d2003-10-13 22:26:55 +00004588}
4589
sewardja8d8e232005-06-07 20:04:56 +00004590PRE(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004591{
sewardja8d8e232005-06-07 20:04:56 +00004592 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004593 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004594 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004595 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004596
sewardj7eb7c582005-06-23 01:02:53 +00004597 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00004598 SET_STATUS_Failure( VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004599 else
njn22cfccb2004-11-27 16:10:23 +00004600 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004601}
4602
nethercote85a456f2004-11-16 17:31:56 +00004603POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004604{
sewardja8d8e232005-06-07 20:04:56 +00004605 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00004606 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004607}
4608
sewardja8d8e232005-06-07 20:04:56 +00004609PRE(sys_write)
jsgf855d93d2003-10-13 22:26:55 +00004610{
sewardja8d8e232005-06-07 20:04:56 +00004611 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004612 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004613 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004614 unsigned int, fd, const char *, buf, vki_size_t, count);
sewardj7eb7c582005-06-23 01:02:53 +00004615 if (!ML_(fd_allowed)(ARG1, "write", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00004616 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004617 else
njn22cfccb2004-11-27 16:10:23 +00004618 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004619}
4620
sewardja8d8e232005-06-07 20:04:56 +00004621PRE(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004622{
sewardja8d8e232005-06-07 20:04:56 +00004623 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004624 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004625 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004626 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004627}
4628
nethercote85a456f2004-11-16 17:31:56 +00004629POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004630{
sewardja8d8e232005-06-07 20:04:56 +00004631 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004632 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00004633 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00004634 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004635 } else {
nethercote493dd182004-02-24 23:57:47 +00004636 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00004637 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004638 }
jsgf855d93d2003-10-13 22:26:55 +00004639}
4640
nethercote9a3beb92004-11-12 17:07:26 +00004641// XXX: sort of x86-specific
sewardja8d8e232005-06-07 20:04:56 +00004642PRE(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004643{
njn22cfccb2004-11-27 16:10:23 +00004644 PRINT("sys_pipe ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004645 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
njn22cfccb2004-11-27 16:10:23 +00004646 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004647}
4648
nethercote85a456f2004-11-16 17:31:56 +00004649POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004650{
njn22cfccb2004-11-27 16:10:23 +00004651 Int *p = (Int *)ARG1;
jsgf855d93d2003-10-13 22:26:55 +00004652
sewardj7eb7c582005-06-23 01:02:53 +00004653 if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
4654 !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004655 VG_(close)(p[0]);
4656 VG_(close)(p[1]);
sewardja8d8e232005-06-07 20:04:56 +00004657 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004658 } else {
njn22cfccb2004-11-27 16:10:23 +00004659 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004660 if (VG_(clo_track_fds)) {
njnf845f8f2005-06-23 02:26:47 +00004661 ML_(record_fd_open_nameless)(tid, p[0]);
4662 ML_(record_fd_open_nameless)(tid, p[1]);
rjwalshf5f536f2003-11-17 17:45:00 +00004663 }
4664 }
jsgf855d93d2003-10-13 22:26:55 +00004665}
4666
nethercotef90953e2004-11-15 14:50:02 +00004667// XXX: x86-specific, due to pollfd struct
sewardja8d8e232005-06-07 20:04:56 +00004668PRE(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004669{
4670 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004671 int fd; -- file descriptor
4672 short events; -- requested events
4673 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004674 };
nethercoteeb0592d2004-11-05 12:02:27 +00004675 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004676 */
nethercoteeb0592d2004-11-05 12:02:27 +00004677 UInt i;
sewardja8d8e232005-06-07 20:04:56 +00004678 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004679 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
4680 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00004681 PRE_REG_READ3(long, "poll",
4682 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004683
njn22cfccb2004-11-27 16:10:23 +00004684 for (i = 0; i < ARG2; i++) {
nethercoteeb0592d2004-11-05 12:02:27 +00004685 // 'fd' and 'events' field are inputs; 'revents' is output.
4686 // XXX: this is x86 specific -- the pollfd struct varies across
4687 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004688 PRE_MEM_READ( "poll(ufds)",
4689 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4690 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4691 }
jsgf855d93d2003-10-13 22:26:55 +00004692}
4693
nethercote85a456f2004-11-16 17:31:56 +00004694POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004695{
njn22cfccb2004-11-27 16:10:23 +00004696 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004697 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004698 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
nethercoteeb0592d2004-11-05 12:02:27 +00004699 // XXX: again, this is x86-specific
njn22cfccb2004-11-27 16:10:23 +00004700 for (i = 0; i < ARG2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004701 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004702 }
4703}
4704
sewardja8d8e232005-06-07 20:04:56 +00004705PRE(sys_readlink)
jsgf855d93d2003-10-13 22:26:55 +00004706{
sewardja8d8e232005-06-07 20:04:56 +00004707 Word saved = SYSNO;
njn22cfccb2004-11-27 16:10:23 +00004708 PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00004709 PRE_REG_READ3(long, "readlink",
4710 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00004711 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4712 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004713
rjwalsh17d85302004-11-18 22:56:09 +00004714 /*
rjwalsh093047d2004-11-19 02:11:56 +00004715 * Handle the case where readlink is looking at /proc/self/exe or
4716 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004717 */
4718
sewardja8d8e232005-06-07 20:04:56 +00004719 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004720
sewardja8d8e232005-06-07 20:04:56 +00004721 /* jrs 20050604: where does the magic value 2 come from? It seems
4722 like it should be a kernel error value, but we don't know of any
4723 such. */
4724 if (SWHAT == SsFailure && RES_unchecked == 2) {
4725 HChar name[25];
rjwalsh093047d2004-11-19 02:11:56 +00004726 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
njn22cfccb2004-11-27 16:10:23 +00004727 if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
4728 VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
rjwalsh093047d2004-11-19 02:11:56 +00004729 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
sewardja8d8e232005-06-07 20:04:56 +00004730 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004731 }
rjwalsh17d85302004-11-18 22:56:09 +00004732 }
4733
sewardja8d8e232005-06-07 20:04:56 +00004734 if (SUCCESS && RES > 0)
njn22cfccb2004-11-27 16:10:23 +00004735 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004736}
4737
sewardja8d8e232005-06-07 20:04:56 +00004738PRE(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004739{
jsgf855d93d2003-10-13 22:26:55 +00004740 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004741 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00004742 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004743 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00004744 PRE_REG_READ3(ssize_t, "readv",
4745 unsigned long, fd, const struct iovec *, vector,
4746 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00004747 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00004748 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004749 } else {
njn22cfccb2004-11-27 16:10:23 +00004750 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004751
njn22cfccb2004-11-27 16:10:23 +00004752 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004753 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00004754 vec = (struct vki_iovec *)ARG2;
4755 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00004756 PRE_MEM_WRITE( "readv(vector[...])",
4757 (Addr)vec[i].iov_base, vec[i].iov_len );
4758 }
jsgf855d93d2003-10-13 22:26:55 +00004759 }
4760}
4761
nethercote85a456f2004-11-16 17:31:56 +00004762POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004763{
sewardja8d8e232005-06-07 20:04:56 +00004764 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00004765 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004766 Int i;
njn22cfccb2004-11-27 16:10:23 +00004767 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4768 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00004769
njn22cfccb2004-11-27 16:10:23 +00004770 /* RES holds the number of bytes read. */
4771 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00004772 Int nReadThisBuf = vec[i].iov_len;
4773 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004774 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004775 remains -= nReadThisBuf;
4776 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4777 }
4778 }
4779}
4780
sewardja8d8e232005-06-07 20:04:56 +00004781PRE(sys_rename)
jsgf855d93d2003-10-13 22:26:55 +00004782{
njn22cfccb2004-11-27 16:10:23 +00004783 PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
nethercote9a3beb92004-11-12 17:07:26 +00004784 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004785 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4786 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004787}
4788
sewardj78b50e42005-06-08 01:47:28 +00004789PRE(sys_rmdir)
4790{
4791 *flags |= SfMayBlock;
4792 PRINT("sys_rmdir ( %p )", ARG1);
4793 PRE_REG_READ1(long, "rmdir", const char *, pathname);
4794 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
4795}
4796
sewardje6d5e722005-06-10 10:27:55 +00004797PRE(sys_sched_setparam)
4798{
4799 PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
4800 PRE_REG_READ2(long, "sched_setparam",
4801 vki_pid_t, pid, struct sched_param *, p);
4802 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
4803}
4804POST(sys_sched_setparam)
4805{
4806 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
4807}
sewardj78b50e42005-06-08 01:47:28 +00004808
4809PRE(sys_sched_getparam)
4810{
4811 PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
4812 PRE_REG_READ2(long, "sched_getparam",
4813 vki_pid_t, pid, struct sched_param *, p);
4814 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
4815}
4816
4817POST(sys_sched_getparam)
4818{
4819 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
4820}
jsgf855d93d2003-10-13 22:26:55 +00004821
sewardja8d8e232005-06-07 20:04:56 +00004822PRE(sys_select)
jsgf855d93d2003-10-13 22:26:55 +00004823{
sewardja8d8e232005-06-07 20:04:56 +00004824 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00004825 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00004826 PRE_REG_READ5(long, "select",
4827 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4828 vki_fd_set *, exceptfds, struct timeval *, timeout);
4829 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00004830 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004831 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00004832 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4833 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004834 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00004835 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4836 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004837 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00004838 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4839 if (ARG5 != 0)
4840 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00004841}
4842
sewardj8c9ea4e2005-06-08 10:46:56 +00004843PRE(sys_setgid16)
4844{
4845 PRINT("sys_setgid16 ( %d )", ARG1);
4846 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4847}
4848
sewardje6d5e722005-06-10 10:27:55 +00004849PRE(sys_setgid)
4850{
4851 PRINT("sys_setgid ( %d )", ARG1);
4852 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
4853}
sewardj696c5512005-06-08 23:38:32 +00004854
4855PRE(sys_setsid)
4856{
4857 PRINT("sys_setsid ( )");
4858 PRE_REG_READ0(long, "setsid");
4859}
4860
4861PRE(sys_setgroups16)
4862{
4863 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
4864 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
4865 if (ARG1 > 0)
4866 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
4867}
4868
sewardje6d5e722005-06-10 10:27:55 +00004869PRE(sys_setgroups)
4870{
4871 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
4872 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
4873 if (ARG1 > 0)
4874 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
4875}
sewardj696c5512005-06-08 23:38:32 +00004876
4877PRE(sys_setpgid)
4878{
4879 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
4880 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
4881}
4882
4883PRE(sys_setregid)
4884{
4885 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
4886 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
4887}
4888
4889PRE(sys_setreuid16)
4890{
4891 PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
4892 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4893}
4894
sewardje6d5e722005-06-10 10:27:55 +00004895PRE(sys_setreuid)
4896{
4897 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
4898 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
4899}
nethercote9c311eb2004-11-12 18:20:12 +00004900
sewardja8d8e232005-06-07 20:04:56 +00004901PRE(sys_setrlimit)
jsgf855d93d2003-10-13 22:26:55 +00004902{
njn22cfccb2004-11-27 16:10:23 +00004903 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004904 PRE_REG_READ2(long, "setrlimit",
4905 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00004906 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004907
njn22cfccb2004-11-27 16:10:23 +00004908 if (ARG1 == VKI_RLIMIT_NOFILE) {
4909 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4910 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
sewardja8d8e232005-06-07 20:04:56 +00004911 SET_STATUS_Failure( VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004912 }
4913 else {
njn22cfccb2004-11-27 16:10:23 +00004914 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
sewardja8d8e232005-06-07 20:04:56 +00004915 SET_STATUS_Success( 0 );
thughesad1c9562004-06-26 11:27:52 +00004916 }
4917 }
njn22cfccb2004-11-27 16:10:23 +00004918 else if (ARG1 == VKI_RLIMIT_DATA) {
4919 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4920 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00004921 SET_STATUS_Failure( VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004922 }
4923 else {
njn22cfccb2004-11-27 16:10:23 +00004924 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00004925 SET_STATUS_Success( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004926 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004927 }
njn22cfccb2004-11-27 16:10:23 +00004928 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
4929 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4930 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00004931 SET_STATUS_Failure( VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004932 }
4933 else {
sewardja8d8e232005-06-07 20:04:56 +00004934 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
njn22cfccb2004-11-27 16:10:23 +00004935 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00004936 SET_STATUS_Success( 0 );
thughesc37184f2004-09-11 14:16:57 +00004937 }
4938 }
jsgf855d93d2003-10-13 22:26:55 +00004939}
4940
sewardja8d8e232005-06-07 20:04:56 +00004941PRE(sys_setuid16)
jsgf855d93d2003-10-13 22:26:55 +00004942{
njn22cfccb2004-11-27 16:10:23 +00004943 PRINT("sys_setuid16 ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004944 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004945}
4946
sewardje6d5e722005-06-10 10:27:55 +00004947PRE(sys_setuid)
4948{
4949 PRINT("sys_setuid ( %d )", ARG1);
4950 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4951}
jsgf855d93d2003-10-13 22:26:55 +00004952
sewardj696c5512005-06-08 23:38:32 +00004953PRE(sys_newstat)
4954{
4955 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
4956 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
4957 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4958 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
4959}
4960
4961POST(sys_newstat)
4962{
4963 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4964}
4965
4966PRE(sys_statfs)
4967{
4968 PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
4969 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
4970 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4971 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
4972}
sewardj696c5512005-06-08 23:38:32 +00004973POST(sys_statfs)
4974{
4975 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
4976}
4977
sewardje6d5e722005-06-10 10:27:55 +00004978PRE(sys_statfs64)
4979{
4980 PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
4981 PRE_REG_READ3(long, "statfs64",
4982 const char *, path, vki_size_t, size, struct statfs64 *, buf);
4983 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4984 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
4985}
4986POST(sys_statfs64)
4987{
4988 POST_MEM_WRITE( ARG3, ARG2 );
4989}
sewardj78b50e42005-06-08 01:47:28 +00004990
4991PRE(sys_symlink)
4992{
4993 *flags |= SfMayBlock;
4994 PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
4995 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
4996 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4997 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
4998}
sewardj9efbbef2005-03-01 16:45:23 +00004999
sewardja8d8e232005-06-07 20:04:56 +00005000PRE(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005001{
5002 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00005003 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005004 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00005005 if (ARG1 != 0) {
5006 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005007 }
5008}
5009
nethercote85a456f2004-11-16 17:31:56 +00005010POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005011{
njn22cfccb2004-11-27 16:10:23 +00005012 if (ARG1 != 0) {
5013 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005014 }
5015}
5016
sewardj78b50e42005-06-08 01:47:28 +00005017PRE(sys_times)
5018{
5019 PRINT("sys_times ( %p )", ARG1);
5020 PRE_REG_READ1(long, "times", struct tms *, buf);
5021 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
5022}
5023
5024POST(sys_times)
5025{
5026 if (ARG1 != 0) {
5027 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
5028 }
5029}
5030
5031PRE(sys_umask)
5032{
5033 PRINT("sys_umask ( %d )", ARG1);
5034 PRE_REG_READ1(long, "umask", int, mask);
5035}
jsgf855d93d2003-10-13 22:26:55 +00005036
sewardja8d8e232005-06-07 20:04:56 +00005037PRE(sys_unlink)
jsgf855d93d2003-10-13 22:26:55 +00005038{
sewardja8d8e232005-06-07 20:04:56 +00005039 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005040 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005041 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00005042 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005043}
5044
sewardja8d8e232005-06-07 20:04:56 +00005045PRE(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005046{
njn22cfccb2004-11-27 16:10:23 +00005047 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00005048 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00005049 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005050}
5051
nethercote85a456f2004-11-16 17:31:56 +00005052POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005053{
njn22cfccb2004-11-27 16:10:23 +00005054 if (ARG1 != 0) {
5055 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005056 }
5057}
5058
sewardj8c9ea4e2005-06-08 10:46:56 +00005059PRE(sys_utime)
5060{
5061 *flags |= SfMayBlock;
5062 PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
5063 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
5064 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
5065 if (ARG2 != 0)
5066 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
5067}
jsgf855d93d2003-10-13 22:26:55 +00005068
sewardja8d8e232005-06-07 20:04:56 +00005069PRE(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005070{
sewardja8d8e232005-06-07 20:04:56 +00005071 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005072 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00005073 PRE_REG_READ3(long, "waitpid",
5074 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005075
njn22cfccb2004-11-27 16:10:23 +00005076 if (ARG2 != (Addr)NULL)
5077 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005078}
5079
nethercote85a456f2004-11-16 17:31:56 +00005080POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005081{
njn22cfccb2004-11-27 16:10:23 +00005082 if (ARG2 != (Addr)NULL)
5083 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005084}
5085
sewardja8d8e232005-06-07 20:04:56 +00005086PRE(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005087{
sewardja8d8e232005-06-07 20:04:56 +00005088 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005089 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
jsgf855d93d2003-10-13 22:26:55 +00005090
nethercote7f7e4d12004-11-15 12:28:58 +00005091 PRE_REG_READ4(long, "wait4",
5092 vki_pid_t, pid, unsigned int *, status, int, options,
5093 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00005094 if (ARG2 != (Addr)NULL)
5095 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5096 if (ARG4 != (Addr)NULL)
5097 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005098}
5099
nethercote85a456f2004-11-16 17:31:56 +00005100POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005101{
njn22cfccb2004-11-27 16:10:23 +00005102 if (ARG2 != (Addr)NULL)
5103 POST_MEM_WRITE( ARG2, sizeof(int) );
5104 if (ARG4 != (Addr)NULL)
5105 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005106}
5107
sewardja8d8e232005-06-07 20:04:56 +00005108PRE(sys_writev)
jsgf855d93d2003-10-13 22:26:55 +00005109{
jsgf855d93d2003-10-13 22:26:55 +00005110 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005111 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00005112 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005113 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005114 PRE_REG_READ3(ssize_t, "writev",
5115 unsigned long, fd, const struct iovec *, vector,
5116 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00005117 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00005118 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005119 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005120 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005121 ARG2, ARG3 * sizeof(struct vki_iovec) );
5122 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005123 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005124 vec = (struct vki_iovec *)ARG2;
5125 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005126 PRE_MEM_READ( "writev(vector[...])",
5127 (Addr)vec[i].iov_base, vec[i].iov_len );
5128 }
jsgf855d93d2003-10-13 22:26:55 +00005129 }
5130}
5131
sewardje6d5e722005-06-10 10:27:55 +00005132PRE(sys_utimes)
5133{
5134 PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
5135 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
5136 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5137 if (ARG2 != 0)
5138 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
5139}
5140
5141PRE(sys_sched_setaffinity)
5142{
5143 PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
5144 PRE_REG_READ3(long, "sched_setaffinity",
5145 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
5146 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
5147}
5148
5149PRE(sys_sched_getaffinity)
5150{
5151 PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
5152 PRE_REG_READ3(long, "sched_getaffinity",
5153 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
5154 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
5155}
5156POST(sys_sched_getaffinity)
5157{
5158 POST_MEM_WRITE(ARG3, ARG2);
5159}
sewardj696c5512005-06-08 23:38:32 +00005160
5161PRE(sys_acct)
5162{
5163 PRINT("sys_acct ( %p )", ARG1);
5164 PRE_REG_READ1(long, "acct", const char *, filename);
5165 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
5166}
muellerd3502b62003-11-19 00:43:57 +00005167
sewardja8d8e232005-06-07 20:04:56 +00005168PRE(sys_pause)
thughes2f8d5f82004-09-11 14:29:19 +00005169{
sewardja8d8e232005-06-07 20:04:56 +00005170 *flags |= SfMayBlock;
nethercote0df495a2004-11-11 16:38:21 +00005171 PRINT("sys_pause ( )");
5172 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005173}
5174
sewardja8d8e232005-06-07 20:04:56 +00005175//zz // XXX: x86-specific
5176//zz PRE(sys_sigsuspend, SfMayBlock)
5177//zz {
5178//zz /* The C library interface to sigsuspend just takes a pointer to
5179//zz a signal mask but this system call has three arguments - the first
5180//zz two don't appear to be used by the kernel and are always passed as
5181//zz zero by glibc and the third is the first word of the signal mask
5182//zz so only 32 signals are supported.
5183//zz
5184//zz In fact glibc normally uses rt_sigsuspend if it is available as
5185//zz that takes a pointer to the signal mask so supports more signals.
5186//zz */
5187//zz PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
5188//zz PRE_REG_READ3(int, "sigsuspend",
5189//zz int, history0, int, history1,
5190//zz vki_old_sigset_t, mask);
5191//zz }
jsgf855d93d2003-10-13 22:26:55 +00005192
nethercotea3a2c142004-11-14 14:13:05 +00005193// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005194PRE(sys_rt_sigsuspend)
nethercotea3a2c142004-11-14 14:13:05 +00005195{
thughesc3e85df2004-11-15 09:27:24 +00005196 /* The C library interface to sigsuspend just takes a pointer to
5197 a signal mask but this system call has two arguments - a pointer
5198 to the mask and the number of bytes used by it. The kernel insists
5199 on the size being equal to sizeof(sigset_t) however and will just
5200 return EINVAL if it isn't.
5201 */
sewardja8d8e232005-06-07 20:04:56 +00005202 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005203 PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
nethercotea3a2c142004-11-14 14:13:05 +00005204 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
njn22cfccb2004-11-27 16:10:23 +00005205 if (ARG1 != (Addr)NULL) {
5206 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
nethercotea3a2c142004-11-14 14:13:05 +00005207 }
5208}
jsgf855d93d2003-10-13 22:26:55 +00005209
sewardja8d8e232005-06-07 20:04:56 +00005210PRE(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005211{
sewardja8d8e232005-06-07 20:04:56 +00005212 *flags |= SfMayBlock;
nethercoteac866b92004-11-15 20:23:15 +00005213 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
njn22cfccb2004-11-27 16:10:23 +00005214 ARG1,ARG2,ARG3,(ULong)ARG4);
nethercoteac866b92004-11-15 20:23:15 +00005215 PRE_REG_READ4(long, "rt_sigtimedwait",
5216 const vki_sigset_t *, set, vki_siginfo_t *, info,
5217 const struct timespec *, timeout, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005218 if (ARG1 != 0)
5219 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
5220 if (ARG2 != 0)
5221 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
nethercoteac866b92004-11-15 20:23:15 +00005222 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
njn22cfccb2004-11-27 16:10:23 +00005223 ARG4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005224}
5225
nethercote85a456f2004-11-16 17:31:56 +00005226POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005227{
njn22cfccb2004-11-27 16:10:23 +00005228 if (ARG2 != 0)
5229 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005230}
5231
sewardje6d5e722005-06-10 10:27:55 +00005232PRE(sys_rt_sigqueueinfo)
5233{
5234 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
5235 PRE_REG_READ3(long, "rt_sigqueueinfo",
5236 int, pid, int, sig, vki_siginfo_t *, uinfo);
5237 if (ARG2 != 0)
5238 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
5239}
5240POST(sys_rt_sigqueueinfo)
5241{
sewardj7eb7c582005-06-23 01:02:53 +00005242 if (!ML_(client_signal_OK)(ARG2))
sewardje6d5e722005-06-10 10:27:55 +00005243 SET_STATUS_Failure( VKI_EINVAL );
5244}
jsgf855d93d2003-10-13 22:26:55 +00005245
nethercoteb77dee62004-11-16 17:13:24 +00005246// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005247PRE(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005248{
5249 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
njn22cfccb2004-11-27 16:10:23 +00005250 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005251 PRE_REG_READ2(int, "sigaltstack",
5252 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005253 if (ARG1 != 0) {
5254 PRE_MEM_READ( "sigaltstack(ss)", ARG1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005255 }
njn22cfccb2004-11-27 16:10:23 +00005256 if (ARG2 != 0) {
5257 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005258 }
5259
sewardja8d8e232005-06-07 20:04:56 +00005260 SET_STATUS_from_SysRes(
5261 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1,
5262 (vki_stack_t*)ARG2)
5263 );
jsgf855d93d2003-10-13 22:26:55 +00005264}
nethercote85a456f2004-11-16 17:31:56 +00005265POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005266{
sewardja8d8e232005-06-07 20:04:56 +00005267 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005268 if (RES == 0 && ARG2 != 0)
5269 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005270}
5271
nethercote71f05f32004-11-12 18:49:27 +00005272// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005273PRE(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005274{
njn22cfccb2004-11-27 16:10:23 +00005275 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
nethercote686b5db2004-11-14 13:42:51 +00005276 PRE_REG_READ4(long, "rt_sigaction",
5277 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005278 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005279
njn22cfccb2004-11-27 16:10:23 +00005280 if (ARG2 != 0)
5281 PRE_MEM_READ( "rt_sigaction(act)", ARG2, sizeof(struct vki_sigaction));
5282 if (ARG3 != 0)
5283 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005284
njnb249fd72004-11-29 14:24:57 +00005285 // XXX: doesn't seem right to be calling do_sys_sigaction for
5286 // sys_rt_sigaction... perhaps this function should be renamed
5287 // VG_(do_sys_rt_sigaction)() --njn
sewardjb5f6f512005-03-10 23:59:00 +00005288
sewardja8d8e232005-06-07 20:04:56 +00005289 SET_STATUS_from_SysRes(
sewardjb5f6f512005-03-10 23:59:00 +00005290 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
5291 (struct vki_sigaction *)ARG3)
5292 );
nethercote686b5db2004-11-14 13:42:51 +00005293}
nethercote85a456f2004-11-16 17:31:56 +00005294POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005295{
sewardja8d8e232005-06-07 20:04:56 +00005296 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005297 if (RES == 0 && ARG3 != 0)
5298 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005299}
jsgf855d93d2003-10-13 22:26:55 +00005300
njnc6168192004-11-29 13:54:10 +00005301// XXX: This syscall is not used on amd64 -- it only provides
5302// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
5303// This wrapper is only suitable for 32-bit architectures.
sewardja8d8e232005-06-07 20:04:56 +00005304#if defined(VGP_x86_linux)
5305PRE(sys_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005306{
sewardj970ac792004-12-31 18:09:32 +00005307 vki_old_sigset_t* set;
5308 vki_old_sigset_t* oldset;
5309 vki_sigset_t bigger_set;
5310 vki_sigset_t bigger_oldset;
5311
njn22cfccb2004-11-27 16:10:23 +00005312 PRINT("sys_sigprocmask ( %d, %p, %p )",ARG1,ARG2,ARG3);
nethercote7fbe08a2004-11-15 19:03:27 +00005313 PRE_REG_READ3(long, "sigprocmask",
5314 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
njn22cfccb2004-11-27 16:10:23 +00005315 if (ARG2 != 0)
5316 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
5317 if (ARG3 != 0)
5318 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005319
njnb249fd72004-11-29 14:24:57 +00005320 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5321 // vki_sigset_t params.
sewardj970ac792004-12-31 18:09:32 +00005322 set = (vki_old_sigset_t*)ARG2;
5323 oldset = (vki_old_sigset_t*)ARG3;
nethercote7fbe08a2004-11-15 19:03:27 +00005324
sewardj1f276622004-12-06 16:18:58 +00005325 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5326 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
5327 if (set)
5328 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
nethercote7fbe08a2004-11-15 19:03:27 +00005329
sewardja8d8e232005-06-07 20:04:56 +00005330 SET_STATUS_from_SysRes(
njn4fbc86c2005-05-08 00:45:11 +00005331 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
5332 set ? &bigger_set : NULL,
5333 oldset ? &bigger_oldset : NULL)
5334 );
nethercote7fbe08a2004-11-15 19:03:27 +00005335
njnb249fd72004-11-29 14:24:57 +00005336 if (oldset)
5337 *oldset = bigger_oldset.sig[0];
sewardja8d8e232005-06-07 20:04:56 +00005338
5339 if (SUCCESS)
5340 *flags |= SfPollAfter;
nethercote7fbe08a2004-11-15 19:03:27 +00005341}
5342
nethercote85a456f2004-11-16 17:31:56 +00005343POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005344{
sewardja8d8e232005-06-07 20:04:56 +00005345 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005346 if (RES == 0 && ARG3 != 0)
5347 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005348}
njnc6168192004-11-29 13:54:10 +00005349#endif
nethercote7fbe08a2004-11-15 19:03:27 +00005350
sewardja8d8e232005-06-07 20:04:56 +00005351PRE(sys_rt_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005352{
njn22cfccb2004-11-27 16:10:23 +00005353 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
nethercote7fbe08a2004-11-15 19:03:27 +00005354 PRE_REG_READ4(long, "rt_sigprocmask",
5355 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5356 vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005357 if (ARG2 != 0)
5358 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
5359 if (ARG3 != 0)
5360 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005361
5362 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
njn22cfccb2004-11-27 16:10:23 +00005363 if (sizeof(vki_sigset_t) != ARG4)
sewardja8d8e232005-06-07 20:04:56 +00005364 SET_STATUS_Failure( VKI_EMFILE );
sewardj004e8ca2005-02-28 17:27:04 +00005365 else {
sewardja8d8e232005-06-07 20:04:56 +00005366 SET_STATUS_from_SysRes(
5367 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
njn4fbc86c2005-05-08 00:45:11 +00005368 (vki_sigset_t*) ARG2,
5369 (vki_sigset_t*) ARG3 )
5370 );
sewardj004e8ca2005-02-28 17:27:04 +00005371 }
sewardja8d8e232005-06-07 20:04:56 +00005372
5373 if (SUCCESS)
5374 *flags |= SfPollAfter;
jsgf855d93d2003-10-13 22:26:55 +00005375}
5376
nethercote85a456f2004-11-16 17:31:56 +00005377POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005378{
sewardja8d8e232005-06-07 20:04:56 +00005379 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005380 if (RES == 0 && ARG3 != 0)
5381 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005382}
5383
sewardj696c5512005-06-08 23:38:32 +00005384PRE(sys_sigpending)
5385{
5386 PRINT( "sys_sigpending ( %p )", ARG1 );
5387 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
5388 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
5389}
5390
5391POST(sys_sigpending)
5392{
5393 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
5394}
5395
sewardje6d5e722005-06-10 10:27:55 +00005396PRE(sys_rt_sigpending)
5397{
5398 PRINT( "sys_rt_sigpending ( %p )", ARG1 );
5399 PRE_REG_READ2(long, "rt_sigpending",
5400 vki_sigset_t *, set, vki_size_t, sigsetsize);
5401 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
5402}
5403POST(sys_rt_sigpending)
5404{
5405 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
5406}
sewardj8c257322005-06-08 01:01:48 +00005407
5408PRE(sys_mq_open)
5409{
5410 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
5411 ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
5412 PRE_REG_READ4(long, "mq_open",
5413 const char *, name, int, oflag, vki_mode_t, mode,
5414 struct mq_attr *, attr);
5415 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
5416 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
5417 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
5418 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
5419 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
5420 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
5421 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5422 }
5423}
5424
5425POST(sys_mq_open)
5426{
5427 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00005428 if (!ML_(fd_allowed)(RES, "mq_open", tid, True)) {
sewardj8c257322005-06-08 01:01:48 +00005429 VG_(close)(RES);
5430 SET_STATUS_Failure( VKI_EMFILE );
5431 } else {
5432 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00005433 record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
sewardj8c257322005-06-08 01:01:48 +00005434 }
5435}
5436
5437PRE(sys_mq_unlink)
5438{
5439 PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
5440 PRE_REG_READ1(long, "mq_unlink", const char *, name);
5441 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
5442}
5443
sewardj8c9ea4e2005-06-08 10:46:56 +00005444PRE(sys_mq_timedsend)
5445{
5446 *flags |= SfMayBlock;
5447 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
5448 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
5449 PRE_REG_READ5(long, "mq_timedsend",
5450 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5451 unsigned int, msg_prio, const struct timespec *, abs_timeout);
sewardj7eb7c582005-06-23 01:02:53 +00005452 if (!ML_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005453 SET_STATUS_Failure( VKI_EBADF );
5454 } else {
5455 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5456 if (ARG5 != 0)
5457 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
5458 sizeof(struct vki_timespec) );
5459 }
5460}
5461
5462PRE(sys_mq_timedreceive)
5463{
5464 *flags |= SfMayBlock;
5465 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
5466 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
5467 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5468 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5469 unsigned int *, msg_prio,
5470 const struct timespec *, abs_timeout);
sewardj7eb7c582005-06-23 01:02:53 +00005471 if (!ML_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005472 SET_STATUS_Failure( VKI_EBADF );
5473 } else {
5474 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
5475 if (ARG4 != 0)
5476 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
5477 ARG4, sizeof(unsigned int) );
5478 if (ARG5 != 0)
5479 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
5480 ARG5, sizeof(struct vki_timespec) );
5481 }
5482}
5483
5484POST(sys_mq_timedreceive)
5485{
5486 POST_MEM_WRITE( ARG2, ARG3 );
5487 if (ARG4 != 0)
5488 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
5489}
5490
5491PRE(sys_mq_notify)
5492{
5493 PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
5494 PRE_REG_READ2(long, "mq_notify",
5495 vki_mqd_t, mqdes, const struct sigevent *, notification);
sewardj7eb7c582005-06-23 01:02:53 +00005496 if (!ML_(fd_allowed)(ARG1, "mq_notify", tid, False))
sewardj8c9ea4e2005-06-08 10:46:56 +00005497 SET_STATUS_Failure( VKI_EBADF );
5498 else if (ARG2 != 0)
5499 PRE_MEM_READ( "mq_notify(notification)",
5500 ARG2, sizeof(struct vki_sigevent) );
5501}
5502
5503PRE(sys_mq_getsetattr)
5504{
5505 PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
5506 PRE_REG_READ3(long, "mq_getsetattr",
5507 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5508 struct mq_attr *, omqstat);
sewardj7eb7c582005-06-23 01:02:53 +00005509 if (!ML_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
sewardj8c9ea4e2005-06-08 10:46:56 +00005510 SET_STATUS_Failure( VKI_EBADF );
5511 } else {
5512 if (ARG2 != 0) {
5513 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
5514 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
5515 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5516 }
5517 if (ARG3 != 0)
5518 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
5519 sizeof(struct vki_mq_attr) );
5520 }
5521}
5522
5523POST(sys_mq_getsetattr)
5524{
5525 if (ARG3 != 0)
5526 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
5527}
5528
sewardje6d5e722005-06-10 10:27:55 +00005529PRE(sys_timer_create)
5530{
5531 PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
5532 PRE_REG_READ3(long, "timer_create",
5533 vki_clockid_t, clockid, struct sigevent *, evp,
5534 vki_timer_t *, timerid);
5535 if (ARG2 != 0)
5536 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
5537 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
5538}
5539POST(sys_timer_create)
5540{
5541 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
5542}
5543
5544PRE(sys_timer_settime)
5545{
5546 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
5547 PRE_REG_READ4(long, "timer_settime",
5548 vki_timer_t, timerid, int, flags,
5549 const struct itimerspec *, value,
5550 struct itimerspec *, ovalue);
5551 PRE_MEM_READ( "timer_settime(value)", ARG3,
5552 sizeof(struct vki_itimerspec) );
5553 if (ARG4 != 0)
5554 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
5555 sizeof(struct vki_itimerspec) );
5556}
5557POST(sys_timer_settime)
5558{
5559 if (ARG4 != 0)
5560 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
5561}
5562
5563PRE(sys_timer_gettime)
5564{
5565 PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
5566 PRE_REG_READ2(long, "timer_gettime",
5567 vki_timer_t, timerid, struct itimerspec *, value);
5568 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
5569 sizeof(struct vki_itimerspec));
5570}
5571POST(sys_timer_gettime)
5572{
5573 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
5574}
5575
5576PRE(sys_timer_getoverrun)
5577{
5578 PRINT("sys_timer_getoverrun( %p )", ARG1);
5579 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
5580}
5581
5582PRE(sys_timer_delete)
5583{
5584 PRINT("sys_timer_delete( %p )", ARG1);
5585 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
5586}
5587
5588PRE(sys_clock_settime)
5589{
5590 PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
5591 PRE_REG_READ2(long, "clock_settime",
5592 vki_clockid_t, clk_id, const struct timespec *, tp);
5593 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
5594}
jsgf855d93d2003-10-13 22:26:55 +00005595
sewardja8d8e232005-06-07 20:04:56 +00005596PRE(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005597{
njn22cfccb2004-11-27 16:10:23 +00005598 PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005599 PRE_REG_READ2(long, "clock_gettime",
5600 vki_clockid_t, clk_id, struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005601 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005602}
nethercote85a456f2004-11-16 17:31:56 +00005603POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005604{
njn22cfccb2004-11-27 16:10:23 +00005605 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005606}
5607
sewardje6d5e722005-06-10 10:27:55 +00005608PRE(sys_clock_getres)
5609{
5610 PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
5611 // Nb: we can't use "RES" as the param name because that's a macro
5612 // defined above!
5613 PRE_REG_READ2(long, "clock_getres",
5614 vki_clockid_t, clk_id, struct timespec *, res);
5615 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
5616}
5617POST(sys_clock_getres)
5618{
5619 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
5620}
thughese1a925d2004-08-30 19:50:02 +00005621
sewardje6d5e722005-06-10 10:27:55 +00005622#undef PRE
5623#undef POST
sewardj2e93c502002-04-12 11:12:52 +00005624
sewardjde4a1d02002-03-22 01:27:54 +00005625/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00005626/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005627/*--------------------------------------------------------------------*/