blob: 46c2d90d3a271f73c9a4a9e3445f30e616447377 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njn87ef6a62003-08-14 15:23:55 +00003/*--- Handle system calls. vg_syscalls.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
nethercotef1e5e152004-09-01 23:58:16 +000031#include "core.h"
njnd01fef72005-03-25 23:35:48 +000032#include "pub_core_stacktrace.h"
sewardjde4a1d02002-03-22 01:27:54 +000033
njn25e49d8e72002-09-23 09:36:25 +000034/* All system calls are channelled through here, doing two things:
sewardjde4a1d02002-03-22 01:27:54 +000035
nethercote4fa681f2004-11-08 17:51:39 +000036 * notify the tool of the events (mem/reg reads, writes) happening
sewardjde4a1d02002-03-22 01:27:54 +000037
38 * perform the syscall, usually by passing it along to the kernel
jsgf855d93d2003-10-13 22:26:55 +000039 unmodified.
sewardjde4a1d02002-03-22 01:27:54 +000040
jsgf855d93d2003-10-13 22:26:55 +000041 A magical piece of assembly code, VG_(do_syscall)(), in vg_syscall.S
sewardjde4a1d02002-03-22 01:27:54 +000042 does the tricky bit of passing a syscall to the kernel, whilst
43 having the simulator retain control.
44*/
45
jsgf855d93d2003-10-13 22:26:55 +000046/* ---------------------------------------------------------------------
47 A simple atfork() facility for Valgrind's internal use
48 ------------------------------------------------------------------ */
49
50struct atfork {
51 vg_atfork_t pre;
52 vg_atfork_t parent;
53 vg_atfork_t child;
54};
55
56#define VG_MAX_ATFORK 10
57
58static struct atfork atforks[VG_MAX_ATFORK];
59static Int n_atfork;
60
61void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
62{
63 Int i;
64
65 for(i = 0; i < n_atfork; i++) {
66 if (atforks[i].pre == pre &&
67 atforks[i].parent == parent &&
68 atforks[i].child == child)
69 return;
70 }
71
72 if (n_atfork >= VG_MAX_ATFORK)
73 VG_(core_panic)("Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
74
75 atforks[n_atfork].pre = pre;
76 atforks[n_atfork].parent = parent;
77 atforks[n_atfork].child = child;
78
79 n_atfork++;
80}
81
sewardjb5f6f512005-03-10 23:59:00 +000082void VG_(do_atfork_pre)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000083{
84 Int i;
85
86 for(i = 0; i < n_atfork; i++)
87 if (atforks[i].pre != NULL)
88 (*atforks[i].pre)(tid);
89}
90
sewardjb5f6f512005-03-10 23:59:00 +000091void VG_(do_atfork_parent)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000092{
93 Int i;
94
95 for(i = 0; i < n_atfork; i++)
96 if (atforks[i].parent != NULL)
97 (*atforks[i].parent)(tid);
98}
99
sewardjb5f6f512005-03-10 23:59:00 +0000100void VG_(do_atfork_child)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +0000101{
102 Int i;
103
104 for(i = 0; i < n_atfork; i++)
105 if (atforks[i].child != NULL)
106 (*atforks[i].child)(tid);
107}
108
fitzhardinge1a303042003-12-22 08:48:50 +0000109/* return true if address range entirely contained within client
110 address space */
nethercote8ff888f2004-11-17 17:11:45 +0000111Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
112 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +0000113{
114 Addr end = start+size;
115 Addr cl_base = VG_(client_base);
116 Bool ret;
117
118 if (size == 0)
119 return True;
120
sewardj16063e62005-03-15 23:29:13 +0000121 if (0 && cl_base < 0x10000)
fitzhardinge1a303042003-12-22 08:48:50 +0000122 cl_base = 0x10000;
123
124 ret =
125 (end >= start) &&
126 start >= cl_base && start < VG_(client_end) &&
127 (end <= VG_(client_end));
128
129 if (0)
130 VG_(printf)("%s: test=%p-%p client=%p-%p ret=%d\n",
nethercote1543adf2004-10-25 15:43:21 +0000131 syscallname, start, end, cl_base, VG_(client_end), ret);
fitzhardinge1a303042003-12-22 08:48:50 +0000132
nethercote1543adf2004-10-25 15:43:21 +0000133 if (!ret && syscallname != NULL) {
fitzhardinge1a303042003-12-22 08:48:50 +0000134 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried to modify addresses %p-%p",
nethercote1543adf2004-10-25 15:43:21 +0000135 syscallname, start, end);
fitzhardinge1a303042003-12-22 08:48:50 +0000136
137 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000138 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge1a303042003-12-22 08:48:50 +0000139 }
140 }
141
142 return ret;
143}
144
njn25e49d8e72002-09-23 09:36:25 +0000145/* ---------------------------------------------------------------------
nethercote27ea8bc2004-07-10 17:21:14 +0000146 Doing mmap, mremap
njn25e49d8e72002-09-23 09:36:25 +0000147 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000148
njn25e49d8e72002-09-23 09:36:25 +0000149// Nb: this isn't done as precisely as possible, but it seems that programs
150// are usually sufficiently well-behaved that the more obscure corner cases
151// aren't important. Various comments in the few functions below give more
152// details... njn 2002-Sep-17
153
154/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
155 munmap, mprotect (and mremap??) work at the page level. So addresses
156 and lengths must be adjusted for this. */
157
158/* Mash around start and length so that the area exactly covers
159 an integral number of pages. If we don't do that, memcheck's
160 idea of addressible memory diverges from that of the
161 kernel's, which causes the leak detector to crash. */
162static
nethercote928a5f72004-11-03 18:10:37 +0000163void mash_addr_and_len( Addr* a, SizeT* len)
sewardjde4a1d02002-03-22 01:27:54 +0000164{
fitzhardinge98abfc72003-12-16 02:05:15 +0000165 Addr ra;
166
167 ra = PGROUNDDN(*a);
168 *len = PGROUNDUP(*a + *len) - ra;
169 *a = ra;
sewardjde4a1d02002-03-22 01:27:54 +0000170}
171
172static
nethercote928a5f72004-11-03 18:10:37 +0000173void mmap_segment ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, ULong offset )
sewardjde4a1d02002-03-22 01:27:54 +0000174{
sewardj40f8ebe2002-10-23 21:46:13 +0000175 Bool rr, ww, xx;
fitzhardinge98abfc72003-12-16 02:05:15 +0000176 UInt flags;
njn25e49d8e72002-09-23 09:36:25 +0000177
fitzhardinge98abfc72003-12-16 02:05:15 +0000178 flags = SF_MMAP;
179
180 if (mm_flags & VKI_MAP_FIXED)
181 flags |= SF_FIXED;
182 if (!(mm_flags & VKI_MAP_PRIVATE))
183 flags |= SF_SHARED;
184
185 if (fd != -1)
186 flags |= SF_FILE;
187
188 VG_(map_fd_segment)(a, len, prot, flags, fd, offset, NULL);
njn25e49d8e72002-09-23 09:36:25 +0000189
fitzhardinge1a303042003-12-22 08:48:50 +0000190 rr = prot & VKI_PROT_READ;
191 ww = prot & VKI_PROT_WRITE;
192 xx = prot & VKI_PROT_EXEC;
njn25e49d8e72002-09-23 09:36:25 +0000193
sewardj40f8ebe2002-10-23 21:46:13 +0000194 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
sewardjde4a1d02002-03-22 01:27:54 +0000195}
196
njn25e49d8e72002-09-23 09:36:25 +0000197static
nethercote928a5f72004-11-03 18:10:37 +0000198Addr mremap_segment ( Addr old_addr, SizeT old_size,
199 Addr new_addr, SizeT new_size,
fitzhardinge1a303042003-12-22 08:48:50 +0000200 UInt flags, ThreadId tid)
njn25e49d8e72002-09-23 09:36:25 +0000201{
fitzhardinge1a303042003-12-22 08:48:50 +0000202 Addr ret;
203 Segment *seg, *next;
njn25e49d8e72002-09-23 09:36:25 +0000204
fitzhardinge1a303042003-12-22 08:48:50 +0000205 old_size = PGROUNDUP(old_size);
206 new_size = PGROUNDUP(new_size);
njn25e49d8e72002-09-23 09:36:25 +0000207
fitzhardinge1a303042003-12-22 08:48:50 +0000208 if (PGROUNDDN(old_addr) != old_addr)
209 return -VKI_EINVAL;
210
nethercote8ff888f2004-11-17 17:11:45 +0000211 if (!VG_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
fitzhardinge1a303042003-12-22 08:48:50 +0000212 return -VKI_EFAULT;
213
214 /* fixed at the current address means we don't move it */
215 if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
216 flags &= ~(VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE);
217
218 if (flags & VKI_MREMAP_FIXED) {
219 if (PGROUNDDN(new_addr) != new_addr)
220 return -VKI_EINVAL;
221
nethercote8ff888f2004-11-17 17:11:45 +0000222 if (!VG_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
fitzhardinge1a303042003-12-22 08:48:50 +0000223 return -VKI_ENOMEM;
224
225 /* check for overlaps */
226 if ((old_addr < (new_addr+new_size) &&
227 (old_addr+old_size) > new_addr) ||
228 (new_addr < (old_addr+new_size) &&
229 (new_addr+new_size) > old_addr))
230 return -VKI_EINVAL;
njn25e49d8e72002-09-23 09:36:25 +0000231 }
fitzhardinge1a303042003-12-22 08:48:50 +0000232
233 /* Do nothing */
234 if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
235 return old_addr;
236
237 seg = VG_(find_segment)(old_addr);
238
239 /* range must be contained within segment */
240 if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
241 return -VKI_EINVAL;
242
sewardj1024cf72005-02-28 14:39:21 +0000243 next = VG_(find_segment_above_mapped)(old_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000244
245 if (0)
246 VG_(printf)("mremap: old_addr+new_size=%p next->addr=%p flags=%d\n",
247 old_addr+new_size, next->addr, flags);
248
249 if ((flags & VKI_MREMAP_FIXED) ||
250 (next != NULL && (old_addr+new_size) > next->addr)) {
251 /* we're moving the block */
252 Addr a;
253
254 if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
255 return -VKI_ENOMEM; /* not allowed to move */
256
257 if ((flags & VKI_MREMAP_FIXED) == 0)
258 new_addr = 0;
259
260 a = VG_(find_map_space)(new_addr, new_size, True);
261
262 if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
263 return -VKI_ENOMEM; /* didn't find the place we wanted */
264
265 new_addr = a;
266 ret = a;
267
268 /* we've nailed down the location */
269 flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
270
njnca6fef02004-11-29 16:49:18 +0000271 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
272 flags, new_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000273
274 if (ret != new_addr) {
275 vg_assert(VG_(is_kerror)(ret));
276 return ret;
277 }
278
279 VG_TRACK(copy_mem_remap, old_addr, new_addr,
280 (old_size < new_size) ? old_size : new_size);
281
282 if (new_size > old_size)
283 VG_TRACK(new_mem_mmap, new_addr+old_size, new_size-old_size,
284 seg->prot & VKI_PROT_READ,
285 seg->prot & VKI_PROT_WRITE,
286 seg->prot & VKI_PROT_EXEC);
287 VG_TRACK(die_mem_munmap, old_addr, old_size);
288
289 VG_(map_file_segment)(new_addr, new_size,
290 seg->prot,
291 seg->flags,
292 seg->dev, seg->ino,
293 seg->offset, seg->filename);
294
295 VG_(munmap)((void *)old_addr, old_size);
296 } else {
297 /* staying in place */
298 ret = old_addr;
299
300 if (new_size < old_size) {
301 VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
302 VG_(munmap)((void *)(old_addr+new_size), old_size-new_size);
303 } else {
304 /* we've nailed down the location */
305 flags &= ~VKI_MREMAP_MAYMOVE;
306
307 if (0)
308 VG_(printf)("mremap: old_addr=%p old_size=%d new_size=%d flags=%d\n",
309 old_addr, old_size, new_size, flags);
310
njnca6fef02004-11-29 16:49:18 +0000311 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
312 flags, 0);
fitzhardinge1a303042003-12-22 08:48:50 +0000313
314 if (ret != old_addr)
315 return ret;
316
317 VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
318 seg->prot & VKI_PROT_READ,
319 seg->prot & VKI_PROT_WRITE,
320 seg->prot & VKI_PROT_EXEC);
321
322 VG_(map_file_segment)(old_addr+old_size, new_size-old_size,
323 seg->prot,
324 seg->flags,
325 seg->dev, seg->ino,
326 seg->offset, seg->filename);
327 }
328 }
329
330 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000331}
332
333
334/* Is this a Linux kernel error return value? */
335/* From:
336 http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
337 linux/i386/sysdep.h?
338 rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
339
njn25e49d8e72002-09-23 09:36:25 +0000340 \begin{quote}:
sewardjde4a1d02002-03-22 01:27:54 +0000341
342 Linux uses a negative return value to indicate syscall errors,
343 unlike most Unices, which use the condition codes' carry flag.
344
345 Since version 2.1 the return value of a system call might be
346 negative even if the call succeeded. E.g., the `lseek' system call
347 might return a large offset. Therefore we must not anymore test
348 for < 0, but test for a real error by making sure the value in %eax
349 is a real error number. Linus said he will make sure the no syscall
daywalker7e73e5f2003-07-04 16:18:15 +0000350 returns a value in -1 .. -4095 as a valid result so we can safely
sewardjde4a1d02002-03-22 01:27:54 +0000351 test with -4095.
352
353 END QUOTE
354*/
nethercoteada0d2b2004-11-04 19:10:43 +0000355Bool VG_(is_kerror) ( Word res )
sewardjde4a1d02002-03-22 01:27:54 +0000356{
357 if (res >= -4095 && res <= -1)
358 return True;
359 else
360 return False;
361}
362
rjwalshf5f536f2003-11-17 17:45:00 +0000363/* One of these is allocated for each open file descriptor. */
364
365typedef struct OpenFd
366{
367 Int fd; /* The file descriptor */
368 Char *pathname; /* NULL if not a regular file or unknown */
369 ExeContext *where; /* NULL if inherited from parent */
370 struct OpenFd *next, *prev;
371} OpenFd;
372
373/* List of allocated file descriptors. */
374
375static OpenFd *allocated_fds;
376
377/* Count of open file descriptors. */
378
379static int fd_count = 0;
380
rjwalshf5f536f2003-11-17 17:45:00 +0000381
sewardj79048ce2005-02-18 08:28:32 +0000382
383/* Given a file descriptor, attempt to deduce its filename. To do
384 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
385 or if it doesn't exist, we just return NULL. The caller is
386 responsible for copying the contents of buf out immediately. */
387
388static HChar resolve_filename_buf[VKI_PATH_MAX];
389
390HChar* VG_(resolve_filename_nodup) ( Int fd )
rjwalshf5f536f2003-11-17 17:45:00 +0000391{
sewardj79048ce2005-02-18 08:28:32 +0000392 HChar tmp[64];
rjwalshf5f536f2003-11-17 17:45:00 +0000393
394 VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
sewardj79048ce2005-02-18 08:28:32 +0000395 VG_(memset)(resolve_filename_buf, 0, VKI_PATH_MAX);
rjwalshf5f536f2003-11-17 17:45:00 +0000396
sewardj79048ce2005-02-18 08:28:32 +0000397 if (VG_(readlink)(tmp, resolve_filename_buf, VKI_PATH_MAX) == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000398 return NULL;
399
sewardj79048ce2005-02-18 08:28:32 +0000400 return (resolve_filename_buf[0] == '/')
401 ? resolve_filename_buf
402 : NULL;
403}
404
405/* Same as resolve_filename_nodup, except that the result is copied
406 into new memory which the caller is responsible for freeing. */
407
408HChar* VG_(resolve_filename) ( Int fd )
409{
410 HChar* transient = VG_(resolve_filename_nodup)(fd);
411 return transient
412 ? VG_(arena_strdup)(VG_AR_CORE, transient)
413 : NULL;
rjwalshf5f536f2003-11-17 17:45:00 +0000414}
415
416
417/* Note the fact that a file descriptor was just closed. */
418
419static
njnc6168192004-11-29 13:54:10 +0000420void record_fd_close(ThreadId tid, Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000421{
422 OpenFd *i = allocated_fds;
423
thughesad1c9562004-06-26 11:27:52 +0000424 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000425 return; /* Valgrind internal */
426
rjwalshf5f536f2003-11-17 17:45:00 +0000427 while(i) {
428 if(i->fd == fd) {
429 if(i->prev)
430 i->prev->next = i->next;
431 else
432 allocated_fds = i->next;
433 if(i->next)
434 i->next->prev = i->prev;
435 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000436 VG_(arena_free) (VG_AR_CORE, i->pathname);
437 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000438 fd_count--;
439 break;
440 }
441 i = i->next;
442 }
443}
444
445/* Note the fact that a file descriptor was just opened. If the
446 tid is -1, this indicates an inherited fd. If the pathname is NULL,
447 this either indicates a non-standard file (i.e. a pipe or socket or
448 some such thing) or that we don't know the filename. If the fd is
449 already open, then we're probably doing a dup2() to an existing fd,
450 so just overwrite the existing one. */
451
njnc6168192004-11-29 13:54:10 +0000452void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000453{
454 OpenFd *i;
455
thughesad1c9562004-06-26 11:27:52 +0000456 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000457 return; /* Valgrind internal */
458
rjwalshf5f536f2003-11-17 17:45:00 +0000459 /* Check to see if this fd is already open. */
460 i = allocated_fds;
461 while (i) {
462 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000463 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000464 break;
465 }
466 i = i->next;
467 }
468
469 /* Not already one: allocate an OpenFd */
470 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000471 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000472
473 i->prev = NULL;
474 i->next = allocated_fds;
475 if(allocated_fds) allocated_fds->prev = i;
476 allocated_fds = i;
477 fd_count++;
478 }
479
480 i->fd = fd;
481 i->pathname = pathname;
njnd01fef72005-03-25 23:35:48 +0000482 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
rjwalshf5f536f2003-11-17 17:45:00 +0000483}
484
485static
nethercote73b526f2004-10-31 18:48:21 +0000486Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000487{
nethercote73b526f2004-10-31 18:48:21 +0000488 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000489 VG_(sprintf)(name, "<unknown>");
490 } else {
491 VG_(sprintf)(name, "%s", sa->sun_path);
492 }
493
494 return name;
495}
496
497static
nethercote73b526f2004-10-31 18:48:21 +0000498Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000499{
nethercote73b526f2004-10-31 18:48:21 +0000500 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000501 VG_(sprintf)(name, "<unknown>");
502 } else {
503 UInt addr = sa->sin_addr.s_addr;
504
505 if (addr == 0) {
506 VG_(sprintf)(name, "<unbound>");
507 } else {
508 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
509 addr & 0xFF, (addr>>8) & 0xFF,
510 (addr>>16) & 0xFF, (addr>>24) & 0xFF,
nethercote73b526f2004-10-31 18:48:21 +0000511 vki_ntohs(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000512 }
513 }
514
515 return name;
516}
517
518
519/*
520 * Try get some details about a socket.
521 */
522
523static void
524getsockdetails(int fd)
525{
526 union u {
nethercote73b526f2004-10-31 18:48:21 +0000527 struct vki_sockaddr a;
528 struct vki_sockaddr_in in;
529 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000530 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000531 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000532
533 llen = sizeof(laddr);
534 VG_(memset)(&laddr, 0, llen);
535
536 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
537 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000538 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000539 static char lname[32];
540 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000541 struct vki_sockaddr_in paddr;
542 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000543
544 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
545 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
546 inet2name(&(laddr.in), llen, lname),
547 inet2name(&paddr, plen, pname));
548 } else {
549 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
550 fd, inet2name(&(laddr.in), llen, lname));
551 }
552 return;
553 }
nethercote73b526f2004-10-31 18:48:21 +0000554 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000555 static char lname[256];
556 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
557 unix2name(&(laddr.un), llen, lname));
558 return;
559 }
560 default:
561 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
562 laddr.a.sa_family, fd);
563 return;
564 }
565 }
566
567 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
568}
569
570
nethercote3a42fb82004-08-03 18:08:50 +0000571/* Dump out a summary, and a more detailed list, of open file descriptors. */
572void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000573{
574 OpenFd *i = allocated_fds;
575
nethercote3a42fb82004-08-03 18:08:50 +0000576 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000577
578 while(i) {
579 if(i->pathname) {
580 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
581 i->pathname);
582 } else {
583 int val;
nethercote73b526f2004-10-31 18:48:21 +0000584 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000585
nethercote73b526f2004-10-31 18:48:21 +0000586 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000587 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
588 } else {
589 getsockdetails(i->fd);
590 }
591 }
592
593 if(i->where) {
594 VG_(pp_ExeContext)(i->where);
595 VG_(message)(Vg_UserMsg, "");
596 } else {
597 VG_(message)(Vg_UserMsg, " <inherited from parent>");
598 VG_(message)(Vg_UserMsg, "");
599 }
600
601 i = i->next;
602 }
603
604 VG_(message)(Vg_UserMsg, "");
605}
606
607/* If /proc/self/fd doesn't exist for some weird reason (like you've
608 got a kernel that doesn't have /proc support compiled in), then we
609 need to find out what file descriptors we inherited from our parent
610 process the hard way - by checking each fd in turn. */
611
612static
613void do_hacky_preopened()
614{
615 struct vki_rlimit lim;
616 unsigned int count;
617 int i;
618
nethercote620154f2004-11-12 21:21:07 +0000619 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000620 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
621 an arbitrarily high number. 1024 happens to be the limit in
622 the 2.4 kernels. */
623 count = 1024;
624 } else {
625 count = lim.rlim_cur;
626 }
627
628 for (i = 0; i < count; i++)
629 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
nethercote3d5e9102004-11-17 18:22:38 +0000630 VG_(record_fd_open)(-1, i, NULL);
rjwalshf5f536f2003-11-17 17:45:00 +0000631}
632
633/* Initialize the list of open file descriptors with the file descriptors
634 we inherited from out parent process. */
635
636void VG_(init_preopened_fds)()
637{
638 int f, ret;
639 struct vki_dirent d;
640
641 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
642 if(f == -1) {
643 do_hacky_preopened();
644 return;
645 }
646
647 while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
648 if(ret == -1)
649 goto out;
650
651 if(VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
652 int fno = VG_(atoll)(d.d_name);
653
654 if(fno != f)
655 if(VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +0000656 VG_(record_fd_open)(-1, fno, VG_(resolve_filename)(fno));
rjwalshf5f536f2003-11-17 17:45:00 +0000657 }
658
659 VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
660 }
661
662out:
663 VG_(close)(f);
664}
665
sewardjde4a1d02002-03-22 01:27:54 +0000666static
sewardj8c824512002-04-14 04:16:48 +0000667Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000668{
669 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000670 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000671 VG_(strcpy) ( result, s1 );
672 VG_(strcat) ( result, s2 );
673 return result;
674}
675
676static
jsgf855d93d2003-10-13 22:26:55 +0000677void pre_mem_read_sendmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000678 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000679{
njn9f46df62005-03-13 18:11:44 +0000680 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000681 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000682
njn9f46df62005-03-13 18:11:44 +0000683 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000684}
685
686static
jsgf855d93d2003-10-13 22:26:55 +0000687void pre_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000688 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000689{
njn9f46df62005-03-13 18:11:44 +0000690 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000691 PRE_MEM_WRITE( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000692 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000693}
694
695static
njn72718642003-07-24 08:45:32 +0000696void post_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000697 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000698{
nethercoteef0c7662004-11-06 15:38:43 +0000699 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000700}
701
702static
sewardj8c824512002-04-14 04:16:48 +0000703void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000704 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000705 struct vki_msghdr *msg,
nethercote928a5f72004-11-03 18:10:37 +0000706 void (*foreach_func)( ThreadId, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000707 )
sewardjde4a1d02002-03-22 01:27:54 +0000708{
709 if ( !msg )
710 return;
711
nethercote73b526f2004-10-31 18:48:21 +0000712 foreach_func ( tid, "(msg)", (Addr)msg, sizeof( struct vki_msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000713
714 if ( msg->msg_name )
njn72718642003-07-24 08:45:32 +0000715 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000716 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000717 (Addr)msg->msg_name, msg->msg_namelen );
718
719 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000720 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000721 UInt i;
722
njn72718642003-07-24 08:45:32 +0000723 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000724 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000725 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000726
727 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
njn72718642003-07-24 08:45:32 +0000728 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000729 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000730 (Addr)iov->iov_base, iov->iov_len );
731 }
732
733 if ( msg->msg_control )
njn72718642003-07-24 08:45:32 +0000734 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000735 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000736 (Addr)msg->msg_control, msg->msg_controllen );
737}
738
sewardjb5f6f512005-03-10 23:59:00 +0000739static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000740{
nethercote73b526f2004-10-31 18:48:21 +0000741 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000742
743 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000744 if (cm->cmsg_level == VKI_SOL_SOCKET &&
745 cm->cmsg_type == VKI_SCM_RIGHTS ) {
746 int *fds = (int *) VKI_CMSG_DATA(cm);
747 int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000748 / sizeof(int);
749 int i;
750
751 for (i = 0; i < fdc; i++)
752 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000753 // XXX: must we check the range on these fds with
nethercote3d5e9102004-11-17 18:22:38 +0000754 // VG_(fd_allowed)()?
755 VG_(record_fd_open) (tid, fds[i], VG_(resolve_filename)(fds[i]));
rjwalshf5f536f2003-11-17 17:45:00 +0000756 }
757
nethercote73b526f2004-10-31 18:48:21 +0000758 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000759 }
760}
761
sewardjc483e8f2002-05-03 21:01:35 +0000762static
jsgf855d93d2003-10-13 22:26:55 +0000763void pre_mem_read_sockaddr ( ThreadId tid,
764 Char *description,
nethercote73b526f2004-10-31 18:48:21 +0000765 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000766{
sewardjff7c1ab2003-02-24 21:55:34 +0000767 Char *outmsg;
768
769 /* NULL/zero-length sockaddrs are legal */
770 if ( sa == NULL || salen == 0 ) return;
771
njn9f46df62005-03-13 18:11:44 +0000772 outmsg = VG_(arena_malloc) ( VG_AR_CORE,
nethercote73b526f2004-10-31 18:48:21 +0000773 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000774
775 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000776 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000777
sewardjc483e8f2002-05-03 21:01:35 +0000778 switch (sa->sa_family) {
779
nethercote73b526f2004-10-31 18:48:21 +0000780 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000781 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000782 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000783 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000784 break;
785
nethercote73b526f2004-10-31 18:48:21 +0000786 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000787 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000788 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000789 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
790 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000791 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000792 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000793 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
794 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000795 break;
796
nethercote73b526f2004-10-31 18:48:21 +0000797 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000798 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000799 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000800 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
801 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000802 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000803 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000804 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
805 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000806 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000807 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000808 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_addr,
809 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000810 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
nethercoteef0c7662004-11-06 15:38:43 +0000811 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000812 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_scope_id,
813 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000814 break;
815
816 default:
817 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000818 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000819 break;
820 }
821
njn9f46df62005-03-13 18:11:44 +0000822 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000823}
824
njn25e49d8e72002-09-23 09:36:25 +0000825/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000826static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000827{
828 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000829 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000830 if (a_p == NULL)
831 return 0;
832 else
833 return *a_p;
834}
835
njn25e49d8e72002-09-23 09:36:25 +0000836static
njn72718642003-07-24 08:45:32 +0000837void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000838 Char* buf_s, Char* buflen_s )
839{
fitzhardinge98abfc72003-12-16 02:05:15 +0000840 if (VG_(defined_pre_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000841 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000842 if (buflen_in > 0) {
njncf45fd42004-11-24 16:30:22 +0000843 TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000844 }
845 }
846}
847
848static
njn72718642003-07-24 08:45:32 +0000849void buf_and_len_post_check( ThreadId tid, Int res,
njn25e49d8e72002-09-23 09:36:25 +0000850 Addr buf_p, Addr buflen_p, Char* s )
851{
fitzhardinge98abfc72003-12-16 02:05:15 +0000852 if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000853 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000854 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njncf45fd42004-11-24 16:30:22 +0000855 TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000856 }
857 }
858}
859
860/* ---------------------------------------------------------------------
861 Data seg end, for brk()
862 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000863
fitzhardinge98abfc72003-12-16 02:05:15 +0000864static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000865{
fitzhardinge98abfc72003-12-16 02:05:15 +0000866 Addr ret = VG_(brk_limit);
sewardje517b802005-02-16 01:58:51 +0000867 static const Bool debug = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000868 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000869 Addr current, newaddr;
870
fitzhardinge98abfc72003-12-16 02:05:15 +0000871
872 if (debug)
sewardj548be6d2005-02-16 01:31:37 +0000873 VG_(printf)("\ndo_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
fitzhardinge98abfc72003-12-16 02:05:15 +0000874 VG_(brk_base), VG_(brk_limit), newbrk);
875
sewardj79048ce2005-02-18 08:28:32 +0000876# if 0
sewardje517b802005-02-16 01:58:51 +0000877 if (0) show_segments("in_brk");
sewardj79048ce2005-02-18 08:28:32 +0000878# endif
sewardj548be6d2005-02-16 01:31:37 +0000879
fitzhardinge98abfc72003-12-16 02:05:15 +0000880 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
881 return VG_(brk_limit);
882
883 /* brk isn't allowed to grow over anything else */
sewardj548be6d2005-02-16 01:31:37 +0000884 seg = VG_(find_segment)(VG_(brk_limit) -1);
fitzhardinge98abfc72003-12-16 02:05:15 +0000885
886 vg_assert(seg != NULL);
887
njn25e49d8e72002-09-23 09:36:25 +0000888 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000889 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
890 VG_(brk_limit), seg->addr, seg->addr+seg->len);
sewardj79048ce2005-02-18 08:28:32 +0000891 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit)
892 <= (seg->addr + seg->len));
fitzhardinge98abfc72003-12-16 02:05:15 +0000893
sewardj79048ce2005-02-18 08:28:32 +0000894 seg = VG_(find_segment_above_mapped)(VG_(brk_limit)-1);
895 if (0 && seg)
896 VG_(printf)("NEXT addr = %p\n", seg->addr);
fitzhardinge98abfc72003-12-16 02:05:15 +0000897 if (seg != NULL && newbrk > seg->addr)
898 return VG_(brk_limit);
899
nethercotece471262004-08-25 13:43:44 +0000900 current = PGROUNDUP(VG_(brk_limit));
901 newaddr = PGROUNDUP(newbrk);
902 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000903
904 /* new brk in a new page - fix the mappings */
905 if (newbrk > VG_(brk_limit)) {
906
907 if (debug)
908 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
909 current, newaddr, newaddr-current);
910
911 if (newaddr == current) {
912 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000913 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
914 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
915 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
916 SF_FIXED|SF_BRK, -1, 0))
917 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000918 ret = newbrk;
919 }
920 } else {
921 vg_assert(newbrk < VG_(brk_limit));
922
923 if (debug)
924 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
925 current, newaddr, current-newaddr);
926
927 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000928 int res = VG_(munmap)((void *)newaddr, current - newaddr);
929 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000930 }
931 ret = newbrk;
932 }
933 } else
934 ret = newbrk;
935
936 VG_(brk_limit) = ret;
937
938 return ret;
939}
940
941
njn25e49d8e72002-09-23 09:36:25 +0000942/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000943 Vet file descriptors for sanity
944 ------------------------------------------------------------------ */
945
946/* Return true if we're allowed to use or create this fd */
nethercote3d5e9102004-11-17 18:22:38 +0000947Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000948{
thughesad1c9562004-06-26 11:27:52 +0000949 if (fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) {
jsewardd9320a42003-12-12 06:40:05 +0000950 VG_(message)(Vg_UserMsg,
951 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000952 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000953 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000954 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000955 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000956 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000957 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
jsgf855d93d2003-10-13 22:26:55 +0000958 }
959 return False;
960 }
thughesad1c9562004-06-26 11:27:52 +0000961 else if (soft && fd >= VG_(fd_soft_limit)) {
962 return False;
963 }
jsgf855d93d2003-10-13 22:26:55 +0000964 return True;
965}
966
967
968/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +0000969 Deal with a bunch of socket-related syscalls
970 ------------------------------------------------------------------ */
971
972/* ------ */
973
sewardj987a8eb2005-03-01 19:00:30 +0000974void
975VG_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000976 UWord arg0, UWord arg1,
977 UWord arg2, UWord arg3 )
978{
979 /* int socketpair(int d, int type, int protocol, int sv[2]); */
980 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
981 arg3, 2*sizeof(int) );
982}
983
sewardj987a8eb2005-03-01 19:00:30 +0000984UWord
985VG_(generic_POST_sys_socketpair) ( ThreadId tid,
986 UWord res,
987 UWord arg0, UWord arg1,
988 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +0000989{
990 UWord r = res;
991 Int fd1 = ((Int*)arg3)[0];
992 Int fd2 = ((Int*)arg3)[1];
993 POST_MEM_WRITE( arg3, 2*sizeof(int) );
994 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
995 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
996 VG_(close)(fd1);
997 VG_(close)(fd2);
998 r = -VKI_EMFILE;
999 } else {
1000 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1001 if (VG_(clo_track_fds)) {
1002 VG_(record_fd_open)(tid, fd1, NULL);
1003 VG_(record_fd_open)(tid, fd2, NULL);
1004 }
1005 }
1006 return r;
1007}
1008
1009/* ------ */
1010
sewardj987a8eb2005-03-01 19:00:30 +00001011UWord
1012VG_(generic_POST_sys_socket) ( ThreadId tid, UWord res )
sewardj9efbbef2005-03-01 16:45:23 +00001013{
1014 UWord r = res;
1015 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
1016 VG_(close)(res);
1017 r = -VKI_EMFILE;
1018 } else {
1019 if (VG_(clo_track_fds))
1020 VG_(record_fd_open)(tid, res, NULL);
1021 }
1022 return r;
1023}
1024
1025/* ------ */
1026
sewardj987a8eb2005-03-01 19:00:30 +00001027void
1028VG_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001029 UWord arg0, UWord arg1, UWord arg2 )
1030{
1031 /* int bind(int sockfd, struct sockaddr *my_addr,
1032 int addrlen); */
1033 pre_mem_read_sockaddr(
1034 tid, "socketcall.bind(my_addr.%s)",
1035 (struct vki_sockaddr *) arg1, arg2
1036 );
1037}
1038
1039/* ------ */
1040
sewardj987a8eb2005-03-01 19:00:30 +00001041void
1042VG_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001043 UWord arg0, UWord arg1, UWord arg2 )
1044{
1045 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1046 Addr addr_p = arg1;
1047 Addr addrlen_p = arg2;
1048 if (addr_p != (Addr)NULL)
1049 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
1050 "socketcall.accept(addr)",
1051 "socketcall.accept(addrlen_in)" );
1052}
1053
sewardj987a8eb2005-03-01 19:00:30 +00001054UWord
1055VG_(generic_POST_sys_accept) ( ThreadId tid,
1056 UWord res,
1057 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +00001058{
1059 UWord r = res;
1060 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
1061 VG_(close)(res);
1062 r = -VKI_EMFILE;
1063 } else {
1064 Addr addr_p = arg1;
1065 Addr addrlen_p = arg2;
1066 if (addr_p != (Addr)NULL)
1067 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
1068 "socketcall.accept(addrlen_out)" );
1069 if (VG_(clo_track_fds))
1070 VG_(record_fd_open)(tid, res, NULL);
1071 }
1072 return r;
1073}
1074
1075/* ------ */
1076
sewardj987a8eb2005-03-01 19:00:30 +00001077void
1078VG_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001079 UWord arg0, UWord arg1, UWord arg2,
1080 UWord arg3, UWord arg4, UWord arg5 )
1081{
1082 /* int sendto(int s, const void *msg, int len,
1083 unsigned int flags,
1084 const struct sockaddr *to, int tolen); */
1085 PRE_MEM_READ( "socketcall.sendto(msg)",
1086 arg1, /* msg */
1087 arg2 /* len */ );
1088 pre_mem_read_sockaddr(
1089 tid, "socketcall.sendto(to.%s)",
1090 (struct vki_sockaddr *) arg4, arg5
1091 );
1092}
1093
1094/* ------ */
1095
sewardj987a8eb2005-03-01 19:00:30 +00001096void
1097VG_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001098 UWord arg0, UWord arg1, UWord arg2 )
1099{
1100 /* int send(int s, const void *msg, size_t len, int flags); */
1101 PRE_MEM_READ( "socketcall.send(msg)",
1102 arg1, /* msg */
1103 arg2 /* len */ );
1104
1105}
1106
1107/* ------ */
1108
sewardj987a8eb2005-03-01 19:00:30 +00001109void
1110VG_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001111 UWord arg0, UWord arg1, UWord arg2,
1112 UWord arg3, UWord arg4, UWord arg5 )
1113{
1114 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1115 struct sockaddr *from, int *fromlen); */
1116 Addr buf_p = arg1;
1117 Int len = arg2;
1118 Addr from_p = arg4;
1119 Addr fromlen_p = arg5;
1120 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1121 if (from_p != (Addr)NULL)
1122 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1123 "socketcall.recvfrom(from)",
1124 "socketcall.recvfrom(fromlen_in)" );
1125}
1126
sewardj987a8eb2005-03-01 19:00:30 +00001127void
1128VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001129 UWord res,
1130 UWord arg0, UWord arg1, UWord arg2,
1131 UWord arg3, UWord arg4, UWord arg5 )
1132{
1133 Addr buf_p = arg1;
1134 Int len = arg2;
1135 Addr from_p = arg4;
1136 Addr fromlen_p = arg5;
1137
1138 if (from_p != (Addr)NULL)
1139 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1140 "socketcall.recvfrom(fromlen_out)" );
1141 POST_MEM_WRITE( buf_p, len );
1142}
1143
1144/* ------ */
1145
sewardj987a8eb2005-03-01 19:00:30 +00001146void
1147VG_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001148 UWord arg0, UWord arg1, UWord arg2 )
1149{
1150 /* int recv(int s, void *buf, int len, unsigned int flags); */
1151 /* man 2 recv says:
1152 The recv call is normally used only on a connected socket
1153 (see connect(2)) and is identical to recvfrom with a NULL
1154 from parameter.
1155 */
1156 PRE_MEM_WRITE( "socketcall.recv(buf)",
1157 arg1, /* buf */
1158 arg2 /* len */ );
1159}
1160
sewardj987a8eb2005-03-01 19:00:30 +00001161void
1162VG_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001163 UWord res,
1164 UWord arg0, UWord arg1, UWord arg2 )
1165{
1166 if (res >= 0 && arg1 != 0) {
1167 POST_MEM_WRITE( arg1, /* buf */
1168 arg2 /* len */ );
1169 }
1170}
1171
1172/* ------ */
1173
sewardj987a8eb2005-03-01 19:00:30 +00001174void
1175VG_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001176 UWord arg0, UWord arg1, UWord arg2 )
1177{
1178 /* int connect(int sockfd,
1179 struct sockaddr *serv_addr, int addrlen ); */
1180 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1181 arg1, /* serv_addr */
1182 sizeof(vki_sa_family_t));
1183 pre_mem_read_sockaddr( tid,
1184 "socketcall.connect(serv_addr.%s)",
1185 (struct vki_sockaddr *) arg1, arg2);
1186}
1187
1188/* ------ */
1189
sewardj987a8eb2005-03-01 19:00:30 +00001190void
1191VG_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001192 UWord arg0, UWord arg1, UWord arg2,
1193 UWord arg3, UWord arg4 )
1194{
1195 /* int setsockopt(int s, int level, int optname,
1196 const void *optval, int optlen); */
1197 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1198 arg3, /* optval */
1199 arg4 /* optlen */ );
1200}
1201
1202/* ------ */
1203
sewardj987a8eb2005-03-01 19:00:30 +00001204void
1205VG_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001206 UWord arg0, UWord arg1, UWord arg2,
1207 UWord arg3, UWord arg4 )
1208{
1209 /* int getsockopt(int s, int level, int optname,
1210 void *optval, socklen_t *optlen); */
1211 Addr optval_p = arg3;
1212 Addr optlen_p = arg4;
1213 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
1214 if (optval_p != (Addr)NULL)
1215 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1216 "socketcall.getsockopt(optval)",
1217 "socketcall.getsockopt(optlen)" );
1218}
1219
sewardj987a8eb2005-03-01 19:00:30 +00001220void
1221VG_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001222 UWord res,
1223 UWord arg0, UWord arg1, UWord arg2,
1224 UWord arg3, UWord arg4 )
1225{
1226 Addr optval_p = arg3;
1227 Addr optlen_p = arg4;
1228 if (optval_p != (Addr)NULL)
1229 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1230 "socketcall.getsockopt(optlen_out)" );
1231}
1232
1233/* ------ */
1234
sewardj987a8eb2005-03-01 19:00:30 +00001235void
1236VG_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001237 UWord arg0, UWord arg1, UWord arg2 )
1238{
1239 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1240 Addr name_p = arg1;
1241 Addr namelen_p = arg2;
1242 /* Nb: name_p cannot be NULL */
1243 buf_and_len_pre_check ( tid, name_p, namelen_p,
1244 "socketcall.getsockname(name)",
1245 "socketcall.getsockname(namelen_in)" );
1246}
1247
sewardj987a8eb2005-03-01 19:00:30 +00001248void
1249VG_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001250 UWord res,
1251 UWord arg0, UWord arg1, UWord arg2 )
1252{
1253 Addr name_p = arg1;
1254 Addr namelen_p = arg2;
1255 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1256 "socketcall.getsockname(namelen_out)" );
1257}
1258
1259/* ------ */
1260
sewardj987a8eb2005-03-01 19:00:30 +00001261void
1262VG_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001263 UWord arg0, UWord arg1, UWord arg2 )
1264{
1265 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1266 Addr name_p = arg1;
1267 Addr namelen_p = arg2;
1268 /* Nb: name_p cannot be NULL */
1269 buf_and_len_pre_check ( tid, name_p, namelen_p,
1270 "socketcall.getpeername(name)",
1271 "socketcall.getpeername(namelen_in)" );
1272}
1273
sewardj987a8eb2005-03-01 19:00:30 +00001274void
1275VG_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001276 UWord res,
1277 UWord arg0, UWord arg1, UWord arg2 )
1278{
1279 Addr name_p = arg1;
1280 Addr namelen_p = arg2;
1281 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1282 "socketcall.getpeername(namelen_out)" );
1283}
1284
1285/* ------ */
1286
sewardj987a8eb2005-03-01 19:00:30 +00001287void
1288VG_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001289 UWord arg0, UWord arg1 )
1290{
1291 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1292 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1293 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1294}
1295
1296/* ------ */
1297
sewardj987a8eb2005-03-01 19:00:30 +00001298void
1299VG_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001300 UWord arg0, UWord arg1 )
1301{
1302 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1303 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1304 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1305}
1306
sewardj987a8eb2005-03-01 19:00:30 +00001307void
1308VG_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001309 UWord res,
1310 UWord arg0, UWord arg1 )
1311{
1312 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1313 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1314 check_cmsg_for_fds( tid, msg );
1315}
1316
1317
1318/* ---------------------------------------------------------------------
sewardjb369c5e2005-03-24 17:52:02 +00001319 Deal with a bunch of IPC related syscalls
1320 ------------------------------------------------------------------ */
1321
1322/* ------ */
1323
1324void
1325VG_(generic_PRE_sys_semop) ( ThreadId tid,
1326 UWord arg0, UWord arg1, UWord arg2 )
1327{
1328 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1329 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1330}
1331
1332/* ------ */
1333
1334void
1335VG_(generic_PRE_sys_semtimedop) ( ThreadId tid,
1336 UWord arg0, UWord arg1,
1337 UWord arg2, UWord arg3 )
1338{
1339 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1340 struct timespec *timeout); */
1341 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1342 if (arg3 != 0)
1343 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1344}
1345
1346/* ------ */
1347
1348static
1349UInt get_sem_count( Int semid )
1350{
1351 struct vki_semid_ds buf;
1352 union vki_semun arg;
1353 long res;
1354
1355 arg.buf = &buf;
1356
1357#ifdef __NR_semctl
1358 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1359#else
1360 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
1361 VKI_IPC_STAT, (UWord)&arg);
1362#endif
1363 if ( VG_(is_kerror)(res) )
1364 return 0;
1365
1366 return buf.sem_nsems;
1367}
1368
1369void
1370VG_(generic_PRE_sys_semctl) ( ThreadId tid,
1371 UWord arg0, UWord arg1,
1372 UWord arg2, UWord arg3 )
1373{
1374 /* int semctl(int semid, int semnum, int cmd, ...); */
1375 union vki_semun arg = *(union vki_semun *)&arg3;
1376 UInt nsems;
1377 switch (arg2 /* cmd */) {
1378 case VKI_IPC_INFO:
1379 case VKI_SEM_INFO:
1380 case VKI_IPC_INFO|VKI_IPC_64:
1381 case VKI_SEM_INFO|VKI_IPC_64:
1382 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
1383 (Addr)arg.buf, sizeof(struct vki_seminfo) );
1384 break;
1385 case VKI_IPC_STAT:
1386 case VKI_SEM_STAT:
1387 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1388 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1389 break;
1390 case VKI_IPC_STAT|VKI_IPC_64:
1391 case VKI_SEM_STAT|VKI_IPC_64:
1392 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1393 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1394 break;
1395 case VKI_IPC_SET:
1396 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1397 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1398 break;
1399 case VKI_IPC_SET|VKI_IPC_64:
1400 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1401 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1402 break;
1403 case VKI_GETALL:
1404 case VKI_GETALL|VKI_IPC_64:
1405 nsems = get_sem_count( arg0 );
1406 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
1407 (Addr)arg.array, sizeof(unsigned short) * nsems );
1408 break;
1409 case VKI_SETALL:
1410 case VKI_SETALL|VKI_IPC_64:
1411 nsems = get_sem_count( arg0 );
1412 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
1413 (Addr)arg.array, sizeof(unsigned short) * nsems );
1414 break;
1415 }
1416}
1417
1418void
1419VG_(generic_POST_sys_semctl) ( ThreadId tid,
1420 UWord res,
1421 UWord arg0, UWord arg1,
1422 UWord arg2, UWord arg3 )
1423{
1424 union vki_semun arg = *(union vki_semun *)&arg3;
1425 UInt nsems;
1426 switch (arg2 /* cmd */) {
1427 case VKI_IPC_INFO:
1428 case VKI_SEM_INFO:
1429 case VKI_IPC_INFO|VKI_IPC_64:
1430 case VKI_SEM_INFO|VKI_IPC_64:
1431 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
1432 break;
1433 case VKI_IPC_STAT:
1434 case VKI_SEM_STAT:
1435 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1436 break;
1437 case VKI_IPC_STAT|VKI_IPC_64:
1438 case VKI_SEM_STAT|VKI_IPC_64:
1439 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1440 break;
1441 case VKI_GETALL:
1442 case VKI_GETALL|VKI_IPC_64:
1443 nsems = get_sem_count( arg0 );
1444 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
1445 break;
1446 }
1447}
1448
1449/* ------ */
1450
1451void
1452VG_(generic_PRE_sys_msgsnd) ( ThreadId tid,
1453 UWord arg0, UWord arg1,
1454 UWord arg2, UWord arg3 )
1455{
1456 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
1457 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1458 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1459 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1460}
1461
1462/* ------ */
1463
1464void
1465VG_(generic_PRE_sys_msgrcv) ( ThreadId tid,
1466 UWord arg0, UWord arg1, UWord arg2,
1467 UWord arg3, UWord arg4 )
1468{
1469 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
1470 long msgtyp, int msgflg); */
1471 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1472 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1473 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1474}
1475
1476void
1477VG_(generic_POST_sys_msgrcv) ( ThreadId tid,
1478 UWord res,
1479 UWord arg0, UWord arg1, UWord arg2,
1480 UWord arg3, UWord arg4 )
1481{
1482 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1483 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1484 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
1485}
1486
1487/* ------ */
1488
1489void
1490VG_(generic_PRE_sys_msgctl) ( ThreadId tid,
1491 UWord arg0, UWord arg1, UWord arg2 )
1492{
1493 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
1494 switch (arg1 /* cmd */) {
1495 case VKI_IPC_INFO:
1496 case VKI_MSG_INFO:
1497 case VKI_IPC_INFO|VKI_IPC_64:
1498 case VKI_MSG_INFO|VKI_IPC_64:
1499 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
1500 arg2, sizeof(struct vki_msginfo) );
1501 break;
1502 case VKI_IPC_STAT:
1503 case VKI_MSG_STAT:
1504 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
1505 arg2, sizeof(struct vki_msqid_ds) );
1506 break;
1507 case VKI_IPC_STAT|VKI_IPC_64:
1508 case VKI_MSG_STAT|VKI_IPC_64:
1509 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
1510 arg2, sizeof(struct vki_msqid64_ds) );
1511 break;
1512 case VKI_IPC_SET:
1513 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1514 arg2, sizeof(struct vki_msqid_ds) );
1515 break;
1516 case VKI_IPC_SET|VKI_IPC_64:
1517 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1518 arg2, sizeof(struct vki_msqid64_ds) );
1519 break;
1520 }
1521}
1522
1523void
1524VG_(generic_POST_sys_msgctl) ( ThreadId tid,
1525 UWord res,
1526 UWord arg0, UWord arg1, UWord arg2 )
1527{
1528 switch (arg1 /* cmd */) {
1529 case VKI_IPC_INFO:
1530 case VKI_MSG_INFO:
1531 case VKI_IPC_INFO|VKI_IPC_64:
1532 case VKI_MSG_INFO|VKI_IPC_64:
1533 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
1534 break;
1535 case VKI_IPC_STAT:
1536 case VKI_MSG_STAT:
1537 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
1538 break;
1539 case VKI_IPC_STAT|VKI_IPC_64:
1540 case VKI_MSG_STAT|VKI_IPC_64:
1541 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
1542 break;
1543 }
1544}
1545
1546/* ------ */
1547
1548static
1549UInt get_shm_size ( Int shmid )
1550{
1551#ifdef __NR_shmctl
1552 struct vki_shmid64_ds buf;
1553 long __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
1554#else
1555 struct vki_shmid_ds buf;
1556 long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
1557 VKI_IPC_STAT, 0, (UWord)&buf);
1558#endif
1559 if ( VG_(is_kerror) ( __res ) )
1560 return 0;
1561
1562 return buf.shm_segsz;
1563}
1564
1565UWord
1566VG_(generic_PRE_sys_shmat) ( ThreadId tid,
1567 UWord arg0, UWord arg1, UWord arg2 )
1568{
1569 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
1570 UInt segmentSize = get_shm_size ( arg0 );
1571 if (arg1 == 0)
1572 arg1 = VG_(find_map_space)(0, segmentSize, True);
1573 else if (!VG_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
1574 arg1 = 0;
1575 return arg1;
1576}
1577
1578void
1579VG_(generic_POST_sys_shmat) ( ThreadId tid,
1580 UWord res,
1581 UWord arg0, UWord arg1, UWord arg2 )
1582{
1583 UInt segmentSize = get_shm_size ( arg0 );
1584 if ( segmentSize > 0 ) {
1585 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
1586 /* we don't distinguish whether it's read-only or
1587 * read-write -- it doesn't matter really. */
1588 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
1589
1590 if (!(arg2 & 010000)) /* = SHM_RDONLY */
1591 prot &= ~VKI_PROT_WRITE;
1592 VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
1593 }
1594}
1595
1596/* ------ */
1597
1598Bool
1599VG_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
1600{
1601 /* int shmdt(const void *shmaddr); */
1602 return VG_(valid_client_addr)(arg0, 1, tid, "shmdt");
1603}
1604
1605void
1606VG_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
1607{
1608 Segment *s = VG_(find_segment)(arg0);
1609
1610 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, 1)) {
1611 VG_TRACK( die_mem_munmap, s->addr, s->len );
1612 VG_(unmap_range)(s->addr, s->len);
1613 }
1614}
1615/* ------ */
1616
1617void
1618VG_(generic_PRE_sys_shmctl) ( ThreadId tid,
1619 UWord arg0, UWord arg1, UWord arg2 )
1620{
1621 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
1622 switch (arg1 /* cmd */) {
1623 case VKI_IPC_INFO:
1624 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1625 arg2, sizeof(struct vki_shminfo) );
1626 break;
1627 case VKI_IPC_INFO|VKI_IPC_64:
1628 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1629 arg2, sizeof(struct vki_shminfo64) );
1630 break;
1631 case VKI_SHM_INFO:
1632 case VKI_SHM_INFO|VKI_IPC_64:
1633 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
1634 arg2, sizeof(struct vki_shm_info) );
1635 break;
1636 case VKI_IPC_STAT:
1637 case VKI_SHM_STAT:
1638 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
1639 arg2, sizeof(struct vki_shmid_ds) );
1640 break;
1641 case VKI_IPC_STAT|VKI_IPC_64:
1642 case VKI_SHM_STAT|VKI_IPC_64:
1643 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
1644 arg2, sizeof(struct vki_shmid64_ds) );
1645 break;
1646 case VKI_IPC_SET:
1647 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1648 arg2, sizeof(struct vki_shmid_ds) );
1649 break;
1650 case VKI_IPC_SET|VKI_IPC_64:
1651 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1652 arg2, sizeof(struct vki_shmid64_ds) );
1653 break;
1654 }
1655}
1656
1657void
1658VG_(generic_POST_sys_shmctl) ( ThreadId tid,
1659 UWord res,
1660 UWord arg0, UWord arg1, UWord arg2 )
1661{
1662 switch (arg1 /* cmd */) {
1663 case VKI_IPC_INFO:
1664 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
1665 break;
1666 case VKI_IPC_INFO|VKI_IPC_64:
1667 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
1668 break;
1669 case VKI_SHM_INFO:
1670 case VKI_SHM_INFO|VKI_IPC_64:
1671 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
1672 break;
1673 case VKI_IPC_STAT:
1674 case VKI_SHM_STAT:
1675 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
1676 break;
1677 case VKI_IPC_STAT|VKI_IPC_64:
1678 case VKI_SHM_STAT|VKI_IPC_64:
1679 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
1680 break;
1681 }
1682}
1683
1684
1685/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001686 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001687 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001688
nethercote4fa681f2004-11-08 17:51:39 +00001689/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001690 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001691 names like sys_write(); a few have names like old_mmap(). See the
nethercote8ff888f2004-11-17 17:11:45 +00001692 comment for VGA_(syscall_table)[] for important info about the __NR_foo
1693 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001694
nethercote92b2fd52004-11-16 16:15:41 +00001695 Some notes about names used for syscalls and args:
1696 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1697 ambiguity.
1698
1699 - For error messages, we generally use a somewhat generic name
1700 for the syscall (eg. "write" rather than "sys_write"). This should be
1701 good enough for the average user to understand what is happening,
1702 without confusing them with names like "sys_write".
1703
1704 - Also, for error messages the arg names are mostly taken from the man
1705 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001706 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001707 for the same reason -- a user presented with a "bogus foo(bar)" arg
1708 will most likely look at the "foo" man page to see which is the "bar"
1709 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001710
nethercote9c311eb2004-11-12 18:20:12 +00001711 Note that we use our own vki_* types. The one exception is in
1712 PRE_REG_READn calls, where pointer types haven't been changed, because
1713 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1714 be visible.
1715
nethercote4fa681f2004-11-08 17:51:39 +00001716 XXX: some of these are arch-specific, and should be factored out.
1717*/
1718
njn61fa0af2004-11-27 15:22:24 +00001719#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f)
1720#define POST(name) POST_TEMPLATE( , vgArch_gen, name)
jsgf855d93d2003-10-13 22:26:55 +00001721
nethercoteef0c7662004-11-06 15:38:43 +00001722// Combine two 32-bit values into a 64-bit value
1723#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1724
sewardjb5f6f512005-03-10 23:59:00 +00001725//PRE(sys_exit_group, Special)
1726//{
1727// VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1728//}
jsgf855d93d2003-10-13 22:26:55 +00001729
nethercote85a456f2004-11-16 17:31:56 +00001730PRE(sys_exit, Special)
jsgf855d93d2003-10-13 22:26:55 +00001731{
sewardja922b612005-03-11 02:47:32 +00001732 /* simple; just make this thread exit */
1733 PRINT("exit( %d )", ARG1);
1734 PRE_REG_READ1(void, "exit", int, exitcode);
1735 tst->exitreason = VgSrc_ExitSyscall;
1736 tst->os_state.exitcode = ARG1;
1737 /* exit doesn't return anything (it doesn't return.)
1738 Nevertheless, if we don't do this, the result-not-assigned-
1739 yet-you-said-you-were-Special assertion in the main syscall
1740 handling logic will fire. Hence ..
1741 */
1742 SET_RESULT(0);
jsgf855d93d2003-10-13 22:26:55 +00001743}
1744
sewardjb5f6f512005-03-10 23:59:00 +00001745PRE(sys_sched_yield, MayBlock)
nethercote5b653bc2004-11-15 14:32:12 +00001746{
sewardjb5f6f512005-03-10 23:59:00 +00001747 PRINT("sched_yield()");
1748 PRE_REG_READ0(long, "sys_sched_yield");
nethercote5b653bc2004-11-15 14:32:12 +00001749}
1750
nethercote85a456f2004-11-16 17:31:56 +00001751PRE(sys_ni_syscall, Special)
nethercoteeb1c7b72004-11-11 19:43:50 +00001752{
1753 PRINT("non-existent syscall! (ni_syscall)");
1754 PRE_REG_READ0(long, "ni_syscall");
njn22cfccb2004-11-27 16:10:23 +00001755 SET_RESULT( -VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001756}
1757
sewardjb5f6f512005-03-10 23:59:00 +00001758PRE(sys_set_tid_address, 0)
rjwalshcdf1cb52004-04-29 08:40:50 +00001759{
njn22cfccb2004-11-27 16:10:23 +00001760 PRINT("sys_set_tid_address ( %p )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001761 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
rjwalshcdf1cb52004-04-29 08:40:50 +00001762}
1763
nethercote85a456f2004-11-16 17:31:56 +00001764PRE(sys_iopl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001765{
njn22cfccb2004-11-27 16:10:23 +00001766 PRINT("sys_iopl ( %d )", ARG1);
nethercote7f7e4d12004-11-15 12:28:58 +00001767 PRE_REG_READ1(long, "iopl", unsigned long, level);
jsgf855d93d2003-10-13 22:26:55 +00001768}
1769
nethercote85a456f2004-11-16 17:31:56 +00001770PRE(sys_setxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001771{
nethercote2e1c37d2004-11-13 13:57:12 +00001772 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001773 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001774 PRE_REG_READ5(long, "setxattr",
1775 char *, path, char *, name,
1776 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001777 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1778 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1779 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001780}
1781
nethercote85a456f2004-11-16 17:31:56 +00001782PRE(sys_lsetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001783{
nethercote2e1c37d2004-11-13 13:57:12 +00001784 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001785 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001786 PRE_REG_READ5(long, "lsetxattr",
1787 char *, path, char *, name,
1788 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001789 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
1790 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
1791 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001792}
1793
nethercote85a456f2004-11-16 17:31:56 +00001794PRE(sys_fsetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001795{
1796 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001797 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001798 PRE_REG_READ5(long, "fsetxattr",
1799 int, fd, char *, name, void *, value,
1800 vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001801 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1802 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001803}
1804
nethercote85a456f2004-11-16 17:31:56 +00001805PRE(sys_getxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001806{
njn22cfccb2004-11-27 16:10:23 +00001807 PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001808 PRE_REG_READ4(ssize_t, "getxattr",
1809 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001810 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
1811 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
1812 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001813}
1814
nethercote85a456f2004-11-16 17:31:56 +00001815POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001816{
njn22cfccb2004-11-27 16:10:23 +00001817 if (RES > 0 && ARG3 != (Addr)NULL) {
1818 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001819 }
1820}
1821
nethercote85a456f2004-11-16 17:31:56 +00001822PRE(sys_lgetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001823{
njn22cfccb2004-11-27 16:10:23 +00001824 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001825 PRE_REG_READ4(ssize_t, "lgetxattr",
1826 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001827 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
1828 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
1829 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001830}
1831
nethercote85a456f2004-11-16 17:31:56 +00001832POST(sys_lgetxattr)
nethercote2e1c37d2004-11-13 13:57:12 +00001833{
njn22cfccb2004-11-27 16:10:23 +00001834 if (RES > 0 && ARG3 != (Addr)NULL) {
1835 POST_MEM_WRITE( ARG3, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001836 }
1837}
1838
nethercote85a456f2004-11-16 17:31:56 +00001839PRE(sys_fgetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001840{
njn22cfccb2004-11-27 16:10:23 +00001841 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001842 PRE_REG_READ4(ssize_t, "fgetxattr",
1843 int, fd, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001844 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
1845 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001846}
1847
nethercote85a456f2004-11-16 17:31:56 +00001848POST(sys_fgetxattr)
jsgf855d93d2003-10-13 22:26:55 +00001849{
njn22cfccb2004-11-27 16:10:23 +00001850 if (RES > 0 && ARG3 != (Addr)NULL)
1851 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001852}
1853
nethercote85a456f2004-11-16 17:31:56 +00001854PRE(sys_listxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001855{
njn22cfccb2004-11-27 16:10:23 +00001856 PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001857 PRE_REG_READ3(ssize_t, "listxattr",
1858 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001859 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1860 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001861}
1862
nethercote85a456f2004-11-16 17:31:56 +00001863POST(sys_listxattr)
jsgf855d93d2003-10-13 22:26:55 +00001864{
njn22cfccb2004-11-27 16:10:23 +00001865 if (RES > 0 && ARG2 != (Addr)NULL)
1866 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001867}
1868
nethercote85a456f2004-11-16 17:31:56 +00001869PRE(sys_llistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001870{
njn22cfccb2004-11-27 16:10:23 +00001871 PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001872 PRE_REG_READ3(ssize_t, "llistxattr",
1873 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001874 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
1875 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001876}
1877
nethercote85a456f2004-11-16 17:31:56 +00001878POST(sys_llistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001879{
njn22cfccb2004-11-27 16:10:23 +00001880 if (RES > 0 && ARG2 != (Addr)NULL)
1881 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001882}
1883
nethercote85a456f2004-11-16 17:31:56 +00001884PRE(sys_flistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001885{
njn22cfccb2004-11-27 16:10:23 +00001886 PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001887 PRE_REG_READ3(ssize_t, "flistxattr",
1888 int, fd, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001889 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001890}
1891
nethercote85a456f2004-11-16 17:31:56 +00001892POST(sys_flistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001893{
njn22cfccb2004-11-27 16:10:23 +00001894 if (RES > 0 && ARG2 != (Addr)NULL)
1895 POST_MEM_WRITE( ARG2, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001896}
1897
nethercote85a456f2004-11-16 17:31:56 +00001898PRE(sys_removexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001899{
njn22cfccb2004-11-27 16:10:23 +00001900 PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001901 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001902 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1903 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001904}
1905
nethercote85a456f2004-11-16 17:31:56 +00001906PRE(sys_lremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001907{
njn22cfccb2004-11-27 16:10:23 +00001908 PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001909 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001910 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
1911 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001912}
1913
nethercote85a456f2004-11-16 17:31:56 +00001914PRE(sys_fremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001915{
njn22cfccb2004-11-27 16:10:23 +00001916 PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001917 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001918 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001919}
1920
nethercote85a456f2004-11-16 17:31:56 +00001921PRE(sys_quotactl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001922{
njn22cfccb2004-11-27 16:10:23 +00001923 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
nethercote5b653bc2004-11-15 14:32:12 +00001924 PRE_REG_READ4(long, "quotactl",
1925 unsigned int, cmd, const char *, special, vki_qid_t, id,
1926 void *, addr);
njn22cfccb2004-11-27 16:10:23 +00001927 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001928}
1929
nethercote5a945af2004-11-14 18:37:07 +00001930// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00001931PRE(sys_lookup_dcookie, 0)
jsgf855d93d2003-10-13 22:26:55 +00001932{
njn22cfccb2004-11-27 16:10:23 +00001933 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
nethercote660e4ee2004-11-12 13:29:24 +00001934 PRE_REG_READ4(long, "lookup_dcookie",
1935 vki_u32, cookie_low32, vki_u32, cookie_high32,
1936 char *, buf, vki_size_t, len);
njn22cfccb2004-11-27 16:10:23 +00001937 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
jsgf855d93d2003-10-13 22:26:55 +00001938}
1939
nethercote85a456f2004-11-16 17:31:56 +00001940POST(sys_lookup_dcookie)
jsgf855d93d2003-10-13 22:26:55 +00001941{
njn22cfccb2004-11-27 16:10:23 +00001942 if (ARG3 != (Addr)NULL)
1943 POST_MEM_WRITE( ARG3, RES);
jsgf855d93d2003-10-13 22:26:55 +00001944}
1945
nethercote85a456f2004-11-16 17:31:56 +00001946PRE(sys_fsync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001947{
njn22cfccb2004-11-27 16:10:23 +00001948 PRINT("sys_fsync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001949 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1950}
1951
nethercote85a456f2004-11-16 17:31:56 +00001952PRE(sys_fdatasync, MayBlock)
nethercotedc18c0a2004-11-14 20:06:27 +00001953{
njn22cfccb2004-11-27 16:10:23 +00001954 PRINT("sys_fdatasync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001955 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001956}
1957
nethercote85a456f2004-11-16 17:31:56 +00001958PRE(sys_msync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001959{
njn22cfccb2004-11-27 16:10:23 +00001960 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00001961 PRE_REG_READ3(long, "msync",
1962 unsigned long, start, vki_size_t, length, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001963 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001964}
1965
nethercoteef0c7662004-11-06 15:38:43 +00001966// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1967// versions of LiS (Linux Streams). They are not part of the kernel.
1968// Therefore, we have to provide this type ourself, rather than getting it
1969// from the kernel sources.
nethercoteb77dee62004-11-16 17:13:24 +00001970struct vki_pmsg_strbuf {
jsgf855d93d2003-10-13 22:26:55 +00001971 int maxlen; /* no. of bytes in buffer */
1972 int len; /* no. of bytes returned */
nethercote73b526f2004-10-31 18:48:21 +00001973 vki_caddr_t buf; /* pointer to data */
jsgf855d93d2003-10-13 22:26:55 +00001974};
1975
nethercote85a456f2004-11-16 17:31:56 +00001976PRE(sys_getpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001977{
1978 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001979 struct vki_pmsg_strbuf *ctrl;
1980 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00001981 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00001982 PRE_REG_READ5(int, "getpmsg",
1983 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1984 int *, bandp, int *, flagsp);
njn22cfccb2004-11-27 16:10:23 +00001985 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1986 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00001987 if (ctrl && ctrl->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001988 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001989 if (data && data->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001990 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
njn22cfccb2004-11-27 16:10:23 +00001991 if (ARG4)
1992 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
1993 if (ARG5)
1994 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001995}
1996
nethercote85a456f2004-11-16 17:31:56 +00001997POST(sys_getpmsg)
jsgf855d93d2003-10-13 22:26:55 +00001998{
nethercoteb77dee62004-11-16 17:13:24 +00001999 struct vki_pmsg_strbuf *ctrl;
2000 struct vki_pmsg_strbuf *data;
jsgf855d93d2003-10-13 22:26:55 +00002001
njn22cfccb2004-11-27 16:10:23 +00002002 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2003 data = (struct vki_pmsg_strbuf *)ARG3;
2004 if (RES == 0 && ctrl && ctrl->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002005 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00002006 }
njn22cfccb2004-11-27 16:10:23 +00002007 if (RES == 0 && data && data->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002008 POST_MEM_WRITE( (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00002009 }
2010}
2011
nethercote85a456f2004-11-16 17:31:56 +00002012PRE(sys_putpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002013{
2014 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00002015 struct vki_pmsg_strbuf *ctrl;
2016 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00002017 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00002018 PRE_REG_READ5(int, "putpmsg",
2019 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2020 int, band, int, flags);
njn22cfccb2004-11-27 16:10:23 +00002021 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2022 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00002023 if (ctrl && ctrl->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002024 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00002025 if (data && data->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002026 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00002027}
2028
sewardjb5f6f512005-03-10 23:59:00 +00002029PRE(sys_getitimer, 0)
jsgf855d93d2003-10-13 22:26:55 +00002030{
njn22cfccb2004-11-27 16:10:23 +00002031 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00002032 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
njn22cfccb2004-11-27 16:10:23 +00002033 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
jsgf855d93d2003-10-13 22:26:55 +00002034}
2035
nethercote85a456f2004-11-16 17:31:56 +00002036POST(sys_getitimer)
jsgf855d93d2003-10-13 22:26:55 +00002037{
njn22cfccb2004-11-27 16:10:23 +00002038 if (ARG2 != (Addr)NULL) {
2039 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
jsgf855d93d2003-10-13 22:26:55 +00002040 }
2041}
2042
sewardjb5f6f512005-03-10 23:59:00 +00002043PRE(sys_setitimer, 0)
nethercote5b653bc2004-11-15 14:32:12 +00002044{
njn22cfccb2004-11-27 16:10:23 +00002045 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00002046 PRE_REG_READ3(long, "setitimer",
2047 int, which,
2048 struct itimerval *, value, struct itimerval *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00002049 if (ARG2 != (Addr)NULL)
2050 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
2051 if (ARG3 != (Addr)NULL)
2052 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00002053}
2054
nethercote85a456f2004-11-16 17:31:56 +00002055POST(sys_setitimer)
nethercote5b653bc2004-11-15 14:32:12 +00002056{
njn22cfccb2004-11-27 16:10:23 +00002057 if (ARG3 != (Addr)NULL) {
2058 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00002059 }
2060}
2061
nethercote85a456f2004-11-16 17:31:56 +00002062PRE(sys_chroot, 0)
jsgf855d93d2003-10-13 22:26:55 +00002063{
njn22cfccb2004-11-27 16:10:23 +00002064 PRINT("sys_chroot ( %p )", ARG1);
nethercote71f05f32004-11-12 18:49:27 +00002065 PRE_REG_READ1(long, "chroot", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002066 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002067}
2068
nethercote85a456f2004-11-16 17:31:56 +00002069PRE(sys_madvise, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002070{
njn22cfccb2004-11-27 16:10:23 +00002071 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00002072 PRE_REG_READ3(long, "madvise",
2073 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00002074}
2075
nethercote85a456f2004-11-16 17:31:56 +00002076PRE(sys_mremap, Special)
jsgf855d93d2003-10-13 22:26:55 +00002077{
nethercote27ea8bc2004-07-10 17:21:14 +00002078 // Nb: this is different to the glibc version described in the man pages,
2079 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00002080 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
njn22cfccb2004-11-27 16:10:23 +00002081 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
nethercote06c7bd72004-11-14 19:11:56 +00002082 PRE_REG_READ5(unsigned long, "mremap",
2083 unsigned long, old_addr, unsigned long, old_size,
2084 unsigned long, new_size, unsigned long, flags,
2085 unsigned long, new_addr);
njn22cfccb2004-11-27 16:10:23 +00002086 SET_RESULT( mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) );
jsgf855d93d2003-10-13 22:26:55 +00002087}
2088
nethercote85a456f2004-11-16 17:31:56 +00002089PRE(sys_nice, 0)
jsgf855d93d2003-10-13 22:26:55 +00002090{
njn22cfccb2004-11-27 16:10:23 +00002091 PRINT("sys_nice ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002092 PRE_REG_READ1(long, "nice", int, inc);
jsgf855d93d2003-10-13 22:26:55 +00002093}
2094
nethercote85a456f2004-11-16 17:31:56 +00002095PRE(sys_sched_getscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00002096{
njn22cfccb2004-11-27 16:10:23 +00002097 PRINT("sys_sched_getscheduler ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002098 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002099}
2100
nethercote85a456f2004-11-16 17:31:56 +00002101PRE(sys_sched_setscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00002102{
njn22cfccb2004-11-27 16:10:23 +00002103 PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00002104 PRE_REG_READ3(long, "sched_setscheduler",
2105 vki_pid_t, pid, int, policy, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00002106 if (ARG3 != 0)
nethercote5b653bc2004-11-15 14:32:12 +00002107 PRE_MEM_READ( "sched_setscheduler(p)",
njn22cfccb2004-11-27 16:10:23 +00002108 ARG3, sizeof(struct vki_sched_param));
jsgf855d93d2003-10-13 22:26:55 +00002109}
2110
nethercote85a456f2004-11-16 17:31:56 +00002111PRE(sys_mlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002112{
njn22cfccb2004-11-27 16:10:23 +00002113 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00002114 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00002115}
2116
nethercote85a456f2004-11-16 17:31:56 +00002117PRE(sys_munlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002118{
njn22cfccb2004-11-27 16:10:23 +00002119 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00002120 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00002121}
2122
nethercote85a456f2004-11-16 17:31:56 +00002123PRE(sys_mlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002124{
njn22cfccb2004-11-27 16:10:23 +00002125 PRINT("sys_mlockall ( %x )", ARG1);
nethercote06c7bd72004-11-14 19:11:56 +00002126 PRE_REG_READ1(long, "mlockall", int, flags);
jsgf855d93d2003-10-13 22:26:55 +00002127}
2128
nethercote85a456f2004-11-16 17:31:56 +00002129PRE(sys_munlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002130{
nethercote0df495a2004-11-11 16:38:21 +00002131 PRINT("sys_munlockall ( )");
2132 PRE_REG_READ0(long, "munlockall");
jsgf855d93d2003-10-13 22:26:55 +00002133}
2134
nethercote85a456f2004-11-16 17:31:56 +00002135PRE(sys_sched_get_priority_max, 0)
jsgf855d93d2003-10-13 22:26:55 +00002136{
njn22cfccb2004-11-27 16:10:23 +00002137 PRINT("sched_get_priority_max ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002138 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00002139}
2140
nethercote85a456f2004-11-16 17:31:56 +00002141PRE(sys_sched_get_priority_min, 0)
jsgf855d93d2003-10-13 22:26:55 +00002142{
njn22cfccb2004-11-27 16:10:23 +00002143 PRINT("sched_get_priority_min ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002144 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00002145}
2146
nethercote85a456f2004-11-16 17:31:56 +00002147PRE(sys_setpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00002148{
njn22cfccb2004-11-27 16:10:23 +00002149 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00002150 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
jsgf855d93d2003-10-13 22:26:55 +00002151}
2152
nethercote85a456f2004-11-16 17:31:56 +00002153PRE(sys_getpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00002154{
njn22cfccb2004-11-27 16:10:23 +00002155 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002156 PRE_REG_READ2(long, "getpriority", int, which, int, who);
jsgf855d93d2003-10-13 22:26:55 +00002157}
2158
nethercote85a456f2004-11-16 17:31:56 +00002159PRE(sys_setregid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002160{
njn22cfccb2004-11-27 16:10:23 +00002161 PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00002162 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00002163}
2164
nethercoteac866b92004-11-15 20:23:15 +00002165// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00002166PRE(sys_pwrite64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002167{
nethercoteac866b92004-11-15 20:23:15 +00002168 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00002169 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00002170 PRE_REG_READ5(ssize_t, "pwrite64",
2171 unsigned int, fd, const char *, buf, vki_size_t, count,
2172 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00002173 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002174}
2175
nethercote85a456f2004-11-16 17:31:56 +00002176PRE(sys_sync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002177{
nethercote0df495a2004-11-11 16:38:21 +00002178 PRINT("sys_sync ( )");
2179 PRE_REG_READ0(long, "sync");
jsgf855d93d2003-10-13 22:26:55 +00002180}
2181
nethercote85a456f2004-11-16 17:31:56 +00002182PRE(sys_fstatfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00002183{
njn22cfccb2004-11-27 16:10:23 +00002184 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002185 PRE_REG_READ2(long, "fstatfs",
2186 unsigned int, fd, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00002187 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00002188}
2189
nethercote85a456f2004-11-16 17:31:56 +00002190POST(sys_fstatfs)
jsgf855d93d2003-10-13 22:26:55 +00002191{
njn22cfccb2004-11-27 16:10:23 +00002192 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00002193}
2194
nethercote85a456f2004-11-16 17:31:56 +00002195PRE(sys_fstatfs64, 0)
thughesa996d3b2004-09-24 22:57:17 +00002196{
njn22cfccb2004-11-27 16:10:23 +00002197 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00002198 PRE_REG_READ3(long, "fstatfs64",
2199 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00002200 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00002201}
2202
nethercote85a456f2004-11-16 17:31:56 +00002203POST(sys_fstatfs64)
thughesa996d3b2004-09-24 22:57:17 +00002204{
njn22cfccb2004-11-27 16:10:23 +00002205 POST_MEM_WRITE( ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00002206}
2207
nethercote85a456f2004-11-16 17:31:56 +00002208PRE(sys_getsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002209{
njn22cfccb2004-11-27 16:10:23 +00002210 PRINT("sys_getsid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002211 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002212}
2213
nethercoteac866b92004-11-15 20:23:15 +00002214// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00002215PRE(sys_pread64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002216{
nethercoteac866b92004-11-15 20:23:15 +00002217 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00002218 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00002219 PRE_REG_READ5(ssize_t, "pread64",
2220 unsigned int, fd, char *, buf, vki_size_t, count,
2221 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00002222 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002223}
2224
nethercote85a456f2004-11-16 17:31:56 +00002225POST(sys_pread64)
jsgf855d93d2003-10-13 22:26:55 +00002226{
njn22cfccb2004-11-27 16:10:23 +00002227 if (RES > 0) {
2228 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002229 }
2230}
2231
nethercote85a456f2004-11-16 17:31:56 +00002232PRE(sys_mknod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002233{
njn22cfccb2004-11-27 16:10:23 +00002234 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00002235 PRE_REG_READ3(long, "mknod",
2236 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00002237 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002238}
2239
nethercote85a456f2004-11-16 17:31:56 +00002240PRE(sys_flock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002241{
njn22cfccb2004-11-27 16:10:23 +00002242 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
nethercote06c7bd72004-11-14 19:11:56 +00002243 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
jsgf855d93d2003-10-13 22:26:55 +00002244}
2245
nethercote85a456f2004-11-16 17:31:56 +00002246PRE(sys_init_module, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002247{
njn22cfccb2004-11-27 16:10:23 +00002248 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
nethercote0eafe552004-11-15 16:40:40 +00002249 PRE_REG_READ3(long, "init_module",
2250 void *, umod, unsigned long, len, const char *, uargs);
njn22cfccb2004-11-27 16:10:23 +00002251 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
2252 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002253}
2254
nethercote85a456f2004-11-16 17:31:56 +00002255PRE(sys_capget, 0)
jsgf855d93d2003-10-13 22:26:55 +00002256{
njn22cfccb2004-11-27 16:10:23 +00002257 PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00002258 PRE_REG_READ2(long, "capget",
2259 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
njn22cfccb2004-11-27 16:10:23 +00002260 PRE_MEM_READ( "capget(header)", ARG1,
nethercote73b526f2004-10-31 18:48:21 +00002261 sizeof(struct __vki_user_cap_header_struct) );
njn22cfccb2004-11-27 16:10:23 +00002262 PRE_MEM_WRITE( "capget(data)", ARG2,
nethercote73b526f2004-10-31 18:48:21 +00002263 sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002264}
2265
nethercote85a456f2004-11-16 17:31:56 +00002266POST(sys_capget)
jsgf855d93d2003-10-13 22:26:55 +00002267{
njn22cfccb2004-11-27 16:10:23 +00002268 if (ARG2 != (Addr)NULL)
2269 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002270}
2271
nethercote85a456f2004-11-16 17:31:56 +00002272PRE(sys_capset, 0)
jsgf855d93d2003-10-13 22:26:55 +00002273{
njn22cfccb2004-11-27 16:10:23 +00002274 PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00002275 PRE_REG_READ2(long, "capset",
2276 vki_cap_user_header_t, header,
2277 const vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00002278 PRE_MEM_READ( "capset(header)",
njn22cfccb2004-11-27 16:10:23 +00002279 ARG1, sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00002280 PRE_MEM_READ( "capset(data)",
njn22cfccb2004-11-27 16:10:23 +00002281 ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002282}
2283
nethercotea81e9162004-02-12 14:34:14 +00002284// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00002285static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00002286{
2287 while (True) {
njnb249fd72004-11-29 14:24:57 +00002288 Addr a_deref;
2289 Addr* a_p = (Addr*)a;
2290 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2291 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00002292 if (0 == a_deref)
2293 break;
nethercoteef0c7662004-11-06 15:38:43 +00002294 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00002295 a += sizeof(char*);
2296 }
2297}
2298
nethercote7310afb2004-11-12 15:41:06 +00002299// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
2300// but it seems to work nonetheless...
nethercote85a456f2004-11-16 17:31:56 +00002301PRE(sys_execve, Special)
jsgf855d93d2003-10-13 22:26:55 +00002302{
sewardjb5f6f512005-03-10 23:59:00 +00002303 Char *path; /* path to executable */
2304
njn22cfccb2004-11-27 16:10:23 +00002305 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00002306 PRE_REG_READ3(vki_off_t, "execve",
2307 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00002308 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
2309 if (ARG2 != 0)
2310 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
2311 if (ARG3 != 0)
2312 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00002313
sewardjb5f6f512005-03-10 23:59:00 +00002314 path = (Char *)ARG1;
2315
fitzhardingee1c06d82003-10-30 07:21:44 +00002316 /* Erk. If the exec fails, then the following will have made a
2317 mess of things which makes it hard for us to continue. The
2318 right thing to do is piece everything together again in
2319 POST(execve), but that's hard work. Instead, we make an effort
2320 to check that the execve will work before actually calling
2321 exec. */
2322 {
2323 struct vki_stat st;
njn22cfccb2004-11-27 16:10:23 +00002324 Int ret = VG_(stat)((Char *)ARG1, &st);
fitzhardingee1c06d82003-10-30 07:21:44 +00002325
2326 if (ret < 0) {
njn22cfccb2004-11-27 16:10:23 +00002327 SET_RESULT( ret );
fitzhardingee1c06d82003-10-30 07:21:44 +00002328 return;
2329 }
thughes90efa302004-09-25 16:13:55 +00002330 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00002331 XXX do proper permissions check?
2332 */
thughes90efa302004-09-25 16:13:55 +00002333 if ((st.st_mode & 0100111) == 0100000) {
njn22cfccb2004-11-27 16:10:23 +00002334 SET_RESULT( -VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00002335 return;
2336 }
2337 }
2338
2339 /* Resistance is futile. Nuke all other threads. POSIX mandates
2340 this. (Really, nuke them all, since the new process will make
2341 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00002342 VG_(master_tid) = tid; /* become the master */
2343 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
2344 VGA_(reap_threads)(tid);
2345
2346 if (0) {
2347 /* Shut down cleanly and report final state
2348 XXX Is this reasonable? */
2349 tst->exitreason = VgSrc_ExitSyscall;
2350 VG_(shutdown_actions)(tid);
2351 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002352
fitzhardinge5408c062004-01-04 23:52:59 +00002353 {
nethercote60a96c52004-08-03 13:08:31 +00002354 // Remove the valgrind-specific stuff from the environment so the
sewardjb5f6f512005-03-10 23:59:00 +00002355 // child doesn't get vg_inject.so, vgpreload.so, etc. This is
nethercote60a96c52004-08-03 13:08:31 +00002356 // done unconditionally, since if we are tracing the child,
2357 // stage1/2 will set up the appropriate client environment.
njn22cfccb2004-11-27 16:10:23 +00002358 Char** envp = (Char**)ARG3;
fitzhardinge98abfc72003-12-16 02:05:15 +00002359
2360 if (envp != NULL) {
sewardjb5f6f512005-03-10 23:59:00 +00002361 VG_(env_remove_valgrind_env_stuff)( envp );
jsgf855d93d2003-10-13 22:26:55 +00002362 }
fitzhardinge5408c062004-01-04 23:52:59 +00002363 }
2364
2365 if (VG_(clo_trace_children)) {
njn22cfccb2004-11-27 16:10:23 +00002366 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)ARG1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00002367
njn22cfccb2004-11-27 16:10:23 +00002368 // Set VALGRINDCLO and VALGRINDLIB in ARG3 (the environment)
2369 VG_(env_setenv)( (Char***)&ARG3, VALGRINDCLO, optvar);
2370 VG_(env_setenv)( (Char***)&ARG3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002371
njn22cfccb2004-11-27 16:10:23 +00002372 // Create executable name: "/proc/self/fd/<vgexecfd>", update ARG1
sewardj8e332792005-03-11 12:56:56 +00002373 path = VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00002374 }
2375
2376 if (0) {
2377 Char **cpp;
2378
njn22cfccb2004-11-27 16:10:23 +00002379 VG_(printf)("exec: %s\n", (Char *)ARG1);
2380 for(cpp = (Char **)ARG2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002381 VG_(printf)("argv: %s\n", *cpp);
njn22cfccb2004-11-27 16:10:23 +00002382 for(cpp = (Char **)ARG3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002383 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00002384 }
jsgf855d93d2003-10-13 22:26:55 +00002385
sewardjb5f6f512005-03-10 23:59:00 +00002386 /* restore the DATA rlimit for the child */
2387 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2388
2389 /*
2390 Set the signal state up for exec.
2391
2392 We need to set the real signal state to make sure the exec'd
2393 process gets SIG_IGN properly.
2394
2395 Also set our real sigmask to match the client's sigmask so that
2396 the exec'd child will get the right mask. First we need to
2397 clear out any pending signals so they they don't get delivered,
2398 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002399
2400 XXX This is a bug - the signals should remain pending, and be
2401 delivered to the new process after exec. There's also a
2402 race-condition, since if someone delivers us a signal between
2403 the sigprocmask and the execve, we'll still get the signal. Oh
2404 well.
2405 */
2406 {
nethercote73b526f2004-10-31 18:48:21 +00002407 vki_sigset_t allsigs;
2408 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002409 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002410 Int i;
2411
2412 for(i = 1; i < VG_(max_signal); i++) {
2413 struct vki_sigaction sa;
2414 VG_(do_sys_sigaction)(i, NULL, &sa);
2415 if (sa.ksa_handler == VKI_SIG_IGN)
2416 VG_(sigaction)(i, &sa, NULL);
2417 else {
2418 sa.ksa_handler = VKI_SIG_DFL;
2419 VG_(sigaction)(i, &sa, NULL);
2420 }
2421 }
2422
nethercote73b526f2004-10-31 18:48:21 +00002423 VG_(sigfillset)(&allsigs);
2424 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002425 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002426
nethercote73b526f2004-10-31 18:48:21 +00002427 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002428 }
2429
sewardjb5f6f512005-03-10 23:59:00 +00002430 SET_RESULT( VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) );
fitzhardingeb50068f2004-02-24 23:42:55 +00002431
sewardjb5f6f512005-03-10 23:59:00 +00002432 /* If we got here, then the execve failed. We've already made too
2433 much of a mess of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00002434 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
sewardjb5f6f512005-03-10 23:59:00 +00002435 ARG1, ARG1, ARG2, ARG3, -RES);
2436 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2437 "execve() failing, so I'm dying.");
2438 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(execve), "
2439 "or work out how to recover.");
2440 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002441}
2442
nethercote85a456f2004-11-16 17:31:56 +00002443PRE(sys_access, 0)
jsgf855d93d2003-10-13 22:26:55 +00002444{
njn22cfccb2004-11-27 16:10:23 +00002445 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002446 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002447 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002448}
2449
sewardjb5f6f512005-03-10 23:59:00 +00002450PRE(sys_alarm, 0)
jsgf855d93d2003-10-13 22:26:55 +00002451{
njn22cfccb2004-11-27 16:10:23 +00002452 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002453 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002454}
2455
nethercote85a456f2004-11-16 17:31:56 +00002456PRE(sys_brk, Special)
jsgf855d93d2003-10-13 22:26:55 +00002457{
fitzhardinge98abfc72003-12-16 02:05:15 +00002458 Addr brk_limit = VG_(brk_limit);
2459
jsgf855d93d2003-10-13 22:26:55 +00002460 /* libc says: int brk(void *end_data_segment);
2461 kernel says: void* brk(void* end_data_segment); (more or less)
2462
2463 libc returns 0 on success, and -1 (and sets errno) on failure.
2464 Nb: if you ask to shrink the dataseg end below what it
2465 currently is, that always succeeds, even if the dataseg end
2466 doesn't actually change (eg. brk(0)). Unless it seg faults.
2467
2468 Kernel returns the new dataseg end. If the brk() failed, this
2469 will be unchanged from the old one. That's why calling (kernel)
2470 brk(0) gives the current dataseg end (libc brk() just returns
2471 zero in that case).
2472
2473 Both will seg fault if you shrink it back into a text segment.
2474 */
njn22cfccb2004-11-27 16:10:23 +00002475 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002476 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002477
njn22cfccb2004-11-27 16:10:23 +00002478 SET_RESULT( do_brk(ARG1) );
fitzhardinge98abfc72003-12-16 02:05:15 +00002479
njn22cfccb2004-11-27 16:10:23 +00002480 if (RES == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002481 /* brk() succeeded */
njn22cfccb2004-11-27 16:10:23 +00002482 if (RES < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002483 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002484 VG_TRACK( die_mem_brk, (Addr)ARG1,
2485 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002486 } else
njn22cfccb2004-11-27 16:10:23 +00002487 if (RES > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002488 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002489 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002490 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002491 }
jsgf855d93d2003-10-13 22:26:55 +00002492 } else {
2493 /* brk() failed */
njn22cfccb2004-11-27 16:10:23 +00002494 vg_assert(brk_limit == RES);
jsgf855d93d2003-10-13 22:26:55 +00002495 }
2496}
2497
nethercote85a456f2004-11-16 17:31:56 +00002498PRE(sys_chdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002499{
njn22cfccb2004-11-27 16:10:23 +00002500 PRINT("sys_chdir ( %p )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002501 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002502 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002503}
2504
nethercote85a456f2004-11-16 17:31:56 +00002505PRE(sys_chmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002506{
njn22cfccb2004-11-27 16:10:23 +00002507 PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002508 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002509 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002510}
2511
nethercote85a456f2004-11-16 17:31:56 +00002512PRE(sys_chown16, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002513{
njn22cfccb2004-11-27 16:10:23 +00002514 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002515 PRE_REG_READ3(long, "chown16",
2516 const char *, path,
2517 vki_old_uid_t, owner, vki_old_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002518 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002519}
2520
nethercote85a456f2004-11-16 17:31:56 +00002521PRE(sys_chown, 0)
jsgf855d93d2003-10-13 22:26:55 +00002522{
2523 /* int chown(const char *path, uid_t owner, gid_t group); */
njn22cfccb2004-11-27 16:10:23 +00002524 PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002525 PRE_REG_READ3(long, "chown",
2526 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002527 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002528}
2529
nethercote85a456f2004-11-16 17:31:56 +00002530PRE(sys_lchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002531{
njn22cfccb2004-11-27 16:10:23 +00002532 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002533 PRE_REG_READ3(long, "lchown",
2534 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002535 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002536}
jsgf855d93d2003-10-13 22:26:55 +00002537
nethercote85a456f2004-11-16 17:31:56 +00002538PRE(sys_close, 0)
jsgf855d93d2003-10-13 22:26:55 +00002539{
njn22cfccb2004-11-27 16:10:23 +00002540 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002541 PRE_REG_READ1(long, "close", unsigned int, fd);
2542
nethercotef8548672004-06-21 12:42:35 +00002543 /* Detect and negate attempts by the client to close Valgrind's log fd */
njn22cfccb2004-11-27 16:10:23 +00002544 if (!VG_(fd_allowed)(ARG1, "close", tid, False))
2545 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002546}
2547
nethercote85a456f2004-11-16 17:31:56 +00002548POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002549{
njn22cfccb2004-11-27 16:10:23 +00002550 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002551}
jsgf855d93d2003-10-13 22:26:55 +00002552
nethercote85a456f2004-11-16 17:31:56 +00002553PRE(sys_dup, 0)
jsgf855d93d2003-10-13 22:26:55 +00002554{
njn22cfccb2004-11-27 16:10:23 +00002555 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002556 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002557}
2558
nethercote85a456f2004-11-16 17:31:56 +00002559POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002560{
njn22cfccb2004-11-27 16:10:23 +00002561 if (!VG_(fd_allowed)(RES, "dup", tid, True)) {
2562 VG_(close)(RES);
2563 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002564 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002565 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002566 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002567 }
2568}
2569
nethercote85a456f2004-11-16 17:31:56 +00002570PRE(sys_dup2, 0)
jsgf855d93d2003-10-13 22:26:55 +00002571{
njn22cfccb2004-11-27 16:10:23 +00002572 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002573 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
njn22cfccb2004-11-27 16:10:23 +00002574 if (!VG_(fd_allowed)(ARG2, "dup2", tid, True))
2575 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002576}
2577
nethercote85a456f2004-11-16 17:31:56 +00002578POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002579{
nethercote71f05f32004-11-12 18:49:27 +00002580 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002581 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002582}
2583
nethercote85a456f2004-11-16 17:31:56 +00002584PRE(sys_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002585{
njn22cfccb2004-11-27 16:10:23 +00002586 PRINT("sys_fchdir ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002587 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00002588}
2589
nethercote85a456f2004-11-16 17:31:56 +00002590PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002591{
njn22cfccb2004-11-27 16:10:23 +00002592 PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002593 PRE_REG_READ3(long, "fchown16",
2594 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00002595}
2596
nethercote85a456f2004-11-16 17:31:56 +00002597PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002598{
njn22cfccb2004-11-27 16:10:23 +00002599 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002600 PRE_REG_READ3(long, "fchown",
2601 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2602}
jsgf855d93d2003-10-13 22:26:55 +00002603
nethercote85a456f2004-11-16 17:31:56 +00002604PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002605{
njn22cfccb2004-11-27 16:10:23 +00002606 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002607 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00002608}
2609
njnc6168192004-11-29 13:54:10 +00002610PRE(sys_fcntl, 0)
njncfb8ad52004-11-23 14:57:49 +00002611{
njn22cfccb2004-11-27 16:10:23 +00002612 switch (ARG2) {
2613 // These ones ignore ARG3.
njncfb8ad52004-11-23 14:57:49 +00002614 case VKI_F_GETFD:
2615 case VKI_F_GETFL:
2616 case VKI_F_GETOWN:
2617 case VKI_F_SETOWN:
2618 case VKI_F_GETSIG:
2619 case VKI_F_SETSIG:
2620 case VKI_F_GETLEASE:
njnc6168192004-11-29 13:54:10 +00002621 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2622 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
njncfb8ad52004-11-23 14:57:49 +00002623 break;
2624
njn22cfccb2004-11-27 16:10:23 +00002625 // These ones use ARG3 as "arg".
njncfb8ad52004-11-23 14:57:49 +00002626 case VKI_F_DUPFD:
2627 case VKI_F_SETFD:
2628 case VKI_F_SETFL:
2629 case VKI_F_SETLEASE:
2630 case VKI_F_NOTIFY:
njnc6168192004-11-29 13:54:10 +00002631 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2632 PRE_REG_READ3(long, "fcntl",
2633 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
njncfb8ad52004-11-23 14:57:49 +00002634 break;
2635
njn22cfccb2004-11-27 16:10:23 +00002636 // These ones use ARG3 as "lock".
njncfb8ad52004-11-23 14:57:49 +00002637 case VKI_F_GETLK:
2638 case VKI_F_SETLK:
2639 case VKI_F_SETLKW:
njnc6168192004-11-29 13:54:10 +00002640#ifndef __amd64__
njncfb8ad52004-11-23 14:57:49 +00002641 case VKI_F_GETLK64:
2642 case VKI_F_SETLK64:
2643 case VKI_F_SETLKW64:
njnc6168192004-11-29 13:54:10 +00002644#else
2645#endif
2646 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2647 PRE_REG_READ3(long, "fcntl",
2648 unsigned int, fd, unsigned int, cmd,
2649 struct flock64 *, lock);
njncfb8ad52004-11-23 14:57:49 +00002650 break;
2651 }
njncfb8ad52004-11-23 14:57:49 +00002652
sewardjb5f6f512005-03-10 23:59:00 +00002653 //if (ARG2 == VKI_F_SETLKW)
2654 // tst->sys_flags |= MayBlock;
njncfb8ad52004-11-23 14:57:49 +00002655}
2656
2657POST(sys_fcntl)
2658{
njn22cfccb2004-11-27 16:10:23 +00002659 if (ARG2 == VKI_F_DUPFD) {
2660 if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
2661 VG_(close)(RES);
2662 SET_RESULT( -VKI_EMFILE );
njncfb8ad52004-11-23 14:57:49 +00002663 } else {
2664 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002665 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
njncfb8ad52004-11-23 14:57:49 +00002666 }
2667 }
2668}
2669
nethercote06c7bd72004-11-14 19:11:56 +00002670// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00002671PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00002672{
njnc6168192004-11-29 13:54:10 +00002673 switch (ARG2) {
2674 // These ones ignore ARG3.
2675 case VKI_F_GETFD:
2676 case VKI_F_GETFL:
2677 case VKI_F_GETOWN:
2678 case VKI_F_SETOWN:
2679 case VKI_F_GETSIG:
2680 case VKI_F_SETSIG:
2681 case VKI_F_GETLEASE:
2682 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2683 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2684 break;
2685
2686 // These ones use ARG3 as "arg".
2687 case VKI_F_DUPFD:
2688 case VKI_F_SETFD:
2689 case VKI_F_SETFL:
2690 case VKI_F_SETLEASE:
2691 case VKI_F_NOTIFY:
2692 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2693 PRE_REG_READ3(long, "fcntl64",
2694 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2695 break;
2696
2697 // These ones use ARG3 as "lock".
2698 case VKI_F_GETLK:
2699 case VKI_F_SETLK:
2700 case VKI_F_SETLKW:
2701#ifndef __amd64__
2702 case VKI_F_GETLK64:
2703 case VKI_F_SETLK64:
2704 case VKI_F_SETLKW64:
2705#endif
2706 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2707 PRE_REG_READ3(long, "fcntl64",
2708 unsigned int, fd, unsigned int, cmd,
2709 struct flock64 *, lock);
2710 break;
2711 }
njncfb8ad52004-11-23 14:57:49 +00002712
njnc6168192004-11-29 13:54:10 +00002713#ifndef __amd64__
sewardjb5f6f512005-03-10 23:59:00 +00002714 //if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2715 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002716#else
sewardjb5f6f512005-03-10 23:59:00 +00002717 //if (ARG2 == VKI_F_SETLKW)
2718 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002719#endif
rjwalshf5f536f2003-11-17 17:45:00 +00002720}
2721
nethercote85a456f2004-11-16 17:31:56 +00002722POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002723{
njn22cfccb2004-11-27 16:10:23 +00002724 if (ARG2 == VKI_F_DUPFD) {
2725 if (!VG_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
2726 VG_(close)(RES);
2727 SET_RESULT( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002728 } else {
2729 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002730 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
nethercote493dd182004-02-24 23:57:47 +00002731 }
2732 }
jsgf855d93d2003-10-13 22:26:55 +00002733}
2734
nethercote85a456f2004-11-16 17:31:56 +00002735PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00002736{
njn22cfccb2004-11-27 16:10:23 +00002737 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00002738 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00002739 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002740}
2741
nethercote85a456f2004-11-16 17:31:56 +00002742POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00002743{
njn22cfccb2004-11-27 16:10:23 +00002744 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002745}
2746
nethercote73b526f2004-10-31 18:48:21 +00002747static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002748
nethercote75a8c982004-11-11 19:03:34 +00002749// In Linux, the sys_fork() function varies across architectures, but we
2750// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00002751PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00002752{
nethercote73b526f2004-10-31 18:48:21 +00002753 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002754
nethercote75a8c982004-11-11 19:03:34 +00002755 PRINT("sys_fork ( )");
2756 PRE_REG_READ0(long, "fork");
2757
jsgf855d93d2003-10-13 22:26:55 +00002758 /* Block all signals during fork, so that we can fix things up in
2759 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002760 VG_(sigfillset)(&mask);
2761 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002762
sewardjb5f6f512005-03-10 23:59:00 +00002763 VG_(do_atfork_pre)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002764
sewardjb5f6f512005-03-10 23:59:00 +00002765 SET_RESULT(VG_(do_syscall0)(__NR_fork));
2766
njn22cfccb2004-11-27 16:10:23 +00002767 if (RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002768 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002769
2770 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002771 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002772 } else if (RES > 0) {
2773 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002774
sewardjb5f6f512005-03-10 23:59:00 +00002775 VG_(do_atfork_parent)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002776
2777 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002778 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002779 }
2780}
2781
nethercote85a456f2004-11-16 17:31:56 +00002782PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002783{
njn22cfccb2004-11-27 16:10:23 +00002784 PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002785 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002786}
2787
nethercote85a456f2004-11-16 17:31:56 +00002788PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002789{
njn22cfccb2004-11-27 16:10:23 +00002790 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002791 PRE_REG_READ2(long, "truncate",
2792 const char *, path, unsigned long, length);
njn22cfccb2004-11-27 16:10:23 +00002793 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002794}
2795
nethercote5a945af2004-11-14 18:37:07 +00002796// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002797PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002798{
njn22cfccb2004-11-27 16:10:23 +00002799 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002800 PRE_REG_READ3(long, "ftruncate64",
2801 unsigned int, fd,
2802 vki_u32, length_low32, vki_u32, length_high32);
2803}
2804
2805// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002806PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002807{
njn22cfccb2004-11-27 16:10:23 +00002808 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002809 PRE_REG_READ3(long, "truncate64",
2810 const char *, path,
2811 vki_u32, length_low32, vki_u32, length_high32);
njn22cfccb2004-11-27 16:10:23 +00002812 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
nethercote5a945af2004-11-14 18:37:07 +00002813}
2814
2815
nethercote85a456f2004-11-16 17:31:56 +00002816PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002817{
njn22cfccb2004-11-27 16:10:23 +00002818 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002819 PRE_REG_READ3(long, "getdents",
2820 unsigned int, fd, struct linux_dirent *, dirp,
2821 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002822 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002823}
2824
nethercote85a456f2004-11-16 17:31:56 +00002825POST(sys_getdents)
jsgf855d93d2003-10-13 22:26:55 +00002826{
njn22cfccb2004-11-27 16:10:23 +00002827 if (RES > 0)
2828 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002829}
2830
nethercote85a456f2004-11-16 17:31:56 +00002831PRE(sys_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002832{
njn22cfccb2004-11-27 16:10:23 +00002833 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002834 PRE_REG_READ3(long, "getdents64",
2835 unsigned int, fd, struct linux_dirent64 *, dirp,
2836 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002837 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002838}
2839
nethercote85a456f2004-11-16 17:31:56 +00002840POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002841{
njn22cfccb2004-11-27 16:10:23 +00002842 if (RES > 0)
2843 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002844}
2845
nethercote85a456f2004-11-16 17:31:56 +00002846PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002847{
njn22cfccb2004-11-27 16:10:23 +00002848 PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002849 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002850 if (ARG1 > 0)
2851 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002852}
2853
nethercote85a456f2004-11-16 17:31:56 +00002854POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002855{
njn22cfccb2004-11-27 16:10:23 +00002856 if (ARG1 > 0 && RES > 0)
2857 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002858}
2859
nethercote85a456f2004-11-16 17:31:56 +00002860PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002861{
njn22cfccb2004-11-27 16:10:23 +00002862 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002863 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002864 if (ARG1 > 0)
2865 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002866}
2867
nethercote85a456f2004-11-16 17:31:56 +00002868POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002869{
njn22cfccb2004-11-27 16:10:23 +00002870 if (ARG1 > 0 && RES > 0)
2871 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002872}
2873
nethercote85a456f2004-11-16 17:31:56 +00002874PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002875{
nethercoteac866b92004-11-15 20:23:15 +00002876 // Note that the kernel version of getcwd() behaves quite differently to
2877 // the glibc one.
njn22cfccb2004-11-27 16:10:23 +00002878 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002879 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002880 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002881}
2882
nethercote85a456f2004-11-16 17:31:56 +00002883POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002884{
njn22cfccb2004-11-27 16:10:23 +00002885 if (RES != (Addr)NULL)
2886 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002887}
2888
nethercote85a456f2004-11-16 17:31:56 +00002889PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002890{
nethercote0df495a2004-11-11 16:38:21 +00002891 PRINT("sys_geteuid16 ( )");
2892 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002893}
2894
nethercote85a456f2004-11-16 17:31:56 +00002895PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002896{
nethercote0df495a2004-11-11 16:38:21 +00002897 PRINT("sys_geteuid ( )");
2898 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002899}
2900
nethercote85a456f2004-11-16 17:31:56 +00002901PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002902{
nethercote0df495a2004-11-11 16:38:21 +00002903 PRINT("sys_getegid16 ( )");
2904 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002905}
2906
nethercote85a456f2004-11-16 17:31:56 +00002907PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002908{
nethercote0df495a2004-11-11 16:38:21 +00002909 PRINT("sys_getegid ( )");
2910 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002911}
2912
nethercote85a456f2004-11-16 17:31:56 +00002913PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002914{
nethercote0df495a2004-11-11 16:38:21 +00002915 PRINT("sys_getgid16 ( )");
2916 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002917}
2918
nethercote85a456f2004-11-16 17:31:56 +00002919PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002920{
nethercote0df495a2004-11-11 16:38:21 +00002921 PRINT("sys_getgid ( )");
2922 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002923}
2924
nethercote85a456f2004-11-16 17:31:56 +00002925PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002926{
nethercote4e632c22004-11-09 16:45:33 +00002927 PRINT("sys_getpid ()");
2928 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002929}
2930
nethercote85a456f2004-11-16 17:31:56 +00002931PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002932{
njn22cfccb2004-11-27 16:10:23 +00002933 PRINT("sys_getpgid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002934 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002935}
2936
nethercote85a456f2004-11-16 17:31:56 +00002937PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002938{
nethercote0df495a2004-11-11 16:38:21 +00002939 PRINT("sys_getpgrp ()");
2940 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002941}
2942
nethercote85a456f2004-11-16 17:31:56 +00002943PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002944{
nethercote4e632c22004-11-09 16:45:33 +00002945 PRINT("sys_getppid ()");
2946 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002947}
2948
njncf45fd42004-11-24 16:30:22 +00002949static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002950{
nethercote620154f2004-11-12 21:21:07 +00002951 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002952
nethercote620154f2004-11-12 21:21:07 +00002953 switch (a1) {
2954 case VKI_RLIMIT_NOFILE:
2955 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2956 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2957 break;
nethercote535f03b2004-02-15 15:32:51 +00002958
nethercote620154f2004-11-12 21:21:07 +00002959 case VKI_RLIMIT_DATA:
2960 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2961 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002962
nethercote620154f2004-11-12 21:21:07 +00002963 case VKI_RLIMIT_STACK:
2964 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2965 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002966 }
jsgf855d93d2003-10-13 22:26:55 +00002967}
2968
nethercote85a456f2004-11-16 17:31:56 +00002969PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002970{
njn22cfccb2004-11-27 16:10:23 +00002971 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002972 PRE_REG_READ2(long, "old_getrlimit",
2973 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002974 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002975}
2976
nethercote85a456f2004-11-16 17:31:56 +00002977POST(sys_old_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}
2981
nethercote85a456f2004-11-16 17:31:56 +00002982PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002983{
njn22cfccb2004-11-27 16:10:23 +00002984 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002985 PRE_REG_READ2(long, "getrlimit",
2986 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002987 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002988}
2989
nethercote85a456f2004-11-16 17:31:56 +00002990POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002991{
njn22cfccb2004-11-27 16:10:23 +00002992 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002993}
jsgf855d93d2003-10-13 22:26:55 +00002994
nethercote85a456f2004-11-16 17:31:56 +00002995PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00002996{
2997 /* int getrusage (int who, struct rusage *usage); */
njn22cfccb2004-11-27 16:10:23 +00002998 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
nethercotef1049bf2004-11-14 17:03:47 +00002999 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
njn22cfccb2004-11-27 16:10:23 +00003000 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00003001}
3002
nethercote85a456f2004-11-16 17:31:56 +00003003POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00003004{
njn22cfccb2004-11-27 16:10:23 +00003005 if (RES == 0)
3006 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00003007}
3008
nethercote85a456f2004-11-16 17:31:56 +00003009PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00003010{
njn22cfccb2004-11-27 16:10:23 +00003011 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003012 PRE_REG_READ2(long, "gettimeofday",
3013 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003014 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3015 if (ARG2 != 0)
3016 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003017}
3018
nethercote85a456f2004-11-16 17:31:56 +00003019POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003020{
njn22cfccb2004-11-27 16:10:23 +00003021 if (RES == 0) {
3022 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
3023 if (ARG2 != 0)
3024 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003025 }
3026}
3027
nethercote85a456f2004-11-16 17:31:56 +00003028PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00003029{
njn22cfccb2004-11-27 16:10:23 +00003030 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003031 PRE_REG_READ2(long, "settimeofday",
3032 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003033 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3034 if (ARG2 != 0) {
3035 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
nethercote686b5db2004-11-14 13:42:51 +00003036 /* maybe should warn if tz->tz_dsttime is non-zero? */
3037 }
3038}
3039
nethercote85a456f2004-11-16 17:31:56 +00003040PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00003041{
nethercote0df495a2004-11-11 16:38:21 +00003042 PRINT("sys_getuid16 ( )");
3043 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00003044}
3045
nethercote85a456f2004-11-16 17:31:56 +00003046PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00003047{
nethercote0df495a2004-11-11 16:38:21 +00003048 PRINT("sys_getuid ( )");
3049 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00003050}
3051
nethercote2e1c37d2004-11-13 13:57:12 +00003052// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00003053PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00003054{
njn22cfccb2004-11-27 16:10:23 +00003055 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00003056 PRE_REG_READ3(long, "ioctl",
3057 unsigned int, fd, unsigned int, request, unsigned long, arg);
3058
njn22cfccb2004-11-27 16:10:23 +00003059 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003060 case VKI_TCSETS:
3061 case VKI_TCSETSW:
3062 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00003063 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003064 break;
nethercote73b526f2004-10-31 18:48:21 +00003065 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003066 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003067 break;
nethercote73b526f2004-10-31 18:48:21 +00003068 case VKI_TCSETA:
3069 case VKI_TCSETAW:
3070 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00003071 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003072 break;
nethercote73b526f2004-10-31 18:48:21 +00003073 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003074 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003075 break;
nethercote73b526f2004-10-31 18:48:21 +00003076 case VKI_TCSBRK:
3077 case VKI_TCXONC:
3078 case VKI_TCSBRKP:
3079 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003080 /* These just take an int by value */
3081 break;
nethercote73b526f2004-10-31 18:48:21 +00003082 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003083 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003084 break;
nethercote73b526f2004-10-31 18:48:21 +00003085 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003086 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003087 break;
nethercote73b526f2004-10-31 18:48:21 +00003088 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00003089 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003090 break;
nethercote73b526f2004-10-31 18:48:21 +00003091 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00003092 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003093 break;
nethercote73b526f2004-10-31 18:48:21 +00003094 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00003095 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003096 break;
nethercote73b526f2004-10-31 18:48:21 +00003097 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003098 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
3099 if (*(char *)ARG3 == 11) {
3100 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003101 }
3102 break;
nethercote73b526f2004-10-31 18:48:21 +00003103 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003104 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003105 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003106 break;
nethercote73b526f2004-10-31 18:48:21 +00003107 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003108 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003109 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003110 break;
nethercote73b526f2004-10-31 18:48:21 +00003111 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003112 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003113 break;
nethercote73b526f2004-10-31 18:48:21 +00003114 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003115 /* Just takes an int value. */
3116 break;
nethercote73b526f2004-10-31 18:48:21 +00003117 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00003118 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003119 break;
nethercote73b526f2004-10-31 18:48:21 +00003120 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00003121 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003122 break;
nethercote73b526f2004-10-31 18:48:21 +00003123 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00003124 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003125 break;
nethercote73b526f2004-10-31 18:48:21 +00003126 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003127 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003128 break;
3129
nethercote73b526f2004-10-31 18:48:21 +00003130 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00003131 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003132 break;
nethercote73b526f2004-10-31 18:48:21 +00003133 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003134 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00003135 break;
nethercote73b526f2004-10-31 18:48:21 +00003136 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003137 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00003138 break;
nethercote73b526f2004-10-31 18:48:21 +00003139 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003140 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003141 break;
nethercote73b526f2004-10-31 18:48:21 +00003142 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003143 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003144 break;
nethercote73b526f2004-10-31 18:48:21 +00003145 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003146 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003147 break;
nethercote73b526f2004-10-31 18:48:21 +00003148 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003149 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003150 break;
nethercote73b526f2004-10-31 18:48:21 +00003151 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00003152 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003153 break;
nethercote73b526f2004-10-31 18:48:21 +00003154 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00003155 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003156 break;
nethercote73b526f2004-10-31 18:48:21 +00003157 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00003158 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003159 break;
jsgf855d93d2003-10-13 22:26:55 +00003160
muellera4b153a2003-11-19 22:07:14 +00003161 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003162 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00003163 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003164 break;
muellera4b153a2003-11-19 22:07:14 +00003165 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003166 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00003167 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
3168 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
3169 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003170 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003171 break;
3172
3173 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003174 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00003175 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00003176 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3177 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003178 break;
nethercote73b526f2004-10-31 18:48:21 +00003179 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00003180 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003181 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3182 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003183 break;
nethercote73b526f2004-10-31 18:48:21 +00003184 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003185 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003186 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3187 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003188 break;
nethercote73b526f2004-10-31 18:48:21 +00003189 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003190 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003191 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3192 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003193 break;
nethercote73b526f2004-10-31 18:48:21 +00003194 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003195 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00003196 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3197 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003198 break;
nethercote73b526f2004-10-31 18:48:21 +00003199 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003200 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00003201 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3202 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003203 break;
nethercote73b526f2004-10-31 18:48:21 +00003204 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00003205 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003206 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3207 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003208 break;
nethercote73b526f2004-10-31 18:48:21 +00003209 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003210 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003211 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3212 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003213 break;
nethercote73b526f2004-10-31 18:48:21 +00003214 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003215 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003216 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3217 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003218 break;
nethercote73b526f2004-10-31 18:48:21 +00003219 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003220 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00003221 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3222 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003223 break;
nethercote73b526f2004-10-31 18:48:21 +00003224 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003225 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00003226 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3227 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003228 break;
nethercote73b526f2004-10-31 18:48:21 +00003229 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003230 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
njn22cfccb2004-11-27 16:10:23 +00003231 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3232 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
3233 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003234 break;
nethercote73b526f2004-10-31 18:48:21 +00003235 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003236 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00003237 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3238 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003239 break;
nethercote73b526f2004-10-31 18:48:21 +00003240 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003241 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003242 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003243 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003244 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3245 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003246 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003247 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3248 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
3249 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003250 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003251 break;
nethercote73b526f2004-10-31 18:48:21 +00003252 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003253 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003254 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3255 KERNEL_DO_SYSCALL(tid,RES);
3256 if (!VG_(is_kerror)(RES) && RES == 0)
3257 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003258 */
njn22cfccb2004-11-27 16:10:23 +00003259 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct vki_ifconf));
3260 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00003261 // TODO len must be readable and writable
3262 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00003263 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003264 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003265 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003266 }
3267 break;
nethercote73b526f2004-10-31 18:48:21 +00003268 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003269 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003270 break;
3271 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3272 the number of bytes currently in that socket's send buffer.
3273 It writes this value as an int to the memory location
3274 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003275 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003276 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003277 break;
nethercote73b526f2004-10-31 18:48:21 +00003278 case VKI_SIOCGRARP: /* get RARP table entry */
3279 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003280 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003281 break;
3282
nethercote73b526f2004-10-31 18:48:21 +00003283 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003284 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003285 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003286 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003287 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3288 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003289 break;
nethercote73b526f2004-10-31 18:48:21 +00003290 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003291 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003292 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003293 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003294 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3295 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003296 break;
nethercote73b526f2004-10-31 18:48:21 +00003297 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003298 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
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(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003301 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3302 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003303 break;
nethercote73b526f2004-10-31 18:48:21 +00003304 case VKI_SIOCSIFADDR: /* set PA address */
3305 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3306 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3307 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003308 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003309 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003310 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003311 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3312 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003313 break;
nethercote73b526f2004-10-31 18:48:21 +00003314 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003315 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003316 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003317 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003318 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3319 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003320 break;
nethercote73b526f2004-10-31 18:48:21 +00003321 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003322 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003323 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003324 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003325 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3326 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003327 break;
nethercote73b526f2004-10-31 18:48:21 +00003328 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003329 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003330 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003331 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003332 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3333 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003334 break;
nethercote73b526f2004-10-31 18:48:21 +00003335 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003336 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003337 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003338 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003339 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3340 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003341 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003342 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3343 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003344 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003345 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
3346 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003347 break;
jsgf855d93d2003-10-13 22:26:55 +00003348 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003349 case VKI_SIOCADDRT: /* add routing table entry */
3350 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00003351 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00003352 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003353 break;
3354
3355 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003356 case VKI_SIOCDRARP: /* delete RARP table entry */
3357 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003358 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003359 case VKI_SIOCSARP: /* set ARP table entry */
3360 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003361 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003362 break;
3363
nethercote73b526f2004-10-31 18:48:21 +00003364 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003365 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003366 break;
nethercote73b526f2004-10-31 18:48:21 +00003367 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003368 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardjb5f6f512005-03-10 23:59:00 +00003369 //tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003370 break;
3371
3372 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003373 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3374 case VKI_SNDCTL_SEQ_GETINCOUNT:
3375 case VKI_SNDCTL_SEQ_PERCMODE:
3376 case VKI_SNDCTL_SEQ_TESTMIDI:
3377 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3378 case VKI_SNDCTL_SEQ_NRSYNTHS:
3379 case VKI_SNDCTL_SEQ_NRMIDIS:
3380 case VKI_SNDCTL_SEQ_GETTIME:
3381 case VKI_SNDCTL_DSP_GETFMTS:
3382 case VKI_SNDCTL_DSP_GETTRIGGER:
3383 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003384 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003385 case VKI_SNDCTL_DSP_GETCAPS:
3386 case VKI_SOUND_PCM_READ_RATE:
3387 case VKI_SOUND_PCM_READ_CHANNELS:
3388 case VKI_SOUND_PCM_READ_BITS:
3389 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3390 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003391 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003392 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003393 break;
nethercote73b526f2004-10-31 18:48:21 +00003394 case VKI_SNDCTL_SEQ_CTRLRATE:
3395 case VKI_SNDCTL_DSP_SPEED:
3396 case VKI_SNDCTL_DSP_STEREO:
3397 case VKI_SNDCTL_DSP_GETBLKSIZE:
3398 case VKI_SNDCTL_DSP_CHANNELS:
3399 case VKI_SOUND_PCM_WRITE_FILTER:
3400 case VKI_SNDCTL_DSP_SUBDIVIDE:
3401 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003402 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003403 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003404 case VKI_SNDCTL_TMR_TIMEBASE:
3405 case VKI_SNDCTL_TMR_TEMPO:
3406 case VKI_SNDCTL_TMR_SOURCE:
3407 case VKI_SNDCTL_MIDI_PRETIME:
3408 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003409 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003410 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003411 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003412 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003413 break;
nethercote73b526f2004-10-31 18:48:21 +00003414 case VKI_SNDCTL_DSP_GETOSPACE:
3415 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003416 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003417 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003418 break;
nethercote73b526f2004-10-31 18:48:21 +00003419 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003420 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003421 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003422 break;
3423
nethercote73b526f2004-10-31 18:48:21 +00003424 case VKI_SNDCTL_DSP_POST:
3425 case VKI_SNDCTL_DSP_RESET:
3426 case VKI_SNDCTL_DSP_SYNC:
3427 case VKI_SNDCTL_DSP_SETSYNCRO:
3428 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003429 break;
3430
3431 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003432 case VKI_RTC_UIE_ON:
3433 case VKI_RTC_UIE_OFF:
3434 case VKI_RTC_AIE_ON:
3435 case VKI_RTC_AIE_OFF:
3436 case VKI_RTC_PIE_ON:
3437 case VKI_RTC_PIE_OFF:
3438 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003439 break;
nethercote73b526f2004-10-31 18:48:21 +00003440 case VKI_RTC_RD_TIME:
3441 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003442 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003443 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003444 break;
nethercote73b526f2004-10-31 18:48:21 +00003445 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003446 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003447 break;
nethercote73b526f2004-10-31 18:48:21 +00003448 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003449 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003450 break;
jsgf855d93d2003-10-13 22:26:55 +00003451
nethercote95a97862004-11-06 16:31:43 +00003452 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003453 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003454 break;
jsgf855d93d2003-10-13 22:26:55 +00003455
thughesacbbc322004-06-19 12:12:01 +00003456 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003457 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003458 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003459 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003460 break;
3461
jsgf855d93d2003-10-13 22:26:55 +00003462 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003463 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003464 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003465 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003466 break;
nethercote73b526f2004-10-31 18:48:21 +00003467 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003468 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003469 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003470 break;
nethercote73b526f2004-10-31 18:48:21 +00003471 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003472 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003473 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3474 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3475 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003476 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003477 break;
nethercote73b526f2004-10-31 18:48:21 +00003478 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003479 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003480 break;
nethercote73b526f2004-10-31 18:48:21 +00003481 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003482 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003483 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003484 break;
nethercote73b526f2004-10-31 18:48:21 +00003485 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003486 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003487 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3488 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003489 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003490 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3491 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3492 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003493 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003494 break;
nethercote73b526f2004-10-31 18:48:21 +00003495 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003496 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003497 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003498 break;
nethercote73b526f2004-10-31 18:48:21 +00003499 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003500 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003501 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003502 break;
nethercote73b526f2004-10-31 18:48:21 +00003503 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003504 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003505 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003506 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003507 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003508 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003509 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3510 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003511 }
3512 break;
nethercote73b526f2004-10-31 18:48:21 +00003513 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003514 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003515 break;
3516 /* The following two are probably bogus (should check args
3517 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003518 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3519 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003520 break;
thughes66d80092004-06-19 12:41:05 +00003521
nethercote73b526f2004-10-31 18:48:21 +00003522 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003523 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003524 break;
nethercote73b526f2004-10-31 18:48:21 +00003525 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003526 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003527 break;
3528
nethercote73b526f2004-10-31 18:48:21 +00003529 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003530 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003531 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003532 break;
nethercote73b526f2004-10-31 18:48:21 +00003533 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003534 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003535 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003536 break;
jsgf855d93d2003-10-13 22:26:55 +00003537
nethercote73b526f2004-10-31 18:48:21 +00003538 case VKI_PPCLAIM:
3539 case VKI_PPEXCL:
3540 case VKI_PPYIELD:
3541 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003542 break;
nethercote73b526f2004-10-31 18:48:21 +00003543 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003544 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003545 break;
nethercote73b526f2004-10-31 18:48:21 +00003546 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003547 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003548 break;
nethercote73b526f2004-10-31 18:48:21 +00003549 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003550 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003551 break;
nethercote73b526f2004-10-31 18:48:21 +00003552 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003553 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003554 break;
nethercote73b526f2004-10-31 18:48:21 +00003555 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003556 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003557 break;
nethercote73b526f2004-10-31 18:48:21 +00003558 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003559 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003560 break;
nethercote73b526f2004-10-31 18:48:21 +00003561 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003562 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003563 break;
nethercote73b526f2004-10-31 18:48:21 +00003564 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003565 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003566 break;
nethercote73b526f2004-10-31 18:48:21 +00003567 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003568 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003569 break;
nethercote73b526f2004-10-31 18:48:21 +00003570 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003571 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003572 break;
nethercote73b526f2004-10-31 18:48:21 +00003573 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003574 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003575 break;
nethercote73b526f2004-10-31 18:48:21 +00003576 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003577 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003578 break;
nethercote73b526f2004-10-31 18:48:21 +00003579 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003580 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003581 break;
nethercote73b526f2004-10-31 18:48:21 +00003582 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003583 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003584 break;
nethercote73b526f2004-10-31 18:48:21 +00003585 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003586 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003587 break;
nethercote73b526f2004-10-31 18:48:21 +00003588 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003589 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003590 break;
nethercote73b526f2004-10-31 18:48:21 +00003591 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003592 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003593 break;
nethercote73b526f2004-10-31 18:48:21 +00003594 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003595 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003596 break;
nethercote73b526f2004-10-31 18:48:21 +00003597 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003598 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003599 break;
3600
thughesb3d3bcf2004-11-13 00:36:15 +00003601 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003602 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003603 break;
3604 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003605 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003606 break;
3607
3608 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003609 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3610 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003611 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003612 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003613 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3614 32 * cfd->charcount );
3615 }
3616 break;
3617 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003618 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3619 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003620 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003621 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003622 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3623 32 * cfd->charcount );
3624 }
3625 break;
3626
3627 case VKI_PIO_FONTRESET:
3628 break;
3629
3630 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003631 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003632 break;
3633 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003634 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003635 break;
3636
3637 case VKI_KIOCSOUND:
3638 case VKI_KDMKTONE:
3639 break;
3640
3641 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003642 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003643 break;
3644 case VKI_KDSETLED:
3645 break;
3646
3647 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003648 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003649 break;
3650
3651 case VKI_KDADDIO:
3652 case VKI_KDDELIO:
3653 case VKI_KDENABIO:
3654 case VKI_KDDISABIO:
3655 break;
3656
3657 case VKI_KDSETMODE:
3658 break;
3659 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003660 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003661 break;
3662
3663 case VKI_KDMAPDISP:
3664 case VKI_KDUNMAPDISP:
3665 break;
3666
3667 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003668 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003669 break;
3670 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003671 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003672 break;
3673 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003674 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003675 VKI_E_TABSZ * sizeof(unsigned short) );
3676 break;
3677 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003678 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003679 VKI_E_TABSZ * sizeof(unsigned short) );
3680 break;
3681
3682 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003683 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003684 break;
3685 case VKI_KDSKBMODE:
3686 break;
3687
3688 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003689 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003690 break;
3691 case VKI_KDSKBMETA:
3692 break;
3693
3694 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003695 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003696 break;
3697 case VKI_KDSKBLED:
3698 break;
3699
3700 case VKI_KDGKBENT:
3701 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003702 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3703 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003704 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003705 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3706 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003707 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003708 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3709 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003710 break;
3711 case VKI_KDSKBENT:
3712 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003713 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3714 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003715 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003716 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3717 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003718 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003719 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3720 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003721 break;
3722
3723 case VKI_KDGKBSENT:
3724 PRE_MEM_READ( "ioctl(KDGKBSENT).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_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003728 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3729 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003730 break;
3731 case VKI_KDSKBSENT:
3732 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003733 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3734 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003735 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003736 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003737 break;
3738
3739 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003740 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003741 break;
3742 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003743 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003744 break;
3745
3746 case VKI_KDGETKEYCODE:
3747 PRE_MEM_READ( "ioctl(KDGETKEYCODE).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_WRITE( "ioctl(KDGETKEYCODE).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 case VKI_KDSETKEYCODE:
3755 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003756 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3757 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003758 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003759 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3760 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003761 break;
3762
3763 case VKI_KDSIGACCEPT:
3764 break;
3765
3766 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003767 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003768 break;
3769
jsgf855d93d2003-10-13 22:26:55 +00003770 /* We don't have any specific information on it, so
3771 try to do something reasonable based on direction and
3772 size bits. The encoding scheme is described in
3773 /usr/include/asm/ioctl.h.
3774
3775 According to Simon Hausmann, _IOC_READ means the kernel
3776 writes a value to the ioctl value passed from the user
3777 space and the other way around with _IOC_WRITE. */
3778 default: {
njn22cfccb2004-11-27 16:10:23 +00003779 UInt dir = _VKI_IOC_DIR(ARG2);
3780 UInt size = _VKI_IOC_SIZE(ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003781 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3782 /*
3783 * Be very lax about ioctl handling; the only
3784 * assumption is that the size is correct. Doesn't
3785 * require the full buffer to be initialized when
3786 * writing. Without this, using some device
3787 * drivers with a large number of strange ioctl
3788 * commands becomes very tiresome.
3789 */
nethercote73b526f2004-10-31 18:48:21 +00003790 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003791 static Int moans = 3;
3792 if (moans > 0) {
3793 moans--;
3794 VG_(message)(Vg_UserMsg,
3795 "Warning: noted but unhandled ioctl 0x%x"
3796 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00003797 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003798 VG_(message)(Vg_UserMsg,
3799 " This could cause spurious value errors"
3800 " to appear.");
3801 VG_(message)(Vg_UserMsg,
3802 " See README_MISSING_SYSCALL_OR_IOCTL for "
3803 "guidance on writing a proper wrapper." );
3804 }
3805 } else {
nethercote73b526f2004-10-31 18:48:21 +00003806 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003807 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00003808 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003809 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003810 }
3811 break;
3812 }
3813 }
3814}
3815
nethercote85a456f2004-11-16 17:31:56 +00003816POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003817{
njn22cfccb2004-11-27 16:10:23 +00003818 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003819 case VKI_TCSETS:
3820 case VKI_TCSETSW:
3821 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003822 break;
nethercote73b526f2004-10-31 18:48:21 +00003823 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003824 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003825 break;
nethercote73b526f2004-10-31 18:48:21 +00003826 case VKI_TCSETA:
3827 case VKI_TCSETAW:
3828 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003829 break;
nethercote73b526f2004-10-31 18:48:21 +00003830 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003831 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003832 break;
nethercote73b526f2004-10-31 18:48:21 +00003833 case VKI_TCSBRK:
3834 case VKI_TCXONC:
3835 case VKI_TCSBRKP:
3836 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003837 break;
nethercote73b526f2004-10-31 18:48:21 +00003838 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003839 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003840 break;
nethercote73b526f2004-10-31 18:48:21 +00003841 case VKI_TIOCSWINSZ:
3842 case VKI_TIOCMBIS:
3843 case VKI_TIOCMBIC:
3844 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003845 break;
nethercote73b526f2004-10-31 18:48:21 +00003846 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003847 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003848 break;
nethercote73b526f2004-10-31 18:48:21 +00003849 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003850 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003851 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003852 break;
nethercote73b526f2004-10-31 18:48:21 +00003853 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003854 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003855 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003856 break;
nethercote73b526f2004-10-31 18:48:21 +00003857 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003858 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003859 break;
nethercote73b526f2004-10-31 18:48:21 +00003860 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003861 break;
nethercote73b526f2004-10-31 18:48:21 +00003862 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003863 break;
nethercote73b526f2004-10-31 18:48:21 +00003864 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003865 break;
nethercote73b526f2004-10-31 18:48:21 +00003866 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003867 break;
nethercote73b526f2004-10-31 18:48:21 +00003868 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003869 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003870 break;
3871
nethercote73b526f2004-10-31 18:48:21 +00003872 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003873 break;
nethercote73b526f2004-10-31 18:48:21 +00003874 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003875 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003876 break;
nethercote73b526f2004-10-31 18:48:21 +00003877 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003878 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003879 break;
nethercote73b526f2004-10-31 18:48:21 +00003880 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003881 break;
nethercote73b526f2004-10-31 18:48:21 +00003882 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003883 break;
nethercote73b526f2004-10-31 18:48:21 +00003884 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003885 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003886 break;
nethercote73b526f2004-10-31 18:48:21 +00003887 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003888 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003889 break;
nethercote73b526f2004-10-31 18:48:21 +00003890 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003891 break;
nethercote73b526f2004-10-31 18:48:21 +00003892 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00003893 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003894 break;
nethercote73b526f2004-10-31 18:48:21 +00003895 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00003896 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003897 break;
jsgf855d93d2003-10-13 22:26:55 +00003898
muellera4b153a2003-11-19 22:07:14 +00003899 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003900 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003901 break;
muellera4b153a2003-11-19 22:07:14 +00003902 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00003903 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003904 break;
3905
3906 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003907 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00003908 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3909 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003910 break;
nethercote73b526f2004-10-31 18:48:21 +00003911 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00003912 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3913 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003914 break;
nethercote73b526f2004-10-31 18:48:21 +00003915 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00003916 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3917 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003918 break;
nethercote73b526f2004-10-31 18:48:21 +00003919 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00003920 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3921 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003922 break;
nethercote73b526f2004-10-31 18:48:21 +00003923 case VKI_SIOCGIFADDR: /* get PA address */
3924 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3925 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3926 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003927 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003928 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3929 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003930 break;
nethercote73b526f2004-10-31 18:48:21 +00003931 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003932 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003933 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3934 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003935 break;
nethercote73b526f2004-10-31 18:48:21 +00003936 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003937 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003938 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3939 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003940 break;
3941 break;
nethercote73b526f2004-10-31 18:48:21 +00003942 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003943 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003944 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3945 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003946 break;
nethercote73b526f2004-10-31 18:48:21 +00003947 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003948 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003949 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
3950 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003951 break;
nethercote73b526f2004-10-31 18:48:21 +00003952 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003953 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003954 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3955 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003956 break;
nethercote73b526f2004-10-31 18:48:21 +00003957 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003958 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003959 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
3960 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003961 break;
nethercote73b526f2004-10-31 18:48:21 +00003962 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003963 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003964 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3965 KERNEL_DO_SYSCALL(tid,RES);
3966 if (!VG_(is_kerror)(RES) && RES == 0)
3967 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003968 */
njn22cfccb2004-11-27 16:10:23 +00003969 if (RES == 0 && ARG3 ) {
3970 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00003971 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003972 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003973 }
3974 break;
nethercote73b526f2004-10-31 18:48:21 +00003975 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003976 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003977 break;
3978 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3979 the number of bytes currently in that socket's send buffer.
3980 It writes this value as an int to the memory location
3981 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003982 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003983 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003984 break;
nethercote73b526f2004-10-31 18:48:21 +00003985 case VKI_SIOCGRARP: /* get RARP table entry */
3986 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003987 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003988 break;
3989
nethercote73b526f2004-10-31 18:48:21 +00003990 case VKI_SIOCSIFFLAGS: /* set flags */
3991 case VKI_SIOCSIFMAP: /* Set device parameters */
3992 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3993 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3994 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3995 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3996 case VKI_SIOCSIFMETRIC: /* set metric */
3997 case VKI_SIOCSIFADDR: /* set PA address */
3998 case VKI_SIOCSIFMTU: /* set MTU size */
3999 case VKI_SIOCSIFHWADDR: /* set hardware address */
4000 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00004001 break;
4002 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00004003 case VKI_SIOCADDRT: /* add routing table entry */
4004 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00004005 break;
4006
4007 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004008 case VKI_SIOCDRARP: /* delete RARP table entry */
4009 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004010 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004011 case VKI_SIOCSARP: /* set ARP table entry */
4012 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004013 break;
4014
nethercote73b526f2004-10-31 18:48:21 +00004015 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00004016 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00004017 break;
nethercote73b526f2004-10-31 18:48:21 +00004018 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004019 break;
4020
4021 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00004022 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4023 case VKI_SNDCTL_SEQ_GETINCOUNT:
4024 case VKI_SNDCTL_SEQ_PERCMODE:
4025 case VKI_SNDCTL_SEQ_TESTMIDI:
4026 case VKI_SNDCTL_SEQ_RESETSAMPLES:
4027 case VKI_SNDCTL_SEQ_NRSYNTHS:
4028 case VKI_SNDCTL_SEQ_NRMIDIS:
4029 case VKI_SNDCTL_SEQ_GETTIME:
4030 case VKI_SNDCTL_DSP_GETFMTS:
4031 case VKI_SNDCTL_DSP_GETTRIGGER:
4032 case VKI_SNDCTL_DSP_GETODELAY:
4033 case VKI_SNDCTL_DSP_GETSPDIF:
4034 case VKI_SNDCTL_DSP_GETCAPS:
4035 case VKI_SOUND_PCM_READ_RATE:
4036 case VKI_SOUND_PCM_READ_CHANNELS:
4037 case VKI_SOUND_PCM_READ_BITS:
4038 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
4039 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00004040 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004041 break;
nethercote73b526f2004-10-31 18:48:21 +00004042 case VKI_SNDCTL_SEQ_CTRLRATE:
4043 case VKI_SNDCTL_DSP_SPEED:
4044 case VKI_SNDCTL_DSP_STEREO:
4045 case VKI_SNDCTL_DSP_GETBLKSIZE:
4046 case VKI_SNDCTL_DSP_CHANNELS:
4047 case VKI_SOUND_PCM_WRITE_FILTER:
4048 case VKI_SNDCTL_DSP_SUBDIVIDE:
4049 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00004050 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00004051 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00004052 case VKI_SNDCTL_TMR_TIMEBASE:
4053 case VKI_SNDCTL_TMR_TEMPO:
4054 case VKI_SNDCTL_TMR_SOURCE:
4055 case VKI_SNDCTL_MIDI_PRETIME:
4056 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00004057 break;
nethercote73b526f2004-10-31 18:48:21 +00004058 case VKI_SNDCTL_DSP_GETOSPACE:
4059 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00004060 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00004061 break;
nethercote73b526f2004-10-31 18:48:21 +00004062 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00004063 break;
4064
nethercote73b526f2004-10-31 18:48:21 +00004065 case VKI_SNDCTL_DSP_POST:
4066 case VKI_SNDCTL_DSP_RESET:
4067 case VKI_SNDCTL_DSP_SYNC:
4068 case VKI_SNDCTL_DSP_SETSYNCRO:
4069 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00004070 break;
4071
4072 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00004073 case VKI_RTC_UIE_ON:
4074 case VKI_RTC_UIE_OFF:
4075 case VKI_RTC_AIE_ON:
4076 case VKI_RTC_AIE_OFF:
4077 case VKI_RTC_PIE_ON:
4078 case VKI_RTC_PIE_OFF:
4079 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00004080 break;
nethercote73b526f2004-10-31 18:48:21 +00004081 case VKI_RTC_RD_TIME:
4082 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00004083 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00004084 break;
nethercote73b526f2004-10-31 18:48:21 +00004085 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00004086 break;
nethercote73b526f2004-10-31 18:48:21 +00004087 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00004088 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004089 break;
jsgf855d93d2003-10-13 22:26:55 +00004090
nethercote95a97862004-11-06 16:31:43 +00004091 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00004092 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004093 break;
jsgf855d93d2003-10-13 22:26:55 +00004094
thughesacbbc322004-06-19 12:12:01 +00004095 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00004096 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00004097 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00004098 break;
4099
jsgf855d93d2003-10-13 22:26:55 +00004100 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00004101 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00004102 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00004103 break;
nethercote73b526f2004-10-31 18:48:21 +00004104 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00004105 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004106 break;
nethercote73b526f2004-10-31 18:48:21 +00004107 case VKI_CDROMREADTOCENTRY:
njn22cfccb2004-11-27 16:10:23 +00004108 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004109 break;
nethercote73b526f2004-10-31 18:48:21 +00004110 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00004111 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00004112 break;
nethercote73b526f2004-10-31 18:48:21 +00004113 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00004114 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00004115 break;
nethercote73b526f2004-10-31 18:48:21 +00004116 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00004117 {
njn22cfccb2004-11-27 16:10:23 +00004118 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00004119 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00004120 break;
4121 }
4122
nethercote73b526f2004-10-31 18:48:21 +00004123 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00004124 break;
4125 /* The following two are probably bogus (should check args
4126 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00004127 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4128 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00004129 break;
4130
nethercote73b526f2004-10-31 18:48:21 +00004131 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00004132 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004133 break;
nethercote73b526f2004-10-31 18:48:21 +00004134 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00004135 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004136 break;
4137
nethercote73b526f2004-10-31 18:48:21 +00004138 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00004139 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004140 break;
nethercote73b526f2004-10-31 18:48:21 +00004141 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00004142 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004143 break;
4144
nethercote73b526f2004-10-31 18:48:21 +00004145 case VKI_PPCLAIM:
4146 case VKI_PPEXCL:
4147 case VKI_PPYIELD:
4148 case VKI_PPRELEASE:
4149 case VKI_PPSETMODE:
4150 case VKI_PPSETPHASE:
4151 case VKI_PPSETFLAGS:
4152 case VKI_PPWDATA:
4153 case VKI_PPWCONTROL:
4154 case VKI_PPFCONTROL:
4155 case VKI_PPDATADIR:
4156 case VKI_PPNEGOT:
4157 case VKI_PPWCTLONIRQ:
4158 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00004159 break;
nethercote73b526f2004-10-31 18:48:21 +00004160 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004161 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004162 break;
nethercote73b526f2004-10-31 18:48:21 +00004163 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00004164 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004165 break;
nethercote73b526f2004-10-31 18:48:21 +00004166 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00004167 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00004168 break;
nethercote73b526f2004-10-31 18:48:21 +00004169 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00004170 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004171 break;
nethercote73b526f2004-10-31 18:48:21 +00004172 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00004173 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004174 break;
nethercote73b526f2004-10-31 18:48:21 +00004175 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00004176 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004177 break;
nethercote73b526f2004-10-31 18:48:21 +00004178 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00004179 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004180 break;
nethercote73b526f2004-10-31 18:48:21 +00004181 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00004182 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004183 break;
nethercote73b526f2004-10-31 18:48:21 +00004184 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00004185 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00004186 break;
4187
thughesc3b842d2004-11-13 10:38:04 +00004188 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00004189 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00004190 break;
4191 case VKI_PIO_FONT:
4192 break;
4193
4194 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00004195 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
4196 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00004197 break;
4198 case VKI_PIO_FONTX:
4199 break;
4200
4201 case VKI_PIO_FONTRESET:
4202 break;
4203
4204 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00004205 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00004206 break;
4207 case VKI_PIO_CMAP:
4208 break;
4209
4210 case VKI_KIOCSOUND:
4211 case VKI_KDMKTONE:
4212 break;
4213
4214 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00004215 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004216 break;
4217 case VKI_KDSETLED:
4218 break;
4219
4220 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00004221 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004222 break;
4223
4224 case VKI_KDADDIO:
4225 case VKI_KDDELIO:
4226 case VKI_KDENABIO:
4227 case VKI_KDDISABIO:
4228 break;
4229
4230 case VKI_KDSETMODE:
4231 break;
4232 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004233 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004234 break;
4235
4236 case VKI_KDMAPDISP:
4237 case VKI_KDUNMAPDISP:
4238 break;
4239
4240 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004241 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00004242 break;
4243 case VKI_PIO_SCRNMAP:
4244 break;
4245 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004246 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00004247 break;
4248 case VKI_PIO_UNISCRNMAP:
4249 break;
4250
4251 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00004252 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004253 break;
4254 case VKI_KDSKBMODE:
4255 break;
4256
4257 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00004258 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004259 break;
4260 case VKI_KDSKBMETA:
4261 break;
4262
4263 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00004264 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004265 break;
4266 case VKI_KDSKBLED:
4267 break;
4268
4269 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00004270 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
4271 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00004272 break;
4273 case VKI_KDSKBENT:
4274 break;
4275
4276 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00004277 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
4278 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00004279 break;
4280 case VKI_KDSKBSENT:
4281 break;
4282
4283 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00004284 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00004285 break;
4286 case VKI_KDSKBDIACR:
4287 break;
4288
4289 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00004290 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
4291 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00004292 break;
4293 case VKI_KDSETKEYCODE:
4294 break;
4295
4296 case VKI_KDSIGACCEPT:
4297 break;
4298
4299 case VKI_KDKBDREP:
4300 break;
4301
jsgf855d93d2003-10-13 22:26:55 +00004302 /* We don't have any specific information on it, so
4303 try to do something reasonable based on direction and
4304 size bits. The encoding scheme is described in
4305 /usr/include/asm/ioctl.h.
4306
4307 According to Simon Hausmann, _IOC_READ means the kernel
4308 writes a value to the ioctl value passed from the user
4309 space and the other way around with _IOC_WRITE. */
4310 default: {
njn22cfccb2004-11-27 16:10:23 +00004311 UInt dir = _VKI_IOC_DIR(ARG2);
4312 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00004313 if (size > 0 && (dir & _VKI_IOC_READ)
njn22cfccb2004-11-27 16:10:23 +00004314 && RES == 0
4315 && ARG3 != (Addr)NULL)
4316 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004317 break;
4318 }
4319 }
4320}
4321
nethercote85a456f2004-11-16 17:31:56 +00004322PRE(sys_kill, 0)
jsgf855d93d2003-10-13 22:26:55 +00004323{
4324 /* int kill(pid_t pid, int sig); */
njn22cfccb2004-11-27 16:10:23 +00004325 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004326 PRE_REG_READ2(long, "kill", int, pid, int, sig);
sewardjb5f6f512005-03-10 23:59:00 +00004327 if (!VG_(client_signal_OK)(ARG2))
njn22cfccb2004-11-27 16:10:23 +00004328 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004329}
4330
nethercote85a456f2004-11-16 17:31:56 +00004331POST(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004332{
sewardjb5f6f512005-03-10 23:59:00 +00004333 if (VG_(clo_trace_signals))
4334 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
4335 ARG2, ARG1);
4336 // Check to see if this kill gave us a pending signal
4337 VG_(poll_signals)(tid);
jsgf855d93d2003-10-13 22:26:55 +00004338}
4339
nethercote85a456f2004-11-16 17:31:56 +00004340PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004341{
njn22cfccb2004-11-27 16:10:23 +00004342 PRINT("sys_link ( %p, %p)", ARG1, ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004343 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004344 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4345 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004346}
4347
nethercote85a456f2004-11-16 17:31:56 +00004348PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00004349{
njn22cfccb2004-11-27 16:10:23 +00004350 PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00004351 PRE_REG_READ3(vki_off_t, "lseek",
4352 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004353}
4354
nethercote85a456f2004-11-16 17:31:56 +00004355PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004356{
njn22cfccb2004-11-27 16:10:23 +00004357 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004358 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00004359 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4360 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004361}
4362
nethercote85a456f2004-11-16 17:31:56 +00004363POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00004364{
njn22cfccb2004-11-27 16:10:23 +00004365 if (RES == 0) {
4366 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004367 }
4368}
4369
njnc6168192004-11-29 13:54:10 +00004370// XXX: this syscall is generic, but not necessarily applicable to every
4371// architecture -- I think only to 32-bit archs. We're going to need
4372// something like linux/core_os32.h for such things, eventually, I think.
4373// --njn
4374#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00004375PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004376{
njn22cfccb2004-11-27 16:10:23 +00004377 PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004378 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004379 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
4380 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004381}
4382
nethercote85a456f2004-11-16 17:31:56 +00004383POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004384{
njn22cfccb2004-11-27 16:10:23 +00004385 if (RES == 0) {
4386 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004387 }
4388}
njnc6168192004-11-29 13:54:10 +00004389#endif
jsgf855d93d2003-10-13 22:26:55 +00004390
nethercote85a456f2004-11-16 17:31:56 +00004391PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004392{
njn22cfccb2004-11-27 16:10:23 +00004393 PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004394 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004395 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004396}
4397
nethercote85a456f2004-11-16 17:31:56 +00004398PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004399{
nethercote151effa2004-11-15 12:57:39 +00004400 /* struct mmap_arg_struct {
4401 unsigned long addr;
4402 unsigned long len;
4403 unsigned long prot;
4404 unsigned long flags;
4405 unsigned long fd;
4406 unsigned long offset;
4407 }; */
jsgf855d93d2003-10-13 22:26:55 +00004408 UInt a1, a2, a3, a4, a5, a6;
4409
nethercote151effa2004-11-15 12:57:39 +00004410 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
njnf6d228b2005-03-26 02:42:31 +00004411 VGP_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004412
nethercote151effa2004-11-15 12:57:39 +00004413 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4414 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004415
sewardjb5f6f512005-03-10 23:59:00 +00004416 if (a2 == 0) {
4417 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4418 shall be established. */
4419 SET_RESULT( -VKI_EINVAL );
4420 return;
4421 }
4422
sewardj565b1ed2005-03-11 14:12:38 +00004423 if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
4424 /* zap any misaligned addresses. */
4425 SET_RESULT( -VKI_EINVAL );
4426 return;
4427 }
4428
fitzhardinge98abfc72003-12-16 02:05:15 +00004429 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004430 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004431 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
njn22cfccb2004-11-27 16:10:23 +00004432 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004433 }
4434 } else {
sewardjd0d97312005-03-23 02:53:13 +00004435 Addr a = VG_(find_map_space)(a1, a2, True);
4436 if (a == 0 && a1 != 0)
4437 a1 = VG_(find_map_space)(0, a2, True);
4438 else
4439 a1 = a;
fitzhardinge98abfc72003-12-16 02:05:15 +00004440 if (a1 == 0)
njn22cfccb2004-11-27 16:10:23 +00004441 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004442 else
nethercote151effa2004-11-15 12:57:39 +00004443 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004444 }
jsgf855d93d2003-10-13 22:26:55 +00004445
njn22cfccb2004-11-27 16:10:23 +00004446 if (RES != -VKI_ENOMEM) {
njnf6d228b2005-03-26 02:42:31 +00004447 VGP_DO_MMAP(RES, a1, a2, a3, a4, a5, a6);
sewardj004e8ca2005-02-28 17:27:04 +00004448 SET_RESULT(RES);
fitzhardingec2d65072004-01-07 08:44:43 +00004449
njn22cfccb2004-11-27 16:10:23 +00004450 if (!VG_(is_kerror)(RES)) {
4451 vg_assert(VG_(valid_client_addr)(RES, a2, tid, "old_mmap"));
4452 mmap_segment( (Addr)RES, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004453 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004454 }
jsgf855d93d2003-10-13 22:26:55 +00004455}
4456
nethercote3d5e9102004-11-17 18:22:38 +00004457PRE(sys_mmap2, 0)
4458{
4459 // Exactly like old_mmap() except:
4460 // - all 6 args are passed in regs, rather than in a memory-block.
4461 // - the file offset is specified in pagesize units rather than bytes,
4462 // so that it can be used for files bigger than 2^32 bytes.
4463 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
njn22cfccb2004-11-27 16:10:23 +00004464 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
nethercote3d5e9102004-11-17 18:22:38 +00004465 PRE_REG_READ6(long, "mmap2",
4466 unsigned long, start, unsigned long, length,
4467 unsigned long, prot, unsigned long, flags,
4468 unsigned long, fd, unsigned long, offset);
4469
sewardjb5f6f512005-03-10 23:59:00 +00004470 if (ARG2 == 0) {
4471 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4472 shall be established. */
4473 SET_RESULT( -VKI_EINVAL );
4474 return;
4475 }
4476
sewardj565b1ed2005-03-11 14:12:38 +00004477 if (/*(ARG4 & VKI_MAP_FIXED) && */ (0 != (ARG1 & (VKI_PAGE_SIZE-1)))) {
4478 /* zap any misaligned addresses. */
sewardjd0d97312005-03-23 02:53:13 +00004479 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
4480 to fail. Here, we catch them all. */
sewardj565b1ed2005-03-11 14:12:38 +00004481 SET_RESULT( -VKI_EINVAL );
4482 return;
4483 }
4484
njn22cfccb2004-11-27 16:10:23 +00004485 if (ARG4 & VKI_MAP_FIXED) {
4486 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
4487 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004488 } else {
sewardjd0d97312005-03-23 02:53:13 +00004489 Addr a = VG_(find_map_space)(ARG1, ARG2, True);
4490 if (a == 0 && ARG1 != 0)
4491 ARG1 = VG_(find_map_space)(0, ARG2, True);
4492 else
4493 ARG1 = a;
njn22cfccb2004-11-27 16:10:23 +00004494 if (ARG1 == 0)
4495 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004496 else
njn22cfccb2004-11-27 16:10:23 +00004497 ARG4 |= VKI_MAP_FIXED;
nethercote3d5e9102004-11-17 18:22:38 +00004498 }
4499}
4500
4501POST(sys_mmap2)
4502{
njn22cfccb2004-11-27 16:10:23 +00004503 vg_assert(VG_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
4504 mmap_segment( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
4505 ARG6 * (ULong)VKI_PAGE_SIZE );
nethercote3d5e9102004-11-17 18:22:38 +00004506}
4507
nethercote85a456f2004-11-16 17:31:56 +00004508PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004509{
njn22cfccb2004-11-27 16:10:23 +00004510 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004511 PRE_REG_READ3(long, "mprotect",
4512 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004513
njn22cfccb2004-11-27 16:10:23 +00004514 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
4515 SET_RESULT( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004516}
4517
nethercote85a456f2004-11-16 17:31:56 +00004518POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004519{
njn22cfccb2004-11-27 16:10:23 +00004520 Addr a = ARG1;
4521 SizeT len = ARG2;
4522 Int prot = ARG3;
nethercote27ea8bc2004-07-10 17:21:14 +00004523 Bool rr = prot & VKI_PROT_READ;
4524 Bool ww = prot & VKI_PROT_WRITE;
4525 Bool xx = prot & VKI_PROT_EXEC;
4526
nethercote27ea8bc2004-07-10 17:21:14 +00004527 mash_addr_and_len(&a, &len);
4528 VG_(mprotect_range)(a, len, prot);
4529 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004530}
4531
nethercote85a456f2004-11-16 17:31:56 +00004532PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004533{
njn22cfccb2004-11-27 16:10:23 +00004534 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004535 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004536
njn22cfccb2004-11-27 16:10:23 +00004537 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4538 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004539}
4540
nethercote85a456f2004-11-16 17:31:56 +00004541POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004542{
njn22cfccb2004-11-27 16:10:23 +00004543 Addr a = ARG1;
4544 SizeT len = ARG2;
nethercote27ea8bc2004-07-10 17:21:14 +00004545
4546 mash_addr_and_len(&a, &len);
4547 VG_(unmap_range)(a, len);
4548 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004549}
4550
nethercote85a456f2004-11-16 17:31:56 +00004551PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004552{
njn22cfccb2004-11-27 16:10:23 +00004553 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00004554 PRE_REG_READ3(long, "mincore",
4555 unsigned long, start, vki_size_t, length,
4556 unsigned char *, vec);
njn22cfccb2004-11-27 16:10:23 +00004557 PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004558}
4559
nethercote85a456f2004-11-16 17:31:56 +00004560POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004561{
njn22cfccb2004-11-27 16:10:23 +00004562 POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004563}
4564
nethercote85a456f2004-11-16 17:31:56 +00004565PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004566{
njn22cfccb2004-11-27 16:10:23 +00004567 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004568 PRE_REG_READ2(long, "nanosleep",
4569 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004570 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4571 if (ARG2 != 0)
4572 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004573}
4574
nethercote85a456f2004-11-16 17:31:56 +00004575POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004576{
njn22cfccb2004-11-27 16:10:23 +00004577 if (ARG2 != 0 && RES == -VKI_EINTR)
4578 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004579}
4580
nethercote85a456f2004-11-16 17:31:56 +00004581PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004582{
njn22cfccb2004-11-27 16:10:23 +00004583 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004584 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004585 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004586 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004587 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004588 } else {
nethercotee824cc42004-11-09 16:20:46 +00004589 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004590 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004591 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004592 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004593 }
njn22cfccb2004-11-27 16:10:23 +00004594 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004595}
4596
nethercote85a456f2004-11-16 17:31:56 +00004597POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004598{
njn22cfccb2004-11-27 16:10:23 +00004599 if (!VG_(fd_allowed)(RES, "open", tid, True)) {
4600 VG_(close)(RES);
4601 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004602 } else {
nethercote493dd182004-02-24 23:57:47 +00004603 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004604 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004605 }
jsgf855d93d2003-10-13 22:26:55 +00004606}
4607
nethercote85a456f2004-11-16 17:31:56 +00004608PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004609{
njn22cfccb2004-11-27 16:10:23 +00004610 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004611 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004612 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004613
njn22cfccb2004-11-27 16:10:23 +00004614 if (!VG_(fd_allowed)(ARG1, "read", tid, False))
4615 SET_RESULT( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004616 else
njn22cfccb2004-11-27 16:10:23 +00004617 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004618}
4619
nethercote85a456f2004-11-16 17:31:56 +00004620POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004621{
njn22cfccb2004-11-27 16:10:23 +00004622 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004623}
4624
nethercote85a456f2004-11-16 17:31:56 +00004625PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004626{
njn22cfccb2004-11-27 16:10:23 +00004627 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004628 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004629 unsigned int, fd, const char *, buf, vki_size_t, count);
njn22cfccb2004-11-27 16:10:23 +00004630 if (!VG_(fd_allowed)(ARG1, "write", tid, False))
4631 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004632 else
njn22cfccb2004-11-27 16:10:23 +00004633 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004634}
4635
nethercote85a456f2004-11-16 17:31:56 +00004636PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004637{
njn22cfccb2004-11-27 16:10:23 +00004638 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004639 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004640 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004641}
4642
nethercote85a456f2004-11-16 17:31:56 +00004643POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004644{
njn22cfccb2004-11-27 16:10:23 +00004645 if (!VG_(fd_allowed)(RES, "creat", tid, True)) {
4646 VG_(close)(RES);
4647 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004648 } else {
nethercote493dd182004-02-24 23:57:47 +00004649 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004650 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004651 }
jsgf855d93d2003-10-13 22:26:55 +00004652}
4653
nethercote9a3beb92004-11-12 17:07:26 +00004654// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004655PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004656{
njn22cfccb2004-11-27 16:10:23 +00004657 PRINT("sys_pipe ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004658 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
njn22cfccb2004-11-27 16:10:23 +00004659 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004660}
4661
nethercote85a456f2004-11-16 17:31:56 +00004662POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004663{
njn22cfccb2004-11-27 16:10:23 +00004664 Int *p = (Int *)ARG1;
jsgf855d93d2003-10-13 22:26:55 +00004665
nethercote3d5e9102004-11-17 18:22:38 +00004666 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4667 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004668 VG_(close)(p[0]);
4669 VG_(close)(p[1]);
njn22cfccb2004-11-27 16:10:23 +00004670 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004671 } else {
njn22cfccb2004-11-27 16:10:23 +00004672 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004673 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004674 VG_(record_fd_open)(tid, p[0], NULL);
4675 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004676 }
4677 }
jsgf855d93d2003-10-13 22:26:55 +00004678}
4679
nethercotef90953e2004-11-15 14:50:02 +00004680// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004681PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004682{
4683 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004684 int fd; -- file descriptor
4685 short events; -- requested events
4686 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004687 };
nethercoteeb0592d2004-11-05 12:02:27 +00004688 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004689 */
nethercoteeb0592d2004-11-05 12:02:27 +00004690 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004691 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
4692 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00004693 PRE_REG_READ3(long, "poll",
4694 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004695
njn22cfccb2004-11-27 16:10:23 +00004696 for (i = 0; i < ARG2; i++) {
nethercoteeb0592d2004-11-05 12:02:27 +00004697 // 'fd' and 'events' field are inputs; 'revents' is output.
4698 // XXX: this is x86 specific -- the pollfd struct varies across
4699 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004700 PRE_MEM_READ( "poll(ufds)",
4701 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4702 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4703 }
jsgf855d93d2003-10-13 22:26:55 +00004704}
4705
nethercote85a456f2004-11-16 17:31:56 +00004706POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004707{
njn22cfccb2004-11-27 16:10:23 +00004708 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004709 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004710 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
nethercoteeb0592d2004-11-05 12:02:27 +00004711 // XXX: again, this is x86-specific
njn22cfccb2004-11-27 16:10:23 +00004712 for (i = 0; i < ARG2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004713 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004714 }
4715}
4716
rjwalsh17d85302004-11-18 22:56:09 +00004717PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004718{
rjwalsh093047d2004-11-19 02:11:56 +00004719 int saved = SYSNO;
njn22cfccb2004-11-27 16:10:23 +00004720 PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00004721 PRE_REG_READ3(long, "readlink",
4722 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00004723 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4724 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004725
rjwalsh17d85302004-11-18 22:56:09 +00004726 /*
rjwalsh093047d2004-11-19 02:11:56 +00004727 * Handle the case where readlink is looking at /proc/self/exe or
4728 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004729 */
4730
njnca6fef02004-11-29 16:49:18 +00004731 SET_RESULT( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
njn22cfccb2004-11-27 16:10:23 +00004732 if ((Int)RES == -2) {
rjwalsh093047d2004-11-19 02:11:56 +00004733 char name[25];
4734
4735 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004736
njn22cfccb2004-11-27 16:10:23 +00004737 if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
4738 VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
rjwalsh093047d2004-11-19 02:11:56 +00004739 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
njnca6fef02004-11-29 16:49:18 +00004740 SET_RESULT( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004741 }
rjwalsh17d85302004-11-18 22:56:09 +00004742 }
4743
njn22cfccb2004-11-27 16:10:23 +00004744 if ((Int)RES > 0)
4745 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004746}
4747
nethercote85a456f2004-11-16 17:31:56 +00004748PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004749{
jsgf855d93d2003-10-13 22:26:55 +00004750 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004751 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00004752 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00004753 PRE_REG_READ3(ssize_t, "readv",
4754 unsigned long, fd, const struct iovec *, vector,
4755 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00004756 if (!VG_(fd_allowed)(ARG1, "readv", tid, False)) {
4757 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004758 } else {
njn22cfccb2004-11-27 16:10:23 +00004759 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004760
njn22cfccb2004-11-27 16:10:23 +00004761 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004762 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00004763 vec = (struct vki_iovec *)ARG2;
4764 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00004765 PRE_MEM_WRITE( "readv(vector[...])",
4766 (Addr)vec[i].iov_base, vec[i].iov_len );
4767 }
jsgf855d93d2003-10-13 22:26:55 +00004768 }
4769}
4770
nethercote85a456f2004-11-16 17:31:56 +00004771POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004772{
njn22cfccb2004-11-27 16:10:23 +00004773 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004774 Int i;
njn22cfccb2004-11-27 16:10:23 +00004775 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4776 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00004777
njn22cfccb2004-11-27 16:10:23 +00004778 /* RES holds the number of bytes read. */
4779 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00004780 Int nReadThisBuf = vec[i].iov_len;
4781 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004782 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004783 remains -= nReadThisBuf;
4784 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4785 }
4786 }
4787}
4788
nethercote85a456f2004-11-16 17:31:56 +00004789PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004790{
njn22cfccb2004-11-27 16:10:23 +00004791 PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
nethercote9a3beb92004-11-12 17:07:26 +00004792 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004793 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4794 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004795}
4796
nethercote85a456f2004-11-16 17:31:56 +00004797PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004798{
njn22cfccb2004-11-27 16:10:23 +00004799 PRINT("sys_rmdir ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004800 PRE_REG_READ1(long, "rmdir", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00004801 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004802}
4803
nethercote85a456f2004-11-16 17:31:56 +00004804PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004805{
njn22cfccb2004-11-27 16:10:23 +00004806 PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004807 PRE_REG_READ2(long, "sched_setparam",
4808 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004809 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004810}
4811
nethercote85a456f2004-11-16 17:31:56 +00004812POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004813{
njn22cfccb2004-11-27 16:10:23 +00004814 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004815}
4816
nethercote85a456f2004-11-16 17:31:56 +00004817PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004818{
njn22cfccb2004-11-27 16:10:23 +00004819 PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004820 PRE_REG_READ2(long, "sched_getparam",
4821 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004822 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004823}
4824
nethercote85a456f2004-11-16 17:31:56 +00004825POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004826{
njn22cfccb2004-11-27 16:10:23 +00004827 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004828}
4829
nethercote85a456f2004-11-16 17:31:56 +00004830PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004831{
njn22cfccb2004-11-27 16:10:23 +00004832 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00004833 PRE_REG_READ5(long, "select",
4834 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4835 vki_fd_set *, exceptfds, struct timeval *, timeout);
4836 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00004837 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004838 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00004839 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4840 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004841 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00004842 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4843 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004844 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00004845 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4846 if (ARG5 != 0)
4847 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00004848}
4849
nethercote85a456f2004-11-16 17:31:56 +00004850PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004851{
njn22cfccb2004-11-27 16:10:23 +00004852 PRINT("sys_setgid16 ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004853 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4854}
4855
nethercote85a456f2004-11-16 17:31:56 +00004856PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004857{
njn22cfccb2004-11-27 16:10:23 +00004858 PRINT("sys_setgid ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004859 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004860}
4861
nethercote85a456f2004-11-16 17:31:56 +00004862PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004863{
nethercote0df495a2004-11-11 16:38:21 +00004864 PRINT("sys_setsid ( )");
4865 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004866}
4867
nethercote85a456f2004-11-16 17:31:56 +00004868PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004869{
njn22cfccb2004-11-27 16:10:23 +00004870 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004871 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004872 if (ARG1 > 0)
4873 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00004874}
4875
nethercote85a456f2004-11-16 17:31:56 +00004876PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004877{
njn22cfccb2004-11-27 16:10:23 +00004878 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004879 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004880 if (ARG1 > 0)
4881 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004882}
4883
nethercote85a456f2004-11-16 17:31:56 +00004884PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004885{
njn22cfccb2004-11-27 16:10:23 +00004886 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
nethercote9c311eb2004-11-12 18:20:12 +00004887 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004888}
4889
nethercote85a456f2004-11-16 17:31:56 +00004890PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004891{
njn22cfccb2004-11-27 16:10:23 +00004892 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004893 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004894}
4895
nethercote85a456f2004-11-16 17:31:56 +00004896PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004897{
njn22cfccb2004-11-27 16:10:23 +00004898 PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004899 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4900}
4901
nethercote85a456f2004-11-16 17:31:56 +00004902PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004903{
njn22cfccb2004-11-27 16:10:23 +00004904 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004905 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004906}
4907
nethercote85a456f2004-11-16 17:31:56 +00004908PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004909{
njn22cfccb2004-11-27 16:10:23 +00004910 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004911 PRE_REG_READ2(long, "setrlimit",
4912 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00004913 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004914
njn22cfccb2004-11-27 16:10:23 +00004915 if (ARG1 == VKI_RLIMIT_NOFILE) {
4916 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4917 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4918 SET_RESULT( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004919 }
4920 else {
njn22cfccb2004-11-27 16:10:23 +00004921 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
4922 SET_RESULT( 0 );
thughesad1c9562004-06-26 11:27:52 +00004923 }
4924 }
njn22cfccb2004-11-27 16:10:23 +00004925 else if (ARG1 == VKI_RLIMIT_DATA) {
4926 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4927 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
4928 SET_RESULT( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004929 }
4930 else {
njn22cfccb2004-11-27 16:10:23 +00004931 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
4932 SET_RESULT( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004933 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004934 }
njn22cfccb2004-11-27 16:10:23 +00004935 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
4936 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4937 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
4938 SET_RESULT( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004939 }
4940 else {
njn22cfccb2004-11-27 16:10:23 +00004941 VG_(threads)[tid].stack_size = ((struct vki_rlimit *)ARG2)->rlim_cur;
4942 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
4943 SET_RESULT( 0 );
thughesc37184f2004-09-11 14:16:57 +00004944 }
4945 }
jsgf855d93d2003-10-13 22:26:55 +00004946}
4947
nethercote85a456f2004-11-16 17:31:56 +00004948PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004949{
njn22cfccb2004-11-27 16:10:23 +00004950 PRINT("sys_setuid16 ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004951 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004952}
4953
nethercote85a456f2004-11-16 17:31:56 +00004954PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00004955{
njn22cfccb2004-11-27 16:10:23 +00004956 PRINT("sys_setuid ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004957 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4958}
jsgf855d93d2003-10-13 22:26:55 +00004959
nethercote85a456f2004-11-16 17:31:56 +00004960PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004961{
sewardj9efbbef2005-03-01 16:45:23 +00004962# define ARG2_0 (((UWord*)ARG2)[0])
4963# define ARG2_1 (((UWord*)ARG2)[1])
4964# define ARG2_2 (((UWord*)ARG2)[2])
4965# define ARG2_3 (((UWord*)ARG2)[3])
4966# define ARG2_4 (((UWord*)ARG2)[4])
4967# define ARG2_5 (((UWord*)ARG2)[5])
4968
njn22cfccb2004-11-27 16:10:23 +00004969 PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00004970 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4971
njn22cfccb2004-11-27 16:10:23 +00004972 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00004973
nethercote73b526f2004-10-31 18:48:21 +00004974 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00004975 /* int socketpair(int d, int type, int protocol, int sv[2]); */
njn22cfccb2004-11-27 16:10:23 +00004976 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004977 VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00004978 break;
4979
nethercote73b526f2004-10-31 18:48:21 +00004980 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00004981 /* int socket(int domain, int type, int protocol); */
njn22cfccb2004-11-27 16:10:23 +00004982 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004983 break;
4984
nethercote73b526f2004-10-31 18:48:21 +00004985 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004986 /* int bind(int sockfd, struct sockaddr *my_addr,
4987 int addrlen); */
njn22cfccb2004-11-27 16:10:23 +00004988 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004989 VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004990 break;
4991
nethercote73b526f2004-10-31 18:48:21 +00004992 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004993 /* int listen(int s, int backlog); */
njn22cfccb2004-11-27 16:10:23 +00004994 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004995 break;
4996
nethercote73b526f2004-10-31 18:48:21 +00004997 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004998 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
njn22cfccb2004-11-27 16:10:23 +00004999 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005000 VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005001 break;
5002 }
5003
nethercote73b526f2004-10-31 18:48:21 +00005004 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00005005 /* int sendto(int s, const void *msg, int len,
sewardj9efbbef2005-03-01 16:45:23 +00005006 unsigned int flags,
5007 const struct sockaddr *to, int tolen); */
njn22cfccb2004-11-27 16:10:23 +00005008 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005009 VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005010 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005011 break;
5012
nethercote73b526f2004-10-31 18:48:21 +00005013 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00005014 /* int send(int s, const void *msg, size_t len, int flags); */
njn22cfccb2004-11-27 16:10:23 +00005015 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005016 VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005017 break;
5018
nethercote73b526f2004-10-31 18:48:21 +00005019 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00005020 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5021 struct sockaddr *from, int *fromlen); */
njn22cfccb2004-11-27 16:10:23 +00005022 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005023 VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005024 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005025 break;
5026
nethercote73b526f2004-10-31 18:48:21 +00005027 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00005028 /* int recv(int s, void *buf, int len, unsigned int flags); */
5029 /* man 2 recv says:
5030 The recv call is normally used only on a connected socket
5031 (see connect(2)) and is identical to recvfrom with a NULL
5032 from parameter.
5033 */
njn22cfccb2004-11-27 16:10:23 +00005034 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005035 VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005036 break;
5037
nethercote73b526f2004-10-31 18:48:21 +00005038 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00005039 /* int connect(int sockfd,
sewardj9efbbef2005-03-01 16:45:23 +00005040 struct sockaddr *serv_addr, int addrlen ); */
njn22cfccb2004-11-27 16:10:23 +00005041 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005042 VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005043 break;
5044
nethercote73b526f2004-10-31 18:48:21 +00005045 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005046 /* int setsockopt(int s, int level, int optname,
sewardj9efbbef2005-03-01 16:45:23 +00005047 const void *optval, int optlen); */
njn22cfccb2004-11-27 16:10:23 +00005048 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005049 VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005050 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005051 break;
5052
nethercote73b526f2004-10-31 18:48:21 +00005053 case VKI_SYS_GETSOCKOPT:
sewardj9efbbef2005-03-01 16:45:23 +00005054 /* int getsockopt(int s, int level, int optname,
5055 void *optval, socklen_t *optlen); */
njn22cfccb2004-11-27 16:10:23 +00005056 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005057 VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005058 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005059 break;
5060
nethercote73b526f2004-10-31 18:48:21 +00005061 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00005062 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00005063 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005064 VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005065 break;
5066
nethercote73b526f2004-10-31 18:48:21 +00005067 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00005068 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00005069 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005070 VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005071 break;
5072
nethercote73b526f2004-10-31 18:48:21 +00005073 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00005074 /* int shutdown(int s, int how); */
njn22cfccb2004-11-27 16:10:23 +00005075 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005076 break;
5077
nethercote73b526f2004-10-31 18:48:21 +00005078 case VKI_SYS_SENDMSG: {
jsgf855d93d2003-10-13 22:26:55 +00005079 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5080
5081 /* this causes warnings, and I don't get why. glibc bug?
5082 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00005083 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005084 */
sewardj987a8eb2005-03-01 19:00:30 +00005085 VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00005086 break;
5087 }
5088
nethercote73b526f2004-10-31 18:48:21 +00005089 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00005090 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5091
5092 /* this causes warnings, and I don't get why. glibc bug?
5093 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00005094 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005095 */
sewardj987a8eb2005-03-01 19:00:30 +00005096 VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00005097 break;
5098 }
5099
5100 default:
njn22cfccb2004-11-27 16:10:23 +00005101 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
5102 SET_RESULT( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00005103 break;
jsgf855d93d2003-10-13 22:26:55 +00005104 }
sewardj9efbbef2005-03-01 16:45:23 +00005105# undef ARG2_0
5106# undef ARG2_1
5107# undef ARG2_2
5108# undef ARG2_3
5109# undef ARG2_4
5110# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00005111}
5112
nethercote85a456f2004-11-16 17:31:56 +00005113POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00005114{
sewardj9efbbef2005-03-01 16:45:23 +00005115# define ARG2_0 (((UWord*)ARG2)[0])
5116# define ARG2_1 (((UWord*)ARG2)[1])
5117# define ARG2_2 (((UWord*)ARG2)[2])
5118# define ARG2_3 (((UWord*)ARG2)[3])
5119# define ARG2_4 (((UWord*)ARG2)[4])
5120# define ARG2_5 (((UWord*)ARG2)[5])
5121
5122 UWord r;
njn22cfccb2004-11-27 16:10:23 +00005123 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00005124
sewardj9efbbef2005-03-01 16:45:23 +00005125 case VKI_SYS_SOCKETPAIR:
sewardj987a8eb2005-03-01 19:00:30 +00005126 VG_(generic_POST_sys_socketpair)( tid, RES, ARG2_0,
sewardj9efbbef2005-03-01 16:45:23 +00005127 ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00005128 break;
5129
nethercote73b526f2004-10-31 18:48:21 +00005130 case VKI_SYS_SOCKET:
sewardj987a8eb2005-03-01 19:00:30 +00005131 r = VG_(generic_POST_sys_socket)( tid, RES );
sewardj9efbbef2005-03-01 16:45:23 +00005132 SET_RESULT(r);
5133 break;
jsgf855d93d2003-10-13 22:26:55 +00005134
nethercote73b526f2004-10-31 18:48:21 +00005135 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00005136 /* int bind(int sockfd, struct sockaddr *my_addr,
5137 int addrlen); */
5138 break;
5139
nethercote73b526f2004-10-31 18:48:21 +00005140 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00005141 /* int listen(int s, int backlog); */
5142 break;
5143
sewardj9efbbef2005-03-01 16:45:23 +00005144 case VKI_SYS_ACCEPT:
jsgf855d93d2003-10-13 22:26:55 +00005145 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
sewardj987a8eb2005-03-01 19:00:30 +00005146 r = VG_(generic_POST_sys_accept)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
sewardj9efbbef2005-03-01 16:45:23 +00005147 SET_RESULT(r);
5148 break;
jsgf855d93d2003-10-13 22:26:55 +00005149
nethercote73b526f2004-10-31 18:48:21 +00005150 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00005151 break;
5152
nethercote73b526f2004-10-31 18:48:21 +00005153 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00005154 break;
5155
nethercote73b526f2004-10-31 18:48:21 +00005156 case VKI_SYS_RECVFROM:
sewardj987a8eb2005-03-01 19:00:30 +00005157 VG_(generic_POST_sys_recvfrom)( tid, RES, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005158 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005159 break;
5160
nethercote73b526f2004-10-31 18:48:21 +00005161 case VKI_SYS_RECV:
sewardj987a8eb2005-03-01 19:00:30 +00005162 VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005163 break;
5164
nethercote73b526f2004-10-31 18:48:21 +00005165 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00005166 break;
5167
nethercote73b526f2004-10-31 18:48:21 +00005168 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005169 break;
5170
nethercote73b526f2004-10-31 18:48:21 +00005171 case VKI_SYS_GETSOCKOPT:
sewardj987a8eb2005-03-01 19:00:30 +00005172 VG_(generic_POST_sys_getsockopt)( tid, RES, ARG2_0, ARG2_1,
sewardj9efbbef2005-03-01 16:45:23 +00005173 ARG2_2, ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005174 break;
5175
nethercote73b526f2004-10-31 18:48:21 +00005176 case VKI_SYS_GETSOCKNAME:
sewardj987a8eb2005-03-01 19:00:30 +00005177 VG_(generic_POST_sys_getsockname)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005178 break;
5179
nethercote73b526f2004-10-31 18:48:21 +00005180 case VKI_SYS_GETPEERNAME:
sewardj987a8eb2005-03-01 19:00:30 +00005181 VG_(generic_POST_sys_getpeername)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005182 break;
5183
nethercote73b526f2004-10-31 18:48:21 +00005184 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00005185 break;
5186
nethercote73b526f2004-10-31 18:48:21 +00005187 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00005188 break;
5189
nethercote73b526f2004-10-31 18:48:21 +00005190 case VKI_SYS_RECVMSG:
sewardj987a8eb2005-03-01 19:00:30 +00005191 VG_(generic_POST_sys_recvmsg)( tid, RES, ARG2_0, ARG2_1 );
sewardj9efbbef2005-03-01 16:45:23 +00005192 break;
jsgf855d93d2003-10-13 22:26:55 +00005193
5194 default:
njn22cfccb2004-11-27 16:10:23 +00005195 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
jsgf855d93d2003-10-13 22:26:55 +00005196 VG_(core_panic)("... bye!\n");
5197 break; /*NOTREACHED*/
5198 }
sewardj9efbbef2005-03-01 16:45:23 +00005199# undef ARG2_0
5200# undef ARG2_1
5201# undef ARG2_2
5202# undef ARG2_3
5203# undef ARG2_4
5204# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00005205}
5206
nethercote85a456f2004-11-16 17:31:56 +00005207PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00005208{
njn22cfccb2004-11-27 16:10:23 +00005209 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005210 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00005211 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
5212 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005213}
5214
nethercote85a456f2004-11-16 17:31:56 +00005215POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00005216{
njn22cfccb2004-11-27 16:10:23 +00005217 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005218}
5219
nethercote85a456f2004-11-16 17:31:56 +00005220PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00005221{
njn22cfccb2004-11-27 16:10:23 +00005222 PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00005223 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00005224 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
5225 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00005226}
5227
nethercote85a456f2004-11-16 17:31:56 +00005228POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00005229{
njn22cfccb2004-11-27 16:10:23 +00005230 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00005231}
5232
nethercote85a456f2004-11-16 17:31:56 +00005233PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00005234{
njn22cfccb2004-11-27 16:10:23 +00005235 PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00005236 PRE_REG_READ3(long, "statfs64",
5237 const char *, path, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005238 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
5239 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00005240}
5241
nethercote85a456f2004-11-16 17:31:56 +00005242POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00005243{
njn22cfccb2004-11-27 16:10:23 +00005244 POST_MEM_WRITE( ARG3, ARG2 );
muellerd3502b62003-11-19 00:43:57 +00005245}
5246
nethercote85a456f2004-11-16 17:31:56 +00005247PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005248{
njn22cfccb2004-11-27 16:10:23 +00005249 PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00005250 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00005251 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
5252 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00005253}
5254
njnc6168192004-11-29 13:54:10 +00005255// See comment above PRE(sys_lstat64) for an explanation of this #ifdef.
5256#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00005257PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005258{
njn22cfccb2004-11-27 16:10:23 +00005259 PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005260 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005261 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
5262 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005263}
5264
nethercote85a456f2004-11-16 17:31:56 +00005265POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00005266{
njn22cfccb2004-11-27 16:10:23 +00005267 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005268}
5269
nethercote85a456f2004-11-16 17:31:56 +00005270PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005271{
njn22cfccb2004-11-27 16:10:23 +00005272 PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005273 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005274 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005275}
5276
nethercote85a456f2004-11-16 17:31:56 +00005277POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00005278{
njn22cfccb2004-11-27 16:10:23 +00005279 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005280}
njnc6168192004-11-29 13:54:10 +00005281#endif
jsgf855d93d2003-10-13 22:26:55 +00005282
nethercote85a456f2004-11-16 17:31:56 +00005283PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00005284{
5285 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00005286 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005287 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00005288 if (ARG1 != 0) {
5289 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005290 }
5291}
5292
nethercote85a456f2004-11-16 17:31:56 +00005293POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005294{
njn22cfccb2004-11-27 16:10:23 +00005295 if (ARG1 != 0) {
5296 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005297 }
5298}
5299
nethercote85a456f2004-11-16 17:31:56 +00005300PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00005301{
njn22cfccb2004-11-27 16:10:23 +00005302 PRINT("sys_times ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00005303 PRE_REG_READ1(long, "times", struct tms *, buf);
njn22cfccb2004-11-27 16:10:23 +00005304 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005305}
5306
nethercote85a456f2004-11-16 17:31:56 +00005307POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00005308{
njn22cfccb2004-11-27 16:10:23 +00005309 if (ARG1 != 0) {
5310 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005311 }
5312}
5313
nethercote85a456f2004-11-16 17:31:56 +00005314PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00005315{
njn22cfccb2004-11-27 16:10:23 +00005316 PRINT("sys_umask ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00005317 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00005318}
5319
nethercote85a456f2004-11-16 17:31:56 +00005320PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005321{
njn22cfccb2004-11-27 16:10:23 +00005322 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005323 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00005324 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005325}
5326
nethercote85a456f2004-11-16 17:31:56 +00005327PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00005328{
njn22cfccb2004-11-27 16:10:23 +00005329 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00005330 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00005331 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005332}
5333
nethercote85a456f2004-11-16 17:31:56 +00005334POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005335{
njn22cfccb2004-11-27 16:10:23 +00005336 if (ARG1 != 0) {
5337 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005338 }
5339}
5340
nethercote85a456f2004-11-16 17:31:56 +00005341PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005342{
njn22cfccb2004-11-27 16:10:23 +00005343 PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00005344 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
njn22cfccb2004-11-27 16:10:23 +00005345 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
5346 if (ARG2 != 0)
5347 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00005348}
5349
nethercote85a456f2004-11-16 17:31:56 +00005350PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005351{
njn22cfccb2004-11-27 16:10:23 +00005352 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00005353 PRE_REG_READ3(long, "waitpid",
5354 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005355
njn22cfccb2004-11-27 16:10:23 +00005356 if (ARG2 != (Addr)NULL)
5357 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005358}
5359
nethercote85a456f2004-11-16 17:31:56 +00005360POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005361{
njn22cfccb2004-11-27 16:10:23 +00005362 if (ARG2 != (Addr)NULL)
5363 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005364}
5365
nethercote85a456f2004-11-16 17:31:56 +00005366PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005367{
njn22cfccb2004-11-27 16:10:23 +00005368 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
jsgf855d93d2003-10-13 22:26:55 +00005369
nethercote7f7e4d12004-11-15 12:28:58 +00005370 PRE_REG_READ4(long, "wait4",
5371 vki_pid_t, pid, unsigned int *, status, int, options,
5372 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00005373 if (ARG2 != (Addr)NULL)
5374 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5375 if (ARG4 != (Addr)NULL)
5376 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005377}
5378
nethercote85a456f2004-11-16 17:31:56 +00005379POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005380{
njn22cfccb2004-11-27 16:10:23 +00005381 if (ARG2 != (Addr)NULL)
5382 POST_MEM_WRITE( ARG2, sizeof(int) );
5383 if (ARG4 != (Addr)NULL)
5384 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005385}
5386
nethercote85a456f2004-11-16 17:31:56 +00005387PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005388{
jsgf855d93d2003-10-13 22:26:55 +00005389 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005390 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00005391 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005392 PRE_REG_READ3(ssize_t, "writev",
5393 unsigned long, fd, const struct iovec *, vector,
5394 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00005395 if (!VG_(fd_allowed)(ARG1, "writev", tid, False)) {
5396 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005397 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005398 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005399 ARG2, ARG3 * sizeof(struct vki_iovec) );
5400 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005401 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005402 vec = (struct vki_iovec *)ARG2;
5403 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005404 PRE_MEM_READ( "writev(vector[...])",
5405 (Addr)vec[i].iov_base, vec[i].iov_len );
5406 }
jsgf855d93d2003-10-13 22:26:55 +00005407 }
5408}
5409
nethercote85a456f2004-11-16 17:31:56 +00005410PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005411{
njn22cfccb2004-11-27 16:10:23 +00005412 PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
nethercoteac866b92004-11-15 20:23:15 +00005413 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
njn22cfccb2004-11-27 16:10:23 +00005414 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5415 if (ARG2 != 0)
5416 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005417}
5418
nethercote85a456f2004-11-16 17:31:56 +00005419PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005420{
njn22cfccb2004-11-27 16:10:23 +00005421 PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005422 PRE_REG_READ3(long, "sched_setaffinity",
5423 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005424 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005425}
5426
nethercote85a456f2004-11-16 17:31:56 +00005427PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005428{
njn22cfccb2004-11-27 16:10:23 +00005429 PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005430 PRE_REG_READ3(long, "sched_getaffinity",
5431 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005432 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005433}
5434
nethercote85a456f2004-11-16 17:31:56 +00005435POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005436{
njn22cfccb2004-11-27 16:10:23 +00005437 POST_MEM_WRITE(ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005438}
5439
nethercote85a456f2004-11-16 17:31:56 +00005440PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005441{
njn22cfccb2004-11-27 16:10:23 +00005442 PRINT("sys_acct ( %p )", ARG1);
nethercote2b0cae62004-11-12 14:57:34 +00005443 PRE_REG_READ1(long, "acct", const char *, filename);
njn22cfccb2004-11-27 16:10:23 +00005444 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
nethercote2bc5a212004-04-10 00:26:10 +00005445}
5446
nethercote85a456f2004-11-16 17:31:56 +00005447PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005448{
nethercote0df495a2004-11-11 16:38:21 +00005449 PRINT("sys_pause ( )");
5450 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005451}
5452
nethercotea3a2c142004-11-14 14:13:05 +00005453// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005454PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005455{
thughesc3e85df2004-11-15 09:27:24 +00005456 /* The C library interface to sigsuspend just takes a pointer to
5457 a signal mask but this system call has three arguments - the first
5458 two don't appear to be used by the kernel and are always passed as
5459 zero by glibc and the third is the first word of the signal mask
5460 so only 32 signals are supported.
5461
5462 In fact glibc normally uses rt_sigsuspend if it is available as
5463 that takes a pointer to the signal mask so supports more signals.
5464 */
njn22cfccb2004-11-27 16:10:23 +00005465 PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
thughesd8e00412004-11-14 19:44:25 +00005466 PRE_REG_READ3(int, "sigsuspend",
5467 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005468 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005469}
5470
nethercotea3a2c142004-11-14 14:13:05 +00005471// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005472PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005473{
thughesc3e85df2004-11-15 09:27:24 +00005474 /* The C library interface to sigsuspend just takes a pointer to
5475 a signal mask but this system call has two arguments - a pointer
5476 to the mask and the number of bytes used by it. The kernel insists
5477 on the size being equal to sizeof(sigset_t) however and will just
5478 return EINVAL if it isn't.
5479 */
njn22cfccb2004-11-27 16:10:23 +00005480 PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
nethercotea3a2c142004-11-14 14:13:05 +00005481 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
njn22cfccb2004-11-27 16:10:23 +00005482 if (ARG1 != (Addr)NULL) {
5483 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
nethercotea3a2c142004-11-14 14:13:05 +00005484 }
5485}
jsgf855d93d2003-10-13 22:26:55 +00005486
nethercote85a456f2004-11-16 17:31:56 +00005487PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005488{
nethercoteac866b92004-11-15 20:23:15 +00005489 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
njn22cfccb2004-11-27 16:10:23 +00005490 ARG1,ARG2,ARG3,(ULong)ARG4);
nethercoteac866b92004-11-15 20:23:15 +00005491 PRE_REG_READ4(long, "rt_sigtimedwait",
5492 const vki_sigset_t *, set, vki_siginfo_t *, info,
5493 const struct timespec *, timeout, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005494 if (ARG1 != 0)
5495 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
5496 if (ARG2 != 0)
5497 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
nethercoteac866b92004-11-15 20:23:15 +00005498 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
njn22cfccb2004-11-27 16:10:23 +00005499 ARG4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005500}
5501
nethercote85a456f2004-11-16 17:31:56 +00005502POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005503{
njn22cfccb2004-11-27 16:10:23 +00005504 if (ARG2 != 0)
5505 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005506}
5507
nethercote85a456f2004-11-16 17:31:56 +00005508PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005509{
njn22cfccb2004-11-27 16:10:23 +00005510 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005511 PRE_REG_READ3(long, "rt_sigqueueinfo",
5512 int, pid, int, sig, vki_siginfo_t *, uinfo);
njn22cfccb2004-11-27 16:10:23 +00005513 if (ARG2 != 0)
5514 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005515}
5516
nethercote85a456f2004-11-16 17:31:56 +00005517POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005518{
sewardjb5f6f512005-03-10 23:59:00 +00005519 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
5520 PRE_REG_READ3(long, "rt_sigqueueinfo",
5521 int, pid, int, sig, vki_siginfo_t *, uinfo);
5522 if (ARG2 != 0)
5523 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
5524 if (!VG_(client_signal_OK)(ARG2))
5525 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00005526}
5527
nethercoteb77dee62004-11-16 17:13:24 +00005528// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005529PRE(sys_sigaltstack, Special)
jsgf855d93d2003-10-13 22:26:55 +00005530{
5531 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
njn22cfccb2004-11-27 16:10:23 +00005532 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005533 PRE_REG_READ2(int, "sigaltstack",
5534 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005535 if (ARG1 != 0) {
5536 PRE_MEM_READ( "sigaltstack(ss)", ARG1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005537 }
njn22cfccb2004-11-27 16:10:23 +00005538 if (ARG2 != 0) {
5539 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005540 }
5541
njnb249fd72004-11-29 14:24:57 +00005542 VG_(do_sys_sigaltstack) (tid);
sewardja93f66a2005-02-28 20:50:29 +00005543 SET_RESULT(RES); /* sigh */
jsgf855d93d2003-10-13 22:26:55 +00005544}
5545
nethercote85a456f2004-11-16 17:31:56 +00005546POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005547{
njn22cfccb2004-11-27 16:10:23 +00005548 if (RES == 0 && ARG2 != 0)
5549 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005550}
5551
nethercote71f05f32004-11-12 18:49:27 +00005552// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005553PRE(sys_rt_sigaction, Special)
nethercote686b5db2004-11-14 13:42:51 +00005554{
njn22cfccb2004-11-27 16:10:23 +00005555 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
nethercote686b5db2004-11-14 13:42:51 +00005556 PRE_REG_READ4(long, "rt_sigaction",
5557 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005558 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005559
njn22cfccb2004-11-27 16:10:23 +00005560 if (ARG2 != 0)
5561 PRE_MEM_READ( "rt_sigaction(act)", ARG2, sizeof(struct vki_sigaction));
5562 if (ARG3 != 0)
5563 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005564
njnb249fd72004-11-29 14:24:57 +00005565 // XXX: doesn't seem right to be calling do_sys_sigaction for
5566 // sys_rt_sigaction... perhaps this function should be renamed
5567 // VG_(do_sys_rt_sigaction)() --njn
sewardjb5f6f512005-03-10 23:59:00 +00005568
5569 SET_RESULT(
5570 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
5571 (struct vki_sigaction *)ARG3)
5572 );
nethercote686b5db2004-11-14 13:42:51 +00005573}
5574
nethercote85a456f2004-11-16 17:31:56 +00005575POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005576{
njn22cfccb2004-11-27 16:10:23 +00005577 if (RES == 0 && ARG3 != 0)
5578 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005579}
jsgf855d93d2003-10-13 22:26:55 +00005580
njnc6168192004-11-29 13:54:10 +00005581// XXX: This syscall is not used on amd64 -- it only provides
5582// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
5583// This wrapper is only suitable for 32-bit architectures.
5584#ifndef __amd64__
njnb249fd72004-11-29 14:24:57 +00005585PRE(sys_sigprocmask, Special)
jsgf855d93d2003-10-13 22:26:55 +00005586{
sewardj970ac792004-12-31 18:09:32 +00005587 vki_old_sigset_t* set;
5588 vki_old_sigset_t* oldset;
5589 vki_sigset_t bigger_set;
5590 vki_sigset_t bigger_oldset;
5591
njn22cfccb2004-11-27 16:10:23 +00005592 PRINT("sys_sigprocmask ( %d, %p, %p )",ARG1,ARG2,ARG3);
nethercote7fbe08a2004-11-15 19:03:27 +00005593 PRE_REG_READ3(long, "sigprocmask",
5594 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
njn22cfccb2004-11-27 16:10:23 +00005595 if (ARG2 != 0)
5596 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
5597 if (ARG3 != 0)
5598 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005599
njnb249fd72004-11-29 14:24:57 +00005600 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5601 // vki_sigset_t params.
sewardj970ac792004-12-31 18:09:32 +00005602 set = (vki_old_sigset_t*)ARG2;
5603 oldset = (vki_old_sigset_t*)ARG3;
nethercote7fbe08a2004-11-15 19:03:27 +00005604
sewardj1f276622004-12-06 16:18:58 +00005605 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5606 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
5607 if (set)
5608 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
nethercote7fbe08a2004-11-15 19:03:27 +00005609
njnb249fd72004-11-29 14:24:57 +00005610 VG_(do_sys_sigprocmask) ( tid,
5611 ARG1 /*how*/,
sewardj1f276622004-12-06 16:18:58 +00005612 set ? &bigger_set : NULL,
5613 oldset ? &bigger_oldset : NULL);
sewardj3876e8d2005-03-16 00:40:48 +00005614 SET_RESULT(RES);
nethercote7fbe08a2004-11-15 19:03:27 +00005615
njnb249fd72004-11-29 14:24:57 +00005616 if (oldset)
5617 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005618}
5619
nethercote85a456f2004-11-16 17:31:56 +00005620POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005621{
njn22cfccb2004-11-27 16:10:23 +00005622 if (RES == 0 && ARG3 != 0)
5623 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005624}
njnc6168192004-11-29 13:54:10 +00005625#endif
nethercote7fbe08a2004-11-15 19:03:27 +00005626
njnb249fd72004-11-29 14:24:57 +00005627PRE(sys_rt_sigprocmask, Special)
nethercote7fbe08a2004-11-15 19:03:27 +00005628{
njn22cfccb2004-11-27 16:10:23 +00005629 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
nethercote7fbe08a2004-11-15 19:03:27 +00005630 PRE_REG_READ4(long, "rt_sigprocmask",
5631 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5632 vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005633 if (ARG2 != 0)
5634 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
5635 if (ARG3 != 0)
5636 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005637
5638 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
njn22cfccb2004-11-27 16:10:23 +00005639 if (sizeof(vki_sigset_t) != ARG4)
5640 SET_RESULT( -VKI_EMFILE );
sewardj004e8ca2005-02-28 17:27:04 +00005641 else {
nethercote93d9aa12004-11-10 19:08:31 +00005642 VG_(do_sys_sigprocmask) ( tid,
njn22cfccb2004-11-27 16:10:23 +00005643 ARG1 /*how*/,
5644 (vki_sigset_t*) ARG2,
5645 (vki_sigset_t*) ARG3 );
sewardja93f66a2005-02-28 20:50:29 +00005646 /* Mark that the result is set. */
5647 SET_RESULT(RES);
sewardj004e8ca2005-02-28 17:27:04 +00005648 }
jsgf855d93d2003-10-13 22:26:55 +00005649}
5650
nethercote85a456f2004-11-16 17:31:56 +00005651POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005652{
njn22cfccb2004-11-27 16:10:23 +00005653 if (RES == 0 && ARG3 != 0)
5654 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005655}
5656
sewardjb5f6f512005-03-10 23:59:00 +00005657PRE(sys_sigpending, 0)
jsgf855d93d2003-10-13 22:26:55 +00005658{
njn22cfccb2004-11-27 16:10:23 +00005659 PRINT( "sys_sigpending ( %p )", ARG1 );
nethercote17258dc2004-11-12 19:55:08 +00005660 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
njn22cfccb2004-11-27 16:10:23 +00005661 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005662}
5663
nethercote85a456f2004-11-16 17:31:56 +00005664POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005665{
njn22cfccb2004-11-27 16:10:23 +00005666 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005667}
5668
sewardjb5f6f512005-03-10 23:59:00 +00005669PRE(sys_rt_sigpending, 0)
nethercotea6395d12004-11-15 19:23:46 +00005670{
njn22cfccb2004-11-27 16:10:23 +00005671 PRINT( "sys_rt_sigpending ( %p )", ARG1 );
nethercotea6395d12004-11-15 19:23:46 +00005672 PRE_REG_READ2(long, "rt_sigpending",
5673 vki_sigset_t *, set, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005674 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005675}
5676
nethercote85a456f2004-11-16 17:31:56 +00005677POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005678{
njn22cfccb2004-11-27 16:10:23 +00005679 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
nethercotea6395d12004-11-15 19:23:46 +00005680}
jsgf855d93d2003-10-13 22:26:55 +00005681
nethercote85a456f2004-11-16 17:31:56 +00005682PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005683{
nethercote330abb52004-11-16 12:58:04 +00005684 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
njn22cfccb2004-11-27 16:10:23 +00005685 ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
nethercote330abb52004-11-16 12:58:04 +00005686 PRE_REG_READ4(long, "mq_open",
5687 const char *, name, int, oflag, vki_mode_t, mode,
5688 struct mq_attr *, attr);
njn22cfccb2004-11-27 16:10:23 +00005689 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
5690 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
5691 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
nethercoteef0c7662004-11-06 15:38:43 +00005692 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005693 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005694 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005695 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5696 }
5697}
5698
nethercote85a456f2004-11-16 17:31:56 +00005699POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005700{
njn22cfccb2004-11-27 16:10:23 +00005701 if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
5702 VG_(close)(RES);
5703 SET_RESULT( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005704 } else {
5705 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00005706 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
thughes8579b102004-08-14 18:52:27 +00005707 }
thughes8579b102004-08-14 18:52:27 +00005708}
5709
nethercote85a456f2004-11-16 17:31:56 +00005710PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005711{
njn22cfccb2004-11-27 16:10:23 +00005712 PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
nethercote330abb52004-11-16 12:58:04 +00005713 PRE_REG_READ1(long, "mq_unlink", const char *, name);
njn22cfccb2004-11-27 16:10:23 +00005714 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
thughes8579b102004-08-14 18:52:27 +00005715}
5716
nethercote85a456f2004-11-16 17:31:56 +00005717PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005718{
nethercote330abb52004-11-16 12:58:04 +00005719 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
njn22cfccb2004-11-27 16:10:23 +00005720 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005721 PRE_REG_READ5(long, "mq_timedsend",
5722 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5723 unsigned int, msg_prio, const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005724 if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
5725 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005726 } else {
njn22cfccb2004-11-27 16:10:23 +00005727 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5728 if (ARG5 != 0)
5729 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
nethercote73b526f2004-10-31 18:48:21 +00005730 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005731 }
5732}
5733
nethercote85a456f2004-11-16 17:31:56 +00005734PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005735{
nethercote330abb52004-11-16 12:58:04 +00005736 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
njn22cfccb2004-11-27 16:10:23 +00005737 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005738 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5739 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5740 unsigned int *, msg_prio,
5741 const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005742 if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
5743 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005744 } else {
njn22cfccb2004-11-27 16:10:23 +00005745 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
5746 if (ARG4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005747 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
njn22cfccb2004-11-27 16:10:23 +00005748 ARG4, sizeof(unsigned int) );
5749 if (ARG5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005750 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
njn22cfccb2004-11-27 16:10:23 +00005751 ARG5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005752 }
5753}
5754
nethercote85a456f2004-11-16 17:31:56 +00005755POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005756{
njn22cfccb2004-11-27 16:10:23 +00005757 POST_MEM_WRITE( ARG2, ARG3 );
5758 if (ARG4 != 0)
5759 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005760}
5761
nethercote85a456f2004-11-16 17:31:56 +00005762PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005763{
njn22cfccb2004-11-27 16:10:23 +00005764 PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
nethercote330abb52004-11-16 12:58:04 +00005765 PRE_REG_READ2(long, "mq_notify",
5766 vki_mqd_t, mqdes, const struct sigevent *, notification);
njn22cfccb2004-11-27 16:10:23 +00005767 if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
5768 SET_RESULT( -VKI_EBADF );
5769 else if (ARG2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005770 PRE_MEM_READ( "mq_notify(notification)",
njn22cfccb2004-11-27 16:10:23 +00005771 ARG2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005772}
5773
nethercote85a456f2004-11-16 17:31:56 +00005774PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005775{
njn22cfccb2004-11-27 16:10:23 +00005776 PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
nethercote330abb52004-11-16 12:58:04 +00005777 PRE_REG_READ3(long, "mq_getsetattr",
5778 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5779 struct mq_attr *, omqstat);
njn22cfccb2004-11-27 16:10:23 +00005780 if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
5781 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005782 } else {
njn22cfccb2004-11-27 16:10:23 +00005783 if (ARG2 != 0) {
5784 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
nethercoteef0c7662004-11-06 15:38:43 +00005785 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005786 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5787 }
njn22cfccb2004-11-27 16:10:23 +00005788 if (ARG3 != 0)
5789 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
thughes8579b102004-08-14 18:52:27 +00005790 sizeof(struct vki_mq_attr) );
5791 }
5792}
5793
nethercote85a456f2004-11-16 17:31:56 +00005794POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005795{
njn22cfccb2004-11-27 16:10:23 +00005796 if (ARG3 != 0)
5797 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005798}
5799
nethercote85a456f2004-11-16 17:31:56 +00005800PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005801{
njn22cfccb2004-11-27 16:10:23 +00005802 PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005803 PRE_REG_READ3(long, "timer_create",
5804 vki_clockid_t, clockid, struct sigevent *, evp,
5805 vki_timer_t *, timerid);
njn22cfccb2004-11-27 16:10:23 +00005806 if (ARG2 != 0)
5807 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
5808 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005809}
5810
nethercote85a456f2004-11-16 17:31:56 +00005811POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005812{
njn22cfccb2004-11-27 16:10:23 +00005813 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005814}
5815
nethercote85a456f2004-11-16 17:31:56 +00005816PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005817{
njn22cfccb2004-11-27 16:10:23 +00005818 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
nethercote92b2fd52004-11-16 16:15:41 +00005819 PRE_REG_READ4(long, "timer_settime",
5820 vki_timer_t, timerid, int, flags,
5821 const struct itimerspec *, value,
5822 struct itimerspec *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00005823 PRE_MEM_READ( "timer_settime(value)", ARG3,
thughese1a925d2004-08-30 19:50:02 +00005824 sizeof(struct vki_itimerspec) );
njn22cfccb2004-11-27 16:10:23 +00005825 if (ARG4 != 0)
5826 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
thughese1a925d2004-08-30 19:50:02 +00005827 sizeof(struct vki_itimerspec) );
5828}
5829
nethercote85a456f2004-11-16 17:31:56 +00005830POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005831{
njn22cfccb2004-11-27 16:10:23 +00005832 if (ARG4 != 0)
5833 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005834}
5835
nethercote85a456f2004-11-16 17:31:56 +00005836PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005837{
njn22cfccb2004-11-27 16:10:23 +00005838 PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005839 PRE_REG_READ2(long, "timer_gettime",
5840 vki_timer_t, timerid, struct itimerspec *, value);
njn22cfccb2004-11-27 16:10:23 +00005841 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
thughese1a925d2004-08-30 19:50:02 +00005842 sizeof(struct vki_itimerspec));
5843}
5844
nethercote85a456f2004-11-16 17:31:56 +00005845POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005846{
njn22cfccb2004-11-27 16:10:23 +00005847 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005848}
5849
nethercote85a456f2004-11-16 17:31:56 +00005850PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005851{
njn22cfccb2004-11-27 16:10:23 +00005852 PRINT("sys_timer_getoverrun( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005853 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005854}
5855
nethercote85a456f2004-11-16 17:31:56 +00005856PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005857{
njn22cfccb2004-11-27 16:10:23 +00005858 PRINT("sys_timer_delete( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005859 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005860}
5861
nethercote85a456f2004-11-16 17:31:56 +00005862PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005863{
njn22cfccb2004-11-27 16:10:23 +00005864 PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005865 PRE_REG_READ2(long, "clock_settime",
5866 vki_clockid_t, clk_id, const struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005867 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005868}
5869
nethercote85a456f2004-11-16 17:31:56 +00005870PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005871{
njn22cfccb2004-11-27 16:10:23 +00005872 PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005873 PRE_REG_READ2(long, "clock_gettime",
5874 vki_clockid_t, clk_id, struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005875 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005876}
5877
nethercote85a456f2004-11-16 17:31:56 +00005878POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005879{
njn22cfccb2004-11-27 16:10:23 +00005880 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005881}
5882
nethercote85a456f2004-11-16 17:31:56 +00005883PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005884{
njn22cfccb2004-11-27 16:10:23 +00005885 PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
5886 // Nb: we can't use "RES" as the param name because that's a macro
nethercote92b2fd52004-11-16 16:15:41 +00005887 // defined above!
5888 PRE_REG_READ2(long, "clock_getres",
njne1268d32004-11-27 16:57:18 +00005889 vki_clockid_t, clk_id, struct timespec *, res);
5890 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005891}
5892
nethercote85a456f2004-11-16 17:31:56 +00005893POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005894{
njn22cfccb2004-11-27 16:10:23 +00005895 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005896}
5897
nethercote4fa681f2004-11-08 17:51:39 +00005898
5899/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005900 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005901 ------------------------------------------------------------------ */
5902
nethercote85a456f2004-11-16 17:31:56 +00005903static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005904static void bad_before(ThreadId tid, ThreadState *tst)
5905{
5906 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005907 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005908 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +00005909 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge98abfc72003-12-16 02:05:15 +00005910 }
jsgf855d93d2003-10-13 22:26:55 +00005911 VG_(message)
5912 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5913 VG_(message)
5914 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5915
njn22cfccb2004-11-27 16:10:23 +00005916 SET_RESULT( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005917}
5918
nethercote8ff888f2004-11-17 17:11:45 +00005919static const struct SyscallTableEntry bad_sys =
5920 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005921
sewardjb5f6f512005-03-10 23:59:00 +00005922static const struct SyscallTableEntry *get_syscall_entry(UInt syscallno)
5923{
5924 const struct SyscallTableEntry *sys;
nethercote4fa681f2004-11-08 17:51:39 +00005925
sewardjb5f6f512005-03-10 23:59:00 +00005926 if (syscallno < VGA_(syscall_table_size) &&
5927 VGA_(syscall_table)[syscallno].before != NULL)
5928 sys = &VGA_(syscall_table)[syscallno];
5929 else
5930 sys = &bad_sys;
5931
5932 return sys;
5933}
5934
5935/* Perform post-syscall actions */
5936void VG_(post_syscall) (ThreadId tid)
5937{
5938 const struct SyscallTableEntry *sys;
5939 UInt flags;
5940 Bool mayBlock;
5941 ThreadState *tst = VG_(get_ThreadState)(tid);
5942 Int syscallno;
5943
5944 vg_assert(VG_(is_running_thread)(tid));
5945
5946 syscallno = tst->syscallno;
5947 tst->syscallno = -1;
5948
5949 vg_assert(syscallno != -1);
5950
5951 sys = get_syscall_entry(syscallno);
5952 flags = *(sys->flags_ptr);
5953
5954 mayBlock = !!( flags & MayBlock );
5955
5956 if (sys->after != NULL &&
5957 ((flags & PostOnFail) != 0 || !VG_(is_kerror)(RES))) {
5958 if (0)
5959 VG_(printf)("post_syscall: calling sys_after tid=%d syscallno=%d\n",
5960 tid, syscallno);
5961 (sys->after)(tid, tst);
5962 }
5963
5964 /* Do any post-syscall actions
5965
5966 NOTE: this is only called if the syscall completed. If the
5967 syscall was restarted, then it will call the Tool's
5968 pre_syscall again, without calling post_syscall (ie, more
5969 pre's than post's) */
5970 if (VG_(needs).syscall_wrapper) {
5971 //VGP_PUSHCC(VgpSkinSysWrap);
5972 TL_(post_syscall)(tid, syscallno, RES);
5973 //VGP_POPCC(VgpSkinSysWrap);
5974 }
5975}
5976
5977
5978void VG_(client_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00005979{
sewardj018f7622002-05-15 21:13:39 +00005980 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005981 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005982 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00005983 Bool isSpecial = False;
5984 Bool mayBlock = False;
5985 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00005986 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00005987
njn25e49d8e72002-09-23 09:36:25 +00005988 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00005989
jsgf855d93d2003-10-13 22:26:55 +00005990 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00005991
nethercote44d9aaa2004-11-04 19:38:14 +00005992 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00005993
jsgf855d93d2003-10-13 22:26:55 +00005994 /* the syscall no is in %eax. For syscalls with <= 6 args,
5995 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
5996 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00005997 containing the args.
5998
5999 The result is returned in %eax. If this value >= 0, the call
6000 succeeded, and this is the return value. If < 0, it failed, and
6001 the negation of this value is errno. To be more specific,
njn22cfccb2004-11-27 16:10:23 +00006002 if RES is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
sewardjde4a1d02002-03-22 01:27:54 +00006003 (kernel 2.4.9 sources, include/asm-i386/errno.h)
6004 then it indicates an error. Otherwise it doesn't.
6005
6006 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
6007 (inclusive?) indicate error returns. Not sure where the -4095
6008 comes from.
6009 */
6010
sewardjb5f6f512005-03-10 23:59:00 +00006011 vg_assert(VG_(is_running_thread)(tid));
6012 vg_assert(tst->syscallno == -1);
jsgf855d93d2003-10-13 22:26:55 +00006013 tst->syscallno = syscallno;
sewardjde4a1d02002-03-22 01:27:54 +00006014
sewardjb5f6f512005-03-10 23:59:00 +00006015 /* Make sure the tmp signal mask matches the real signal
6016 mask; sigsuspend may change this. */
sewardj62601592005-03-26 13:48:19 +00006017 vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
sewardjb5f6f512005-03-10 23:59:00 +00006018
6019 sys = get_syscall_entry(syscallno);
nethercote85a456f2004-11-16 17:31:56 +00006020 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00006021
sewardjb5f6f512005-03-10 23:59:00 +00006022 /* !! is standard idiom to turn an int->bool */
6023 isSpecial = !!( flags & Special );
6024 mayBlock = !!( flags & MayBlock );
6025 // At most one of these should be true
6026 vg_assert( isSpecial + mayBlock <= 1 );
nethercotec8734892004-11-10 18:57:37 +00006027
jsgf855d93d2003-10-13 22:26:55 +00006028 /* Do any pre-syscall actions */
6029 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00006030 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00006031 TL_(pre_syscall)(tid, syscallno);
njn4be0a692004-11-22 18:10:36 +00006032 VGP_POPCC(VgpToolSysWrap);
jsgf855d93d2003-10-13 22:26:55 +00006033 }
6034
nethercoteef0c7662004-11-06 15:38:43 +00006035 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
6036 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00006037 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00006038 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00006039
sewardjb5f6f512005-03-10 23:59:00 +00006040 tst->syscall_result_set = False;
6041
nethercotec8734892004-11-10 18:57:37 +00006042 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00006043 /* "Special" syscalls are implemented by Valgrind internally,
6044 and do not generate real kernel calls. The expectation,
6045 therefore, is that the "before" function not only does the
6046 appropriate tests, but also performs the syscall itself and
6047 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00006048 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00006049
6050 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00006051 /* This *must* result in tst->syscall_result_set becoming
6052 True. */
jsgf855d93d2003-10-13 22:26:55 +00006053
sewardjb5f6f512005-03-10 23:59:00 +00006054 // vg_assert(tst->sys_flags == flags);
sewardj004e8ca2005-02-28 17:27:04 +00006055 vg_assert(tst->syscall_result_set == True);
thughesbaa46e52004-07-29 17:44:23 +00006056
njn22cfccb2004-11-27 16:10:23 +00006057 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006058 syscall_done = True;
6059 } else {
6060 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00006061 /* This *may* result in tst->syscall_result_set becoming
6062 True. */
jsgf855d93d2003-10-13 22:26:55 +00006063
sewardj004e8ca2005-02-28 17:27:04 +00006064 if (tst->syscall_result_set) {
6065 /* "before" decided to provide a syscall result itself, so
6066 don't do anything - just pretend the syscall happened. */
6067 PRINT(" ==> %lld (0x%llx)\n", (Long)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006068 syscall_done = True;
sewardjb5f6f512005-03-10 23:59:00 +00006069 } else if (mayBlock) {
6070 vki_sigset_t mask;
6071
6072 vg_assert(!(flags & PadAddr));
6073
6074 /* Syscall may block, so run it asynchronously */
nethercoteef0c7662004-11-06 15:38:43 +00006075 PRINT(" --> ...\n");
sewardjb5f6f512005-03-10 23:59:00 +00006076
6077 mask = tst->sig_mask;
6078 VG_(sanitize_client_sigmask)(tid, &mask);
6079
6080 VG_(set_sleeping)(tid, VgTs_WaitSys);
6081 VGA_(client_syscall)(syscallno, tst, &mask);
6082 /* VGA_(client_syscall) may not return if the syscall was
6083 interrupted by a signal. In that case, flow of control
6084 will end up back in the scheduler via the signal
6085 machinery. */
6086 VG_(set_running)(tid);
njn6f46a302005-03-11 05:07:16 +00006087 PRINT("SYSCALL[%d,%d](%3d) --> %lld (0x%llx)\n",
sewardjb5f6f512005-03-10 23:59:00 +00006088 VG_(getpid)(), tid, syscallno, (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006089 } else {
6090 /* run the syscall directly */
sewardjb5f6f512005-03-10 23:59:00 +00006091 if (flags & PadAddr)
6092 VG_(pad_address_space)(VG_(client_end));
6093
njnca6fef02004-11-29 16:49:18 +00006094 RES = VG_(do_syscall6)(syscallno, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
njn22cfccb2004-11-27 16:10:23 +00006095 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006096 syscall_done = True;
6097 }
6098 }
6099
sewardjb5f6f512005-03-10 23:59:00 +00006100 vg_assert(VG_(is_running_thread)(tid));
jsgf855d93d2003-10-13 22:26:55 +00006101
sewardjb5f6f512005-03-10 23:59:00 +00006102 SET_SYSCALL_RETVAL(tid, RES);
fitzhardingef0f911c2003-11-09 09:51:33 +00006103
sewardjb5f6f512005-03-10 23:59:00 +00006104 VG_(post_syscall)(tid);
jsgf855d93d2003-10-13 22:26:55 +00006105
sewardjb5f6f512005-03-10 23:59:00 +00006106 if (flags & PadAddr) {
6107 vg_assert(!mayBlock);
6108 VG_(unpad_address_space)(VG_(client_end));
6109 //VG_(sanity_check_memory)();
fitzhardingee1c06d82003-10-30 07:21:44 +00006110 }
6111
sewardjb5f6f512005-03-10 23:59:00 +00006112 /* VG_(post_syscall) should set this */
6113 vg_assert(tst->syscallno == -1);
sewardj2e93c502002-04-12 11:12:52 +00006114
njn25e49d8e72002-09-23 09:36:25 +00006115 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00006116}
6117
sewardjb5f6f512005-03-10 23:59:00 +00006118//static void restart_syscall(ThreadId tid)
6119//{
6120// ThreadState* tst;
6121// tst = VG_(get_ThreadState)(tid);
6122//
6123// vg_assert(tst != NULL);
6124// vg_assert(tst->status == VgTs_WaitSys);
6125// vg_assert(tst->syscallno != -1);
6126//
6127// SYSNO = tst->syscallno;
6128// VGA_(restart_syscall)(&tst->arch);
6129//}
6130
6131// svn version of post_syscall
6132//void VG_(post_syscall) ( ThreadId tid, Bool restart )
6133//{
6134// ThreadState* tst;
6135// UInt syscallno, flags;
6136// const struct SyscallTableEntry *sys;
6137// Bool isSpecial = False;
6138// Bool restarted = False;
6139//
6140// VGP_PUSHCC(VgpCoreSysWrap);
6141//
6142// tst = VG_(get_ThreadState)(tid);
6143// vg_assert(tst->tid == tid);
6144//
6145// /* Tell the tool about the syscall return value */
6146// SET_SYSCALL_RETVAL(tst->tid, RES);
6147//
6148// syscallno = tst->syscallno;
6149//
6150// vg_assert(syscallno != -1); /* must be a current syscall */
6151//
6152// if (syscallno < VGA_(syscall_table_size) &&
6153// VGA_(syscall_table)[syscallno].before != NULL)
6154// {
6155// sys = &VGA_(syscall_table)[syscallno];
6156// } else {
6157// sys = &bad_sys;
6158// }
6159// flags = *(sys->flags_ptr);
6160//
6161// isSpecial = flags & Special;
6162//
6163// if (RES == -VKI_ERESTARTSYS) {
6164// /* Applications never expect to see this, so we should either
6165// restart the syscall or fail it with EINTR, depending on what
6166// our caller wants. Generally they'll want to restart, but if
6167// client set the signal state to not restart, then we fail with
6168// EINTR. Either way, ERESTARTSYS means the syscall made no
6169// progress, and so can be failed or restarted without
6170// consequence. */
6171// if (0)
6172// VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
6173// syscallno, restart);
6174//
6175// if (restart) {
6176// restarted = True;
6177// restart_syscall(tid);
6178// } else
6179// RES = -VKI_EINTR;
6180// }
6181//
6182// if (!restarted) {
6183// if (sys->after != NULL &&
6184// ((tst->sys_flags & PostOnFail) != 0 || !VG_(is_kerror)(RES)))
6185// (sys->after)(tst->tid, tst);
6186//
6187// /* Do any post-syscall actions
6188//
6189// NOTE: this is only called if the syscall completed. If the
6190// syscall was restarted, then it will call the Tool's
6191// pre_syscall again, without calling post_syscall (ie, more
6192// pre's than post's)
6193// */
6194// if (VG_(needs).syscall_wrapper) {
6195// VGP_PUSHCC(VgpToolSysWrap);
6196// TL_(post_syscall)(tid, syscallno, RES);
6197// VGP_POPCC(VgpToolSysWrap);
6198// }
6199// }
6200//
6201// tst->status = VgTs_Runnable; /* runnable again */
6202// tst->syscallno = -1; /* no current syscall */
6203//
6204// VGP_POPCC(VgpCoreSysWrap);
6205//}
6206
sewardjde4a1d02002-03-22 01:27:54 +00006207/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00006208/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00006209/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00006210