blob: 0be225a4f50c7e263282c2dc910d83d281337b5e [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
nethercotebb1c9912004-01-04 16:43:23 +000010 Copyright (C) 2000-2004 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"
sewardjde4a1d02002-03-22 01:27:54 +000032
njn25e49d8e72002-09-23 09:36:25 +000033/* All system calls are channelled through here, doing two things:
sewardjde4a1d02002-03-22 01:27:54 +000034
nethercote4fa681f2004-11-08 17:51:39 +000035 * notify the tool of the events (mem/reg reads, writes) happening
sewardjde4a1d02002-03-22 01:27:54 +000036
37 * perform the syscall, usually by passing it along to the kernel
jsgf855d93d2003-10-13 22:26:55 +000038 unmodified.
sewardjde4a1d02002-03-22 01:27:54 +000039
jsgf855d93d2003-10-13 22:26:55 +000040 A magical piece of assembly code, VG_(do_syscall)(), in vg_syscall.S
sewardjde4a1d02002-03-22 01:27:54 +000041 does the tricky bit of passing a syscall to the kernel, whilst
42 having the simulator retain control.
43*/
44
jsgf855d93d2003-10-13 22:26:55 +000045/* ---------------------------------------------------------------------
46 A simple atfork() facility for Valgrind's internal use
47 ------------------------------------------------------------------ */
48
49struct atfork {
50 vg_atfork_t pre;
51 vg_atfork_t parent;
52 vg_atfork_t child;
53};
54
55#define VG_MAX_ATFORK 10
56
57static struct atfork atforks[VG_MAX_ATFORK];
58static Int n_atfork;
59
60void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
61{
62 Int i;
63
64 for(i = 0; i < n_atfork; i++) {
65 if (atforks[i].pre == pre &&
66 atforks[i].parent == parent &&
67 atforks[i].child == child)
68 return;
69 }
70
71 if (n_atfork >= VG_MAX_ATFORK)
72 VG_(core_panic)("Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
73
74 atforks[n_atfork].pre = pre;
75 atforks[n_atfork].parent = parent;
76 atforks[n_atfork].child = child;
77
78 n_atfork++;
79}
80
sewardjb5f6f512005-03-10 23:59:00 +000081void VG_(do_atfork_pre)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000082{
83 Int i;
84
85 for(i = 0; i < n_atfork; i++)
86 if (atforks[i].pre != NULL)
87 (*atforks[i].pre)(tid);
88}
89
sewardjb5f6f512005-03-10 23:59:00 +000090void VG_(do_atfork_parent)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000091{
92 Int i;
93
94 for(i = 0; i < n_atfork; i++)
95 if (atforks[i].parent != NULL)
96 (*atforks[i].parent)(tid);
97}
98
sewardjb5f6f512005-03-10 23:59:00 +000099void VG_(do_atfork_child)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +0000100{
101 Int i;
102
103 for(i = 0; i < n_atfork; i++)
104 if (atforks[i].child != NULL)
105 (*atforks[i].child)(tid);
106}
107
fitzhardinge1a303042003-12-22 08:48:50 +0000108/* return true if address range entirely contained within client
109 address space */
nethercote8ff888f2004-11-17 17:11:45 +0000110Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
111 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +0000112{
113 Addr end = start+size;
114 Addr cl_base = VG_(client_base);
115 Bool ret;
116
117 if (size == 0)
118 return True;
119
120 if (cl_base < 0x10000)
121 cl_base = 0x10000;
122
123 ret =
124 (end >= start) &&
125 start >= cl_base && start < VG_(client_end) &&
126 (end <= VG_(client_end));
127
128 if (0)
129 VG_(printf)("%s: test=%p-%p client=%p-%p ret=%d\n",
nethercote1543adf2004-10-25 15:43:21 +0000130 syscallname, start, end, cl_base, VG_(client_end), ret);
fitzhardinge1a303042003-12-22 08:48:50 +0000131
nethercote1543adf2004-10-25 15:43:21 +0000132 if (!ret && syscallname != NULL) {
fitzhardinge1a303042003-12-22 08:48:50 +0000133 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried to modify addresses %p-%p",
nethercote1543adf2004-10-25 15:43:21 +0000134 syscallname, start, end);
fitzhardinge1a303042003-12-22 08:48:50 +0000135
136 if (VG_(clo_verbosity) > 1) {
137 ExeContext *ec = VG_(get_ExeContext)(tid);
138 VG_(pp_ExeContext)(ec);
139 }
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;
482 i->where = (tid == -1) ? NULL : VG_(get_ExeContext)(tid);
483}
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{
680 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_TRANSIENT );
nethercoteef0c7662004-11-06 15:38:43 +0000681 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000682
683 VG_(arena_free) ( VG_AR_TRANSIENT, 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{
690 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_TRANSIENT );
nethercoteef0c7662004-11-06 15:38:43 +0000691 PRE_MEM_WRITE( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000692 VG_(arena_free) ( VG_AR_TRANSIENT, 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
772 outmsg = VG_(arena_malloc) ( VG_AR_TRANSIENT,
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
njn25e49d8e72002-09-23 09:36:25 +0000822 VG_(arena_free) ( VG_AR_TRANSIENT, 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) {
957 ExeContext *ec = VG_(get_ExeContext)(tid);
958 VG_(pp_ExeContext)(ec);
959 }
960 return False;
961 }
thughesad1c9562004-06-26 11:27:52 +0000962 else if (soft && fd >= VG_(fd_soft_limit)) {
963 return False;
964 }
jsgf855d93d2003-10-13 22:26:55 +0000965 return True;
966}
967
968
969/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +0000970 Deal with a bunch of socket-related syscalls
971 ------------------------------------------------------------------ */
972
973/* ------ */
974
sewardj987a8eb2005-03-01 19:00:30 +0000975void
976VG_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000977 UWord arg0, UWord arg1,
978 UWord arg2, UWord arg3 )
979{
980 /* int socketpair(int d, int type, int protocol, int sv[2]); */
981 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
982 arg3, 2*sizeof(int) );
983}
984
sewardj987a8eb2005-03-01 19:00:30 +0000985UWord
986VG_(generic_POST_sys_socketpair) ( ThreadId tid,
987 UWord res,
988 UWord arg0, UWord arg1,
989 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +0000990{
991 UWord r = res;
992 Int fd1 = ((Int*)arg3)[0];
993 Int fd2 = ((Int*)arg3)[1];
994 POST_MEM_WRITE( arg3, 2*sizeof(int) );
995 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
996 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
997 VG_(close)(fd1);
998 VG_(close)(fd2);
999 r = -VKI_EMFILE;
1000 } else {
1001 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1002 if (VG_(clo_track_fds)) {
1003 VG_(record_fd_open)(tid, fd1, NULL);
1004 VG_(record_fd_open)(tid, fd2, NULL);
1005 }
1006 }
1007 return r;
1008}
1009
1010/* ------ */
1011
sewardj987a8eb2005-03-01 19:00:30 +00001012UWord
1013VG_(generic_POST_sys_socket) ( ThreadId tid, UWord res )
sewardj9efbbef2005-03-01 16:45:23 +00001014{
1015 UWord r = res;
1016 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
1017 VG_(close)(res);
1018 r = -VKI_EMFILE;
1019 } else {
1020 if (VG_(clo_track_fds))
1021 VG_(record_fd_open)(tid, res, NULL);
1022 }
1023 return r;
1024}
1025
1026/* ------ */
1027
sewardj987a8eb2005-03-01 19:00:30 +00001028void
1029VG_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001030 UWord arg0, UWord arg1, UWord arg2 )
1031{
1032 /* int bind(int sockfd, struct sockaddr *my_addr,
1033 int addrlen); */
1034 pre_mem_read_sockaddr(
1035 tid, "socketcall.bind(my_addr.%s)",
1036 (struct vki_sockaddr *) arg1, arg2
1037 );
1038}
1039
1040/* ------ */
1041
sewardj987a8eb2005-03-01 19:00:30 +00001042void
1043VG_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001044 UWord arg0, UWord arg1, UWord arg2 )
1045{
1046 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1047 Addr addr_p = arg1;
1048 Addr addrlen_p = arg2;
1049 if (addr_p != (Addr)NULL)
1050 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
1051 "socketcall.accept(addr)",
1052 "socketcall.accept(addrlen_in)" );
1053}
1054
sewardj987a8eb2005-03-01 19:00:30 +00001055UWord
1056VG_(generic_POST_sys_accept) ( ThreadId tid,
1057 UWord res,
1058 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +00001059{
1060 UWord r = res;
1061 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
1062 VG_(close)(res);
1063 r = -VKI_EMFILE;
1064 } else {
1065 Addr addr_p = arg1;
1066 Addr addrlen_p = arg2;
1067 if (addr_p != (Addr)NULL)
1068 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
1069 "socketcall.accept(addrlen_out)" );
1070 if (VG_(clo_track_fds))
1071 VG_(record_fd_open)(tid, res, NULL);
1072 }
1073 return r;
1074}
1075
1076/* ------ */
1077
sewardj987a8eb2005-03-01 19:00:30 +00001078void
1079VG_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001080 UWord arg0, UWord arg1, UWord arg2,
1081 UWord arg3, UWord arg4, UWord arg5 )
1082{
1083 /* int sendto(int s, const void *msg, int len,
1084 unsigned int flags,
1085 const struct sockaddr *to, int tolen); */
1086 PRE_MEM_READ( "socketcall.sendto(msg)",
1087 arg1, /* msg */
1088 arg2 /* len */ );
1089 pre_mem_read_sockaddr(
1090 tid, "socketcall.sendto(to.%s)",
1091 (struct vki_sockaddr *) arg4, arg5
1092 );
1093}
1094
1095/* ------ */
1096
sewardj987a8eb2005-03-01 19:00:30 +00001097void
1098VG_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001099 UWord arg0, UWord arg1, UWord arg2 )
1100{
1101 /* int send(int s, const void *msg, size_t len, int flags); */
1102 PRE_MEM_READ( "socketcall.send(msg)",
1103 arg1, /* msg */
1104 arg2 /* len */ );
1105
1106}
1107
1108/* ------ */
1109
sewardj987a8eb2005-03-01 19:00:30 +00001110void
1111VG_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001112 UWord arg0, UWord arg1, UWord arg2,
1113 UWord arg3, UWord arg4, UWord arg5 )
1114{
1115 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1116 struct sockaddr *from, int *fromlen); */
1117 Addr buf_p = arg1;
1118 Int len = arg2;
1119 Addr from_p = arg4;
1120 Addr fromlen_p = arg5;
1121 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1122 if (from_p != (Addr)NULL)
1123 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1124 "socketcall.recvfrom(from)",
1125 "socketcall.recvfrom(fromlen_in)" );
1126}
1127
sewardj987a8eb2005-03-01 19:00:30 +00001128void
1129VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001130 UWord res,
1131 UWord arg0, UWord arg1, UWord arg2,
1132 UWord arg3, UWord arg4, UWord arg5 )
1133{
1134 Addr buf_p = arg1;
1135 Int len = arg2;
1136 Addr from_p = arg4;
1137 Addr fromlen_p = arg5;
1138
1139 if (from_p != (Addr)NULL)
1140 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1141 "socketcall.recvfrom(fromlen_out)" );
1142 POST_MEM_WRITE( buf_p, len );
1143}
1144
1145/* ------ */
1146
sewardj987a8eb2005-03-01 19:00:30 +00001147void
1148VG_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001149 UWord arg0, UWord arg1, UWord arg2 )
1150{
1151 /* int recv(int s, void *buf, int len, unsigned int flags); */
1152 /* man 2 recv says:
1153 The recv call is normally used only on a connected socket
1154 (see connect(2)) and is identical to recvfrom with a NULL
1155 from parameter.
1156 */
1157 PRE_MEM_WRITE( "socketcall.recv(buf)",
1158 arg1, /* buf */
1159 arg2 /* len */ );
1160}
1161
sewardj987a8eb2005-03-01 19:00:30 +00001162void
1163VG_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001164 UWord res,
1165 UWord arg0, UWord arg1, UWord arg2 )
1166{
1167 if (res >= 0 && arg1 != 0) {
1168 POST_MEM_WRITE( arg1, /* buf */
1169 arg2 /* len */ );
1170 }
1171}
1172
1173/* ------ */
1174
sewardj987a8eb2005-03-01 19:00:30 +00001175void
1176VG_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001177 UWord arg0, UWord arg1, UWord arg2 )
1178{
1179 /* int connect(int sockfd,
1180 struct sockaddr *serv_addr, int addrlen ); */
1181 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1182 arg1, /* serv_addr */
1183 sizeof(vki_sa_family_t));
1184 pre_mem_read_sockaddr( tid,
1185 "socketcall.connect(serv_addr.%s)",
1186 (struct vki_sockaddr *) arg1, arg2);
1187}
1188
1189/* ------ */
1190
sewardj987a8eb2005-03-01 19:00:30 +00001191void
1192VG_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001193 UWord arg0, UWord arg1, UWord arg2,
1194 UWord arg3, UWord arg4 )
1195{
1196 /* int setsockopt(int s, int level, int optname,
1197 const void *optval, int optlen); */
1198 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1199 arg3, /* optval */
1200 arg4 /* optlen */ );
1201}
1202
1203/* ------ */
1204
sewardj987a8eb2005-03-01 19:00:30 +00001205void
1206VG_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001207 UWord arg0, UWord arg1, UWord arg2,
1208 UWord arg3, UWord arg4 )
1209{
1210 /* int getsockopt(int s, int level, int optname,
1211 void *optval, socklen_t *optlen); */
1212 Addr optval_p = arg3;
1213 Addr optlen_p = arg4;
1214 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
1215 if (optval_p != (Addr)NULL)
1216 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1217 "socketcall.getsockopt(optval)",
1218 "socketcall.getsockopt(optlen)" );
1219}
1220
sewardj987a8eb2005-03-01 19:00:30 +00001221void
1222VG_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001223 UWord res,
1224 UWord arg0, UWord arg1, UWord arg2,
1225 UWord arg3, UWord arg4 )
1226{
1227 Addr optval_p = arg3;
1228 Addr optlen_p = arg4;
1229 if (optval_p != (Addr)NULL)
1230 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1231 "socketcall.getsockopt(optlen_out)" );
1232}
1233
1234/* ------ */
1235
sewardj987a8eb2005-03-01 19:00:30 +00001236void
1237VG_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001238 UWord arg0, UWord arg1, UWord arg2 )
1239{
1240 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1241 Addr name_p = arg1;
1242 Addr namelen_p = arg2;
1243 /* Nb: name_p cannot be NULL */
1244 buf_and_len_pre_check ( tid, name_p, namelen_p,
1245 "socketcall.getsockname(name)",
1246 "socketcall.getsockname(namelen_in)" );
1247}
1248
sewardj987a8eb2005-03-01 19:00:30 +00001249void
1250VG_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001251 UWord res,
1252 UWord arg0, UWord arg1, UWord arg2 )
1253{
1254 Addr name_p = arg1;
1255 Addr namelen_p = arg2;
1256 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1257 "socketcall.getsockname(namelen_out)" );
1258}
1259
1260/* ------ */
1261
sewardj987a8eb2005-03-01 19:00:30 +00001262void
1263VG_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001264 UWord arg0, UWord arg1, UWord arg2 )
1265{
1266 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1267 Addr name_p = arg1;
1268 Addr namelen_p = arg2;
1269 /* Nb: name_p cannot be NULL */
1270 buf_and_len_pre_check ( tid, name_p, namelen_p,
1271 "socketcall.getpeername(name)",
1272 "socketcall.getpeername(namelen_in)" );
1273}
1274
sewardj987a8eb2005-03-01 19:00:30 +00001275void
1276VG_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001277 UWord res,
1278 UWord arg0, UWord arg1, UWord arg2 )
1279{
1280 Addr name_p = arg1;
1281 Addr namelen_p = arg2;
1282 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1283 "socketcall.getpeername(namelen_out)" );
1284}
1285
1286/* ------ */
1287
sewardj987a8eb2005-03-01 19:00:30 +00001288void
1289VG_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001290 UWord arg0, UWord arg1 )
1291{
1292 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1293 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1294 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1295}
1296
1297/* ------ */
1298
sewardj987a8eb2005-03-01 19:00:30 +00001299void
1300VG_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001301 UWord arg0, UWord arg1 )
1302{
1303 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1304 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1305 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1306}
1307
sewardj987a8eb2005-03-01 19:00:30 +00001308void
1309VG_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001310 UWord res,
1311 UWord arg0, UWord arg1 )
1312{
1313 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1314 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1315 check_cmsg_for_fds( tid, msg );
1316}
1317
1318
1319/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001320 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001321 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001322
nethercote4fa681f2004-11-08 17:51:39 +00001323/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001324 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001325 names like sys_write(); a few have names like old_mmap(). See the
nethercote8ff888f2004-11-17 17:11:45 +00001326 comment for VGA_(syscall_table)[] for important info about the __NR_foo
1327 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001328
nethercote92b2fd52004-11-16 16:15:41 +00001329 Some notes about names used for syscalls and args:
1330 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1331 ambiguity.
1332
1333 - For error messages, we generally use a somewhat generic name
1334 for the syscall (eg. "write" rather than "sys_write"). This should be
1335 good enough for the average user to understand what is happening,
1336 without confusing them with names like "sys_write".
1337
1338 - Also, for error messages the arg names are mostly taken from the man
1339 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001340 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001341 for the same reason -- a user presented with a "bogus foo(bar)" arg
1342 will most likely look at the "foo" man page to see which is the "bar"
1343 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001344
nethercote9c311eb2004-11-12 18:20:12 +00001345 Note that we use our own vki_* types. The one exception is in
1346 PRE_REG_READn calls, where pointer types haven't been changed, because
1347 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1348 be visible.
1349
nethercote4fa681f2004-11-08 17:51:39 +00001350 XXX: some of these are arch-specific, and should be factored out.
1351*/
1352
njn61fa0af2004-11-27 15:22:24 +00001353#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f)
1354#define POST(name) POST_TEMPLATE( , vgArch_gen, name)
jsgf855d93d2003-10-13 22:26:55 +00001355
nethercoteef0c7662004-11-06 15:38:43 +00001356// Combine two 32-bit values into a 64-bit value
1357#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1358
sewardjb5f6f512005-03-10 23:59:00 +00001359//PRE(sys_exit_group, Special)
1360//{
1361// VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1362//}
jsgf855d93d2003-10-13 22:26:55 +00001363
nethercote85a456f2004-11-16 17:31:56 +00001364PRE(sys_exit, Special)
jsgf855d93d2003-10-13 22:26:55 +00001365{
sewardja922b612005-03-11 02:47:32 +00001366 /* simple; just make this thread exit */
1367 PRINT("exit( %d )", ARG1);
1368 PRE_REG_READ1(void, "exit", int, exitcode);
1369 tst->exitreason = VgSrc_ExitSyscall;
1370 tst->os_state.exitcode = ARG1;
1371 /* exit doesn't return anything (it doesn't return.)
1372 Nevertheless, if we don't do this, the result-not-assigned-
1373 yet-you-said-you-were-Special assertion in the main syscall
1374 handling logic will fire. Hence ..
1375 */
1376 SET_RESULT(0);
jsgf855d93d2003-10-13 22:26:55 +00001377}
1378
sewardjb5f6f512005-03-10 23:59:00 +00001379PRE(sys_sched_yield, MayBlock)
nethercote5b653bc2004-11-15 14:32:12 +00001380{
sewardjb5f6f512005-03-10 23:59:00 +00001381 PRINT("sched_yield()");
1382 PRE_REG_READ0(long, "sys_sched_yield");
nethercote5b653bc2004-11-15 14:32:12 +00001383}
1384
nethercote85a456f2004-11-16 17:31:56 +00001385PRE(sys_ni_syscall, Special)
nethercoteeb1c7b72004-11-11 19:43:50 +00001386{
1387 PRINT("non-existent syscall! (ni_syscall)");
1388 PRE_REG_READ0(long, "ni_syscall");
njn22cfccb2004-11-27 16:10:23 +00001389 SET_RESULT( -VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001390}
1391
sewardjb5f6f512005-03-10 23:59:00 +00001392PRE(sys_set_tid_address, 0)
rjwalshcdf1cb52004-04-29 08:40:50 +00001393{
njn22cfccb2004-11-27 16:10:23 +00001394 PRINT("sys_set_tid_address ( %p )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001395 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
rjwalshcdf1cb52004-04-29 08:40:50 +00001396}
1397
nethercote85a456f2004-11-16 17:31:56 +00001398PRE(sys_iopl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001399{
njn22cfccb2004-11-27 16:10:23 +00001400 PRINT("sys_iopl ( %d )", ARG1);
nethercote7f7e4d12004-11-15 12:28:58 +00001401 PRE_REG_READ1(long, "iopl", unsigned long, level);
jsgf855d93d2003-10-13 22:26:55 +00001402}
1403
nethercote85a456f2004-11-16 17:31:56 +00001404PRE(sys_setxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001405{
nethercote2e1c37d2004-11-13 13:57:12 +00001406 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001407 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001408 PRE_REG_READ5(long, "setxattr",
1409 char *, path, char *, name,
1410 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001411 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1412 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1413 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001414}
1415
nethercote85a456f2004-11-16 17:31:56 +00001416PRE(sys_lsetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001417{
nethercote2e1c37d2004-11-13 13:57:12 +00001418 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001419 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001420 PRE_REG_READ5(long, "lsetxattr",
1421 char *, path, char *, name,
1422 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001423 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
1424 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
1425 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001426}
1427
nethercote85a456f2004-11-16 17:31:56 +00001428PRE(sys_fsetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001429{
1430 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001431 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001432 PRE_REG_READ5(long, "fsetxattr",
1433 int, fd, char *, name, void *, value,
1434 vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001435 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1436 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001437}
1438
nethercote85a456f2004-11-16 17:31:56 +00001439PRE(sys_getxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001440{
njn22cfccb2004-11-27 16:10:23 +00001441 PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001442 PRE_REG_READ4(ssize_t, "getxattr",
1443 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001444 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
1445 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
1446 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001447}
1448
nethercote85a456f2004-11-16 17:31:56 +00001449POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001450{
njn22cfccb2004-11-27 16:10:23 +00001451 if (RES > 0 && ARG3 != (Addr)NULL) {
1452 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001453 }
1454}
1455
nethercote85a456f2004-11-16 17:31:56 +00001456PRE(sys_lgetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001457{
njn22cfccb2004-11-27 16:10:23 +00001458 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001459 PRE_REG_READ4(ssize_t, "lgetxattr",
1460 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001461 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
1462 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
1463 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001464}
1465
nethercote85a456f2004-11-16 17:31:56 +00001466POST(sys_lgetxattr)
nethercote2e1c37d2004-11-13 13:57:12 +00001467{
njn22cfccb2004-11-27 16:10:23 +00001468 if (RES > 0 && ARG3 != (Addr)NULL) {
1469 POST_MEM_WRITE( ARG3, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001470 }
1471}
1472
nethercote85a456f2004-11-16 17:31:56 +00001473PRE(sys_fgetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001474{
njn22cfccb2004-11-27 16:10:23 +00001475 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001476 PRE_REG_READ4(ssize_t, "fgetxattr",
1477 int, fd, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001478 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
1479 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001480}
1481
nethercote85a456f2004-11-16 17:31:56 +00001482POST(sys_fgetxattr)
jsgf855d93d2003-10-13 22:26:55 +00001483{
njn22cfccb2004-11-27 16:10:23 +00001484 if (RES > 0 && ARG3 != (Addr)NULL)
1485 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001486}
1487
nethercote85a456f2004-11-16 17:31:56 +00001488PRE(sys_listxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001489{
njn22cfccb2004-11-27 16:10:23 +00001490 PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001491 PRE_REG_READ3(ssize_t, "listxattr",
1492 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001493 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1494 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001495}
1496
nethercote85a456f2004-11-16 17:31:56 +00001497POST(sys_listxattr)
jsgf855d93d2003-10-13 22:26:55 +00001498{
njn22cfccb2004-11-27 16:10:23 +00001499 if (RES > 0 && ARG2 != (Addr)NULL)
1500 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001501}
1502
nethercote85a456f2004-11-16 17:31:56 +00001503PRE(sys_llistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001504{
njn22cfccb2004-11-27 16:10:23 +00001505 PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001506 PRE_REG_READ3(ssize_t, "llistxattr",
1507 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001508 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
1509 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001510}
1511
nethercote85a456f2004-11-16 17:31:56 +00001512POST(sys_llistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001513{
njn22cfccb2004-11-27 16:10:23 +00001514 if (RES > 0 && ARG2 != (Addr)NULL)
1515 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001516}
1517
nethercote85a456f2004-11-16 17:31:56 +00001518PRE(sys_flistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001519{
njn22cfccb2004-11-27 16:10:23 +00001520 PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001521 PRE_REG_READ3(ssize_t, "flistxattr",
1522 int, fd, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001523 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001524}
1525
nethercote85a456f2004-11-16 17:31:56 +00001526POST(sys_flistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001527{
njn22cfccb2004-11-27 16:10:23 +00001528 if (RES > 0 && ARG2 != (Addr)NULL)
1529 POST_MEM_WRITE( ARG2, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001530}
1531
nethercote85a456f2004-11-16 17:31:56 +00001532PRE(sys_removexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001533{
njn22cfccb2004-11-27 16:10:23 +00001534 PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001535 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001536 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1537 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001538}
1539
nethercote85a456f2004-11-16 17:31:56 +00001540PRE(sys_lremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001541{
njn22cfccb2004-11-27 16:10:23 +00001542 PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001543 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001544 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
1545 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001546}
1547
nethercote85a456f2004-11-16 17:31:56 +00001548PRE(sys_fremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001549{
njn22cfccb2004-11-27 16:10:23 +00001550 PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001551 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001552 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001553}
1554
nethercote85a456f2004-11-16 17:31:56 +00001555PRE(sys_quotactl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001556{
njn22cfccb2004-11-27 16:10:23 +00001557 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
nethercote5b653bc2004-11-15 14:32:12 +00001558 PRE_REG_READ4(long, "quotactl",
1559 unsigned int, cmd, const char *, special, vki_qid_t, id,
1560 void *, addr);
njn22cfccb2004-11-27 16:10:23 +00001561 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001562}
1563
nethercote5a945af2004-11-14 18:37:07 +00001564// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00001565PRE(sys_lookup_dcookie, 0)
jsgf855d93d2003-10-13 22:26:55 +00001566{
njn22cfccb2004-11-27 16:10:23 +00001567 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
nethercote660e4ee2004-11-12 13:29:24 +00001568 PRE_REG_READ4(long, "lookup_dcookie",
1569 vki_u32, cookie_low32, vki_u32, cookie_high32,
1570 char *, buf, vki_size_t, len);
njn22cfccb2004-11-27 16:10:23 +00001571 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
jsgf855d93d2003-10-13 22:26:55 +00001572}
1573
nethercote85a456f2004-11-16 17:31:56 +00001574POST(sys_lookup_dcookie)
jsgf855d93d2003-10-13 22:26:55 +00001575{
njn22cfccb2004-11-27 16:10:23 +00001576 if (ARG3 != (Addr)NULL)
1577 POST_MEM_WRITE( ARG3, RES);
jsgf855d93d2003-10-13 22:26:55 +00001578}
1579
nethercote85a456f2004-11-16 17:31:56 +00001580PRE(sys_fsync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001581{
njn22cfccb2004-11-27 16:10:23 +00001582 PRINT("sys_fsync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001583 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1584}
1585
nethercote85a456f2004-11-16 17:31:56 +00001586PRE(sys_fdatasync, MayBlock)
nethercotedc18c0a2004-11-14 20:06:27 +00001587{
njn22cfccb2004-11-27 16:10:23 +00001588 PRINT("sys_fdatasync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001589 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001590}
1591
nethercote85a456f2004-11-16 17:31:56 +00001592PRE(sys_msync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001593{
njn22cfccb2004-11-27 16:10:23 +00001594 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00001595 PRE_REG_READ3(long, "msync",
1596 unsigned long, start, vki_size_t, length, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001597 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001598}
1599
nethercoteef0c7662004-11-06 15:38:43 +00001600// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1601// versions of LiS (Linux Streams). They are not part of the kernel.
1602// Therefore, we have to provide this type ourself, rather than getting it
1603// from the kernel sources.
nethercoteb77dee62004-11-16 17:13:24 +00001604struct vki_pmsg_strbuf {
jsgf855d93d2003-10-13 22:26:55 +00001605 int maxlen; /* no. of bytes in buffer */
1606 int len; /* no. of bytes returned */
nethercote73b526f2004-10-31 18:48:21 +00001607 vki_caddr_t buf; /* pointer to data */
jsgf855d93d2003-10-13 22:26:55 +00001608};
1609
nethercote85a456f2004-11-16 17:31:56 +00001610PRE(sys_getpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001611{
1612 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001613 struct vki_pmsg_strbuf *ctrl;
1614 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00001615 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00001616 PRE_REG_READ5(int, "getpmsg",
1617 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1618 int *, bandp, int *, flagsp);
njn22cfccb2004-11-27 16:10:23 +00001619 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1620 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00001621 if (ctrl && ctrl->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001622 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001623 if (data && data->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001624 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
njn22cfccb2004-11-27 16:10:23 +00001625 if (ARG4)
1626 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
1627 if (ARG5)
1628 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001629}
1630
nethercote85a456f2004-11-16 17:31:56 +00001631POST(sys_getpmsg)
jsgf855d93d2003-10-13 22:26:55 +00001632{
nethercoteb77dee62004-11-16 17:13:24 +00001633 struct vki_pmsg_strbuf *ctrl;
1634 struct vki_pmsg_strbuf *data;
jsgf855d93d2003-10-13 22:26:55 +00001635
njn22cfccb2004-11-27 16:10:23 +00001636 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1637 data = (struct vki_pmsg_strbuf *)ARG3;
1638 if (RES == 0 && ctrl && ctrl->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001639 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001640 }
njn22cfccb2004-11-27 16:10:23 +00001641 if (RES == 0 && data && data->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001642 POST_MEM_WRITE( (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001643 }
1644}
1645
nethercote85a456f2004-11-16 17:31:56 +00001646PRE(sys_putpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001647{
1648 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001649 struct vki_pmsg_strbuf *ctrl;
1650 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00001651 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00001652 PRE_REG_READ5(int, "putpmsg",
1653 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1654 int, band, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001655 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1656 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00001657 if (ctrl && ctrl->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001658 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001659 if (data && data->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001660 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001661}
1662
sewardjb5f6f512005-03-10 23:59:00 +00001663PRE(sys_getitimer, 0)
jsgf855d93d2003-10-13 22:26:55 +00001664{
njn22cfccb2004-11-27 16:10:23 +00001665 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00001666 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
njn22cfccb2004-11-27 16:10:23 +00001667 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
jsgf855d93d2003-10-13 22:26:55 +00001668}
1669
nethercote85a456f2004-11-16 17:31:56 +00001670POST(sys_getitimer)
jsgf855d93d2003-10-13 22:26:55 +00001671{
njn22cfccb2004-11-27 16:10:23 +00001672 if (ARG2 != (Addr)NULL) {
1673 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
jsgf855d93d2003-10-13 22:26:55 +00001674 }
1675}
1676
sewardjb5f6f512005-03-10 23:59:00 +00001677PRE(sys_setitimer, 0)
nethercote5b653bc2004-11-15 14:32:12 +00001678{
njn22cfccb2004-11-27 16:10:23 +00001679 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00001680 PRE_REG_READ3(long, "setitimer",
1681 int, which,
1682 struct itimerval *, value, struct itimerval *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00001683 if (ARG2 != (Addr)NULL)
1684 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
1685 if (ARG3 != (Addr)NULL)
1686 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00001687}
1688
nethercote85a456f2004-11-16 17:31:56 +00001689POST(sys_setitimer)
nethercote5b653bc2004-11-15 14:32:12 +00001690{
njn22cfccb2004-11-27 16:10:23 +00001691 if (ARG3 != (Addr)NULL) {
1692 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00001693 }
1694}
1695
nethercote85a456f2004-11-16 17:31:56 +00001696PRE(sys_chroot, 0)
jsgf855d93d2003-10-13 22:26:55 +00001697{
njn22cfccb2004-11-27 16:10:23 +00001698 PRINT("sys_chroot ( %p )", ARG1);
nethercote71f05f32004-11-12 18:49:27 +00001699 PRE_REG_READ1(long, "chroot", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00001700 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00001701}
1702
nethercote85a456f2004-11-16 17:31:56 +00001703PRE(sys_madvise, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001704{
njn22cfccb2004-11-27 16:10:23 +00001705 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00001706 PRE_REG_READ3(long, "madvise",
1707 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00001708}
1709
nethercote85a456f2004-11-16 17:31:56 +00001710PRE(sys_mremap, Special)
jsgf855d93d2003-10-13 22:26:55 +00001711{
nethercote27ea8bc2004-07-10 17:21:14 +00001712 // Nb: this is different to the glibc version described in the man pages,
1713 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00001714 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
njn22cfccb2004-11-27 16:10:23 +00001715 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
nethercote06c7bd72004-11-14 19:11:56 +00001716 PRE_REG_READ5(unsigned long, "mremap",
1717 unsigned long, old_addr, unsigned long, old_size,
1718 unsigned long, new_size, unsigned long, flags,
1719 unsigned long, new_addr);
njn22cfccb2004-11-27 16:10:23 +00001720 SET_RESULT( mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) );
jsgf855d93d2003-10-13 22:26:55 +00001721}
1722
nethercote85a456f2004-11-16 17:31:56 +00001723PRE(sys_nice, 0)
jsgf855d93d2003-10-13 22:26:55 +00001724{
njn22cfccb2004-11-27 16:10:23 +00001725 PRINT("sys_nice ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00001726 PRE_REG_READ1(long, "nice", int, inc);
jsgf855d93d2003-10-13 22:26:55 +00001727}
1728
nethercote85a456f2004-11-16 17:31:56 +00001729PRE(sys_sched_getscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001730{
njn22cfccb2004-11-27 16:10:23 +00001731 PRINT("sys_sched_getscheduler ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001732 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001733}
1734
nethercote85a456f2004-11-16 17:31:56 +00001735PRE(sys_sched_setscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001736{
njn22cfccb2004-11-27 16:10:23 +00001737 PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00001738 PRE_REG_READ3(long, "sched_setscheduler",
1739 vki_pid_t, pid, int, policy, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00001740 if (ARG3 != 0)
nethercote5b653bc2004-11-15 14:32:12 +00001741 PRE_MEM_READ( "sched_setscheduler(p)",
njn22cfccb2004-11-27 16:10:23 +00001742 ARG3, sizeof(struct vki_sched_param));
jsgf855d93d2003-10-13 22:26:55 +00001743}
1744
nethercote85a456f2004-11-16 17:31:56 +00001745PRE(sys_mlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001746{
njn22cfccb2004-11-27 16:10:23 +00001747 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00001748 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001749}
1750
nethercote85a456f2004-11-16 17:31:56 +00001751PRE(sys_munlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001752{
njn22cfccb2004-11-27 16:10:23 +00001753 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00001754 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001755}
1756
nethercote85a456f2004-11-16 17:31:56 +00001757PRE(sys_mlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001758{
njn22cfccb2004-11-27 16:10:23 +00001759 PRINT("sys_mlockall ( %x )", ARG1);
nethercote06c7bd72004-11-14 19:11:56 +00001760 PRE_REG_READ1(long, "mlockall", int, flags);
jsgf855d93d2003-10-13 22:26:55 +00001761}
1762
nethercote85a456f2004-11-16 17:31:56 +00001763PRE(sys_munlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001764{
nethercote0df495a2004-11-11 16:38:21 +00001765 PRINT("sys_munlockall ( )");
1766 PRE_REG_READ0(long, "munlockall");
jsgf855d93d2003-10-13 22:26:55 +00001767}
1768
nethercote85a456f2004-11-16 17:31:56 +00001769PRE(sys_sched_get_priority_max, 0)
jsgf855d93d2003-10-13 22:26:55 +00001770{
njn22cfccb2004-11-27 16:10:23 +00001771 PRINT("sched_get_priority_max ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001772 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001773}
1774
nethercote85a456f2004-11-16 17:31:56 +00001775PRE(sys_sched_get_priority_min, 0)
jsgf855d93d2003-10-13 22:26:55 +00001776{
njn22cfccb2004-11-27 16:10:23 +00001777 PRINT("sched_get_priority_min ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001778 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001779}
1780
nethercote85a456f2004-11-16 17:31:56 +00001781PRE(sys_setpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001782{
njn22cfccb2004-11-27 16:10:23 +00001783 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00001784 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
jsgf855d93d2003-10-13 22:26:55 +00001785}
1786
nethercote85a456f2004-11-16 17:31:56 +00001787PRE(sys_getpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001788{
njn22cfccb2004-11-27 16:10:23 +00001789 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00001790 PRE_REG_READ2(long, "getpriority", int, which, int, who);
jsgf855d93d2003-10-13 22:26:55 +00001791}
1792
nethercote85a456f2004-11-16 17:31:56 +00001793PRE(sys_setregid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001794{
njn22cfccb2004-11-27 16:10:23 +00001795 PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00001796 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00001797}
1798
nethercoteac866b92004-11-15 20:23:15 +00001799// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001800PRE(sys_pwrite64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001801{
nethercoteac866b92004-11-15 20:23:15 +00001802 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00001803 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00001804 PRE_REG_READ5(ssize_t, "pwrite64",
1805 unsigned int, fd, const char *, buf, vki_size_t, count,
1806 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00001807 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001808}
1809
nethercote85a456f2004-11-16 17:31:56 +00001810PRE(sys_sync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001811{
nethercote0df495a2004-11-11 16:38:21 +00001812 PRINT("sys_sync ( )");
1813 PRE_REG_READ0(long, "sync");
jsgf855d93d2003-10-13 22:26:55 +00001814}
1815
nethercote85a456f2004-11-16 17:31:56 +00001816PRE(sys_fstatfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00001817{
njn22cfccb2004-11-27 16:10:23 +00001818 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00001819 PRE_REG_READ2(long, "fstatfs",
1820 unsigned int, fd, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00001821 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001822}
1823
nethercote85a456f2004-11-16 17:31:56 +00001824POST(sys_fstatfs)
jsgf855d93d2003-10-13 22:26:55 +00001825{
njn22cfccb2004-11-27 16:10:23 +00001826 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001827}
1828
nethercote85a456f2004-11-16 17:31:56 +00001829PRE(sys_fstatfs64, 0)
thughesa996d3b2004-09-24 22:57:17 +00001830{
njn22cfccb2004-11-27 16:10:23 +00001831 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00001832 PRE_REG_READ3(long, "fstatfs64",
1833 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00001834 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00001835}
1836
nethercote85a456f2004-11-16 17:31:56 +00001837POST(sys_fstatfs64)
thughesa996d3b2004-09-24 22:57:17 +00001838{
njn22cfccb2004-11-27 16:10:23 +00001839 POST_MEM_WRITE( ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00001840}
1841
nethercote85a456f2004-11-16 17:31:56 +00001842PRE(sys_getsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00001843{
njn22cfccb2004-11-27 16:10:23 +00001844 PRINT("sys_getsid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001845 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001846}
1847
nethercoteac866b92004-11-15 20:23:15 +00001848// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001849PRE(sys_pread64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001850{
nethercoteac866b92004-11-15 20:23:15 +00001851 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00001852 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00001853 PRE_REG_READ5(ssize_t, "pread64",
1854 unsigned int, fd, char *, buf, vki_size_t, count,
1855 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00001856 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001857}
1858
nethercote85a456f2004-11-16 17:31:56 +00001859POST(sys_pread64)
jsgf855d93d2003-10-13 22:26:55 +00001860{
njn22cfccb2004-11-27 16:10:23 +00001861 if (RES > 0) {
1862 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001863 }
1864}
1865
nethercote85a456f2004-11-16 17:31:56 +00001866PRE(sys_mknod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001867{
njn22cfccb2004-11-27 16:10:23 +00001868 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00001869 PRE_REG_READ3(long, "mknod",
1870 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00001871 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00001872}
1873
nethercote85a456f2004-11-16 17:31:56 +00001874PRE(sys_flock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001875{
njn22cfccb2004-11-27 16:10:23 +00001876 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
nethercote06c7bd72004-11-14 19:11:56 +00001877 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
jsgf855d93d2003-10-13 22:26:55 +00001878}
1879
nethercote85a456f2004-11-16 17:31:56 +00001880PRE(sys_init_module, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001881{
njn22cfccb2004-11-27 16:10:23 +00001882 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
nethercote0eafe552004-11-15 16:40:40 +00001883 PRE_REG_READ3(long, "init_module",
1884 void *, umod, unsigned long, len, const char *, uargs);
njn22cfccb2004-11-27 16:10:23 +00001885 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
1886 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001887}
1888
nethercote85a456f2004-11-16 17:31:56 +00001889PRE(sys_capget, 0)
jsgf855d93d2003-10-13 22:26:55 +00001890{
njn22cfccb2004-11-27 16:10:23 +00001891 PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00001892 PRE_REG_READ2(long, "capget",
1893 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
njn22cfccb2004-11-27 16:10:23 +00001894 PRE_MEM_READ( "capget(header)", ARG1,
nethercote73b526f2004-10-31 18:48:21 +00001895 sizeof(struct __vki_user_cap_header_struct) );
njn22cfccb2004-11-27 16:10:23 +00001896 PRE_MEM_WRITE( "capget(data)", ARG2,
nethercote73b526f2004-10-31 18:48:21 +00001897 sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001898}
1899
nethercote85a456f2004-11-16 17:31:56 +00001900POST(sys_capget)
jsgf855d93d2003-10-13 22:26:55 +00001901{
njn22cfccb2004-11-27 16:10:23 +00001902 if (ARG2 != (Addr)NULL)
1903 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001904}
1905
nethercote85a456f2004-11-16 17:31:56 +00001906PRE(sys_capset, 0)
jsgf855d93d2003-10-13 22:26:55 +00001907{
njn22cfccb2004-11-27 16:10:23 +00001908 PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00001909 PRE_REG_READ2(long, "capset",
1910 vki_cap_user_header_t, header,
1911 const vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00001912 PRE_MEM_READ( "capset(header)",
njn22cfccb2004-11-27 16:10:23 +00001913 ARG1, sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00001914 PRE_MEM_READ( "capset(data)",
njn22cfccb2004-11-27 16:10:23 +00001915 ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001916}
1917
nethercotea81e9162004-02-12 14:34:14 +00001918// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00001919static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00001920{
1921 while (True) {
njnb249fd72004-11-29 14:24:57 +00001922 Addr a_deref;
1923 Addr* a_p = (Addr*)a;
1924 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
1925 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00001926 if (0 == a_deref)
1927 break;
nethercoteef0c7662004-11-06 15:38:43 +00001928 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00001929 a += sizeof(char*);
1930 }
1931}
1932
nethercote7310afb2004-11-12 15:41:06 +00001933// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
1934// but it seems to work nonetheless...
nethercote85a456f2004-11-16 17:31:56 +00001935PRE(sys_execve, Special)
jsgf855d93d2003-10-13 22:26:55 +00001936{
sewardjb5f6f512005-03-10 23:59:00 +00001937 Char *path; /* path to executable */
1938
njn22cfccb2004-11-27 16:10:23 +00001939 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00001940 PRE_REG_READ3(vki_off_t, "execve",
1941 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00001942 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
1943 if (ARG2 != 0)
1944 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
1945 if (ARG3 != 0)
1946 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00001947
sewardjb5f6f512005-03-10 23:59:00 +00001948 path = (Char *)ARG1;
1949
fitzhardingee1c06d82003-10-30 07:21:44 +00001950 /* Erk. If the exec fails, then the following will have made a
1951 mess of things which makes it hard for us to continue. The
1952 right thing to do is piece everything together again in
1953 POST(execve), but that's hard work. Instead, we make an effort
1954 to check that the execve will work before actually calling
1955 exec. */
1956 {
1957 struct vki_stat st;
njn22cfccb2004-11-27 16:10:23 +00001958 Int ret = VG_(stat)((Char *)ARG1, &st);
fitzhardingee1c06d82003-10-30 07:21:44 +00001959
1960 if (ret < 0) {
njn22cfccb2004-11-27 16:10:23 +00001961 SET_RESULT( ret );
fitzhardingee1c06d82003-10-30 07:21:44 +00001962 return;
1963 }
thughes90efa302004-09-25 16:13:55 +00001964 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00001965 XXX do proper permissions check?
1966 */
thughes90efa302004-09-25 16:13:55 +00001967 if ((st.st_mode & 0100111) == 0100000) {
njn22cfccb2004-11-27 16:10:23 +00001968 SET_RESULT( -VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00001969 return;
1970 }
1971 }
1972
1973 /* Resistance is futile. Nuke all other threads. POSIX mandates
1974 this. (Really, nuke them all, since the new process will make
1975 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00001976 VG_(master_tid) = tid; /* become the master */
1977 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
1978 VGA_(reap_threads)(tid);
1979
1980 if (0) {
1981 /* Shut down cleanly and report final state
1982 XXX Is this reasonable? */
1983 tst->exitreason = VgSrc_ExitSyscall;
1984 VG_(shutdown_actions)(tid);
1985 }
fitzhardingee1c06d82003-10-30 07:21:44 +00001986
fitzhardinge5408c062004-01-04 23:52:59 +00001987 {
nethercote60a96c52004-08-03 13:08:31 +00001988 // Remove the valgrind-specific stuff from the environment so the
sewardjb5f6f512005-03-10 23:59:00 +00001989 // child doesn't get vg_inject.so, vgpreload.so, etc. This is
nethercote60a96c52004-08-03 13:08:31 +00001990 // done unconditionally, since if we are tracing the child,
1991 // stage1/2 will set up the appropriate client environment.
njn22cfccb2004-11-27 16:10:23 +00001992 Char** envp = (Char**)ARG3;
fitzhardinge98abfc72003-12-16 02:05:15 +00001993
1994 if (envp != NULL) {
sewardjb5f6f512005-03-10 23:59:00 +00001995 VG_(env_remove_valgrind_env_stuff)( envp );
jsgf855d93d2003-10-13 22:26:55 +00001996 }
fitzhardinge5408c062004-01-04 23:52:59 +00001997 }
1998
1999 if (VG_(clo_trace_children)) {
njn22cfccb2004-11-27 16:10:23 +00002000 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)ARG1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00002001
njn22cfccb2004-11-27 16:10:23 +00002002 // Set VALGRINDCLO and VALGRINDLIB in ARG3 (the environment)
2003 VG_(env_setenv)( (Char***)&ARG3, VALGRINDCLO, optvar);
2004 VG_(env_setenv)( (Char***)&ARG3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002005
njn22cfccb2004-11-27 16:10:23 +00002006 // Create executable name: "/proc/self/fd/<vgexecfd>", update ARG1
2007 ARG1 = (Addr)VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00002008 }
2009
2010 if (0) {
2011 Char **cpp;
2012
njn22cfccb2004-11-27 16:10:23 +00002013 VG_(printf)("exec: %s\n", (Char *)ARG1);
2014 for(cpp = (Char **)ARG2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002015 VG_(printf)("argv: %s\n", *cpp);
njn22cfccb2004-11-27 16:10:23 +00002016 for(cpp = (Char **)ARG3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002017 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00002018 }
jsgf855d93d2003-10-13 22:26:55 +00002019
sewardjb5f6f512005-03-10 23:59:00 +00002020 /* restore the DATA rlimit for the child */
2021 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2022
2023 /*
2024 Set the signal state up for exec.
2025
2026 We need to set the real signal state to make sure the exec'd
2027 process gets SIG_IGN properly.
2028
2029 Also set our real sigmask to match the client's sigmask so that
2030 the exec'd child will get the right mask. First we need to
2031 clear out any pending signals so they they don't get delivered,
2032 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002033
2034 XXX This is a bug - the signals should remain pending, and be
2035 delivered to the new process after exec. There's also a
2036 race-condition, since if someone delivers us a signal between
2037 the sigprocmask and the execve, we'll still get the signal. Oh
2038 well.
2039 */
2040 {
nethercote73b526f2004-10-31 18:48:21 +00002041 vki_sigset_t allsigs;
2042 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002043 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002044 Int i;
2045
2046 for(i = 1; i < VG_(max_signal); i++) {
2047 struct vki_sigaction sa;
2048 VG_(do_sys_sigaction)(i, NULL, &sa);
2049 if (sa.ksa_handler == VKI_SIG_IGN)
2050 VG_(sigaction)(i, &sa, NULL);
2051 else {
2052 sa.ksa_handler = VKI_SIG_DFL;
2053 VG_(sigaction)(i, &sa, NULL);
2054 }
2055 }
2056
nethercote73b526f2004-10-31 18:48:21 +00002057 VG_(sigfillset)(&allsigs);
2058 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002059 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002060
nethercote73b526f2004-10-31 18:48:21 +00002061 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002062 }
2063
sewardjb5f6f512005-03-10 23:59:00 +00002064 SET_RESULT( VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) );
fitzhardingeb50068f2004-02-24 23:42:55 +00002065
sewardjb5f6f512005-03-10 23:59:00 +00002066 /* If we got here, then the execve failed. We've already made too
2067 much of a mess of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00002068 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
sewardjb5f6f512005-03-10 23:59:00 +00002069 ARG1, ARG1, ARG2, ARG3, -RES);
2070 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2071 "execve() failing, so I'm dying.");
2072 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(execve), "
2073 "or work out how to recover.");
2074 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002075}
2076
nethercote85a456f2004-11-16 17:31:56 +00002077PRE(sys_access, 0)
jsgf855d93d2003-10-13 22:26:55 +00002078{
njn22cfccb2004-11-27 16:10:23 +00002079 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002080 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002081 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002082}
2083
sewardjb5f6f512005-03-10 23:59:00 +00002084PRE(sys_alarm, 0)
jsgf855d93d2003-10-13 22:26:55 +00002085{
njn22cfccb2004-11-27 16:10:23 +00002086 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002087 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002088}
2089
nethercote85a456f2004-11-16 17:31:56 +00002090PRE(sys_brk, Special)
jsgf855d93d2003-10-13 22:26:55 +00002091{
fitzhardinge98abfc72003-12-16 02:05:15 +00002092 Addr brk_limit = VG_(brk_limit);
2093
jsgf855d93d2003-10-13 22:26:55 +00002094 /* libc says: int brk(void *end_data_segment);
2095 kernel says: void* brk(void* end_data_segment); (more or less)
2096
2097 libc returns 0 on success, and -1 (and sets errno) on failure.
2098 Nb: if you ask to shrink the dataseg end below what it
2099 currently is, that always succeeds, even if the dataseg end
2100 doesn't actually change (eg. brk(0)). Unless it seg faults.
2101
2102 Kernel returns the new dataseg end. If the brk() failed, this
2103 will be unchanged from the old one. That's why calling (kernel)
2104 brk(0) gives the current dataseg end (libc brk() just returns
2105 zero in that case).
2106
2107 Both will seg fault if you shrink it back into a text segment.
2108 */
njn22cfccb2004-11-27 16:10:23 +00002109 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002110 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002111
njn22cfccb2004-11-27 16:10:23 +00002112 SET_RESULT( do_brk(ARG1) );
fitzhardinge98abfc72003-12-16 02:05:15 +00002113
njn22cfccb2004-11-27 16:10:23 +00002114 if (RES == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002115 /* brk() succeeded */
njn22cfccb2004-11-27 16:10:23 +00002116 if (RES < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002117 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002118 VG_TRACK( die_mem_brk, (Addr)ARG1,
2119 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002120 } else
njn22cfccb2004-11-27 16:10:23 +00002121 if (RES > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002122 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002123 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002124 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002125 }
jsgf855d93d2003-10-13 22:26:55 +00002126 } else {
2127 /* brk() failed */
njn22cfccb2004-11-27 16:10:23 +00002128 vg_assert(brk_limit == RES);
jsgf855d93d2003-10-13 22:26:55 +00002129 }
2130}
2131
nethercote85a456f2004-11-16 17:31:56 +00002132PRE(sys_chdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002133{
njn22cfccb2004-11-27 16:10:23 +00002134 PRINT("sys_chdir ( %p )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002135 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002136 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002137}
2138
nethercote85a456f2004-11-16 17:31:56 +00002139PRE(sys_chmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002140{
njn22cfccb2004-11-27 16:10:23 +00002141 PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002142 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002143 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002144}
2145
nethercote85a456f2004-11-16 17:31:56 +00002146PRE(sys_chown16, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002147{
njn22cfccb2004-11-27 16:10:23 +00002148 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002149 PRE_REG_READ3(long, "chown16",
2150 const char *, path,
2151 vki_old_uid_t, owner, vki_old_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002152 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002153}
2154
nethercote85a456f2004-11-16 17:31:56 +00002155PRE(sys_chown, 0)
jsgf855d93d2003-10-13 22:26:55 +00002156{
2157 /* int chown(const char *path, uid_t owner, gid_t group); */
njn22cfccb2004-11-27 16:10:23 +00002158 PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002159 PRE_REG_READ3(long, "chown",
2160 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002161 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002162}
2163
nethercote85a456f2004-11-16 17:31:56 +00002164PRE(sys_lchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002165{
njn22cfccb2004-11-27 16:10:23 +00002166 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002167 PRE_REG_READ3(long, "lchown",
2168 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002169 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002170}
jsgf855d93d2003-10-13 22:26:55 +00002171
nethercote85a456f2004-11-16 17:31:56 +00002172PRE(sys_close, 0)
jsgf855d93d2003-10-13 22:26:55 +00002173{
njn22cfccb2004-11-27 16:10:23 +00002174 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002175 PRE_REG_READ1(long, "close", unsigned int, fd);
2176
nethercotef8548672004-06-21 12:42:35 +00002177 /* Detect and negate attempts by the client to close Valgrind's log fd */
njn22cfccb2004-11-27 16:10:23 +00002178 if (!VG_(fd_allowed)(ARG1, "close", tid, False))
2179 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002180}
2181
nethercote85a456f2004-11-16 17:31:56 +00002182POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002183{
njn22cfccb2004-11-27 16:10:23 +00002184 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002185}
jsgf855d93d2003-10-13 22:26:55 +00002186
nethercote85a456f2004-11-16 17:31:56 +00002187PRE(sys_dup, 0)
jsgf855d93d2003-10-13 22:26:55 +00002188{
njn22cfccb2004-11-27 16:10:23 +00002189 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002190 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002191}
2192
nethercote85a456f2004-11-16 17:31:56 +00002193POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002194{
njn22cfccb2004-11-27 16:10:23 +00002195 if (!VG_(fd_allowed)(RES, "dup", tid, True)) {
2196 VG_(close)(RES);
2197 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002198 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002199 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002200 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002201 }
2202}
2203
nethercote85a456f2004-11-16 17:31:56 +00002204PRE(sys_dup2, 0)
jsgf855d93d2003-10-13 22:26:55 +00002205{
njn22cfccb2004-11-27 16:10:23 +00002206 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002207 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
njn22cfccb2004-11-27 16:10:23 +00002208 if (!VG_(fd_allowed)(ARG2, "dup2", tid, True))
2209 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002210}
2211
nethercote85a456f2004-11-16 17:31:56 +00002212POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002213{
nethercote71f05f32004-11-12 18:49:27 +00002214 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002215 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002216}
2217
nethercote85a456f2004-11-16 17:31:56 +00002218PRE(sys_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002219{
njn22cfccb2004-11-27 16:10:23 +00002220 PRINT("sys_fchdir ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002221 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00002222}
2223
nethercote85a456f2004-11-16 17:31:56 +00002224PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002225{
njn22cfccb2004-11-27 16:10:23 +00002226 PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002227 PRE_REG_READ3(long, "fchown16",
2228 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00002229}
2230
nethercote85a456f2004-11-16 17:31:56 +00002231PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002232{
njn22cfccb2004-11-27 16:10:23 +00002233 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002234 PRE_REG_READ3(long, "fchown",
2235 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2236}
jsgf855d93d2003-10-13 22:26:55 +00002237
nethercote85a456f2004-11-16 17:31:56 +00002238PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002239{
njn22cfccb2004-11-27 16:10:23 +00002240 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002241 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00002242}
2243
njnc6168192004-11-29 13:54:10 +00002244PRE(sys_fcntl, 0)
njncfb8ad52004-11-23 14:57:49 +00002245{
njn22cfccb2004-11-27 16:10:23 +00002246 switch (ARG2) {
2247 // These ones ignore ARG3.
njncfb8ad52004-11-23 14:57:49 +00002248 case VKI_F_GETFD:
2249 case VKI_F_GETFL:
2250 case VKI_F_GETOWN:
2251 case VKI_F_SETOWN:
2252 case VKI_F_GETSIG:
2253 case VKI_F_SETSIG:
2254 case VKI_F_GETLEASE:
njnc6168192004-11-29 13:54:10 +00002255 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2256 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
njncfb8ad52004-11-23 14:57:49 +00002257 break;
2258
njn22cfccb2004-11-27 16:10:23 +00002259 // These ones use ARG3 as "arg".
njncfb8ad52004-11-23 14:57:49 +00002260 case VKI_F_DUPFD:
2261 case VKI_F_SETFD:
2262 case VKI_F_SETFL:
2263 case VKI_F_SETLEASE:
2264 case VKI_F_NOTIFY:
njnc6168192004-11-29 13:54:10 +00002265 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2266 PRE_REG_READ3(long, "fcntl",
2267 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
njncfb8ad52004-11-23 14:57:49 +00002268 break;
2269
njn22cfccb2004-11-27 16:10:23 +00002270 // These ones use ARG3 as "lock".
njncfb8ad52004-11-23 14:57:49 +00002271 case VKI_F_GETLK:
2272 case VKI_F_SETLK:
2273 case VKI_F_SETLKW:
njnc6168192004-11-29 13:54:10 +00002274#ifndef __amd64__
njncfb8ad52004-11-23 14:57:49 +00002275 case VKI_F_GETLK64:
2276 case VKI_F_SETLK64:
2277 case VKI_F_SETLKW64:
njnc6168192004-11-29 13:54:10 +00002278#else
2279#endif
2280 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2281 PRE_REG_READ3(long, "fcntl",
2282 unsigned int, fd, unsigned int, cmd,
2283 struct flock64 *, lock);
njncfb8ad52004-11-23 14:57:49 +00002284 break;
2285 }
njncfb8ad52004-11-23 14:57:49 +00002286
sewardjb5f6f512005-03-10 23:59:00 +00002287 //if (ARG2 == VKI_F_SETLKW)
2288 // tst->sys_flags |= MayBlock;
njncfb8ad52004-11-23 14:57:49 +00002289}
2290
2291POST(sys_fcntl)
2292{
njn22cfccb2004-11-27 16:10:23 +00002293 if (ARG2 == VKI_F_DUPFD) {
2294 if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
2295 VG_(close)(RES);
2296 SET_RESULT( -VKI_EMFILE );
njncfb8ad52004-11-23 14:57:49 +00002297 } else {
2298 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002299 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
njncfb8ad52004-11-23 14:57:49 +00002300 }
2301 }
2302}
2303
nethercote06c7bd72004-11-14 19:11:56 +00002304// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00002305PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00002306{
njnc6168192004-11-29 13:54:10 +00002307 switch (ARG2) {
2308 // These ones ignore ARG3.
2309 case VKI_F_GETFD:
2310 case VKI_F_GETFL:
2311 case VKI_F_GETOWN:
2312 case VKI_F_SETOWN:
2313 case VKI_F_GETSIG:
2314 case VKI_F_SETSIG:
2315 case VKI_F_GETLEASE:
2316 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2317 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2318 break;
2319
2320 // These ones use ARG3 as "arg".
2321 case VKI_F_DUPFD:
2322 case VKI_F_SETFD:
2323 case VKI_F_SETFL:
2324 case VKI_F_SETLEASE:
2325 case VKI_F_NOTIFY:
2326 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2327 PRE_REG_READ3(long, "fcntl64",
2328 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2329 break;
2330
2331 // These ones use ARG3 as "lock".
2332 case VKI_F_GETLK:
2333 case VKI_F_SETLK:
2334 case VKI_F_SETLKW:
2335#ifndef __amd64__
2336 case VKI_F_GETLK64:
2337 case VKI_F_SETLK64:
2338 case VKI_F_SETLKW64:
2339#endif
2340 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2341 PRE_REG_READ3(long, "fcntl64",
2342 unsigned int, fd, unsigned int, cmd,
2343 struct flock64 *, lock);
2344 break;
2345 }
njncfb8ad52004-11-23 14:57:49 +00002346
njnc6168192004-11-29 13:54:10 +00002347#ifndef __amd64__
sewardjb5f6f512005-03-10 23:59:00 +00002348 //if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2349 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002350#else
sewardjb5f6f512005-03-10 23:59:00 +00002351 //if (ARG2 == VKI_F_SETLKW)
2352 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002353#endif
rjwalshf5f536f2003-11-17 17:45:00 +00002354}
2355
nethercote85a456f2004-11-16 17:31:56 +00002356POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002357{
njn22cfccb2004-11-27 16:10:23 +00002358 if (ARG2 == VKI_F_DUPFD) {
2359 if (!VG_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
2360 VG_(close)(RES);
2361 SET_RESULT( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002362 } else {
2363 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002364 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
nethercote493dd182004-02-24 23:57:47 +00002365 }
2366 }
jsgf855d93d2003-10-13 22:26:55 +00002367}
2368
nethercote85a456f2004-11-16 17:31:56 +00002369PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00002370{
njn22cfccb2004-11-27 16:10:23 +00002371 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00002372 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00002373 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002374}
2375
nethercote85a456f2004-11-16 17:31:56 +00002376POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00002377{
njn22cfccb2004-11-27 16:10:23 +00002378 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002379}
2380
nethercote73b526f2004-10-31 18:48:21 +00002381static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002382
nethercote75a8c982004-11-11 19:03:34 +00002383// In Linux, the sys_fork() function varies across architectures, but we
2384// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00002385PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00002386{
nethercote73b526f2004-10-31 18:48:21 +00002387 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002388
nethercote75a8c982004-11-11 19:03:34 +00002389 PRINT("sys_fork ( )");
2390 PRE_REG_READ0(long, "fork");
2391
jsgf855d93d2003-10-13 22:26:55 +00002392 /* Block all signals during fork, so that we can fix things up in
2393 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002394 VG_(sigfillset)(&mask);
2395 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002396
sewardjb5f6f512005-03-10 23:59:00 +00002397 VG_(do_atfork_pre)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002398
sewardjb5f6f512005-03-10 23:59:00 +00002399 SET_RESULT(VG_(do_syscall0)(__NR_fork));
2400
njn22cfccb2004-11-27 16:10:23 +00002401 if (RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002402 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002403
2404 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002405 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002406 } else if (RES > 0) {
2407 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002408
sewardjb5f6f512005-03-10 23:59:00 +00002409 VG_(do_atfork_parent)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002410
2411 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002412 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002413 }
2414}
2415
nethercote85a456f2004-11-16 17:31:56 +00002416PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002417{
njn22cfccb2004-11-27 16:10:23 +00002418 PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002419 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002420}
2421
nethercote85a456f2004-11-16 17:31:56 +00002422PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002423{
njn22cfccb2004-11-27 16:10:23 +00002424 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002425 PRE_REG_READ2(long, "truncate",
2426 const char *, path, unsigned long, length);
njn22cfccb2004-11-27 16:10:23 +00002427 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002428}
2429
nethercote5a945af2004-11-14 18:37:07 +00002430// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002431PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002432{
njn22cfccb2004-11-27 16:10:23 +00002433 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002434 PRE_REG_READ3(long, "ftruncate64",
2435 unsigned int, fd,
2436 vki_u32, length_low32, vki_u32, length_high32);
2437}
2438
2439// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002440PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002441{
njn22cfccb2004-11-27 16:10:23 +00002442 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002443 PRE_REG_READ3(long, "truncate64",
2444 const char *, path,
2445 vki_u32, length_low32, vki_u32, length_high32);
njn22cfccb2004-11-27 16:10:23 +00002446 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
nethercote5a945af2004-11-14 18:37:07 +00002447}
2448
2449
nethercote85a456f2004-11-16 17:31:56 +00002450PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002451{
njn22cfccb2004-11-27 16:10:23 +00002452 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002453 PRE_REG_READ3(long, "getdents",
2454 unsigned int, fd, struct linux_dirent *, dirp,
2455 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002456 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002457}
2458
nethercote85a456f2004-11-16 17:31:56 +00002459POST(sys_getdents)
jsgf855d93d2003-10-13 22:26:55 +00002460{
njn22cfccb2004-11-27 16:10:23 +00002461 if (RES > 0)
2462 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002463}
2464
nethercote85a456f2004-11-16 17:31:56 +00002465PRE(sys_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002466{
njn22cfccb2004-11-27 16:10:23 +00002467 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002468 PRE_REG_READ3(long, "getdents64",
2469 unsigned int, fd, struct linux_dirent64 *, dirp,
2470 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002471 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002472}
2473
nethercote85a456f2004-11-16 17:31:56 +00002474POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002475{
njn22cfccb2004-11-27 16:10:23 +00002476 if (RES > 0)
2477 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002478}
2479
nethercote85a456f2004-11-16 17:31:56 +00002480PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002481{
njn22cfccb2004-11-27 16:10:23 +00002482 PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002483 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002484 if (ARG1 > 0)
2485 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002486}
2487
nethercote85a456f2004-11-16 17:31:56 +00002488POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002489{
njn22cfccb2004-11-27 16:10:23 +00002490 if (ARG1 > 0 && RES > 0)
2491 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002492}
2493
nethercote85a456f2004-11-16 17:31:56 +00002494PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002495{
njn22cfccb2004-11-27 16:10:23 +00002496 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002497 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002498 if (ARG1 > 0)
2499 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002500}
2501
nethercote85a456f2004-11-16 17:31:56 +00002502POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002503{
njn22cfccb2004-11-27 16:10:23 +00002504 if (ARG1 > 0 && RES > 0)
2505 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002506}
2507
nethercote85a456f2004-11-16 17:31:56 +00002508PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002509{
nethercoteac866b92004-11-15 20:23:15 +00002510 // Note that the kernel version of getcwd() behaves quite differently to
2511 // the glibc one.
njn22cfccb2004-11-27 16:10:23 +00002512 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002513 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002514 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002515}
2516
nethercote85a456f2004-11-16 17:31:56 +00002517POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002518{
njn22cfccb2004-11-27 16:10:23 +00002519 if (RES != (Addr)NULL)
2520 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002521}
2522
nethercote85a456f2004-11-16 17:31:56 +00002523PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002524{
nethercote0df495a2004-11-11 16:38:21 +00002525 PRINT("sys_geteuid16 ( )");
2526 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002527}
2528
nethercote85a456f2004-11-16 17:31:56 +00002529PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002530{
nethercote0df495a2004-11-11 16:38:21 +00002531 PRINT("sys_geteuid ( )");
2532 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002533}
2534
nethercote85a456f2004-11-16 17:31:56 +00002535PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002536{
nethercote0df495a2004-11-11 16:38:21 +00002537 PRINT("sys_getegid16 ( )");
2538 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002539}
2540
nethercote85a456f2004-11-16 17:31:56 +00002541PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002542{
nethercote0df495a2004-11-11 16:38:21 +00002543 PRINT("sys_getegid ( )");
2544 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002545}
2546
nethercote85a456f2004-11-16 17:31:56 +00002547PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002548{
nethercote0df495a2004-11-11 16:38:21 +00002549 PRINT("sys_getgid16 ( )");
2550 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002551}
2552
nethercote85a456f2004-11-16 17:31:56 +00002553PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002554{
nethercote0df495a2004-11-11 16:38:21 +00002555 PRINT("sys_getgid ( )");
2556 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002557}
2558
nethercote85a456f2004-11-16 17:31:56 +00002559PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002560{
nethercote4e632c22004-11-09 16:45:33 +00002561 PRINT("sys_getpid ()");
2562 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002563}
2564
nethercote85a456f2004-11-16 17:31:56 +00002565PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002566{
njn22cfccb2004-11-27 16:10:23 +00002567 PRINT("sys_getpgid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002568 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002569}
2570
nethercote85a456f2004-11-16 17:31:56 +00002571PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002572{
nethercote0df495a2004-11-11 16:38:21 +00002573 PRINT("sys_getpgrp ()");
2574 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002575}
2576
nethercote85a456f2004-11-16 17:31:56 +00002577PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002578{
nethercote4e632c22004-11-09 16:45:33 +00002579 PRINT("sys_getppid ()");
2580 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002581}
2582
njncf45fd42004-11-24 16:30:22 +00002583static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002584{
nethercote620154f2004-11-12 21:21:07 +00002585 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002586
nethercote620154f2004-11-12 21:21:07 +00002587 switch (a1) {
2588 case VKI_RLIMIT_NOFILE:
2589 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2590 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2591 break;
nethercote535f03b2004-02-15 15:32:51 +00002592
nethercote620154f2004-11-12 21:21:07 +00002593 case VKI_RLIMIT_DATA:
2594 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2595 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002596
nethercote620154f2004-11-12 21:21:07 +00002597 case VKI_RLIMIT_STACK:
2598 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2599 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002600 }
jsgf855d93d2003-10-13 22:26:55 +00002601}
2602
nethercote85a456f2004-11-16 17:31:56 +00002603PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002604{
njn22cfccb2004-11-27 16:10:23 +00002605 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002606 PRE_REG_READ2(long, "old_getrlimit",
2607 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002608 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002609}
2610
nethercote85a456f2004-11-16 17:31:56 +00002611POST(sys_old_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002612{
njn22cfccb2004-11-27 16:10:23 +00002613 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002614}
2615
nethercote85a456f2004-11-16 17:31:56 +00002616PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002617{
njn22cfccb2004-11-27 16:10:23 +00002618 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002619 PRE_REG_READ2(long, "getrlimit",
2620 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002621 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002622}
2623
nethercote85a456f2004-11-16 17:31:56 +00002624POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002625{
njn22cfccb2004-11-27 16:10:23 +00002626 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002627}
jsgf855d93d2003-10-13 22:26:55 +00002628
nethercote85a456f2004-11-16 17:31:56 +00002629PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00002630{
2631 /* int getrusage (int who, struct rusage *usage); */
njn22cfccb2004-11-27 16:10:23 +00002632 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
nethercotef1049bf2004-11-14 17:03:47 +00002633 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
njn22cfccb2004-11-27 16:10:23 +00002634 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002635}
2636
nethercote85a456f2004-11-16 17:31:56 +00002637POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00002638{
njn22cfccb2004-11-27 16:10:23 +00002639 if (RES == 0)
2640 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002641}
2642
nethercote85a456f2004-11-16 17:31:56 +00002643PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00002644{
njn22cfccb2004-11-27 16:10:23 +00002645 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002646 PRE_REG_READ2(long, "gettimeofday",
2647 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00002648 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
2649 if (ARG2 != 0)
2650 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002651}
2652
nethercote85a456f2004-11-16 17:31:56 +00002653POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002654{
njn22cfccb2004-11-27 16:10:23 +00002655 if (RES == 0) {
2656 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
2657 if (ARG2 != 0)
2658 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002659 }
2660}
2661
nethercote85a456f2004-11-16 17:31:56 +00002662PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00002663{
njn22cfccb2004-11-27 16:10:23 +00002664 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002665 PRE_REG_READ2(long, "settimeofday",
2666 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00002667 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
2668 if (ARG2 != 0) {
2669 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
nethercote686b5db2004-11-14 13:42:51 +00002670 /* maybe should warn if tz->tz_dsttime is non-zero? */
2671 }
2672}
2673
nethercote85a456f2004-11-16 17:31:56 +00002674PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002675{
nethercote0df495a2004-11-11 16:38:21 +00002676 PRINT("sys_getuid16 ( )");
2677 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00002678}
2679
nethercote85a456f2004-11-16 17:31:56 +00002680PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002681{
nethercote0df495a2004-11-11 16:38:21 +00002682 PRINT("sys_getuid ( )");
2683 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00002684}
2685
nethercote2e1c37d2004-11-13 13:57:12 +00002686// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00002687PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002688{
njn22cfccb2004-11-27 16:10:23 +00002689 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00002690 PRE_REG_READ3(long, "ioctl",
2691 unsigned int, fd, unsigned int, request, unsigned long, arg);
2692
njn22cfccb2004-11-27 16:10:23 +00002693 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00002694 case VKI_TCSETS:
2695 case VKI_TCSETSW:
2696 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00002697 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002698 break;
nethercote73b526f2004-10-31 18:48:21 +00002699 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00002700 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002701 break;
nethercote73b526f2004-10-31 18:48:21 +00002702 case VKI_TCSETA:
2703 case VKI_TCSETAW:
2704 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00002705 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002706 break;
nethercote73b526f2004-10-31 18:48:21 +00002707 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00002708 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002709 break;
nethercote73b526f2004-10-31 18:48:21 +00002710 case VKI_TCSBRK:
2711 case VKI_TCXONC:
2712 case VKI_TCSBRKP:
2713 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00002714 /* These just take an int by value */
2715 break;
nethercote73b526f2004-10-31 18:48:21 +00002716 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00002717 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002718 break;
nethercote73b526f2004-10-31 18:48:21 +00002719 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00002720 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002721 break;
nethercote73b526f2004-10-31 18:48:21 +00002722 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00002723 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002724 break;
nethercote73b526f2004-10-31 18:48:21 +00002725 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00002726 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002727 break;
nethercote73b526f2004-10-31 18:48:21 +00002728 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00002729 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002730 break;
nethercote73b526f2004-10-31 18:48:21 +00002731 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00002732 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
2733 if (*(char *)ARG3 == 11) {
2734 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002735 }
2736 break;
nethercote73b526f2004-10-31 18:48:21 +00002737 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002738 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00002739 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002740 break;
nethercote73b526f2004-10-31 18:48:21 +00002741 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002742 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00002743 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002744 break;
nethercote73b526f2004-10-31 18:48:21 +00002745 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00002746 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002747 break;
nethercote73b526f2004-10-31 18:48:21 +00002748 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00002749 /* Just takes an int value. */
2750 break;
nethercote73b526f2004-10-31 18:48:21 +00002751 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00002752 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002753 break;
nethercote73b526f2004-10-31 18:48:21 +00002754 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00002755 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002756 break;
nethercote73b526f2004-10-31 18:48:21 +00002757 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00002758 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002759 break;
nethercote73b526f2004-10-31 18:48:21 +00002760 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00002761 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002762 break;
2763
nethercote73b526f2004-10-31 18:48:21 +00002764 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00002765 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002766 break;
nethercote73b526f2004-10-31 18:48:21 +00002767 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00002768 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00002769 break;
nethercote73b526f2004-10-31 18:48:21 +00002770 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00002771 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00002772 break;
nethercote73b526f2004-10-31 18:48:21 +00002773 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00002774 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002775 break;
nethercote73b526f2004-10-31 18:48:21 +00002776 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00002777 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002778 break;
nethercote73b526f2004-10-31 18:48:21 +00002779 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00002780 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002781 break;
nethercote73b526f2004-10-31 18:48:21 +00002782 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00002783 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002784 break;
nethercote73b526f2004-10-31 18:48:21 +00002785 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00002786 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002787 break;
nethercote73b526f2004-10-31 18:48:21 +00002788 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00002789 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002790 break;
nethercote73b526f2004-10-31 18:48:21 +00002791 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00002792 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002793 break;
jsgf855d93d2003-10-13 22:26:55 +00002794
muellera4b153a2003-11-19 22:07:14 +00002795 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00002796 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00002797 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00002798 break;
muellera4b153a2003-11-19 22:07:14 +00002799 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00002800 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00002801 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
2802 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
2803 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00002804 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00002805 break;
2806
2807 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00002808 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00002809 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00002810 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2811 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00002812 break;
nethercote73b526f2004-10-31 18:48:21 +00002813 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00002814 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00002815 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2816 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002817 break;
nethercote73b526f2004-10-31 18:48:21 +00002818 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00002819 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00002820 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2821 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002822 break;
nethercote73b526f2004-10-31 18:48:21 +00002823 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00002824 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00002825 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2826 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002827 break;
nethercote73b526f2004-10-31 18:48:21 +00002828 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002829 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00002830 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2831 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002832 break;
nethercote73b526f2004-10-31 18:48:21 +00002833 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00002834 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00002835 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2836 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002837 break;
nethercote73b526f2004-10-31 18:48:21 +00002838 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00002839 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00002840 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2841 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002842 break;
nethercote73b526f2004-10-31 18:48:21 +00002843 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002844 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00002845 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2846 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002847 break;
nethercote73b526f2004-10-31 18:48:21 +00002848 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002849 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00002850 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2851 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002852 break;
nethercote73b526f2004-10-31 18:48:21 +00002853 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002854 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00002855 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2856 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002857 break;
nethercote73b526f2004-10-31 18:48:21 +00002858 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002859 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00002860 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2861 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002862 break;
nethercote73b526f2004-10-31 18:48:21 +00002863 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00002864 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
njn22cfccb2004-11-27 16:10:23 +00002865 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
2866 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
2867 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002868 break;
nethercote73b526f2004-10-31 18:48:21 +00002869 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00002870 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00002871 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
2872 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002873 break;
nethercote73b526f2004-10-31 18:48:21 +00002874 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00002875 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002876 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002877 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002878 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
2879 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00002880 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002881 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
2882 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
2883 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00002884 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002885 break;
nethercote73b526f2004-10-31 18:48:21 +00002886 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00002887 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00002888 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
2889 KERNEL_DO_SYSCALL(tid,RES);
2890 if (!VG_(is_kerror)(RES) && RES == 0)
2891 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002892 */
njn22cfccb2004-11-27 16:10:23 +00002893 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct vki_ifconf));
2894 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00002895 // TODO len must be readable and writable
2896 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00002897 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00002898 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00002899 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00002900 }
2901 break;
nethercote73b526f2004-10-31 18:48:21 +00002902 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00002903 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00002904 break;
2905 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
2906 the number of bytes currently in that socket's send buffer.
2907 It writes this value as an int to the memory location
2908 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00002909 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00002910 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00002911 break;
nethercote73b526f2004-10-31 18:48:21 +00002912 case VKI_SIOCGRARP: /* get RARP table entry */
2913 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00002914 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00002915 break;
2916
nethercote73b526f2004-10-31 18:48:21 +00002917 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00002918 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00002919 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002920 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00002921 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
2922 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00002923 break;
nethercote73b526f2004-10-31 18:48:21 +00002924 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002925 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00002926 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002927 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00002928 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
2929 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00002930 break;
nethercote73b526f2004-10-31 18:48:21 +00002931 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002932 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00002933 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002934 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00002935 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
2936 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00002937 break;
nethercote73b526f2004-10-31 18:48:21 +00002938 case VKI_SIOCSIFADDR: /* set PA address */
2939 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
2940 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
2941 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00002942 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00002943 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002944 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00002945 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
2946 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00002947 break;
nethercote73b526f2004-10-31 18:48:21 +00002948 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00002949 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00002950 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002951 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00002952 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
2953 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00002954 break;
nethercote73b526f2004-10-31 18:48:21 +00002955 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00002956 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00002957 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002958 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00002959 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
2960 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00002961 break;
nethercote73b526f2004-10-31 18:48:21 +00002962 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00002963 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00002964 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002965 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00002966 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
2967 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00002968 break;
nethercote73b526f2004-10-31 18:48:21 +00002969 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00002970 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002971 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002972 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002973 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
2974 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00002975 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002976 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
2977 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00002978 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00002979 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
2980 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00002981 break;
jsgf855d93d2003-10-13 22:26:55 +00002982 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00002983 case VKI_SIOCADDRT: /* add routing table entry */
2984 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00002985 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00002986 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00002987 break;
2988
2989 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00002990 case VKI_SIOCDRARP: /* delete RARP table entry */
2991 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00002992 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00002993 case VKI_SIOCSARP: /* set ARP table entry */
2994 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00002995 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00002996 break;
2997
nethercote73b526f2004-10-31 18:48:21 +00002998 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00002999 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003000 break;
nethercote73b526f2004-10-31 18:48:21 +00003001 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003002 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardjb5f6f512005-03-10 23:59:00 +00003003 //tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003004 break;
3005
3006 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003007 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3008 case VKI_SNDCTL_SEQ_GETINCOUNT:
3009 case VKI_SNDCTL_SEQ_PERCMODE:
3010 case VKI_SNDCTL_SEQ_TESTMIDI:
3011 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3012 case VKI_SNDCTL_SEQ_NRSYNTHS:
3013 case VKI_SNDCTL_SEQ_NRMIDIS:
3014 case VKI_SNDCTL_SEQ_GETTIME:
3015 case VKI_SNDCTL_DSP_GETFMTS:
3016 case VKI_SNDCTL_DSP_GETTRIGGER:
3017 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003018 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003019 case VKI_SNDCTL_DSP_GETCAPS:
3020 case VKI_SOUND_PCM_READ_RATE:
3021 case VKI_SOUND_PCM_READ_CHANNELS:
3022 case VKI_SOUND_PCM_READ_BITS:
3023 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3024 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003025 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003026 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003027 break;
nethercote73b526f2004-10-31 18:48:21 +00003028 case VKI_SNDCTL_SEQ_CTRLRATE:
3029 case VKI_SNDCTL_DSP_SPEED:
3030 case VKI_SNDCTL_DSP_STEREO:
3031 case VKI_SNDCTL_DSP_GETBLKSIZE:
3032 case VKI_SNDCTL_DSP_CHANNELS:
3033 case VKI_SOUND_PCM_WRITE_FILTER:
3034 case VKI_SNDCTL_DSP_SUBDIVIDE:
3035 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003036 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003037 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003038 case VKI_SNDCTL_TMR_TIMEBASE:
3039 case VKI_SNDCTL_TMR_TEMPO:
3040 case VKI_SNDCTL_TMR_SOURCE:
3041 case VKI_SNDCTL_MIDI_PRETIME:
3042 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003043 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003044 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003045 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003046 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003047 break;
nethercote73b526f2004-10-31 18:48:21 +00003048 case VKI_SNDCTL_DSP_GETOSPACE:
3049 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003050 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003051 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003052 break;
nethercote73b526f2004-10-31 18:48:21 +00003053 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003054 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003055 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003056 break;
3057
nethercote73b526f2004-10-31 18:48:21 +00003058 case VKI_SNDCTL_DSP_POST:
3059 case VKI_SNDCTL_DSP_RESET:
3060 case VKI_SNDCTL_DSP_SYNC:
3061 case VKI_SNDCTL_DSP_SETSYNCRO:
3062 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003063 break;
3064
3065 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003066 case VKI_RTC_UIE_ON:
3067 case VKI_RTC_UIE_OFF:
3068 case VKI_RTC_AIE_ON:
3069 case VKI_RTC_AIE_OFF:
3070 case VKI_RTC_PIE_ON:
3071 case VKI_RTC_PIE_OFF:
3072 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003073 break;
nethercote73b526f2004-10-31 18:48:21 +00003074 case VKI_RTC_RD_TIME:
3075 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003076 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003077 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003078 break;
nethercote73b526f2004-10-31 18:48:21 +00003079 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003080 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003081 break;
nethercote73b526f2004-10-31 18:48:21 +00003082 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003083 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003084 break;
jsgf855d93d2003-10-13 22:26:55 +00003085
nethercote95a97862004-11-06 16:31:43 +00003086 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003087 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003088 break;
jsgf855d93d2003-10-13 22:26:55 +00003089
thughesacbbc322004-06-19 12:12:01 +00003090 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003091 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003092 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003093 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003094 break;
3095
jsgf855d93d2003-10-13 22:26:55 +00003096 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003097 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003098 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003099 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003100 break;
nethercote73b526f2004-10-31 18:48:21 +00003101 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003102 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003103 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003104 break;
nethercote73b526f2004-10-31 18:48:21 +00003105 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003106 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003107 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3108 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3109 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003110 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003111 break;
nethercote73b526f2004-10-31 18:48:21 +00003112 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003113 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003114 break;
nethercote73b526f2004-10-31 18:48:21 +00003115 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003116 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003117 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003118 break;
nethercote73b526f2004-10-31 18:48:21 +00003119 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003120 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003121 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3122 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003123 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003124 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3125 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3126 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003127 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003128 break;
nethercote73b526f2004-10-31 18:48:21 +00003129 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003130 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003131 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003132 break;
nethercote73b526f2004-10-31 18:48:21 +00003133 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003134 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003135 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003136 break;
nethercote73b526f2004-10-31 18:48:21 +00003137 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003138 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003139 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003140 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003141 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003142 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003143 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3144 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003145 }
3146 break;
nethercote73b526f2004-10-31 18:48:21 +00003147 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003148 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003149 break;
3150 /* The following two are probably bogus (should check args
3151 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003152 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3153 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003154 break;
thughes66d80092004-06-19 12:41:05 +00003155
nethercote73b526f2004-10-31 18:48:21 +00003156 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003157 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003158 break;
nethercote73b526f2004-10-31 18:48:21 +00003159 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003160 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003161 break;
3162
nethercote73b526f2004-10-31 18:48:21 +00003163 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003164 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003165 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003166 break;
nethercote73b526f2004-10-31 18:48:21 +00003167 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003168 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003169 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003170 break;
jsgf855d93d2003-10-13 22:26:55 +00003171
nethercote73b526f2004-10-31 18:48:21 +00003172 case VKI_PPCLAIM:
3173 case VKI_PPEXCL:
3174 case VKI_PPYIELD:
3175 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003176 break;
nethercote73b526f2004-10-31 18:48:21 +00003177 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003178 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003179 break;
nethercote73b526f2004-10-31 18:48:21 +00003180 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003181 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003182 break;
nethercote73b526f2004-10-31 18:48:21 +00003183 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003184 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003185 break;
nethercote73b526f2004-10-31 18:48:21 +00003186 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003187 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003188 break;
nethercote73b526f2004-10-31 18:48:21 +00003189 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003190 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003191 break;
nethercote73b526f2004-10-31 18:48:21 +00003192 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003193 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003194 break;
nethercote73b526f2004-10-31 18:48:21 +00003195 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003196 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003197 break;
nethercote73b526f2004-10-31 18:48:21 +00003198 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003199 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003200 break;
nethercote73b526f2004-10-31 18:48:21 +00003201 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003202 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003203 break;
nethercote73b526f2004-10-31 18:48:21 +00003204 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003205 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003206 break;
nethercote73b526f2004-10-31 18:48:21 +00003207 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003208 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003209 break;
nethercote73b526f2004-10-31 18:48:21 +00003210 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003211 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003212 break;
nethercote73b526f2004-10-31 18:48:21 +00003213 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003214 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003215 break;
nethercote73b526f2004-10-31 18:48:21 +00003216 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003217 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003218 break;
nethercote73b526f2004-10-31 18:48:21 +00003219 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003220 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003221 break;
nethercote73b526f2004-10-31 18:48:21 +00003222 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003223 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003224 break;
nethercote73b526f2004-10-31 18:48:21 +00003225 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003226 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003227 break;
nethercote73b526f2004-10-31 18:48:21 +00003228 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003229 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003230 break;
nethercote73b526f2004-10-31 18:48:21 +00003231 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003232 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003233 break;
3234
thughesb3d3bcf2004-11-13 00:36:15 +00003235 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003236 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003237 break;
3238 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003239 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003240 break;
3241
3242 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003243 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3244 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003245 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003246 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003247 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3248 32 * cfd->charcount );
3249 }
3250 break;
3251 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003252 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3253 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003254 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003255 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003256 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3257 32 * cfd->charcount );
3258 }
3259 break;
3260
3261 case VKI_PIO_FONTRESET:
3262 break;
3263
3264 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003265 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003266 break;
3267 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003268 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003269 break;
3270
3271 case VKI_KIOCSOUND:
3272 case VKI_KDMKTONE:
3273 break;
3274
3275 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003276 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003277 break;
3278 case VKI_KDSETLED:
3279 break;
3280
3281 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003282 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003283 break;
3284
3285 case VKI_KDADDIO:
3286 case VKI_KDDELIO:
3287 case VKI_KDENABIO:
3288 case VKI_KDDISABIO:
3289 break;
3290
3291 case VKI_KDSETMODE:
3292 break;
3293 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003294 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003295 break;
3296
3297 case VKI_KDMAPDISP:
3298 case VKI_KDUNMAPDISP:
3299 break;
3300
3301 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003302 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003303 break;
3304 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003305 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003306 break;
3307 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003308 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003309 VKI_E_TABSZ * sizeof(unsigned short) );
3310 break;
3311 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003312 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003313 VKI_E_TABSZ * sizeof(unsigned short) );
3314 break;
3315
3316 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003317 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003318 break;
3319 case VKI_KDSKBMODE:
3320 break;
3321
3322 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003323 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003324 break;
3325 case VKI_KDSKBMETA:
3326 break;
3327
3328 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003329 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003330 break;
3331 case VKI_KDSKBLED:
3332 break;
3333
3334 case VKI_KDGKBENT:
3335 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003336 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3337 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003338 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003339 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3340 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003341 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003342 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3343 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003344 break;
3345 case VKI_KDSKBENT:
3346 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003347 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3348 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003349 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003350 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3351 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003352 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003353 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3354 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003355 break;
3356
3357 case VKI_KDGKBSENT:
3358 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003359 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3360 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003361 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003362 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3363 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003364 break;
3365 case VKI_KDSKBSENT:
3366 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003367 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3368 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003369 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003370 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003371 break;
3372
3373 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003374 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003375 break;
3376 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003377 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003378 break;
3379
3380 case VKI_KDGETKEYCODE:
3381 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003382 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3383 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003384 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003385 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3386 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003387 break;
3388 case VKI_KDSETKEYCODE:
3389 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003390 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3391 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003392 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003393 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3394 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003395 break;
3396
3397 case VKI_KDSIGACCEPT:
3398 break;
3399
3400 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003401 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003402 break;
3403
jsgf855d93d2003-10-13 22:26:55 +00003404 /* We don't have any specific information on it, so
3405 try to do something reasonable based on direction and
3406 size bits. The encoding scheme is described in
3407 /usr/include/asm/ioctl.h.
3408
3409 According to Simon Hausmann, _IOC_READ means the kernel
3410 writes a value to the ioctl value passed from the user
3411 space and the other way around with _IOC_WRITE. */
3412 default: {
njn22cfccb2004-11-27 16:10:23 +00003413 UInt dir = _VKI_IOC_DIR(ARG2);
3414 UInt size = _VKI_IOC_SIZE(ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003415 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3416 /*
3417 * Be very lax about ioctl handling; the only
3418 * assumption is that the size is correct. Doesn't
3419 * require the full buffer to be initialized when
3420 * writing. Without this, using some device
3421 * drivers with a large number of strange ioctl
3422 * commands becomes very tiresome.
3423 */
nethercote73b526f2004-10-31 18:48:21 +00003424 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003425 static Int moans = 3;
3426 if (moans > 0) {
3427 moans--;
3428 VG_(message)(Vg_UserMsg,
3429 "Warning: noted but unhandled ioctl 0x%x"
3430 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00003431 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003432 VG_(message)(Vg_UserMsg,
3433 " This could cause spurious value errors"
3434 " to appear.");
3435 VG_(message)(Vg_UserMsg,
3436 " See README_MISSING_SYSCALL_OR_IOCTL for "
3437 "guidance on writing a proper wrapper." );
3438 }
3439 } else {
nethercote73b526f2004-10-31 18:48:21 +00003440 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003441 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00003442 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003443 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003444 }
3445 break;
3446 }
3447 }
3448}
3449
nethercote85a456f2004-11-16 17:31:56 +00003450POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003451{
njn22cfccb2004-11-27 16:10:23 +00003452 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003453 case VKI_TCSETS:
3454 case VKI_TCSETSW:
3455 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003456 break;
nethercote73b526f2004-10-31 18:48:21 +00003457 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003458 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003459 break;
nethercote73b526f2004-10-31 18:48:21 +00003460 case VKI_TCSETA:
3461 case VKI_TCSETAW:
3462 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003463 break;
nethercote73b526f2004-10-31 18:48:21 +00003464 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003465 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003466 break;
nethercote73b526f2004-10-31 18:48:21 +00003467 case VKI_TCSBRK:
3468 case VKI_TCXONC:
3469 case VKI_TCSBRKP:
3470 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003471 break;
nethercote73b526f2004-10-31 18:48:21 +00003472 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003473 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003474 break;
nethercote73b526f2004-10-31 18:48:21 +00003475 case VKI_TIOCSWINSZ:
3476 case VKI_TIOCMBIS:
3477 case VKI_TIOCMBIC:
3478 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003479 break;
nethercote73b526f2004-10-31 18:48:21 +00003480 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003481 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003482 break;
nethercote73b526f2004-10-31 18:48:21 +00003483 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003484 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003485 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003486 break;
nethercote73b526f2004-10-31 18:48:21 +00003487 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003488 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003489 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003490 break;
nethercote73b526f2004-10-31 18:48:21 +00003491 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003492 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003493 break;
nethercote73b526f2004-10-31 18:48:21 +00003494 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003495 break;
nethercote73b526f2004-10-31 18:48:21 +00003496 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003497 break;
nethercote73b526f2004-10-31 18:48:21 +00003498 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003499 break;
nethercote73b526f2004-10-31 18:48:21 +00003500 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003501 break;
nethercote73b526f2004-10-31 18:48:21 +00003502 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003503 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003504 break;
3505
nethercote73b526f2004-10-31 18:48:21 +00003506 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003507 break;
nethercote73b526f2004-10-31 18:48:21 +00003508 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003509 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003510 break;
nethercote73b526f2004-10-31 18:48:21 +00003511 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003512 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003513 break;
nethercote73b526f2004-10-31 18:48:21 +00003514 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003515 break;
nethercote73b526f2004-10-31 18:48:21 +00003516 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003517 break;
nethercote73b526f2004-10-31 18:48:21 +00003518 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003519 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003520 break;
nethercote73b526f2004-10-31 18:48:21 +00003521 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003522 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003523 break;
nethercote73b526f2004-10-31 18:48:21 +00003524 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003525 break;
nethercote73b526f2004-10-31 18:48:21 +00003526 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00003527 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003528 break;
nethercote73b526f2004-10-31 18:48:21 +00003529 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00003530 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003531 break;
jsgf855d93d2003-10-13 22:26:55 +00003532
muellera4b153a2003-11-19 22:07:14 +00003533 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003534 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003535 break;
muellera4b153a2003-11-19 22:07:14 +00003536 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00003537 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003538 break;
3539
3540 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003541 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00003542 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3543 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003544 break;
nethercote73b526f2004-10-31 18:48:21 +00003545 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00003546 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3547 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003548 break;
nethercote73b526f2004-10-31 18:48:21 +00003549 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00003550 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3551 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003552 break;
nethercote73b526f2004-10-31 18:48:21 +00003553 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00003554 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3555 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003556 break;
nethercote73b526f2004-10-31 18:48:21 +00003557 case VKI_SIOCGIFADDR: /* get PA address */
3558 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3559 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3560 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003561 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003562 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3563 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003564 break;
nethercote73b526f2004-10-31 18:48:21 +00003565 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003566 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003567 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3568 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003569 break;
nethercote73b526f2004-10-31 18:48:21 +00003570 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003571 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003572 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3573 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003574 break;
3575 break;
nethercote73b526f2004-10-31 18:48:21 +00003576 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003577 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003578 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3579 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003580 break;
nethercote73b526f2004-10-31 18:48:21 +00003581 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003582 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003583 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
3584 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003585 break;
nethercote73b526f2004-10-31 18:48:21 +00003586 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003587 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003588 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3589 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003590 break;
nethercote73b526f2004-10-31 18:48:21 +00003591 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003592 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003593 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
3594 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003595 break;
nethercote73b526f2004-10-31 18:48:21 +00003596 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003597 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003598 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3599 KERNEL_DO_SYSCALL(tid,RES);
3600 if (!VG_(is_kerror)(RES) && RES == 0)
3601 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003602 */
njn22cfccb2004-11-27 16:10:23 +00003603 if (RES == 0 && ARG3 ) {
3604 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00003605 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003606 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003607 }
3608 break;
nethercote73b526f2004-10-31 18:48:21 +00003609 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003610 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003611 break;
3612 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3613 the number of bytes currently in that socket's send buffer.
3614 It writes this value as an int to the memory location
3615 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003616 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003617 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003618 break;
nethercote73b526f2004-10-31 18:48:21 +00003619 case VKI_SIOCGRARP: /* get RARP table entry */
3620 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003621 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003622 break;
3623
nethercote73b526f2004-10-31 18:48:21 +00003624 case VKI_SIOCSIFFLAGS: /* set flags */
3625 case VKI_SIOCSIFMAP: /* Set device parameters */
3626 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3627 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3628 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3629 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3630 case VKI_SIOCSIFMETRIC: /* set metric */
3631 case VKI_SIOCSIFADDR: /* set PA address */
3632 case VKI_SIOCSIFMTU: /* set MTU size */
3633 case VKI_SIOCSIFHWADDR: /* set hardware address */
3634 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003635 break;
3636 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003637 case VKI_SIOCADDRT: /* add routing table entry */
3638 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003639 break;
3640
3641 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003642 case VKI_SIOCDRARP: /* delete RARP table entry */
3643 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003644 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003645 case VKI_SIOCSARP: /* set ARP table entry */
3646 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003647 break;
3648
nethercote73b526f2004-10-31 18:48:21 +00003649 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003650 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00003651 break;
nethercote73b526f2004-10-31 18:48:21 +00003652 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003653 break;
3654
3655 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003656 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3657 case VKI_SNDCTL_SEQ_GETINCOUNT:
3658 case VKI_SNDCTL_SEQ_PERCMODE:
3659 case VKI_SNDCTL_SEQ_TESTMIDI:
3660 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3661 case VKI_SNDCTL_SEQ_NRSYNTHS:
3662 case VKI_SNDCTL_SEQ_NRMIDIS:
3663 case VKI_SNDCTL_SEQ_GETTIME:
3664 case VKI_SNDCTL_DSP_GETFMTS:
3665 case VKI_SNDCTL_DSP_GETTRIGGER:
3666 case VKI_SNDCTL_DSP_GETODELAY:
3667 case VKI_SNDCTL_DSP_GETSPDIF:
3668 case VKI_SNDCTL_DSP_GETCAPS:
3669 case VKI_SOUND_PCM_READ_RATE:
3670 case VKI_SOUND_PCM_READ_CHANNELS:
3671 case VKI_SOUND_PCM_READ_BITS:
3672 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3673 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00003674 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003675 break;
nethercote73b526f2004-10-31 18:48:21 +00003676 case VKI_SNDCTL_SEQ_CTRLRATE:
3677 case VKI_SNDCTL_DSP_SPEED:
3678 case VKI_SNDCTL_DSP_STEREO:
3679 case VKI_SNDCTL_DSP_GETBLKSIZE:
3680 case VKI_SNDCTL_DSP_CHANNELS:
3681 case VKI_SOUND_PCM_WRITE_FILTER:
3682 case VKI_SNDCTL_DSP_SUBDIVIDE:
3683 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003684 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003685 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003686 case VKI_SNDCTL_TMR_TIMEBASE:
3687 case VKI_SNDCTL_TMR_TEMPO:
3688 case VKI_SNDCTL_TMR_SOURCE:
3689 case VKI_SNDCTL_MIDI_PRETIME:
3690 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00003691 break;
nethercote73b526f2004-10-31 18:48:21 +00003692 case VKI_SNDCTL_DSP_GETOSPACE:
3693 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00003694 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003695 break;
nethercote73b526f2004-10-31 18:48:21 +00003696 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00003697 break;
3698
nethercote73b526f2004-10-31 18:48:21 +00003699 case VKI_SNDCTL_DSP_POST:
3700 case VKI_SNDCTL_DSP_RESET:
3701 case VKI_SNDCTL_DSP_SYNC:
3702 case VKI_SNDCTL_DSP_SETSYNCRO:
3703 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003704 break;
3705
3706 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003707 case VKI_RTC_UIE_ON:
3708 case VKI_RTC_UIE_OFF:
3709 case VKI_RTC_AIE_ON:
3710 case VKI_RTC_AIE_OFF:
3711 case VKI_RTC_PIE_ON:
3712 case VKI_RTC_PIE_OFF:
3713 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003714 break;
nethercote73b526f2004-10-31 18:48:21 +00003715 case VKI_RTC_RD_TIME:
3716 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00003717 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003718 break;
nethercote73b526f2004-10-31 18:48:21 +00003719 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00003720 break;
nethercote73b526f2004-10-31 18:48:21 +00003721 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003722 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003723 break;
jsgf855d93d2003-10-13 22:26:55 +00003724
nethercote95a97862004-11-06 16:31:43 +00003725 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003726 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003727 break;
jsgf855d93d2003-10-13 22:26:55 +00003728
thughesacbbc322004-06-19 12:12:01 +00003729 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003730 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003731 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003732 break;
3733
jsgf855d93d2003-10-13 22:26:55 +00003734 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003735 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00003736 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003737 break;
nethercote73b526f2004-10-31 18:48:21 +00003738 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003739 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003740 break;
nethercote73b526f2004-10-31 18:48:21 +00003741 case VKI_CDROMREADTOCENTRY:
njn22cfccb2004-11-27 16:10:23 +00003742 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003743 break;
nethercote73b526f2004-10-31 18:48:21 +00003744 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00003745 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003746 break;
nethercote73b526f2004-10-31 18:48:21 +00003747 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00003748 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003749 break;
nethercote73b526f2004-10-31 18:48:21 +00003750 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00003751 {
njn22cfccb2004-11-27 16:10:23 +00003752 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003753 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003754 break;
3755 }
3756
nethercote73b526f2004-10-31 18:48:21 +00003757 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00003758 break;
3759 /* The following two are probably bogus (should check args
3760 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003761 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3762 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003763 break;
3764
nethercote73b526f2004-10-31 18:48:21 +00003765 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003766 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003767 break;
nethercote73b526f2004-10-31 18:48:21 +00003768 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003769 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003770 break;
3771
nethercote73b526f2004-10-31 18:48:21 +00003772 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00003773 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003774 break;
nethercote73b526f2004-10-31 18:48:21 +00003775 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00003776 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003777 break;
3778
nethercote73b526f2004-10-31 18:48:21 +00003779 case VKI_PPCLAIM:
3780 case VKI_PPEXCL:
3781 case VKI_PPYIELD:
3782 case VKI_PPRELEASE:
3783 case VKI_PPSETMODE:
3784 case VKI_PPSETPHASE:
3785 case VKI_PPSETFLAGS:
3786 case VKI_PPWDATA:
3787 case VKI_PPWCONTROL:
3788 case VKI_PPFCONTROL:
3789 case VKI_PPDATADIR:
3790 case VKI_PPNEGOT:
3791 case VKI_PPWCTLONIRQ:
3792 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00003793 break;
nethercote73b526f2004-10-31 18:48:21 +00003794 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003795 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003796 break;
nethercote73b526f2004-10-31 18:48:21 +00003797 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003798 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003799 break;
nethercote73b526f2004-10-31 18:48:21 +00003800 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003801 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003802 break;
nethercote73b526f2004-10-31 18:48:21 +00003803 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003804 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003805 break;
nethercote73b526f2004-10-31 18:48:21 +00003806 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003807 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003808 break;
nethercote73b526f2004-10-31 18:48:21 +00003809 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003810 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003811 break;
nethercote73b526f2004-10-31 18:48:21 +00003812 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003813 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003814 break;
nethercote73b526f2004-10-31 18:48:21 +00003815 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003816 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003817 break;
nethercote73b526f2004-10-31 18:48:21 +00003818 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003819 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003820 break;
3821
thughesc3b842d2004-11-13 10:38:04 +00003822 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003823 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00003824 break;
3825 case VKI_PIO_FONT:
3826 break;
3827
3828 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003829 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
3830 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00003831 break;
3832 case VKI_PIO_FONTX:
3833 break;
3834
3835 case VKI_PIO_FONTRESET:
3836 break;
3837
3838 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003839 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00003840 break;
3841 case VKI_PIO_CMAP:
3842 break;
3843
3844 case VKI_KIOCSOUND:
3845 case VKI_KDMKTONE:
3846 break;
3847
3848 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003849 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00003850 break;
3851 case VKI_KDSETLED:
3852 break;
3853
3854 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003855 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00003856 break;
3857
3858 case VKI_KDADDIO:
3859 case VKI_KDDELIO:
3860 case VKI_KDENABIO:
3861 case VKI_KDDISABIO:
3862 break;
3863
3864 case VKI_KDSETMODE:
3865 break;
3866 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003867 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00003868 break;
3869
3870 case VKI_KDMAPDISP:
3871 case VKI_KDUNMAPDISP:
3872 break;
3873
3874 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003875 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00003876 break;
3877 case VKI_PIO_SCRNMAP:
3878 break;
3879 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003880 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00003881 break;
3882 case VKI_PIO_UNISCRNMAP:
3883 break;
3884
3885 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003886 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00003887 break;
3888 case VKI_KDSKBMODE:
3889 break;
3890
3891 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003892 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00003893 break;
3894 case VKI_KDSKBMETA:
3895 break;
3896
3897 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003898 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00003899 break;
3900 case VKI_KDSKBLED:
3901 break;
3902
3903 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00003904 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3905 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00003906 break;
3907 case VKI_KDSKBENT:
3908 break;
3909
3910 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00003911 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3912 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00003913 break;
3914 case VKI_KDSKBSENT:
3915 break;
3916
3917 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003918 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00003919 break;
3920 case VKI_KDSKBDIACR:
3921 break;
3922
3923 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00003924 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3925 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00003926 break;
3927 case VKI_KDSETKEYCODE:
3928 break;
3929
3930 case VKI_KDSIGACCEPT:
3931 break;
3932
3933 case VKI_KDKBDREP:
3934 break;
3935
jsgf855d93d2003-10-13 22:26:55 +00003936 /* We don't have any specific information on it, so
3937 try to do something reasonable based on direction and
3938 size bits. The encoding scheme is described in
3939 /usr/include/asm/ioctl.h.
3940
3941 According to Simon Hausmann, _IOC_READ means the kernel
3942 writes a value to the ioctl value passed from the user
3943 space and the other way around with _IOC_WRITE. */
3944 default: {
njn22cfccb2004-11-27 16:10:23 +00003945 UInt dir = _VKI_IOC_DIR(ARG2);
3946 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00003947 if (size > 0 && (dir & _VKI_IOC_READ)
njn22cfccb2004-11-27 16:10:23 +00003948 && RES == 0
3949 && ARG3 != (Addr)NULL)
3950 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003951 break;
3952 }
3953 }
3954}
3955
nethercote85a456f2004-11-16 17:31:56 +00003956PRE(sys_kill, 0)
jsgf855d93d2003-10-13 22:26:55 +00003957{
3958 /* int kill(pid_t pid, int sig); */
njn22cfccb2004-11-27 16:10:23 +00003959 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00003960 PRE_REG_READ2(long, "kill", int, pid, int, sig);
sewardjb5f6f512005-03-10 23:59:00 +00003961 if (!VG_(client_signal_OK)(ARG2))
njn22cfccb2004-11-27 16:10:23 +00003962 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00003963}
3964
nethercote85a456f2004-11-16 17:31:56 +00003965POST(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00003966{
sewardjb5f6f512005-03-10 23:59:00 +00003967 if (VG_(clo_trace_signals))
3968 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
3969 ARG2, ARG1);
3970 // Check to see if this kill gave us a pending signal
3971 VG_(poll_signals)(tid);
jsgf855d93d2003-10-13 22:26:55 +00003972}
3973
nethercote85a456f2004-11-16 17:31:56 +00003974PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00003975{
njn22cfccb2004-11-27 16:10:23 +00003976 PRINT("sys_link ( %p, %p)", ARG1, ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00003977 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00003978 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
3979 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003980}
3981
nethercote85a456f2004-11-16 17:31:56 +00003982PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00003983{
njn22cfccb2004-11-27 16:10:23 +00003984 PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00003985 PRE_REG_READ3(vki_off_t, "lseek",
3986 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00003987}
3988
nethercote85a456f2004-11-16 17:31:56 +00003989PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00003990{
njn22cfccb2004-11-27 16:10:23 +00003991 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00003992 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00003993 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
3994 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00003995}
3996
nethercote85a456f2004-11-16 17:31:56 +00003997POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00003998{
njn22cfccb2004-11-27 16:10:23 +00003999 if (RES == 0) {
4000 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004001 }
4002}
4003
njnc6168192004-11-29 13:54:10 +00004004// XXX: this syscall is generic, but not necessarily applicable to every
4005// architecture -- I think only to 32-bit archs. We're going to need
4006// something like linux/core_os32.h for such things, eventually, I think.
4007// --njn
4008#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00004009PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004010{
njn22cfccb2004-11-27 16:10:23 +00004011 PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004012 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004013 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
4014 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004015}
4016
nethercote85a456f2004-11-16 17:31:56 +00004017POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004018{
njn22cfccb2004-11-27 16:10:23 +00004019 if (RES == 0) {
4020 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004021 }
4022}
njnc6168192004-11-29 13:54:10 +00004023#endif
jsgf855d93d2003-10-13 22:26:55 +00004024
nethercote85a456f2004-11-16 17:31:56 +00004025PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004026{
njn22cfccb2004-11-27 16:10:23 +00004027 PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004028 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004029 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004030}
4031
nethercote85a456f2004-11-16 17:31:56 +00004032PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004033{
nethercote151effa2004-11-15 12:57:39 +00004034 /* struct mmap_arg_struct {
4035 unsigned long addr;
4036 unsigned long len;
4037 unsigned long prot;
4038 unsigned long flags;
4039 unsigned long fd;
4040 unsigned long offset;
4041 }; */
jsgf855d93d2003-10-13 22:26:55 +00004042 UInt a1, a2, a3, a4, a5, a6;
4043
nethercote151effa2004-11-15 12:57:39 +00004044 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
nethercote6456ab12004-10-18 14:47:48 +00004045 PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004046
nethercote151effa2004-11-15 12:57:39 +00004047 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4048 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004049
sewardjb5f6f512005-03-10 23:59:00 +00004050 if (a2 == 0) {
4051 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4052 shall be established. */
4053 SET_RESULT( -VKI_EINVAL );
4054 return;
4055 }
4056
fitzhardinge98abfc72003-12-16 02:05:15 +00004057 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004058 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004059 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
njn22cfccb2004-11-27 16:10:23 +00004060 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004061 }
4062 } else {
nethercote6456ab12004-10-18 14:47:48 +00004063 a1 = VG_(find_map_space)(a1, a2, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00004064 if (a1 == 0)
njn22cfccb2004-11-27 16:10:23 +00004065 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004066 else
nethercote151effa2004-11-15 12:57:39 +00004067 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004068 }
jsgf855d93d2003-10-13 22:26:55 +00004069
njn22cfccb2004-11-27 16:10:23 +00004070 if (RES != -VKI_ENOMEM) {
4071 PLATFORM_DO_MMAP(RES, a1, a2, a3, a4, a5, a6);
sewardj004e8ca2005-02-28 17:27:04 +00004072 SET_RESULT(RES);
fitzhardingec2d65072004-01-07 08:44:43 +00004073
njn22cfccb2004-11-27 16:10:23 +00004074 if (!VG_(is_kerror)(RES)) {
4075 vg_assert(VG_(valid_client_addr)(RES, a2, tid, "old_mmap"));
4076 mmap_segment( (Addr)RES, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004077 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004078 }
jsgf855d93d2003-10-13 22:26:55 +00004079}
4080
nethercote3d5e9102004-11-17 18:22:38 +00004081PRE(sys_mmap2, 0)
4082{
4083 // Exactly like old_mmap() except:
4084 // - all 6 args are passed in regs, rather than in a memory-block.
4085 // - the file offset is specified in pagesize units rather than bytes,
4086 // so that it can be used for files bigger than 2^32 bytes.
4087 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
njn22cfccb2004-11-27 16:10:23 +00004088 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
nethercote3d5e9102004-11-17 18:22:38 +00004089 PRE_REG_READ6(long, "mmap2",
4090 unsigned long, start, unsigned long, length,
4091 unsigned long, prot, unsigned long, flags,
4092 unsigned long, fd, unsigned long, offset);
4093
sewardjb5f6f512005-03-10 23:59:00 +00004094 if (ARG2 == 0) {
4095 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4096 shall be established. */
4097 SET_RESULT( -VKI_EINVAL );
4098 return;
4099 }
4100
njn22cfccb2004-11-27 16:10:23 +00004101 if (ARG4 & VKI_MAP_FIXED) {
4102 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
4103 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004104 } else {
njn22cfccb2004-11-27 16:10:23 +00004105 ARG1 = VG_(find_map_space)(ARG1, ARG2, True);
4106 if (ARG1 == 0)
4107 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004108 else
njn22cfccb2004-11-27 16:10:23 +00004109 ARG4 |= VKI_MAP_FIXED;
nethercote3d5e9102004-11-17 18:22:38 +00004110 }
4111}
4112
4113POST(sys_mmap2)
4114{
njn22cfccb2004-11-27 16:10:23 +00004115 vg_assert(VG_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
4116 mmap_segment( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
4117 ARG6 * (ULong)VKI_PAGE_SIZE );
nethercote3d5e9102004-11-17 18:22:38 +00004118}
4119
nethercote85a456f2004-11-16 17:31:56 +00004120PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004121{
njn22cfccb2004-11-27 16:10:23 +00004122 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004123 PRE_REG_READ3(long, "mprotect",
4124 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004125
njn22cfccb2004-11-27 16:10:23 +00004126 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
4127 SET_RESULT( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004128}
4129
nethercote85a456f2004-11-16 17:31:56 +00004130POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004131{
njn22cfccb2004-11-27 16:10:23 +00004132 Addr a = ARG1;
4133 SizeT len = ARG2;
4134 Int prot = ARG3;
nethercote27ea8bc2004-07-10 17:21:14 +00004135 Bool rr = prot & VKI_PROT_READ;
4136 Bool ww = prot & VKI_PROT_WRITE;
4137 Bool xx = prot & VKI_PROT_EXEC;
4138
nethercote27ea8bc2004-07-10 17:21:14 +00004139 mash_addr_and_len(&a, &len);
4140 VG_(mprotect_range)(a, len, prot);
4141 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004142}
4143
nethercote85a456f2004-11-16 17:31:56 +00004144PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004145{
njn22cfccb2004-11-27 16:10:23 +00004146 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004147 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004148
njn22cfccb2004-11-27 16:10:23 +00004149 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4150 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004151}
4152
nethercote85a456f2004-11-16 17:31:56 +00004153POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004154{
njn22cfccb2004-11-27 16:10:23 +00004155 Addr a = ARG1;
4156 SizeT len = ARG2;
nethercote27ea8bc2004-07-10 17:21:14 +00004157
4158 mash_addr_and_len(&a, &len);
4159 VG_(unmap_range)(a, len);
4160 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004161}
4162
nethercote85a456f2004-11-16 17:31:56 +00004163PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004164{
njn22cfccb2004-11-27 16:10:23 +00004165 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00004166 PRE_REG_READ3(long, "mincore",
4167 unsigned long, start, vki_size_t, length,
4168 unsigned char *, vec);
njn22cfccb2004-11-27 16:10:23 +00004169 PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004170}
4171
nethercote85a456f2004-11-16 17:31:56 +00004172POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004173{
njn22cfccb2004-11-27 16:10:23 +00004174 POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004175}
4176
nethercote85a456f2004-11-16 17:31:56 +00004177PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004178{
njn22cfccb2004-11-27 16:10:23 +00004179 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004180 PRE_REG_READ2(long, "nanosleep",
4181 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004182 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4183 if (ARG2 != 0)
4184 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004185}
4186
nethercote85a456f2004-11-16 17:31:56 +00004187POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004188{
njn22cfccb2004-11-27 16:10:23 +00004189 if (ARG2 != 0 && RES == -VKI_EINTR)
4190 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004191}
4192
nethercote85a456f2004-11-16 17:31:56 +00004193PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004194{
njn22cfccb2004-11-27 16:10:23 +00004195 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004196 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004197 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004198 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004199 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004200 } else {
nethercotee824cc42004-11-09 16:20:46 +00004201 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004202 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004203 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004204 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004205 }
njn22cfccb2004-11-27 16:10:23 +00004206 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004207}
4208
nethercote85a456f2004-11-16 17:31:56 +00004209POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004210{
njn22cfccb2004-11-27 16:10:23 +00004211 if (!VG_(fd_allowed)(RES, "open", tid, True)) {
4212 VG_(close)(RES);
4213 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004214 } else {
nethercote493dd182004-02-24 23:57:47 +00004215 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004216 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004217 }
jsgf855d93d2003-10-13 22:26:55 +00004218}
4219
nethercote85a456f2004-11-16 17:31:56 +00004220PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004221{
njn22cfccb2004-11-27 16:10:23 +00004222 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004223 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004224 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004225
njn22cfccb2004-11-27 16:10:23 +00004226 if (!VG_(fd_allowed)(ARG1, "read", tid, False))
4227 SET_RESULT( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004228 else
njn22cfccb2004-11-27 16:10:23 +00004229 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004230}
4231
nethercote85a456f2004-11-16 17:31:56 +00004232POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004233{
njn22cfccb2004-11-27 16:10:23 +00004234 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004235}
4236
nethercote85a456f2004-11-16 17:31:56 +00004237PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004238{
njn22cfccb2004-11-27 16:10:23 +00004239 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004240 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004241 unsigned int, fd, const char *, buf, vki_size_t, count);
njn22cfccb2004-11-27 16:10:23 +00004242 if (!VG_(fd_allowed)(ARG1, "write", tid, False))
4243 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004244 else
njn22cfccb2004-11-27 16:10:23 +00004245 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004246}
4247
nethercote85a456f2004-11-16 17:31:56 +00004248PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004249{
njn22cfccb2004-11-27 16:10:23 +00004250 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004251 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004252 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004253}
4254
nethercote85a456f2004-11-16 17:31:56 +00004255POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004256{
njn22cfccb2004-11-27 16:10:23 +00004257 if (!VG_(fd_allowed)(RES, "creat", tid, True)) {
4258 VG_(close)(RES);
4259 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004260 } else {
nethercote493dd182004-02-24 23:57:47 +00004261 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004262 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004263 }
jsgf855d93d2003-10-13 22:26:55 +00004264}
4265
nethercote9a3beb92004-11-12 17:07:26 +00004266// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004267PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004268{
njn22cfccb2004-11-27 16:10:23 +00004269 PRINT("sys_pipe ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004270 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
njn22cfccb2004-11-27 16:10:23 +00004271 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004272}
4273
nethercote85a456f2004-11-16 17:31:56 +00004274POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004275{
njn22cfccb2004-11-27 16:10:23 +00004276 Int *p = (Int *)ARG1;
jsgf855d93d2003-10-13 22:26:55 +00004277
nethercote3d5e9102004-11-17 18:22:38 +00004278 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4279 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004280 VG_(close)(p[0]);
4281 VG_(close)(p[1]);
njn22cfccb2004-11-27 16:10:23 +00004282 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004283 } else {
njn22cfccb2004-11-27 16:10:23 +00004284 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004285 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004286 VG_(record_fd_open)(tid, p[0], NULL);
4287 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004288 }
4289 }
jsgf855d93d2003-10-13 22:26:55 +00004290}
4291
nethercotef90953e2004-11-15 14:50:02 +00004292// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004293PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004294{
4295 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004296 int fd; -- file descriptor
4297 short events; -- requested events
4298 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004299 };
nethercoteeb0592d2004-11-05 12:02:27 +00004300 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004301 */
nethercoteeb0592d2004-11-05 12:02:27 +00004302 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004303 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
4304 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00004305 PRE_REG_READ3(long, "poll",
4306 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004307
njn22cfccb2004-11-27 16:10:23 +00004308 for (i = 0; i < ARG2; i++) {
nethercoteeb0592d2004-11-05 12:02:27 +00004309 // 'fd' and 'events' field are inputs; 'revents' is output.
4310 // XXX: this is x86 specific -- the pollfd struct varies across
4311 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004312 PRE_MEM_READ( "poll(ufds)",
4313 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4314 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4315 }
jsgf855d93d2003-10-13 22:26:55 +00004316}
4317
nethercote85a456f2004-11-16 17:31:56 +00004318POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004319{
njn22cfccb2004-11-27 16:10:23 +00004320 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004321 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004322 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
nethercoteeb0592d2004-11-05 12:02:27 +00004323 // XXX: again, this is x86-specific
njn22cfccb2004-11-27 16:10:23 +00004324 for (i = 0; i < ARG2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004325 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004326 }
4327}
4328
rjwalsh17d85302004-11-18 22:56:09 +00004329PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004330{
rjwalsh093047d2004-11-19 02:11:56 +00004331 int saved = SYSNO;
njn22cfccb2004-11-27 16:10:23 +00004332 PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00004333 PRE_REG_READ3(long, "readlink",
4334 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00004335 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4336 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004337
rjwalsh17d85302004-11-18 22:56:09 +00004338 /*
rjwalsh093047d2004-11-19 02:11:56 +00004339 * Handle the case where readlink is looking at /proc/self/exe or
4340 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004341 */
4342
njnca6fef02004-11-29 16:49:18 +00004343 SET_RESULT( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
njn22cfccb2004-11-27 16:10:23 +00004344 if ((Int)RES == -2) {
rjwalsh093047d2004-11-19 02:11:56 +00004345 char name[25];
4346
4347 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004348
njn22cfccb2004-11-27 16:10:23 +00004349 if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
4350 VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
rjwalsh093047d2004-11-19 02:11:56 +00004351 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
njnca6fef02004-11-29 16:49:18 +00004352 SET_RESULT( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004353 }
rjwalsh17d85302004-11-18 22:56:09 +00004354 }
4355
njn22cfccb2004-11-27 16:10:23 +00004356 if ((Int)RES > 0)
4357 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004358}
4359
nethercote85a456f2004-11-16 17:31:56 +00004360PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004361{
jsgf855d93d2003-10-13 22:26:55 +00004362 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004363 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00004364 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00004365 PRE_REG_READ3(ssize_t, "readv",
4366 unsigned long, fd, const struct iovec *, vector,
4367 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00004368 if (!VG_(fd_allowed)(ARG1, "readv", tid, False)) {
4369 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004370 } else {
njn22cfccb2004-11-27 16:10:23 +00004371 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004372
njn22cfccb2004-11-27 16:10:23 +00004373 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004374 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00004375 vec = (struct vki_iovec *)ARG2;
4376 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00004377 PRE_MEM_WRITE( "readv(vector[...])",
4378 (Addr)vec[i].iov_base, vec[i].iov_len );
4379 }
jsgf855d93d2003-10-13 22:26:55 +00004380 }
4381}
4382
nethercote85a456f2004-11-16 17:31:56 +00004383POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004384{
njn22cfccb2004-11-27 16:10:23 +00004385 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004386 Int i;
njn22cfccb2004-11-27 16:10:23 +00004387 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4388 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00004389
njn22cfccb2004-11-27 16:10:23 +00004390 /* RES holds the number of bytes read. */
4391 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00004392 Int nReadThisBuf = vec[i].iov_len;
4393 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004394 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004395 remains -= nReadThisBuf;
4396 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4397 }
4398 }
4399}
4400
nethercote85a456f2004-11-16 17:31:56 +00004401PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004402{
njn22cfccb2004-11-27 16:10:23 +00004403 PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
nethercote9a3beb92004-11-12 17:07:26 +00004404 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004405 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4406 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004407}
4408
nethercote85a456f2004-11-16 17:31:56 +00004409PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004410{
njn22cfccb2004-11-27 16:10:23 +00004411 PRINT("sys_rmdir ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004412 PRE_REG_READ1(long, "rmdir", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00004413 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004414}
4415
nethercote85a456f2004-11-16 17:31:56 +00004416PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004417{
njn22cfccb2004-11-27 16:10:23 +00004418 PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004419 PRE_REG_READ2(long, "sched_setparam",
4420 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004421 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004422}
4423
nethercote85a456f2004-11-16 17:31:56 +00004424POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004425{
njn22cfccb2004-11-27 16:10:23 +00004426 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004427}
4428
nethercote85a456f2004-11-16 17:31:56 +00004429PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004430{
njn22cfccb2004-11-27 16:10:23 +00004431 PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004432 PRE_REG_READ2(long, "sched_getparam",
4433 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004434 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004435}
4436
nethercote85a456f2004-11-16 17:31:56 +00004437POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004438{
njn22cfccb2004-11-27 16:10:23 +00004439 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004440}
4441
nethercote85a456f2004-11-16 17:31:56 +00004442PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004443{
njn22cfccb2004-11-27 16:10:23 +00004444 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00004445 PRE_REG_READ5(long, "select",
4446 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4447 vki_fd_set *, exceptfds, struct timeval *, timeout);
4448 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00004449 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004450 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00004451 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4452 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004453 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00004454 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4455 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004456 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00004457 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4458 if (ARG5 != 0)
4459 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00004460}
4461
nethercote85a456f2004-11-16 17:31:56 +00004462PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004463{
njn22cfccb2004-11-27 16:10:23 +00004464 PRINT("sys_setgid16 ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004465 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4466}
4467
nethercote85a456f2004-11-16 17:31:56 +00004468PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004469{
njn22cfccb2004-11-27 16:10:23 +00004470 PRINT("sys_setgid ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004471 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004472}
4473
nethercote85a456f2004-11-16 17:31:56 +00004474PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004475{
nethercote0df495a2004-11-11 16:38:21 +00004476 PRINT("sys_setsid ( )");
4477 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004478}
4479
nethercote85a456f2004-11-16 17:31:56 +00004480PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004481{
njn22cfccb2004-11-27 16:10:23 +00004482 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004483 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004484 if (ARG1 > 0)
4485 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00004486}
4487
nethercote85a456f2004-11-16 17:31:56 +00004488PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004489{
njn22cfccb2004-11-27 16:10:23 +00004490 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004491 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004492 if (ARG1 > 0)
4493 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004494}
4495
nethercote85a456f2004-11-16 17:31:56 +00004496PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004497{
njn22cfccb2004-11-27 16:10:23 +00004498 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
nethercote9c311eb2004-11-12 18:20:12 +00004499 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004500}
4501
nethercote85a456f2004-11-16 17:31:56 +00004502PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004503{
njn22cfccb2004-11-27 16:10:23 +00004504 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004505 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004506}
4507
nethercote85a456f2004-11-16 17:31:56 +00004508PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004509{
njn22cfccb2004-11-27 16:10:23 +00004510 PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004511 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4512}
4513
nethercote85a456f2004-11-16 17:31:56 +00004514PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004515{
njn22cfccb2004-11-27 16:10:23 +00004516 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004517 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004518}
4519
nethercote85a456f2004-11-16 17:31:56 +00004520PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004521{
njn22cfccb2004-11-27 16:10:23 +00004522 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004523 PRE_REG_READ2(long, "setrlimit",
4524 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00004525 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004526
njn22cfccb2004-11-27 16:10:23 +00004527 if (ARG1 == VKI_RLIMIT_NOFILE) {
4528 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4529 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4530 SET_RESULT( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004531 }
4532 else {
njn22cfccb2004-11-27 16:10:23 +00004533 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
4534 SET_RESULT( 0 );
thughesad1c9562004-06-26 11:27:52 +00004535 }
4536 }
njn22cfccb2004-11-27 16:10:23 +00004537 else if (ARG1 == VKI_RLIMIT_DATA) {
4538 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4539 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
4540 SET_RESULT( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004541 }
4542 else {
njn22cfccb2004-11-27 16:10:23 +00004543 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
4544 SET_RESULT( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004545 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004546 }
njn22cfccb2004-11-27 16:10:23 +00004547 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
4548 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4549 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
4550 SET_RESULT( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004551 }
4552 else {
njn22cfccb2004-11-27 16:10:23 +00004553 VG_(threads)[tid].stack_size = ((struct vki_rlimit *)ARG2)->rlim_cur;
4554 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
4555 SET_RESULT( 0 );
thughesc37184f2004-09-11 14:16:57 +00004556 }
4557 }
jsgf855d93d2003-10-13 22:26:55 +00004558}
4559
nethercote85a456f2004-11-16 17:31:56 +00004560PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004561{
njn22cfccb2004-11-27 16:10:23 +00004562 PRINT("sys_setuid16 ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004563 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004564}
4565
nethercote85a456f2004-11-16 17:31:56 +00004566PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00004567{
njn22cfccb2004-11-27 16:10:23 +00004568 PRINT("sys_setuid ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004569 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4570}
jsgf855d93d2003-10-13 22:26:55 +00004571
nethercote85a456f2004-11-16 17:31:56 +00004572PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004573{
sewardj9efbbef2005-03-01 16:45:23 +00004574# define ARG2_0 (((UWord*)ARG2)[0])
4575# define ARG2_1 (((UWord*)ARG2)[1])
4576# define ARG2_2 (((UWord*)ARG2)[2])
4577# define ARG2_3 (((UWord*)ARG2)[3])
4578# define ARG2_4 (((UWord*)ARG2)[4])
4579# define ARG2_5 (((UWord*)ARG2)[5])
4580
njn22cfccb2004-11-27 16:10:23 +00004581 PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00004582 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4583
njn22cfccb2004-11-27 16:10:23 +00004584 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00004585
nethercote73b526f2004-10-31 18:48:21 +00004586 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00004587 /* int socketpair(int d, int type, int protocol, int sv[2]); */
njn22cfccb2004-11-27 16:10:23 +00004588 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004589 VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00004590 break;
4591
nethercote73b526f2004-10-31 18:48:21 +00004592 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00004593 /* int socket(int domain, int type, int protocol); */
njn22cfccb2004-11-27 16:10:23 +00004594 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004595 break;
4596
nethercote73b526f2004-10-31 18:48:21 +00004597 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004598 /* int bind(int sockfd, struct sockaddr *my_addr,
4599 int addrlen); */
njn22cfccb2004-11-27 16:10:23 +00004600 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004601 VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004602 break;
4603
nethercote73b526f2004-10-31 18:48:21 +00004604 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004605 /* int listen(int s, int backlog); */
njn22cfccb2004-11-27 16:10:23 +00004606 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004607 break;
4608
nethercote73b526f2004-10-31 18:48:21 +00004609 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004610 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
njn22cfccb2004-11-27 16:10:23 +00004611 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004612 VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004613 break;
4614 }
4615
nethercote73b526f2004-10-31 18:48:21 +00004616 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004617 /* int sendto(int s, const void *msg, int len,
sewardj9efbbef2005-03-01 16:45:23 +00004618 unsigned int flags,
4619 const struct sockaddr *to, int tolen); */
njn22cfccb2004-11-27 16:10:23 +00004620 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004621 VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00004622 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00004623 break;
4624
nethercote73b526f2004-10-31 18:48:21 +00004625 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004626 /* int send(int s, const void *msg, size_t len, int flags); */
njn22cfccb2004-11-27 16:10:23 +00004627 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004628 VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004629 break;
4630
nethercote73b526f2004-10-31 18:48:21 +00004631 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004632 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4633 struct sockaddr *from, int *fromlen); */
njn22cfccb2004-11-27 16:10:23 +00004634 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004635 VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00004636 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00004637 break;
4638
nethercote73b526f2004-10-31 18:48:21 +00004639 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00004640 /* int recv(int s, void *buf, int len, unsigned int flags); */
4641 /* man 2 recv says:
4642 The recv call is normally used only on a connected socket
4643 (see connect(2)) and is identical to recvfrom with a NULL
4644 from parameter.
4645 */
njn22cfccb2004-11-27 16:10:23 +00004646 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004647 VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004648 break;
4649
nethercote73b526f2004-10-31 18:48:21 +00004650 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004651 /* int connect(int sockfd,
sewardj9efbbef2005-03-01 16:45:23 +00004652 struct sockaddr *serv_addr, int addrlen ); */
njn22cfccb2004-11-27 16:10:23 +00004653 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004654 VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004655 break;
4656
nethercote73b526f2004-10-31 18:48:21 +00004657 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004658 /* int setsockopt(int s, int level, int optname,
sewardj9efbbef2005-03-01 16:45:23 +00004659 const void *optval, int optlen); */
njn22cfccb2004-11-27 16:10:23 +00004660 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004661 VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00004662 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00004663 break;
4664
nethercote73b526f2004-10-31 18:48:21 +00004665 case VKI_SYS_GETSOCKOPT:
sewardj9efbbef2005-03-01 16:45:23 +00004666 /* int getsockopt(int s, int level, int optname,
4667 void *optval, socklen_t *optlen); */
njn22cfccb2004-11-27 16:10:23 +00004668 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004669 VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00004670 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00004671 break;
4672
nethercote73b526f2004-10-31 18:48:21 +00004673 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004674 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00004675 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004676 VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004677 break;
4678
nethercote73b526f2004-10-31 18:48:21 +00004679 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004680 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00004681 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00004682 VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004683 break;
4684
nethercote73b526f2004-10-31 18:48:21 +00004685 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004686 /* int shutdown(int s, int how); */
njn22cfccb2004-11-27 16:10:23 +00004687 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004688 break;
4689
nethercote73b526f2004-10-31 18:48:21 +00004690 case VKI_SYS_SENDMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004691 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4692
4693 /* this causes warnings, and I don't get why. glibc bug?
4694 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00004695 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004696 */
sewardj987a8eb2005-03-01 19:00:30 +00004697 VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00004698 break;
4699 }
4700
nethercote73b526f2004-10-31 18:48:21 +00004701 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004702 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4703
4704 /* this causes warnings, and I don't get why. glibc bug?
4705 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00004706 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004707 */
sewardj987a8eb2005-03-01 19:00:30 +00004708 VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00004709 break;
4710 }
4711
4712 default:
njn22cfccb2004-11-27 16:10:23 +00004713 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
4714 SET_RESULT( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00004715 break;
jsgf855d93d2003-10-13 22:26:55 +00004716 }
sewardj9efbbef2005-03-01 16:45:23 +00004717# undef ARG2_0
4718# undef ARG2_1
4719# undef ARG2_2
4720# undef ARG2_3
4721# undef ARG2_4
4722# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00004723}
4724
nethercote85a456f2004-11-16 17:31:56 +00004725POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00004726{
sewardj9efbbef2005-03-01 16:45:23 +00004727# define ARG2_0 (((UWord*)ARG2)[0])
4728# define ARG2_1 (((UWord*)ARG2)[1])
4729# define ARG2_2 (((UWord*)ARG2)[2])
4730# define ARG2_3 (((UWord*)ARG2)[3])
4731# define ARG2_4 (((UWord*)ARG2)[4])
4732# define ARG2_5 (((UWord*)ARG2)[5])
4733
4734 UWord r;
njn22cfccb2004-11-27 16:10:23 +00004735 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00004736
sewardj9efbbef2005-03-01 16:45:23 +00004737 case VKI_SYS_SOCKETPAIR:
sewardj987a8eb2005-03-01 19:00:30 +00004738 VG_(generic_POST_sys_socketpair)( tid, RES, ARG2_0,
sewardj9efbbef2005-03-01 16:45:23 +00004739 ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00004740 break;
4741
nethercote73b526f2004-10-31 18:48:21 +00004742 case VKI_SYS_SOCKET:
sewardj987a8eb2005-03-01 19:00:30 +00004743 r = VG_(generic_POST_sys_socket)( tid, RES );
sewardj9efbbef2005-03-01 16:45:23 +00004744 SET_RESULT(r);
4745 break;
jsgf855d93d2003-10-13 22:26:55 +00004746
nethercote73b526f2004-10-31 18:48:21 +00004747 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004748 /* int bind(int sockfd, struct sockaddr *my_addr,
4749 int addrlen); */
4750 break;
4751
nethercote73b526f2004-10-31 18:48:21 +00004752 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004753 /* int listen(int s, int backlog); */
4754 break;
4755
sewardj9efbbef2005-03-01 16:45:23 +00004756 case VKI_SYS_ACCEPT:
jsgf855d93d2003-10-13 22:26:55 +00004757 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
sewardj987a8eb2005-03-01 19:00:30 +00004758 r = VG_(generic_POST_sys_accept)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
sewardj9efbbef2005-03-01 16:45:23 +00004759 SET_RESULT(r);
4760 break;
jsgf855d93d2003-10-13 22:26:55 +00004761
nethercote73b526f2004-10-31 18:48:21 +00004762 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004763 break;
4764
nethercote73b526f2004-10-31 18:48:21 +00004765 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004766 break;
4767
nethercote73b526f2004-10-31 18:48:21 +00004768 case VKI_SYS_RECVFROM:
sewardj987a8eb2005-03-01 19:00:30 +00004769 VG_(generic_POST_sys_recvfrom)( tid, RES, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00004770 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00004771 break;
4772
nethercote73b526f2004-10-31 18:48:21 +00004773 case VKI_SYS_RECV:
sewardj987a8eb2005-03-01 19:00:30 +00004774 VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004775 break;
4776
nethercote73b526f2004-10-31 18:48:21 +00004777 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004778 break;
4779
nethercote73b526f2004-10-31 18:48:21 +00004780 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004781 break;
4782
nethercote73b526f2004-10-31 18:48:21 +00004783 case VKI_SYS_GETSOCKOPT:
sewardj987a8eb2005-03-01 19:00:30 +00004784 VG_(generic_POST_sys_getsockopt)( tid, RES, ARG2_0, ARG2_1,
sewardj9efbbef2005-03-01 16:45:23 +00004785 ARG2_2, ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00004786 break;
4787
nethercote73b526f2004-10-31 18:48:21 +00004788 case VKI_SYS_GETSOCKNAME:
sewardj987a8eb2005-03-01 19:00:30 +00004789 VG_(generic_POST_sys_getsockname)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004790 break;
4791
nethercote73b526f2004-10-31 18:48:21 +00004792 case VKI_SYS_GETPEERNAME:
sewardj987a8eb2005-03-01 19:00:30 +00004793 VG_(generic_POST_sys_getpeername)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00004794 break;
4795
nethercote73b526f2004-10-31 18:48:21 +00004796 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004797 break;
4798
nethercote73b526f2004-10-31 18:48:21 +00004799 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00004800 break;
4801
nethercote73b526f2004-10-31 18:48:21 +00004802 case VKI_SYS_RECVMSG:
sewardj987a8eb2005-03-01 19:00:30 +00004803 VG_(generic_POST_sys_recvmsg)( tid, RES, ARG2_0, ARG2_1 );
sewardj9efbbef2005-03-01 16:45:23 +00004804 break;
jsgf855d93d2003-10-13 22:26:55 +00004805
4806 default:
njn22cfccb2004-11-27 16:10:23 +00004807 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004808 VG_(core_panic)("... bye!\n");
4809 break; /*NOTREACHED*/
4810 }
sewardj9efbbef2005-03-01 16:45:23 +00004811# undef ARG2_0
4812# undef ARG2_1
4813# undef ARG2_2
4814# undef ARG2_3
4815# undef ARG2_4
4816# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00004817}
4818
nethercote85a456f2004-11-16 17:31:56 +00004819PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004820{
njn22cfccb2004-11-27 16:10:23 +00004821 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004822 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00004823 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4824 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004825}
4826
nethercote85a456f2004-11-16 17:31:56 +00004827POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00004828{
njn22cfccb2004-11-27 16:10:23 +00004829 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004830}
4831
nethercote85a456f2004-11-16 17:31:56 +00004832PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00004833{
njn22cfccb2004-11-27 16:10:23 +00004834 PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00004835 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00004836 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4837 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00004838}
4839
nethercote85a456f2004-11-16 17:31:56 +00004840POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00004841{
njn22cfccb2004-11-27 16:10:23 +00004842 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00004843}
4844
nethercote85a456f2004-11-16 17:31:56 +00004845PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00004846{
njn22cfccb2004-11-27 16:10:23 +00004847 PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00004848 PRE_REG_READ3(long, "statfs64",
4849 const char *, path, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004850 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4851 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004852}
4853
nethercote85a456f2004-11-16 17:31:56 +00004854POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00004855{
njn22cfccb2004-11-27 16:10:23 +00004856 POST_MEM_WRITE( ARG3, ARG2 );
muellerd3502b62003-11-19 00:43:57 +00004857}
4858
nethercote85a456f2004-11-16 17:31:56 +00004859PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004860{
njn22cfccb2004-11-27 16:10:23 +00004861 PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00004862 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004863 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4864 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004865}
4866
njnc6168192004-11-29 13:54:10 +00004867// See comment above PRE(sys_lstat64) for an explanation of this #ifdef.
4868#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00004869PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004870{
njn22cfccb2004-11-27 16:10:23 +00004871 PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004872 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004873 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
4874 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004875}
4876
nethercote85a456f2004-11-16 17:31:56 +00004877POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00004878{
njn22cfccb2004-11-27 16:10:23 +00004879 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004880}
4881
nethercote85a456f2004-11-16 17:31:56 +00004882PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004883{
njn22cfccb2004-11-27 16:10:23 +00004884 PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004885 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004886 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004887}
4888
nethercote85a456f2004-11-16 17:31:56 +00004889POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00004890{
njn22cfccb2004-11-27 16:10:23 +00004891 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004892}
njnc6168192004-11-29 13:54:10 +00004893#endif
jsgf855d93d2003-10-13 22:26:55 +00004894
nethercote85a456f2004-11-16 17:31:56 +00004895PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00004896{
4897 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00004898 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004899 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00004900 if (ARG1 != 0) {
4901 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00004902 }
4903}
4904
nethercote85a456f2004-11-16 17:31:56 +00004905POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00004906{
njn22cfccb2004-11-27 16:10:23 +00004907 if (ARG1 != 0) {
4908 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00004909 }
4910}
4911
nethercote85a456f2004-11-16 17:31:56 +00004912PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00004913{
njn22cfccb2004-11-27 16:10:23 +00004914 PRINT("sys_times ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004915 PRE_REG_READ1(long, "times", struct tms *, buf);
njn22cfccb2004-11-27 16:10:23 +00004916 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00004917}
4918
nethercote85a456f2004-11-16 17:31:56 +00004919POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00004920{
njn22cfccb2004-11-27 16:10:23 +00004921 if (ARG1 != 0) {
4922 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00004923 }
4924}
4925
nethercote85a456f2004-11-16 17:31:56 +00004926PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00004927{
njn22cfccb2004-11-27 16:10:23 +00004928 PRINT("sys_umask ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004929 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00004930}
4931
nethercote85a456f2004-11-16 17:31:56 +00004932PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004933{
njn22cfccb2004-11-27 16:10:23 +00004934 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00004935 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00004936 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004937}
4938
nethercote85a456f2004-11-16 17:31:56 +00004939PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00004940{
njn22cfccb2004-11-27 16:10:23 +00004941 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00004942 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00004943 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00004944}
4945
nethercote85a456f2004-11-16 17:31:56 +00004946POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00004947{
njn22cfccb2004-11-27 16:10:23 +00004948 if (ARG1 != 0) {
4949 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00004950 }
4951}
4952
nethercote85a456f2004-11-16 17:31:56 +00004953PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004954{
njn22cfccb2004-11-27 16:10:23 +00004955 PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004956 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
njn22cfccb2004-11-27 16:10:23 +00004957 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
4958 if (ARG2 != 0)
4959 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00004960}
4961
nethercote85a456f2004-11-16 17:31:56 +00004962PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004963{
njn22cfccb2004-11-27 16:10:23 +00004964 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00004965 PRE_REG_READ3(long, "waitpid",
4966 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00004967
njn22cfccb2004-11-27 16:10:23 +00004968 if (ARG2 != (Addr)NULL)
4969 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004970}
4971
nethercote85a456f2004-11-16 17:31:56 +00004972POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00004973{
njn22cfccb2004-11-27 16:10:23 +00004974 if (ARG2 != (Addr)NULL)
4975 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004976}
4977
nethercote85a456f2004-11-16 17:31:56 +00004978PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004979{
njn22cfccb2004-11-27 16:10:23 +00004980 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
4981 ARG3 &= ~(__VKI_WCLONE | __VKI_WALL);
jsgf855d93d2003-10-13 22:26:55 +00004982
nethercote7f7e4d12004-11-15 12:28:58 +00004983 PRE_REG_READ4(long, "wait4",
4984 vki_pid_t, pid, unsigned int *, status, int, options,
4985 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00004986 if (ARG2 != (Addr)NULL)
4987 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
4988 if (ARG4 != (Addr)NULL)
4989 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00004990}
4991
nethercote85a456f2004-11-16 17:31:56 +00004992POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00004993{
njn22cfccb2004-11-27 16:10:23 +00004994 if (ARG2 != (Addr)NULL)
4995 POST_MEM_WRITE( ARG2, sizeof(int) );
4996 if (ARG4 != (Addr)NULL)
4997 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00004998}
4999
nethercote85a456f2004-11-16 17:31:56 +00005000PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005001{
jsgf855d93d2003-10-13 22:26:55 +00005002 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005003 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00005004 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005005 PRE_REG_READ3(ssize_t, "writev",
5006 unsigned long, fd, const struct iovec *, vector,
5007 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00005008 if (!VG_(fd_allowed)(ARG1, "writev", tid, False)) {
5009 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005010 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005011 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005012 ARG2, ARG3 * sizeof(struct vki_iovec) );
5013 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005014 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005015 vec = (struct vki_iovec *)ARG2;
5016 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005017 PRE_MEM_READ( "writev(vector[...])",
5018 (Addr)vec[i].iov_base, vec[i].iov_len );
5019 }
jsgf855d93d2003-10-13 22:26:55 +00005020 }
5021}
5022
nethercote85a456f2004-11-16 17:31:56 +00005023PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005024{
njn22cfccb2004-11-27 16:10:23 +00005025 PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
nethercoteac866b92004-11-15 20:23:15 +00005026 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
njn22cfccb2004-11-27 16:10:23 +00005027 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5028 if (ARG2 != 0)
5029 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005030}
5031
nethercote85a456f2004-11-16 17:31:56 +00005032PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005033{
njn22cfccb2004-11-27 16:10:23 +00005034 PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005035 PRE_REG_READ3(long, "sched_setaffinity",
5036 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005037 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005038}
5039
nethercote85a456f2004-11-16 17:31:56 +00005040PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005041{
njn22cfccb2004-11-27 16:10:23 +00005042 PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005043 PRE_REG_READ3(long, "sched_getaffinity",
5044 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005045 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005046}
5047
nethercote85a456f2004-11-16 17:31:56 +00005048POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005049{
njn22cfccb2004-11-27 16:10:23 +00005050 POST_MEM_WRITE(ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005051}
5052
nethercote85a456f2004-11-16 17:31:56 +00005053PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005054{
njn22cfccb2004-11-27 16:10:23 +00005055 PRINT("sys_acct ( %p )", ARG1);
nethercote2b0cae62004-11-12 14:57:34 +00005056 PRE_REG_READ1(long, "acct", const char *, filename);
njn22cfccb2004-11-27 16:10:23 +00005057 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
nethercote2bc5a212004-04-10 00:26:10 +00005058}
5059
nethercote85a456f2004-11-16 17:31:56 +00005060PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005061{
nethercote0df495a2004-11-11 16:38:21 +00005062 PRINT("sys_pause ( )");
5063 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005064}
5065
nethercotea3a2c142004-11-14 14:13:05 +00005066// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005067PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005068{
thughesc3e85df2004-11-15 09:27:24 +00005069 /* The C library interface to sigsuspend just takes a pointer to
5070 a signal mask but this system call has three arguments - the first
5071 two don't appear to be used by the kernel and are always passed as
5072 zero by glibc and the third is the first word of the signal mask
5073 so only 32 signals are supported.
5074
5075 In fact glibc normally uses rt_sigsuspend if it is available as
5076 that takes a pointer to the signal mask so supports more signals.
5077 */
njn22cfccb2004-11-27 16:10:23 +00005078 PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
thughesd8e00412004-11-14 19:44:25 +00005079 PRE_REG_READ3(int, "sigsuspend",
5080 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005081 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005082}
5083
nethercotea3a2c142004-11-14 14:13:05 +00005084// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005085PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005086{
thughesc3e85df2004-11-15 09:27:24 +00005087 /* The C library interface to sigsuspend just takes a pointer to
5088 a signal mask but this system call has two arguments - a pointer
5089 to the mask and the number of bytes used by it. The kernel insists
5090 on the size being equal to sizeof(sigset_t) however and will just
5091 return EINVAL if it isn't.
5092 */
njn22cfccb2004-11-27 16:10:23 +00005093 PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
nethercotea3a2c142004-11-14 14:13:05 +00005094 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
njn22cfccb2004-11-27 16:10:23 +00005095 if (ARG1 != (Addr)NULL) {
5096 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
nethercotea3a2c142004-11-14 14:13:05 +00005097 }
5098}
jsgf855d93d2003-10-13 22:26:55 +00005099
nethercote85a456f2004-11-16 17:31:56 +00005100PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005101{
nethercoteac866b92004-11-15 20:23:15 +00005102 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
njn22cfccb2004-11-27 16:10:23 +00005103 ARG1,ARG2,ARG3,(ULong)ARG4);
nethercoteac866b92004-11-15 20:23:15 +00005104 PRE_REG_READ4(long, "rt_sigtimedwait",
5105 const vki_sigset_t *, set, vki_siginfo_t *, info,
5106 const struct timespec *, timeout, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005107 if (ARG1 != 0)
5108 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
5109 if (ARG2 != 0)
5110 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
nethercoteac866b92004-11-15 20:23:15 +00005111 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
njn22cfccb2004-11-27 16:10:23 +00005112 ARG4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005113}
5114
nethercote85a456f2004-11-16 17:31:56 +00005115POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005116{
njn22cfccb2004-11-27 16:10:23 +00005117 if (ARG2 != 0)
5118 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005119}
5120
nethercote85a456f2004-11-16 17:31:56 +00005121PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005122{
njn22cfccb2004-11-27 16:10:23 +00005123 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005124 PRE_REG_READ3(long, "rt_sigqueueinfo",
5125 int, pid, int, sig, vki_siginfo_t *, uinfo);
njn22cfccb2004-11-27 16:10:23 +00005126 if (ARG2 != 0)
5127 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005128}
5129
nethercote85a456f2004-11-16 17:31:56 +00005130POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005131{
sewardjb5f6f512005-03-10 23:59:00 +00005132 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
5133 PRE_REG_READ3(long, "rt_sigqueueinfo",
5134 int, pid, int, sig, vki_siginfo_t *, uinfo);
5135 if (ARG2 != 0)
5136 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
5137 if (!VG_(client_signal_OK)(ARG2))
5138 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00005139}
5140
nethercoteb77dee62004-11-16 17:13:24 +00005141// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005142PRE(sys_sigaltstack, Special)
jsgf855d93d2003-10-13 22:26:55 +00005143{
5144 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
njn22cfccb2004-11-27 16:10:23 +00005145 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005146 PRE_REG_READ2(int, "sigaltstack",
5147 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005148 if (ARG1 != 0) {
5149 PRE_MEM_READ( "sigaltstack(ss)", ARG1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005150 }
njn22cfccb2004-11-27 16:10:23 +00005151 if (ARG2 != 0) {
5152 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005153 }
5154
njnb249fd72004-11-29 14:24:57 +00005155 VG_(do_sys_sigaltstack) (tid);
sewardja93f66a2005-02-28 20:50:29 +00005156 SET_RESULT(RES); /* sigh */
jsgf855d93d2003-10-13 22:26:55 +00005157}
5158
nethercote85a456f2004-11-16 17:31:56 +00005159POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005160{
njn22cfccb2004-11-27 16:10:23 +00005161 if (RES == 0 && ARG2 != 0)
5162 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005163}
5164
nethercote71f05f32004-11-12 18:49:27 +00005165// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005166PRE(sys_rt_sigaction, Special)
nethercote686b5db2004-11-14 13:42:51 +00005167{
njn22cfccb2004-11-27 16:10:23 +00005168 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
nethercote686b5db2004-11-14 13:42:51 +00005169 PRE_REG_READ4(long, "rt_sigaction",
5170 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005171 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005172
njn22cfccb2004-11-27 16:10:23 +00005173 if (ARG2 != 0)
5174 PRE_MEM_READ( "rt_sigaction(act)", ARG2, sizeof(struct vki_sigaction));
5175 if (ARG3 != 0)
5176 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005177
njnb249fd72004-11-29 14:24:57 +00005178 // XXX: doesn't seem right to be calling do_sys_sigaction for
5179 // sys_rt_sigaction... perhaps this function should be renamed
5180 // VG_(do_sys_rt_sigaction)() --njn
sewardjb5f6f512005-03-10 23:59:00 +00005181
5182 SET_RESULT(
5183 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
5184 (struct vki_sigaction *)ARG3)
5185 );
nethercote686b5db2004-11-14 13:42:51 +00005186}
5187
nethercote85a456f2004-11-16 17:31:56 +00005188POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005189{
njn22cfccb2004-11-27 16:10:23 +00005190 if (RES == 0 && ARG3 != 0)
5191 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005192}
jsgf855d93d2003-10-13 22:26:55 +00005193
njnc6168192004-11-29 13:54:10 +00005194// XXX: This syscall is not used on amd64 -- it only provides
5195// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
5196// This wrapper is only suitable for 32-bit architectures.
5197#ifndef __amd64__
njnb249fd72004-11-29 14:24:57 +00005198PRE(sys_sigprocmask, Special)
jsgf855d93d2003-10-13 22:26:55 +00005199{
sewardj970ac792004-12-31 18:09:32 +00005200 vki_old_sigset_t* set;
5201 vki_old_sigset_t* oldset;
5202 vki_sigset_t bigger_set;
5203 vki_sigset_t bigger_oldset;
5204
njn22cfccb2004-11-27 16:10:23 +00005205 PRINT("sys_sigprocmask ( %d, %p, %p )",ARG1,ARG2,ARG3);
nethercote7fbe08a2004-11-15 19:03:27 +00005206 PRE_REG_READ3(long, "sigprocmask",
5207 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
njn22cfccb2004-11-27 16:10:23 +00005208 if (ARG2 != 0)
5209 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
5210 if (ARG3 != 0)
5211 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005212
njnb249fd72004-11-29 14:24:57 +00005213 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5214 // vki_sigset_t params.
sewardj970ac792004-12-31 18:09:32 +00005215 set = (vki_old_sigset_t*)ARG2;
5216 oldset = (vki_old_sigset_t*)ARG3;
nethercote7fbe08a2004-11-15 19:03:27 +00005217
sewardj1f276622004-12-06 16:18:58 +00005218 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5219 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
5220 if (set)
5221 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
nethercote7fbe08a2004-11-15 19:03:27 +00005222
njnb249fd72004-11-29 14:24:57 +00005223 VG_(do_sys_sigprocmask) ( tid,
5224 ARG1 /*how*/,
sewardj1f276622004-12-06 16:18:58 +00005225 set ? &bigger_set : NULL,
5226 oldset ? &bigger_oldset : NULL);
nethercote7fbe08a2004-11-15 19:03:27 +00005227
njnb249fd72004-11-29 14:24:57 +00005228 if (oldset)
5229 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005230}
5231
nethercote85a456f2004-11-16 17:31:56 +00005232POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005233{
njn22cfccb2004-11-27 16:10:23 +00005234 if (RES == 0 && ARG3 != 0)
5235 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005236}
njnc6168192004-11-29 13:54:10 +00005237#endif
nethercote7fbe08a2004-11-15 19:03:27 +00005238
njnb249fd72004-11-29 14:24:57 +00005239PRE(sys_rt_sigprocmask, Special)
nethercote7fbe08a2004-11-15 19:03:27 +00005240{
njn22cfccb2004-11-27 16:10:23 +00005241 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
nethercote7fbe08a2004-11-15 19:03:27 +00005242 PRE_REG_READ4(long, "rt_sigprocmask",
5243 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5244 vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005245 if (ARG2 != 0)
5246 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
5247 if (ARG3 != 0)
5248 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005249
5250 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
njn22cfccb2004-11-27 16:10:23 +00005251 if (sizeof(vki_sigset_t) != ARG4)
5252 SET_RESULT( -VKI_EMFILE );
sewardj004e8ca2005-02-28 17:27:04 +00005253 else {
nethercote93d9aa12004-11-10 19:08:31 +00005254 VG_(do_sys_sigprocmask) ( tid,
njn22cfccb2004-11-27 16:10:23 +00005255 ARG1 /*how*/,
5256 (vki_sigset_t*) ARG2,
5257 (vki_sigset_t*) ARG3 );
sewardja93f66a2005-02-28 20:50:29 +00005258 /* Mark that the result is set. */
5259 SET_RESULT(RES);
sewardj004e8ca2005-02-28 17:27:04 +00005260 }
jsgf855d93d2003-10-13 22:26:55 +00005261}
5262
nethercote85a456f2004-11-16 17:31:56 +00005263POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005264{
njn22cfccb2004-11-27 16:10:23 +00005265 if (RES == 0 && ARG3 != 0)
5266 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005267}
5268
sewardjb5f6f512005-03-10 23:59:00 +00005269PRE(sys_sigpending, 0)
jsgf855d93d2003-10-13 22:26:55 +00005270{
njn22cfccb2004-11-27 16:10:23 +00005271 PRINT( "sys_sigpending ( %p )", ARG1 );
nethercote17258dc2004-11-12 19:55:08 +00005272 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
njn22cfccb2004-11-27 16:10:23 +00005273 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005274}
5275
nethercote85a456f2004-11-16 17:31:56 +00005276POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005277{
njn22cfccb2004-11-27 16:10:23 +00005278 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005279}
5280
sewardjb5f6f512005-03-10 23:59:00 +00005281PRE(sys_rt_sigpending, 0)
nethercotea6395d12004-11-15 19:23:46 +00005282{
njn22cfccb2004-11-27 16:10:23 +00005283 PRINT( "sys_rt_sigpending ( %p )", ARG1 );
nethercotea6395d12004-11-15 19:23:46 +00005284 PRE_REG_READ2(long, "rt_sigpending",
5285 vki_sigset_t *, set, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005286 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005287}
5288
nethercote85a456f2004-11-16 17:31:56 +00005289POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005290{
njn22cfccb2004-11-27 16:10:23 +00005291 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
nethercotea6395d12004-11-15 19:23:46 +00005292}
jsgf855d93d2003-10-13 22:26:55 +00005293
nethercote85a456f2004-11-16 17:31:56 +00005294PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005295{
nethercote330abb52004-11-16 12:58:04 +00005296 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
njn22cfccb2004-11-27 16:10:23 +00005297 ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
nethercote330abb52004-11-16 12:58:04 +00005298 PRE_REG_READ4(long, "mq_open",
5299 const char *, name, int, oflag, vki_mode_t, mode,
5300 struct mq_attr *, attr);
njn22cfccb2004-11-27 16:10:23 +00005301 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
5302 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
5303 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
nethercoteef0c7662004-11-06 15:38:43 +00005304 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005305 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005306 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005307 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5308 }
5309}
5310
nethercote85a456f2004-11-16 17:31:56 +00005311POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005312{
njn22cfccb2004-11-27 16:10:23 +00005313 if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
5314 VG_(close)(RES);
5315 SET_RESULT( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005316 } else {
5317 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00005318 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
thughes8579b102004-08-14 18:52:27 +00005319 }
thughes8579b102004-08-14 18:52:27 +00005320}
5321
nethercote85a456f2004-11-16 17:31:56 +00005322PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005323{
njn22cfccb2004-11-27 16:10:23 +00005324 PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
nethercote330abb52004-11-16 12:58:04 +00005325 PRE_REG_READ1(long, "mq_unlink", const char *, name);
njn22cfccb2004-11-27 16:10:23 +00005326 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
thughes8579b102004-08-14 18:52:27 +00005327}
5328
nethercote85a456f2004-11-16 17:31:56 +00005329PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005330{
nethercote330abb52004-11-16 12:58:04 +00005331 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
njn22cfccb2004-11-27 16:10:23 +00005332 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005333 PRE_REG_READ5(long, "mq_timedsend",
5334 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5335 unsigned int, msg_prio, const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005336 if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
5337 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005338 } else {
njn22cfccb2004-11-27 16:10:23 +00005339 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5340 if (ARG5 != 0)
5341 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
nethercote73b526f2004-10-31 18:48:21 +00005342 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005343 }
5344}
5345
nethercote85a456f2004-11-16 17:31:56 +00005346PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005347{
nethercote330abb52004-11-16 12:58:04 +00005348 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
njn22cfccb2004-11-27 16:10:23 +00005349 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005350 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5351 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5352 unsigned int *, msg_prio,
5353 const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005354 if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
5355 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005356 } else {
njn22cfccb2004-11-27 16:10:23 +00005357 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
5358 if (ARG4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005359 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
njn22cfccb2004-11-27 16:10:23 +00005360 ARG4, sizeof(unsigned int) );
5361 if (ARG5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005362 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
njn22cfccb2004-11-27 16:10:23 +00005363 ARG5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005364 }
5365}
5366
nethercote85a456f2004-11-16 17:31:56 +00005367POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005368{
njn22cfccb2004-11-27 16:10:23 +00005369 POST_MEM_WRITE( ARG2, ARG3 );
5370 if (ARG4 != 0)
5371 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005372}
5373
nethercote85a456f2004-11-16 17:31:56 +00005374PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005375{
njn22cfccb2004-11-27 16:10:23 +00005376 PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
nethercote330abb52004-11-16 12:58:04 +00005377 PRE_REG_READ2(long, "mq_notify",
5378 vki_mqd_t, mqdes, const struct sigevent *, notification);
njn22cfccb2004-11-27 16:10:23 +00005379 if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
5380 SET_RESULT( -VKI_EBADF );
5381 else if (ARG2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005382 PRE_MEM_READ( "mq_notify(notification)",
njn22cfccb2004-11-27 16:10:23 +00005383 ARG2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005384}
5385
nethercote85a456f2004-11-16 17:31:56 +00005386PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005387{
njn22cfccb2004-11-27 16:10:23 +00005388 PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
nethercote330abb52004-11-16 12:58:04 +00005389 PRE_REG_READ3(long, "mq_getsetattr",
5390 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5391 struct mq_attr *, omqstat);
njn22cfccb2004-11-27 16:10:23 +00005392 if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
5393 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005394 } else {
njn22cfccb2004-11-27 16:10:23 +00005395 if (ARG2 != 0) {
5396 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
nethercoteef0c7662004-11-06 15:38:43 +00005397 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005398 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5399 }
njn22cfccb2004-11-27 16:10:23 +00005400 if (ARG3 != 0)
5401 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
thughes8579b102004-08-14 18:52:27 +00005402 sizeof(struct vki_mq_attr) );
5403 }
5404}
5405
nethercote85a456f2004-11-16 17:31:56 +00005406POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005407{
njn22cfccb2004-11-27 16:10:23 +00005408 if (ARG3 != 0)
5409 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005410}
5411
nethercote85a456f2004-11-16 17:31:56 +00005412PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005413{
njn22cfccb2004-11-27 16:10:23 +00005414 PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005415 PRE_REG_READ3(long, "timer_create",
5416 vki_clockid_t, clockid, struct sigevent *, evp,
5417 vki_timer_t *, timerid);
njn22cfccb2004-11-27 16:10:23 +00005418 if (ARG2 != 0)
5419 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
5420 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005421}
5422
nethercote85a456f2004-11-16 17:31:56 +00005423POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005424{
njn22cfccb2004-11-27 16:10:23 +00005425 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005426}
5427
nethercote85a456f2004-11-16 17:31:56 +00005428PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005429{
njn22cfccb2004-11-27 16:10:23 +00005430 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
nethercote92b2fd52004-11-16 16:15:41 +00005431 PRE_REG_READ4(long, "timer_settime",
5432 vki_timer_t, timerid, int, flags,
5433 const struct itimerspec *, value,
5434 struct itimerspec *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00005435 PRE_MEM_READ( "timer_settime(value)", ARG3,
thughese1a925d2004-08-30 19:50:02 +00005436 sizeof(struct vki_itimerspec) );
njn22cfccb2004-11-27 16:10:23 +00005437 if (ARG4 != 0)
5438 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
thughese1a925d2004-08-30 19:50:02 +00005439 sizeof(struct vki_itimerspec) );
5440}
5441
nethercote85a456f2004-11-16 17:31:56 +00005442POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005443{
njn22cfccb2004-11-27 16:10:23 +00005444 if (ARG4 != 0)
5445 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005446}
5447
nethercote85a456f2004-11-16 17:31:56 +00005448PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005449{
njn22cfccb2004-11-27 16:10:23 +00005450 PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005451 PRE_REG_READ2(long, "timer_gettime",
5452 vki_timer_t, timerid, struct itimerspec *, value);
njn22cfccb2004-11-27 16:10:23 +00005453 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
thughese1a925d2004-08-30 19:50:02 +00005454 sizeof(struct vki_itimerspec));
5455}
5456
nethercote85a456f2004-11-16 17:31:56 +00005457POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005458{
njn22cfccb2004-11-27 16:10:23 +00005459 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005460}
5461
nethercote85a456f2004-11-16 17:31:56 +00005462PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005463{
njn22cfccb2004-11-27 16:10:23 +00005464 PRINT("sys_timer_getoverrun( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005465 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005466}
5467
nethercote85a456f2004-11-16 17:31:56 +00005468PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005469{
njn22cfccb2004-11-27 16:10:23 +00005470 PRINT("sys_timer_delete( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005471 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005472}
5473
nethercote85a456f2004-11-16 17:31:56 +00005474PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005475{
njn22cfccb2004-11-27 16:10:23 +00005476 PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005477 PRE_REG_READ2(long, "clock_settime",
5478 vki_clockid_t, clk_id, const struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005479 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005480}
5481
nethercote85a456f2004-11-16 17:31:56 +00005482PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005483{
njn22cfccb2004-11-27 16:10:23 +00005484 PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005485 PRE_REG_READ2(long, "clock_gettime",
5486 vki_clockid_t, clk_id, struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005487 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005488}
5489
nethercote85a456f2004-11-16 17:31:56 +00005490POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005491{
njn22cfccb2004-11-27 16:10:23 +00005492 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005493}
5494
nethercote85a456f2004-11-16 17:31:56 +00005495PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005496{
njn22cfccb2004-11-27 16:10:23 +00005497 PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
5498 // Nb: we can't use "RES" as the param name because that's a macro
nethercote92b2fd52004-11-16 16:15:41 +00005499 // defined above!
5500 PRE_REG_READ2(long, "clock_getres",
njne1268d32004-11-27 16:57:18 +00005501 vki_clockid_t, clk_id, struct timespec *, res);
5502 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005503}
5504
nethercote85a456f2004-11-16 17:31:56 +00005505POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005506{
njn22cfccb2004-11-27 16:10:23 +00005507 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005508}
5509
nethercote4fa681f2004-11-08 17:51:39 +00005510
5511/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005512 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005513 ------------------------------------------------------------------ */
5514
nethercote85a456f2004-11-16 17:31:56 +00005515static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005516static void bad_before(ThreadId tid, ThreadState *tst)
5517{
5518 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005519 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005520 if (VG_(clo_verbosity) > 1) {
5521 ExeContext *ec = VG_(get_ExeContext)(tid);
5522 VG_(pp_ExeContext)(ec);
5523 }
jsgf855d93d2003-10-13 22:26:55 +00005524 VG_(message)
5525 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5526 VG_(message)
5527 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5528
njn22cfccb2004-11-27 16:10:23 +00005529 SET_RESULT( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005530}
5531
nethercote8ff888f2004-11-17 17:11:45 +00005532static const struct SyscallTableEntry bad_sys =
5533 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005534
sewardjb5f6f512005-03-10 23:59:00 +00005535static const struct SyscallTableEntry *get_syscall_entry(UInt syscallno)
5536{
5537 const struct SyscallTableEntry *sys;
nethercote4fa681f2004-11-08 17:51:39 +00005538
sewardjb5f6f512005-03-10 23:59:00 +00005539 if (syscallno < VGA_(syscall_table_size) &&
5540 VGA_(syscall_table)[syscallno].before != NULL)
5541 sys = &VGA_(syscall_table)[syscallno];
5542 else
5543 sys = &bad_sys;
5544
5545 return sys;
5546}
5547
5548/* Perform post-syscall actions */
5549void VG_(post_syscall) (ThreadId tid)
5550{
5551 const struct SyscallTableEntry *sys;
5552 UInt flags;
5553 Bool mayBlock;
5554 ThreadState *tst = VG_(get_ThreadState)(tid);
5555 Int syscallno;
5556
5557 vg_assert(VG_(is_running_thread)(tid));
5558
5559 syscallno = tst->syscallno;
5560 tst->syscallno = -1;
5561
5562 vg_assert(syscallno != -1);
5563
5564 sys = get_syscall_entry(syscallno);
5565 flags = *(sys->flags_ptr);
5566
5567 mayBlock = !!( flags & MayBlock );
5568
5569 if (sys->after != NULL &&
5570 ((flags & PostOnFail) != 0 || !VG_(is_kerror)(RES))) {
5571 if (0)
5572 VG_(printf)("post_syscall: calling sys_after tid=%d syscallno=%d\n",
5573 tid, syscallno);
5574 (sys->after)(tid, tst);
5575 }
5576
5577 /* Do any post-syscall actions
5578
5579 NOTE: this is only called if the syscall completed. If the
5580 syscall was restarted, then it will call the Tool's
5581 pre_syscall again, without calling post_syscall (ie, more
5582 pre's than post's) */
5583 if (VG_(needs).syscall_wrapper) {
5584 //VGP_PUSHCC(VgpSkinSysWrap);
5585 TL_(post_syscall)(tid, syscallno, RES);
5586 //VGP_POPCC(VgpSkinSysWrap);
5587 }
5588}
5589
5590
5591void VG_(client_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00005592{
sewardj018f7622002-05-15 21:13:39 +00005593 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005594 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005595 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00005596 Bool isSpecial = False;
5597 Bool mayBlock = False;
5598 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00005599 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00005600
njn25e49d8e72002-09-23 09:36:25 +00005601 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00005602
jsgf855d93d2003-10-13 22:26:55 +00005603 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00005604
nethercote44d9aaa2004-11-04 19:38:14 +00005605 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00005606
jsgf855d93d2003-10-13 22:26:55 +00005607 /* the syscall no is in %eax. For syscalls with <= 6 args,
5608 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
5609 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00005610 containing the args.
5611
5612 The result is returned in %eax. If this value >= 0, the call
5613 succeeded, and this is the return value. If < 0, it failed, and
5614 the negation of this value is errno. To be more specific,
njn22cfccb2004-11-27 16:10:23 +00005615 if RES is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
sewardjde4a1d02002-03-22 01:27:54 +00005616 (kernel 2.4.9 sources, include/asm-i386/errno.h)
5617 then it indicates an error. Otherwise it doesn't.
5618
5619 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
5620 (inclusive?) indicate error returns. Not sure where the -4095
5621 comes from.
5622 */
5623
sewardjb5f6f512005-03-10 23:59:00 +00005624 vg_assert(VG_(is_running_thread)(tid));
5625 vg_assert(tst->syscallno == -1);
jsgf855d93d2003-10-13 22:26:55 +00005626 tst->syscallno = syscallno;
sewardjde4a1d02002-03-22 01:27:54 +00005627
sewardjb5f6f512005-03-10 23:59:00 +00005628 /* Make sure the tmp signal mask matches the real signal
5629 mask; sigsuspend may change this. */
5630 vg_assert(tst->sig_mask.sig[0] == tst->tmp_sig_mask.sig[0]);
5631 vg_assert(tst->sig_mask.sig[1] == tst->tmp_sig_mask.sig[1]);
5632
5633 sys = get_syscall_entry(syscallno);
nethercote85a456f2004-11-16 17:31:56 +00005634 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00005635
sewardjb5f6f512005-03-10 23:59:00 +00005636 /* !! is standard idiom to turn an int->bool */
5637 isSpecial = !!( flags & Special );
5638 mayBlock = !!( flags & MayBlock );
5639 // At most one of these should be true
5640 vg_assert( isSpecial + mayBlock <= 1 );
nethercotec8734892004-11-10 18:57:37 +00005641
jsgf855d93d2003-10-13 22:26:55 +00005642 /* Do any pre-syscall actions */
5643 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00005644 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00005645 TL_(pre_syscall)(tid, syscallno);
njn4be0a692004-11-22 18:10:36 +00005646 VGP_POPCC(VgpToolSysWrap);
jsgf855d93d2003-10-13 22:26:55 +00005647 }
5648
nethercoteef0c7662004-11-06 15:38:43 +00005649 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
5650 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00005651 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00005652 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00005653
sewardjb5f6f512005-03-10 23:59:00 +00005654 tst->syscall_result_set = False;
5655
nethercotec8734892004-11-10 18:57:37 +00005656 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00005657 /* "Special" syscalls are implemented by Valgrind internally,
5658 and do not generate real kernel calls. The expectation,
5659 therefore, is that the "before" function not only does the
5660 appropriate tests, but also performs the syscall itself and
5661 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00005662 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00005663
5664 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00005665 /* This *must* result in tst->syscall_result_set becoming
5666 True. */
jsgf855d93d2003-10-13 22:26:55 +00005667
sewardjb5f6f512005-03-10 23:59:00 +00005668 // vg_assert(tst->sys_flags == flags);
sewardj004e8ca2005-02-28 17:27:04 +00005669 vg_assert(tst->syscall_result_set == True);
thughesbaa46e52004-07-29 17:44:23 +00005670
njn22cfccb2004-11-27 16:10:23 +00005671 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00005672 syscall_done = True;
5673 } else {
5674 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00005675 /* This *may* result in tst->syscall_result_set becoming
5676 True. */
jsgf855d93d2003-10-13 22:26:55 +00005677
sewardj004e8ca2005-02-28 17:27:04 +00005678 if (tst->syscall_result_set) {
5679 /* "before" decided to provide a syscall result itself, so
5680 don't do anything - just pretend the syscall happened. */
5681 PRINT(" ==> %lld (0x%llx)\n", (Long)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00005682 syscall_done = True;
sewardjb5f6f512005-03-10 23:59:00 +00005683 } else if (mayBlock) {
5684 vki_sigset_t mask;
5685
5686 vg_assert(!(flags & PadAddr));
5687
5688 /* Syscall may block, so run it asynchronously */
nethercoteef0c7662004-11-06 15:38:43 +00005689 PRINT(" --> ...\n");
sewardjb5f6f512005-03-10 23:59:00 +00005690
5691 mask = tst->sig_mask;
5692 VG_(sanitize_client_sigmask)(tid, &mask);
5693
5694 VG_(set_sleeping)(tid, VgTs_WaitSys);
5695 VGA_(client_syscall)(syscallno, tst, &mask);
5696 /* VGA_(client_syscall) may not return if the syscall was
5697 interrupted by a signal. In that case, flow of control
5698 will end up back in the scheduler via the signal
5699 machinery. */
5700 VG_(set_running)(tid);
5701 PRINT("SYSCALL[%d,%d](%3d) --> %ld (0x%lx)\n",
5702 VG_(getpid)(), tid, syscallno, (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00005703 } else {
5704 /* run the syscall directly */
sewardjb5f6f512005-03-10 23:59:00 +00005705 if (flags & PadAddr)
5706 VG_(pad_address_space)(VG_(client_end));
5707
njnca6fef02004-11-29 16:49:18 +00005708 RES = VG_(do_syscall6)(syscallno, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
njn22cfccb2004-11-27 16:10:23 +00005709 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00005710 syscall_done = True;
5711 }
5712 }
5713
sewardjb5f6f512005-03-10 23:59:00 +00005714 vg_assert(VG_(is_running_thread)(tid));
jsgf855d93d2003-10-13 22:26:55 +00005715
sewardjb5f6f512005-03-10 23:59:00 +00005716 SET_SYSCALL_RETVAL(tid, RES);
fitzhardingef0f911c2003-11-09 09:51:33 +00005717
sewardjb5f6f512005-03-10 23:59:00 +00005718 VG_(post_syscall)(tid);
jsgf855d93d2003-10-13 22:26:55 +00005719
sewardjb5f6f512005-03-10 23:59:00 +00005720 if (flags & PadAddr) {
5721 vg_assert(!mayBlock);
5722 VG_(unpad_address_space)(VG_(client_end));
5723 //VG_(sanity_check_memory)();
fitzhardingee1c06d82003-10-30 07:21:44 +00005724 }
5725
sewardjb5f6f512005-03-10 23:59:00 +00005726 /* VG_(post_syscall) should set this */
5727 vg_assert(tst->syscallno == -1);
sewardj2e93c502002-04-12 11:12:52 +00005728
njn25e49d8e72002-09-23 09:36:25 +00005729 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00005730}
5731
sewardjb5f6f512005-03-10 23:59:00 +00005732//static void restart_syscall(ThreadId tid)
5733//{
5734// ThreadState* tst;
5735// tst = VG_(get_ThreadState)(tid);
5736//
5737// vg_assert(tst != NULL);
5738// vg_assert(tst->status == VgTs_WaitSys);
5739// vg_assert(tst->syscallno != -1);
5740//
5741// SYSNO = tst->syscallno;
5742// VGA_(restart_syscall)(&tst->arch);
5743//}
5744
5745// svn version of post_syscall
5746//void VG_(post_syscall) ( ThreadId tid, Bool restart )
5747//{
5748// ThreadState* tst;
5749// UInt syscallno, flags;
5750// const struct SyscallTableEntry *sys;
5751// Bool isSpecial = False;
5752// Bool restarted = False;
5753//
5754// VGP_PUSHCC(VgpCoreSysWrap);
5755//
5756// tst = VG_(get_ThreadState)(tid);
5757// vg_assert(tst->tid == tid);
5758//
5759// /* Tell the tool about the syscall return value */
5760// SET_SYSCALL_RETVAL(tst->tid, RES);
5761//
5762// syscallno = tst->syscallno;
5763//
5764// vg_assert(syscallno != -1); /* must be a current syscall */
5765//
5766// if (syscallno < VGA_(syscall_table_size) &&
5767// VGA_(syscall_table)[syscallno].before != NULL)
5768// {
5769// sys = &VGA_(syscall_table)[syscallno];
5770// } else {
5771// sys = &bad_sys;
5772// }
5773// flags = *(sys->flags_ptr);
5774//
5775// isSpecial = flags & Special;
5776//
5777// if (RES == -VKI_ERESTARTSYS) {
5778// /* Applications never expect to see this, so we should either
5779// restart the syscall or fail it with EINTR, depending on what
5780// our caller wants. Generally they'll want to restart, but if
5781// client set the signal state to not restart, then we fail with
5782// EINTR. Either way, ERESTARTSYS means the syscall made no
5783// progress, and so can be failed or restarted without
5784// consequence. */
5785// if (0)
5786// VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
5787// syscallno, restart);
5788//
5789// if (restart) {
5790// restarted = True;
5791// restart_syscall(tid);
5792// } else
5793// RES = -VKI_EINTR;
5794// }
5795//
5796// if (!restarted) {
5797// if (sys->after != NULL &&
5798// ((tst->sys_flags & PostOnFail) != 0 || !VG_(is_kerror)(RES)))
5799// (sys->after)(tst->tid, tst);
5800//
5801// /* Do any post-syscall actions
5802//
5803// NOTE: this is only called if the syscall completed. If the
5804// syscall was restarted, then it will call the Tool's
5805// pre_syscall again, without calling post_syscall (ie, more
5806// pre's than post's)
5807// */
5808// if (VG_(needs).syscall_wrapper) {
5809// VGP_PUSHCC(VgpToolSysWrap);
5810// TL_(post_syscall)(tid, syscallno, RES);
5811// VGP_POPCC(VgpToolSysWrap);
5812// }
5813// }
5814//
5815// tst->status = VgTs_Runnable; /* runnable again */
5816// tst->syscallno = -1; /* no current syscall */
5817//
5818// VGP_POPCC(VgpCoreSysWrap);
5819//}
5820
sewardjde4a1d02002-03-22 01:27:54 +00005821/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00005822/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005823/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00005824