blob: e825d4eade9f23ba2e01d3a27d2ce15ca28cd35a [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/*
njnc9539842002-10-02 13:26:35 +00007 This file is part of Valgrind, an extensible x86 protected-mode
8 emulator for monitoring program execution on x86-Unixes.
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
81static void do_atfork_pre(ThreadId tid)
82{
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
90static void do_atfork_parent(ThreadId tid)
91{
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
99static void do_atfork_child(ThreadId tid)
100{
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
243 next = VG_(next_segment)(seg);
244
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
271 ret = VG_(do_syscall)(__NR_mremap, old_addr, old_size, new_size,
272 flags, new_addr);
273
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
311 ret = VG_(do_syscall)(__NR_mremap, old_addr, old_size, new_size,
312 flags, 0);
313
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
nethercoteccc9ecd2004-07-16 17:32:15 +0000381/* Given a file descriptor, attempt to deduce its filename. To do this,
rjwalshf5f536f2003-11-17 17:45:00 +0000382 we use /proc/self/fd/<FD>. If this doesn't point to a file, or if it
383 doesn't exist, we just return NULL. Otherwise, we return a pointer
384 to the file name, which the caller is responsible for freeing. */
385
fitzhardinge98abfc72003-12-16 02:05:15 +0000386Char *VG_(resolve_filename)(Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000387{
nethercote73b526f2004-10-31 18:48:21 +0000388 char tmp[28], buf[VKI_PATH_MAX];
rjwalshf5f536f2003-11-17 17:45:00 +0000389
390 VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
nethercote73b526f2004-10-31 18:48:21 +0000391 VG_(memset)(buf, 0, VKI_PATH_MAX);
rjwalshf5f536f2003-11-17 17:45:00 +0000392
nethercote73b526f2004-10-31 18:48:21 +0000393 if(VG_(readlink)(tmp, buf, VKI_PATH_MAX) == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000394 return NULL;
395
fitzhardingea7728472003-12-16 01:48:38 +0000396 return ((buf[0] == '/') ? VG_(arena_strdup)(VG_AR_CORE, buf) : NULL);
rjwalshf5f536f2003-11-17 17:45:00 +0000397}
398
399
400/* Note the fact that a file descriptor was just closed. */
401
402static
403void record_fd_close(Int tid, Int fd)
404{
405 OpenFd *i = allocated_fds;
406
thughesad1c9562004-06-26 11:27:52 +0000407 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000408 return; /* Valgrind internal */
409
rjwalshf5f536f2003-11-17 17:45:00 +0000410 while(i) {
411 if(i->fd == fd) {
412 if(i->prev)
413 i->prev->next = i->next;
414 else
415 allocated_fds = i->next;
416 if(i->next)
417 i->next->prev = i->prev;
418 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000419 VG_(arena_free) (VG_AR_CORE, i->pathname);
420 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000421 fd_count--;
422 break;
423 }
424 i = i->next;
425 }
426}
427
428/* Note the fact that a file descriptor was just opened. If the
429 tid is -1, this indicates an inherited fd. If the pathname is NULL,
430 this either indicates a non-standard file (i.e. a pipe or socket or
431 some such thing) or that we don't know the filename. If the fd is
432 already open, then we're probably doing a dup2() to an existing fd,
433 so just overwrite the existing one. */
434
nethercote3d5e9102004-11-17 18:22:38 +0000435void VG_(record_fd_open)(Int tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000436{
437 OpenFd *i;
438
thughesad1c9562004-06-26 11:27:52 +0000439 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000440 return; /* Valgrind internal */
441
rjwalshf5f536f2003-11-17 17:45:00 +0000442 /* Check to see if this fd is already open. */
443 i = allocated_fds;
444 while (i) {
445 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000446 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000447 break;
448 }
449 i = i->next;
450 }
451
452 /* Not already one: allocate an OpenFd */
453 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000454 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000455
456 i->prev = NULL;
457 i->next = allocated_fds;
458 if(allocated_fds) allocated_fds->prev = i;
459 allocated_fds = i;
460 fd_count++;
461 }
462
463 i->fd = fd;
464 i->pathname = pathname;
465 i->where = (tid == -1) ? NULL : VG_(get_ExeContext)(tid);
466}
467
468static
nethercote73b526f2004-10-31 18:48:21 +0000469Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000470{
nethercote73b526f2004-10-31 18:48:21 +0000471 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000472 VG_(sprintf)(name, "<unknown>");
473 } else {
474 VG_(sprintf)(name, "%s", sa->sun_path);
475 }
476
477 return name;
478}
479
480static
nethercote73b526f2004-10-31 18:48:21 +0000481Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000482{
nethercote73b526f2004-10-31 18:48:21 +0000483 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000484 VG_(sprintf)(name, "<unknown>");
485 } else {
486 UInt addr = sa->sin_addr.s_addr;
487
488 if (addr == 0) {
489 VG_(sprintf)(name, "<unbound>");
490 } else {
491 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
492 addr & 0xFF, (addr>>8) & 0xFF,
493 (addr>>16) & 0xFF, (addr>>24) & 0xFF,
nethercote73b526f2004-10-31 18:48:21 +0000494 vki_ntohs(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000495 }
496 }
497
498 return name;
499}
500
501
502/*
503 * Try get some details about a socket.
504 */
505
506static void
507getsockdetails(int fd)
508{
509 union u {
nethercote73b526f2004-10-31 18:48:21 +0000510 struct vki_sockaddr a;
511 struct vki_sockaddr_in in;
512 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000513 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000514 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000515
516 llen = sizeof(laddr);
517 VG_(memset)(&laddr, 0, llen);
518
519 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
520 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000521 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000522 static char lname[32];
523 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000524 struct vki_sockaddr_in paddr;
525 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000526
527 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
528 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
529 inet2name(&(laddr.in), llen, lname),
530 inet2name(&paddr, plen, pname));
531 } else {
532 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
533 fd, inet2name(&(laddr.in), llen, lname));
534 }
535 return;
536 }
nethercote73b526f2004-10-31 18:48:21 +0000537 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000538 static char lname[256];
539 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
540 unix2name(&(laddr.un), llen, lname));
541 return;
542 }
543 default:
544 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
545 laddr.a.sa_family, fd);
546 return;
547 }
548 }
549
550 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
551}
552
553
nethercote3a42fb82004-08-03 18:08:50 +0000554/* Dump out a summary, and a more detailed list, of open file descriptors. */
555void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000556{
557 OpenFd *i = allocated_fds;
558
nethercote3a42fb82004-08-03 18:08:50 +0000559 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000560
561 while(i) {
562 if(i->pathname) {
563 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
564 i->pathname);
565 } else {
566 int val;
nethercote73b526f2004-10-31 18:48:21 +0000567 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000568
nethercote73b526f2004-10-31 18:48:21 +0000569 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000570 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
571 } else {
572 getsockdetails(i->fd);
573 }
574 }
575
576 if(i->where) {
577 VG_(pp_ExeContext)(i->where);
578 VG_(message)(Vg_UserMsg, "");
579 } else {
580 VG_(message)(Vg_UserMsg, " <inherited from parent>");
581 VG_(message)(Vg_UserMsg, "");
582 }
583
584 i = i->next;
585 }
586
587 VG_(message)(Vg_UserMsg, "");
588}
589
590/* If /proc/self/fd doesn't exist for some weird reason (like you've
591 got a kernel that doesn't have /proc support compiled in), then we
592 need to find out what file descriptors we inherited from our parent
593 process the hard way - by checking each fd in turn. */
594
595static
596void do_hacky_preopened()
597{
598 struct vki_rlimit lim;
599 unsigned int count;
600 int i;
601
nethercote620154f2004-11-12 21:21:07 +0000602 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000603 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
604 an arbitrarily high number. 1024 happens to be the limit in
605 the 2.4 kernels. */
606 count = 1024;
607 } else {
608 count = lim.rlim_cur;
609 }
610
611 for (i = 0; i < count; i++)
612 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
nethercote3d5e9102004-11-17 18:22:38 +0000613 VG_(record_fd_open)(-1, i, NULL);
rjwalshf5f536f2003-11-17 17:45:00 +0000614}
615
616/* Initialize the list of open file descriptors with the file descriptors
617 we inherited from out parent process. */
618
619void VG_(init_preopened_fds)()
620{
621 int f, ret;
622 struct vki_dirent d;
623
624 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
625 if(f == -1) {
626 do_hacky_preopened();
627 return;
628 }
629
630 while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
631 if(ret == -1)
632 goto out;
633
634 if(VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
635 int fno = VG_(atoll)(d.d_name);
636
637 if(fno != f)
638 if(VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +0000639 VG_(record_fd_open)(-1, fno, VG_(resolve_filename)(fno));
rjwalshf5f536f2003-11-17 17:45:00 +0000640 }
641
642 VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
643 }
644
645out:
646 VG_(close)(f);
647}
648
sewardjde4a1d02002-03-22 01:27:54 +0000649static
650UInt get_shm_size ( Int shmid )
651{
nethercote73b526f2004-10-31 18:48:21 +0000652 struct vki_shmid_ds buf;
653 long __res = VG_(do_syscall)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid, VKI_IPC_STAT, 0, &buf);
sewardjde4a1d02002-03-22 01:27:54 +0000654 if ( VG_(is_kerror) ( __res ) )
655 return 0;
656
657 return buf.shm_segsz;
658}
thughes60797102004-08-13 22:21:51 +0000659
660static
661UInt get_sem_count( Int semid )
662{
nethercote73b526f2004-10-31 18:48:21 +0000663 struct vki_semid_ds buf;
664 union vki_semun arg;
thughes60797102004-08-13 22:21:51 +0000665 long res;
666
667 arg.buf = &buf;
668
nethercote73b526f2004-10-31 18:48:21 +0000669 res = VG_(do_syscall)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0, VKI_IPC_STAT, &arg);
thughes60797102004-08-13 22:21:51 +0000670 if ( VG_(is_kerror)(res) )
671 return 0;
672
673 return buf.sem_nsems;
674}
sewardjde4a1d02002-03-22 01:27:54 +0000675
676static
sewardj8c824512002-04-14 04:16:48 +0000677Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000678{
679 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000680 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000681 VG_(strcpy) ( result, s1 );
682 VG_(strcat) ( result, s2 );
683 return result;
684}
685
686static
jsgf855d93d2003-10-13 22:26:55 +0000687void pre_mem_read_sendmsg ( 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.sendmsg", msg, VG_AR_TRANSIENT );
nethercoteef0c7662004-11-06 15:38:43 +0000691 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000692
693 VG_(arena_free) ( VG_AR_TRANSIENT, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000694}
695
696static
jsgf855d93d2003-10-13 22:26:55 +0000697void pre_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000698 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000699{
700 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_TRANSIENT );
nethercoteef0c7662004-11-06 15:38:43 +0000701 PRE_MEM_WRITE( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000702 VG_(arena_free) ( VG_AR_TRANSIENT, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000703}
704
705static
njn72718642003-07-24 08:45:32 +0000706void post_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000707 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000708{
nethercoteef0c7662004-11-06 15:38:43 +0000709 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000710}
711
712static
sewardj8c824512002-04-14 04:16:48 +0000713void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000714 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000715 struct vki_msghdr *msg,
nethercote928a5f72004-11-03 18:10:37 +0000716 void (*foreach_func)( ThreadId, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000717 )
sewardjde4a1d02002-03-22 01:27:54 +0000718{
719 if ( !msg )
720 return;
721
nethercote73b526f2004-10-31 18:48:21 +0000722 foreach_func ( tid, "(msg)", (Addr)msg, sizeof( struct vki_msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000723
724 if ( msg->msg_name )
njn72718642003-07-24 08:45:32 +0000725 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000726 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000727 (Addr)msg->msg_name, msg->msg_namelen );
728
729 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000730 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000731 UInt i;
732
njn72718642003-07-24 08:45:32 +0000733 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000734 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000735 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000736
737 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
njn72718642003-07-24 08:45:32 +0000738 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000739 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000740 (Addr)iov->iov_base, iov->iov_len );
741 }
742
743 if ( msg->msg_control )
njn72718642003-07-24 08:45:32 +0000744 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000745 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000746 (Addr)msg->msg_control, msg->msg_controllen );
747}
748
nethercote73b526f2004-10-31 18:48:21 +0000749void check_cmsg_for_fds(Int tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000750{
nethercote73b526f2004-10-31 18:48:21 +0000751 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000752
753 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000754 if (cm->cmsg_level == VKI_SOL_SOCKET &&
755 cm->cmsg_type == VKI_SCM_RIGHTS ) {
756 int *fds = (int *) VKI_CMSG_DATA(cm);
757 int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000758 / sizeof(int);
759 int i;
760
761 for (i = 0; i < fdc; i++)
762 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000763 // XXX: must we check the range on these fds with
nethercote3d5e9102004-11-17 18:22:38 +0000764 // VG_(fd_allowed)()?
765 VG_(record_fd_open) (tid, fds[i], VG_(resolve_filename)(fds[i]));
rjwalshf5f536f2003-11-17 17:45:00 +0000766 }
767
nethercote73b526f2004-10-31 18:48:21 +0000768 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000769 }
770}
771
sewardjc483e8f2002-05-03 21:01:35 +0000772static
jsgf855d93d2003-10-13 22:26:55 +0000773void pre_mem_read_sockaddr ( ThreadId tid,
774 Char *description,
nethercote73b526f2004-10-31 18:48:21 +0000775 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000776{
sewardjff7c1ab2003-02-24 21:55:34 +0000777 Char *outmsg;
778
779 /* NULL/zero-length sockaddrs are legal */
780 if ( sa == NULL || salen == 0 ) return;
781
782 outmsg = VG_(arena_malloc) ( VG_AR_TRANSIENT,
nethercote73b526f2004-10-31 18:48:21 +0000783 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000784
785 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000786 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000787
sewardjc483e8f2002-05-03 21:01:35 +0000788 switch (sa->sa_family) {
789
nethercote73b526f2004-10-31 18:48:21 +0000790 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000791 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000792 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000793 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000794 break;
795
nethercote73b526f2004-10-31 18:48:21 +0000796 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000797 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000798 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000799 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
800 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000801 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000802 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000803 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
804 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000805 break;
806
nethercote73b526f2004-10-31 18:48:21 +0000807 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000808 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000809 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000810 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
811 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000812 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000813 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000814 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
815 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000816 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000817 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000818 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_addr,
819 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000820 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
nethercoteef0c7662004-11-06 15:38:43 +0000821 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000822 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_scope_id,
823 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000824 break;
825
826 default:
827 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000828 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000829 break;
830 }
831
njn25e49d8e72002-09-23 09:36:25 +0000832 VG_(arena_free) ( VG_AR_TRANSIENT, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000833}
834
njn25e49d8e72002-09-23 09:36:25 +0000835/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000836static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000837{
838 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000839 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000840 if (a_p == NULL)
841 return 0;
842 else
843 return *a_p;
844}
845
846/* Dereference a pointer to a pointer. */
njn72718642003-07-24 08:45:32 +0000847static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000848{
849 Addr* a_p = (Addr*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000850 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
njn25e49d8e72002-09-23 09:36:25 +0000851 return *a_p;
852}
853
854static
njn72718642003-07-24 08:45:32 +0000855void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000856 Char* buf_s, Char* buflen_s )
857{
fitzhardinge98abfc72003-12-16 02:05:15 +0000858 if (VG_(defined_pre_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000859 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000860 if (buflen_in > 0) {
njncf45fd42004-11-24 16:30:22 +0000861 TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000862 }
863 }
864}
865
866static
njn72718642003-07-24 08:45:32 +0000867void buf_and_len_post_check( ThreadId tid, Int res,
njn25e49d8e72002-09-23 09:36:25 +0000868 Addr buf_p, Addr buflen_p, Char* s )
869{
fitzhardinge98abfc72003-12-16 02:05:15 +0000870 if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000871 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000872 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njncf45fd42004-11-24 16:30:22 +0000873 TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000874 }
875 }
876}
877
878/* ---------------------------------------------------------------------
879 Data seg end, for brk()
880 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000881
fitzhardinge98abfc72003-12-16 02:05:15 +0000882static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000883{
fitzhardinge98abfc72003-12-16 02:05:15 +0000884 Addr ret = VG_(brk_limit);
885 static const Bool debug = False;
886 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000887 Addr current, newaddr;
888
fitzhardinge98abfc72003-12-16 02:05:15 +0000889
890 if (debug)
891 VG_(printf)("do_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
892 VG_(brk_base), VG_(brk_limit), newbrk);
893
894 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
895 return VG_(brk_limit);
896
897 /* brk isn't allowed to grow over anything else */
898 seg = VG_(find_segment)(VG_(brk_limit));
899
900 vg_assert(seg != NULL);
901
njn25e49d8e72002-09-23 09:36:25 +0000902 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000903 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
904 VG_(brk_limit), seg->addr, seg->addr+seg->len);
905 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit) <= (seg->addr + seg->len));
906
907 seg = VG_(next_segment)(seg);
908 if (seg != NULL && newbrk > seg->addr)
909 return VG_(brk_limit);
910
nethercotece471262004-08-25 13:43:44 +0000911 current = PGROUNDUP(VG_(brk_limit));
912 newaddr = PGROUNDUP(newbrk);
913 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000914
915 /* new brk in a new page - fix the mappings */
916 if (newbrk > VG_(brk_limit)) {
917
918 if (debug)
919 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
920 current, newaddr, newaddr-current);
921
922 if (newaddr == current) {
923 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000924 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
925 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
926 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
927 SF_FIXED|SF_BRK, -1, 0))
928 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000929 ret = newbrk;
930 }
931 } else {
932 vg_assert(newbrk < VG_(brk_limit));
933
934 if (debug)
935 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
936 current, newaddr, current-newaddr);
937
938 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000939 int res = VG_(munmap)((void *)newaddr, current - newaddr);
940 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000941 }
942 ret = newbrk;
943 }
944 } else
945 ret = newbrk;
946
947 VG_(brk_limit) = ret;
948
949 return ret;
950}
951
952
njn25e49d8e72002-09-23 09:36:25 +0000953/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000954 Vet file descriptors for sanity
955 ------------------------------------------------------------------ */
956
957/* Return true if we're allowed to use or create this fd */
nethercote3d5e9102004-11-17 18:22:38 +0000958Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000959{
thughesad1c9562004-06-26 11:27:52 +0000960 if (fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) {
jsewardd9320a42003-12-12 06:40:05 +0000961 VG_(message)(Vg_UserMsg,
962 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000963 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000964 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000965 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000966 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000967 if (VG_(clo_verbosity) > 1) {
968 ExeContext *ec = VG_(get_ExeContext)(tid);
969 VG_(pp_ExeContext)(ec);
970 }
971 return False;
972 }
thughesad1c9562004-06-26 11:27:52 +0000973 else if (soft && fd >= VG_(fd_soft_limit)) {
974 return False;
975 }
jsgf855d93d2003-10-13 22:26:55 +0000976 return True;
977}
978
979
980/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +0000981 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +0000982 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000983
nethercote4fa681f2004-11-08 17:51:39 +0000984/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +0000985 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +0000986 names like sys_write(); a few have names like old_mmap(). See the
nethercote8ff888f2004-11-17 17:11:45 +0000987 comment for VGA_(syscall_table)[] for important info about the __NR_foo
988 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +0000989
nethercote92b2fd52004-11-16 16:15:41 +0000990 Some notes about names used for syscalls and args:
991 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
992 ambiguity.
993
994 - For error messages, we generally use a somewhat generic name
995 for the syscall (eg. "write" rather than "sys_write"). This should be
996 good enough for the average user to understand what is happening,
997 without confusing them with names like "sys_write".
998
999 - Also, for error messages the arg names are mostly taken from the man
1000 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001001 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001002 for the same reason -- a user presented with a "bogus foo(bar)" arg
1003 will most likely look at the "foo" man page to see which is the "bar"
1004 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001005
nethercote9c311eb2004-11-12 18:20:12 +00001006 Note that we use our own vki_* types. The one exception is in
1007 PRE_REG_READn calls, where pointer types haven't been changed, because
1008 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1009 be visible.
1010
nethercote4fa681f2004-11-08 17:51:39 +00001011 XXX: some of these are arch-specific, and should be factored out.
1012*/
1013
njn61fa0af2004-11-27 15:22:24 +00001014#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f)
1015#define POST(name) POST_TEMPLATE( , vgArch_gen, name)
jsgf855d93d2003-10-13 22:26:55 +00001016
njncf45fd42004-11-24 16:30:22 +00001017#define SYSNO SYSCALL_NUM(tst->arch) // in PRE(x)
1018#define res SYSCALL_RET(tst->arch) // in POST(x)
1019#define arg1 SYSCALL_ARG1(tst->arch)
1020#define arg2 SYSCALL_ARG2(tst->arch)
1021#define arg3 SYSCALL_ARG3(tst->arch)
1022#define arg4 SYSCALL_ARG4(tst->arch)
1023#define arg5 SYSCALL_ARG5(tst->arch)
1024#define arg6 SYSCALL_ARG6(tst->arch)
jsgf855d93d2003-10-13 22:26:55 +00001025
nethercote35122912004-10-18 17:00:30 +00001026#define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val))
1027
nethercoteef0c7662004-11-06 15:38:43 +00001028#define PRINT(format, args...) \
1029 if (VG_(clo_trace_syscalls)) \
1030 VG_(printf)(format, ## args)
1031
1032// Combine two 32-bit values into a 64-bit value
1033#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1034
nethercote85a456f2004-11-16 17:31:56 +00001035PRE(sys_exit_group, Special)
jsgf855d93d2003-10-13 22:26:55 +00001036{
1037 VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1038}
1039
nethercote85a456f2004-11-16 17:31:56 +00001040PRE(sys_exit, Special)
jsgf855d93d2003-10-13 22:26:55 +00001041{
1042 VG_(core_panic)("syscall exit() not caught by the scheduler?!");
1043}
1044
nethercote85a456f2004-11-16 17:31:56 +00001045PRE(sys_sched_yield, Special)
nethercote5b653bc2004-11-15 14:32:12 +00001046{
1047 VG_(core_panic)("syscall sched_yield() not caught by the scheduler?!");
1048}
1049
nethercote85a456f2004-11-16 17:31:56 +00001050PRE(sys_ni_syscall, Special)
nethercoteeb1c7b72004-11-11 19:43:50 +00001051{
1052 PRINT("non-existent syscall! (ni_syscall)");
1053 PRE_REG_READ0(long, "ni_syscall");
1054 set_result( -VKI_ENOSYS );
1055}
1056
nethercote85a456f2004-11-16 17:31:56 +00001057PRE(sys_set_tid_address, Special)
rjwalshcdf1cb52004-04-29 08:40:50 +00001058{
nethercote328b7692004-11-17 18:24:10 +00001059 // We don't let this syscall run, and don't do anything to simulate it
1060 // ourselves -- it becomes a no-op! Why? Tom says:
1061 //
1062 // I suspect this is deliberate given that all the user level threads
1063 // are running in the same kernel thread under valgrind so we probably
1064 // don't want to be calling the actual system call here.
1065 //
1066 // Hmm.
nethercote5b653bc2004-11-15 14:32:12 +00001067 PRINT("sys_set_tid_address ( %p )", arg1);
1068 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
rjwalshcdf1cb52004-04-29 08:40:50 +00001069}
1070
nethercote85a456f2004-11-16 17:31:56 +00001071PRE(sys_iopl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001072{
nethercote7f7e4d12004-11-15 12:28:58 +00001073 PRINT("sys_iopl ( %d )", arg1);
1074 PRE_REG_READ1(long, "iopl", unsigned long, level);
jsgf855d93d2003-10-13 22:26:55 +00001075}
1076
nethercote85a456f2004-11-16 17:31:56 +00001077PRE(sys_setxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001078{
nethercote2e1c37d2004-11-13 13:57:12 +00001079 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
nethercoteef0c7662004-11-06 15:38:43 +00001080 arg1, arg2, arg3, (ULong)arg4, arg5);
nethercote2e1c37d2004-11-13 13:57:12 +00001081 PRE_REG_READ5(long, "setxattr",
1082 char *, path, char *, name,
1083 void *, value, vki_size_t, size, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001084 PRE_MEM_RASCIIZ( "setxattr(path)", arg1 );
1085 PRE_MEM_RASCIIZ( "setxattr(name)", arg2 );
1086 PRE_MEM_READ( "setxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001087}
1088
nethercote85a456f2004-11-16 17:31:56 +00001089PRE(sys_lsetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001090{
nethercote2e1c37d2004-11-13 13:57:12 +00001091 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
nethercoteef0c7662004-11-06 15:38:43 +00001092 arg1, arg2, arg3, (ULong)arg4, arg5);
nethercote2e1c37d2004-11-13 13:57:12 +00001093 PRE_REG_READ5(long, "lsetxattr",
1094 char *, path, char *, name,
1095 void *, value, vki_size_t, size, int, flags);
1096 PRE_MEM_RASCIIZ( "lsetxattr(path)", arg1 );
1097 PRE_MEM_RASCIIZ( "lsetxattr(name)", arg2 );
1098 PRE_MEM_READ( "lsetxattr(value)", arg3, arg4 );
1099}
1100
nethercote85a456f2004-11-16 17:31:56 +00001101PRE(sys_fsetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001102{
1103 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
1104 arg1, arg2, arg3, (ULong)arg4, arg5);
1105 PRE_REG_READ5(long, "fsetxattr",
1106 int, fd, char *, name, void *, value,
1107 vki_size_t, size, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001108 PRE_MEM_RASCIIZ( "fsetxattr(name)", arg2 );
1109 PRE_MEM_READ( "fsetxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001110}
1111
nethercote85a456f2004-11-16 17:31:56 +00001112PRE(sys_getxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001113{
nethercote2e1c37d2004-11-13 13:57:12 +00001114 PRINT("sys_getxattr ( %p, %p, %p, %llu )", arg1,arg2,arg3, (ULong)arg4);
1115 PRE_REG_READ4(ssize_t, "getxattr",
1116 char *, path, char *, name, void *, value, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001117 PRE_MEM_RASCIIZ( "getxattr(path)", arg1 );
1118 PRE_MEM_RASCIIZ( "getxattr(name)", arg2 );
1119 PRE_MEM_WRITE( "getxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001120}
1121
nethercote85a456f2004-11-16 17:31:56 +00001122POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001123{
1124 if (res > 0 && arg3 != (Addr)NULL) {
nethercoteef0c7662004-11-06 15:38:43 +00001125 POST_MEM_WRITE( arg3, res );
jsgf855d93d2003-10-13 22:26:55 +00001126 }
1127}
1128
nethercote85a456f2004-11-16 17:31:56 +00001129PRE(sys_lgetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001130{
nethercote2e1c37d2004-11-13 13:57:12 +00001131 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", arg1,arg2,arg3, (ULong)arg4);
1132 PRE_REG_READ4(ssize_t, "lgetxattr",
1133 char *, path, char *, name, void *, value, vki_size_t, size);
1134 PRE_MEM_RASCIIZ( "lgetxattr(path)", arg1 );
1135 PRE_MEM_RASCIIZ( "lgetxattr(name)", arg2 );
1136 PRE_MEM_WRITE( "lgetxattr(value)", arg3, arg4 );
1137}
1138
nethercote85a456f2004-11-16 17:31:56 +00001139POST(sys_lgetxattr)
nethercote2e1c37d2004-11-13 13:57:12 +00001140{
1141 if (res > 0 && arg3 != (Addr)NULL) {
1142 POST_MEM_WRITE( arg3, res );
1143 }
1144}
1145
nethercote85a456f2004-11-16 17:31:56 +00001146PRE(sys_fgetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001147{
1148 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", arg1, arg2, arg3, (ULong)arg4);
1149 PRE_REG_READ4(ssize_t, "fgetxattr",
1150 int, fd, char *, name, void *, value, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001151 PRE_MEM_RASCIIZ( "fgetxattr(name)", arg2 );
1152 PRE_MEM_WRITE( "fgetxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001153}
1154
nethercote85a456f2004-11-16 17:31:56 +00001155POST(sys_fgetxattr)
jsgf855d93d2003-10-13 22:26:55 +00001156{
1157 if (res > 0 && arg3 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001158 POST_MEM_WRITE( arg3, res );
jsgf855d93d2003-10-13 22:26:55 +00001159}
1160
nethercote85a456f2004-11-16 17:31:56 +00001161PRE(sys_listxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001162{
nethercote2e1c37d2004-11-13 13:57:12 +00001163 PRINT("sys_listxattr ( %p, %p, %llu )", arg1, arg2, (ULong)arg3);
1164 PRE_REG_READ3(ssize_t, "listxattr",
1165 char *, path, char *, list, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001166 PRE_MEM_RASCIIZ( "listxattr(path)", arg1 );
1167 PRE_MEM_WRITE( "listxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001168}
1169
nethercote85a456f2004-11-16 17:31:56 +00001170POST(sys_listxattr)
jsgf855d93d2003-10-13 22:26:55 +00001171{
1172 if (res > 0 && arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001173 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001174}
1175
nethercote85a456f2004-11-16 17:31:56 +00001176PRE(sys_llistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001177{
nethercote2e1c37d2004-11-13 13:57:12 +00001178 PRINT("sys_llistxattr ( %p, %p, %llu )", arg1, arg2, (ULong)arg3);
1179 PRE_REG_READ3(ssize_t, "llistxattr",
1180 char *, path, char *, list, vki_size_t, size);
1181 PRE_MEM_RASCIIZ( "llistxattr(path)", arg1 );
1182 PRE_MEM_WRITE( "llistxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001183}
1184
nethercote85a456f2004-11-16 17:31:56 +00001185POST(sys_llistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001186{
1187 if (res > 0 && arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001188 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001189}
1190
nethercote85a456f2004-11-16 17:31:56 +00001191PRE(sys_flistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001192{
nethercote2e1c37d2004-11-13 13:57:12 +00001193 PRINT("sys_flistxattr ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
1194 PRE_REG_READ3(ssize_t, "flistxattr",
1195 int, fd, char *, list, vki_size_t, size);
1196 PRE_MEM_WRITE( "flistxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001197}
1198
nethercote85a456f2004-11-16 17:31:56 +00001199POST(sys_flistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001200{
nethercote2e1c37d2004-11-13 13:57:12 +00001201 if (res > 0 && arg2 != (Addr)NULL)
1202 POST_MEM_WRITE( arg2, res );
1203}
1204
nethercote85a456f2004-11-16 17:31:56 +00001205PRE(sys_removexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001206{
1207 PRINT("sys_removexattr ( %p, %p )", arg1, arg2);
1208 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
1209 PRE_MEM_RASCIIZ( "removexattr(path)", arg1 );
1210 PRE_MEM_RASCIIZ( "removexattr(name)", arg2 );
1211}
1212
nethercote85a456f2004-11-16 17:31:56 +00001213PRE(sys_lremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001214{
1215 PRINT("sys_lremovexattr ( %p, %p )", arg1, arg2);
1216 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
1217 PRE_MEM_RASCIIZ( "lremovexattr(path)", arg1 );
1218 PRE_MEM_RASCIIZ( "lremovexattr(name)", arg2 );
1219}
1220
nethercote85a456f2004-11-16 17:31:56 +00001221PRE(sys_fremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001222{
1223 PRINT("sys_fremovexattr ( %d, %p )", arg1, arg2);
1224 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
1225 PRE_MEM_RASCIIZ( "fremovexattr(name)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001226}
1227
nethercote85a456f2004-11-16 17:31:56 +00001228PRE(sys_quotactl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001229{
nethercote5b653bc2004-11-15 14:32:12 +00001230 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", arg1,arg2,arg3, arg4);
1231 PRE_REG_READ4(long, "quotactl",
1232 unsigned int, cmd, const char *, special, vki_qid_t, id,
1233 void *, addr);
nethercoteef0c7662004-11-06 15:38:43 +00001234 PRE_MEM_RASCIIZ( "quotactl(special)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001235}
1236
nethercote5a945af2004-11-14 18:37:07 +00001237// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00001238PRE(sys_lookup_dcookie, 0)
jsgf855d93d2003-10-13 22:26:55 +00001239{
nethercote660e4ee2004-11-12 13:29:24 +00001240 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(arg1,arg2), arg3, arg4);
1241 PRE_REG_READ4(long, "lookup_dcookie",
1242 vki_u32, cookie_low32, vki_u32, cookie_high32,
1243 char *, buf, vki_size_t, len);
nethercoteef0c7662004-11-06 15:38:43 +00001244 PRE_MEM_WRITE( "lookup_dcookie(buf)", arg3, arg4);
jsgf855d93d2003-10-13 22:26:55 +00001245}
1246
nethercote85a456f2004-11-16 17:31:56 +00001247POST(sys_lookup_dcookie)
jsgf855d93d2003-10-13 22:26:55 +00001248{
1249 if (arg3 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001250 POST_MEM_WRITE( arg3, res);
jsgf855d93d2003-10-13 22:26:55 +00001251}
1252
nethercote85a456f2004-11-16 17:31:56 +00001253PRE(sys_fsync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001254{
nethercotedc18c0a2004-11-14 20:06:27 +00001255 PRINT("sys_fsync ( %d )", arg1);
1256 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1257}
1258
nethercote85a456f2004-11-16 17:31:56 +00001259PRE(sys_fdatasync, MayBlock)
nethercotedc18c0a2004-11-14 20:06:27 +00001260{
1261 PRINT("sys_fdatasync ( %d )", arg1);
1262 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001263}
1264
nethercote85a456f2004-11-16 17:31:56 +00001265PRE(sys_msync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001266{
nethercote06c7bd72004-11-14 19:11:56 +00001267 PRINT("sys_msync ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
1268 PRE_REG_READ3(long, "msync",
1269 unsigned long, start, vki_size_t, length, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001270 PRE_MEM_READ( "msync(start)", arg1, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001271}
1272
nethercoteef0c7662004-11-06 15:38:43 +00001273// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1274// versions of LiS (Linux Streams). They are not part of the kernel.
1275// Therefore, we have to provide this type ourself, rather than getting it
1276// from the kernel sources.
nethercoteb77dee62004-11-16 17:13:24 +00001277struct vki_pmsg_strbuf {
jsgf855d93d2003-10-13 22:26:55 +00001278 int maxlen; /* no. of bytes in buffer */
1279 int len; /* no. of bytes returned */
nethercote73b526f2004-10-31 18:48:21 +00001280 vki_caddr_t buf; /* pointer to data */
jsgf855d93d2003-10-13 22:26:55 +00001281};
1282
nethercote85a456f2004-11-16 17:31:56 +00001283PRE(sys_getpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001284{
1285 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001286 struct vki_pmsg_strbuf *ctrl;
1287 struct vki_pmsg_strbuf *data;
1288 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
1289 PRE_REG_READ5(int, "getpmsg",
1290 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1291 int *, bandp, int *, flagsp);
1292 ctrl = (struct vki_pmsg_strbuf *)arg2;
1293 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001294 if (ctrl && ctrl->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001295 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001296 if (data && data->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001297 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001298 if (arg4)
nethercoteef0c7662004-11-06 15:38:43 +00001299 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)arg4, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001300 if (arg5)
nethercoteef0c7662004-11-06 15:38:43 +00001301 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)arg5, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001302}
1303
nethercote85a456f2004-11-16 17:31:56 +00001304POST(sys_getpmsg)
jsgf855d93d2003-10-13 22:26:55 +00001305{
nethercoteb77dee62004-11-16 17:13:24 +00001306 struct vki_pmsg_strbuf *ctrl;
1307 struct vki_pmsg_strbuf *data;
jsgf855d93d2003-10-13 22:26:55 +00001308
nethercoteb77dee62004-11-16 17:13:24 +00001309 ctrl = (struct vki_pmsg_strbuf *)arg2;
1310 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001311 if (res == 0 && ctrl && ctrl->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001312 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001313 }
1314 if (res == 0 && data && data->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001315 POST_MEM_WRITE( (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001316 }
1317}
1318
nethercote85a456f2004-11-16 17:31:56 +00001319PRE(sys_putpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001320{
1321 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001322 struct vki_pmsg_strbuf *ctrl;
1323 struct vki_pmsg_strbuf *data;
1324 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", arg1,arg2,arg3,arg4,arg5);
1325 PRE_REG_READ5(int, "putpmsg",
1326 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1327 int, band, int, flags);
1328 ctrl = (struct vki_pmsg_strbuf *)arg2;
1329 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001330 if (ctrl && ctrl->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001331 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001332 if (data && data->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001333 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001334}
1335
nethercote85a456f2004-11-16 17:31:56 +00001336PRE(sys_getitimer, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00001337{
nethercote5b653bc2004-11-15 14:32:12 +00001338 PRINT("sys_getitimer ( %d, %p )", arg1, arg2);
1339 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
1340 PRE_MEM_WRITE( "getitimer(value)", arg2, sizeof(struct vki_itimerval) );
jsgf855d93d2003-10-13 22:26:55 +00001341}
1342
nethercote85a456f2004-11-16 17:31:56 +00001343POST(sys_getitimer)
jsgf855d93d2003-10-13 22:26:55 +00001344{
1345 if (arg2 != (Addr)NULL) {
njncf45fd42004-11-24 16:30:22 +00001346 POST_MEM_WRITE(arg2, sizeof(struct vki_itimerval));
jsgf855d93d2003-10-13 22:26:55 +00001347 }
1348}
1349
nethercote85a456f2004-11-16 17:31:56 +00001350PRE(sys_setitimer, NBRunInLWP)
nethercote5b653bc2004-11-15 14:32:12 +00001351{
1352 PRINT("sys_setitimer ( %d, %p, %p )", arg1,arg2,arg3);
1353 PRE_REG_READ3(long, "setitimer",
1354 int, which,
1355 struct itimerval *, value, struct itimerval *, ovalue);
1356 if (arg2 != (Addr)NULL)
1357 PRE_MEM_READ( "setitimer(value)", arg2, sizeof(struct vki_itimerval) );
1358 if (arg3 != (Addr)NULL)
1359 PRE_MEM_WRITE( "setitimer(ovalue)", arg3, sizeof(struct vki_itimerval));
1360}
1361
nethercote85a456f2004-11-16 17:31:56 +00001362POST(sys_setitimer)
nethercote5b653bc2004-11-15 14:32:12 +00001363{
1364 if (arg3 != (Addr)NULL) {
njncf45fd42004-11-24 16:30:22 +00001365 POST_MEM_WRITE(arg3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00001366 }
1367}
1368
nethercote85a456f2004-11-16 17:31:56 +00001369PRE(sys_chroot, 0)
jsgf855d93d2003-10-13 22:26:55 +00001370{
nethercote71f05f32004-11-12 18:49:27 +00001371 PRINT("sys_chroot ( %p )", arg1);
1372 PRE_REG_READ1(long, "chroot", const char *, path);
nethercoteef0c7662004-11-06 15:38:43 +00001373 PRE_MEM_RASCIIZ( "chroot(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001374}
1375
nethercote85a456f2004-11-16 17:31:56 +00001376PRE(sys_madvise, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001377{
nethercoteac866b92004-11-15 20:23:15 +00001378 PRINT("sys_madvise ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
1379 PRE_REG_READ3(long, "madvise",
1380 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00001381}
1382
nethercote85a456f2004-11-16 17:31:56 +00001383PRE(sys_mremap, Special)
jsgf855d93d2003-10-13 22:26:55 +00001384{
nethercote27ea8bc2004-07-10 17:21:14 +00001385 // Nb: this is different to the glibc version described in the man pages,
1386 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00001387 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
1388 arg1, (ULong)arg2, arg3, arg4, arg5);
1389 PRE_REG_READ5(unsigned long, "mremap",
1390 unsigned long, old_addr, unsigned long, old_size,
1391 unsigned long, new_size, unsigned long, flags,
1392 unsigned long, new_addr);
nethercote35122912004-10-18 17:00:30 +00001393 set_result( mremap_segment((Addr)arg1, arg2, (Addr)arg5, arg3, arg4, tid) );
jsgf855d93d2003-10-13 22:26:55 +00001394}
1395
nethercote85a456f2004-11-16 17:31:56 +00001396PRE(sys_nice, 0)
jsgf855d93d2003-10-13 22:26:55 +00001397{
nethercote9a3beb92004-11-12 17:07:26 +00001398 PRINT("sys_nice ( %d )", arg1);
1399 PRE_REG_READ1(long, "nice", int, inc);
jsgf855d93d2003-10-13 22:26:55 +00001400}
1401
nethercote85a456f2004-11-16 17:31:56 +00001402PRE(sys_sched_getscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001403{
nethercote5b653bc2004-11-15 14:32:12 +00001404 PRINT("sys_sched_getscheduler ( %d )", arg1);
1405 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001406}
1407
nethercote85a456f2004-11-16 17:31:56 +00001408PRE(sys_sched_setscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001409{
nethercote5b653bc2004-11-15 14:32:12 +00001410 PRINT("sys_sched_setscheduler ( %d, %d, %p )", arg1,arg2,arg3);
1411 PRE_REG_READ3(long, "sched_setscheduler",
1412 vki_pid_t, pid, int, policy, struct sched_param *, p);
nethercote163c5e82004-11-17 18:42:20 +00001413 if (arg3 != 0)
nethercote5b653bc2004-11-15 14:32:12 +00001414 PRE_MEM_READ( "sched_setscheduler(p)",
nethercoteef0c7662004-11-06 15:38:43 +00001415 arg3, sizeof(struct vki_sched_param));
jsgf855d93d2003-10-13 22:26:55 +00001416}
1417
nethercote85a456f2004-11-16 17:31:56 +00001418PRE(sys_mlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001419{
nethercote06c7bd72004-11-14 19:11:56 +00001420 PRINT("sys_mlock ( %p, %llu )", arg1, (ULong)arg2);
1421 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001422}
1423
nethercote85a456f2004-11-16 17:31:56 +00001424PRE(sys_munlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001425{
nethercote06c7bd72004-11-14 19:11:56 +00001426 PRINT("sys_munlock ( %p, %llu )", arg1, (ULong)arg2);
1427 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001428}
1429
nethercote85a456f2004-11-16 17:31:56 +00001430PRE(sys_mlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001431{
nethercote06c7bd72004-11-14 19:11:56 +00001432 PRINT("sys_mlockall ( %x )", arg1);
1433 PRE_REG_READ1(long, "mlockall", int, flags);
jsgf855d93d2003-10-13 22:26:55 +00001434}
1435
nethercote85a456f2004-11-16 17:31:56 +00001436PRE(sys_munlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001437{
nethercote0df495a2004-11-11 16:38:21 +00001438 PRINT("sys_munlockall ( )");
1439 PRE_REG_READ0(long, "munlockall");
jsgf855d93d2003-10-13 22:26:55 +00001440}
1441
nethercote85a456f2004-11-16 17:31:56 +00001442PRE(sys_sched_get_priority_max, 0)
jsgf855d93d2003-10-13 22:26:55 +00001443{
nethercoteef0c7662004-11-06 15:38:43 +00001444 PRINT("sched_get_priority_max ( %d )", arg1);
nethercote5b653bc2004-11-15 14:32:12 +00001445 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001446}
1447
nethercote85a456f2004-11-16 17:31:56 +00001448PRE(sys_sched_get_priority_min, 0)
jsgf855d93d2003-10-13 22:26:55 +00001449{
nethercoteef0c7662004-11-06 15:38:43 +00001450 PRINT("sched_get_priority_min ( %d )", arg1);
nethercote5b653bc2004-11-15 14:32:12 +00001451 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001452}
1453
nethercote85a456f2004-11-16 17:31:56 +00001454PRE(sys_setpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001455{
nethercotedc18c0a2004-11-14 20:06:27 +00001456 PRINT("sys_setpriority ( %d, %d, %d )", arg1, arg2, arg3);
1457 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
jsgf855d93d2003-10-13 22:26:55 +00001458}
1459
nethercote85a456f2004-11-16 17:31:56 +00001460PRE(sys_getpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001461{
nethercotedc18c0a2004-11-14 20:06:27 +00001462 PRINT("sys_getpriority ( %d, %d )", arg1, arg2);
1463 PRE_REG_READ2(long, "getpriority", int, which, int, who);
jsgf855d93d2003-10-13 22:26:55 +00001464}
1465
nethercote85a456f2004-11-16 17:31:56 +00001466PRE(sys_setregid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001467{
nethercote17258dc2004-11-12 19:55:08 +00001468 PRINT("sys_setregid16 ( %d, %d )", arg1, arg2);
1469 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00001470}
1471
nethercoteac866b92004-11-15 20:23:15 +00001472// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001473PRE(sys_pwrite64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001474{
nethercoteac866b92004-11-15 20:23:15 +00001475 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
nethercoteef0c7662004-11-06 15:38:43 +00001476 arg1, arg2, (ULong)arg3, LOHI64(arg4,arg5));
nethercoteac866b92004-11-15 20:23:15 +00001477 PRE_REG_READ5(ssize_t, "pwrite64",
1478 unsigned int, fd, const char *, buf, vki_size_t, count,
1479 vki_u32, offset_low32, vki_u32, offset_high32);
nethercoteef0c7662004-11-06 15:38:43 +00001480 PRE_MEM_READ( "pwrite64(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001481}
1482
nethercote85a456f2004-11-16 17:31:56 +00001483PRE(sys_sync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001484{
nethercote0df495a2004-11-11 16:38:21 +00001485 PRINT("sys_sync ( )");
1486 PRE_REG_READ0(long, "sync");
jsgf855d93d2003-10-13 22:26:55 +00001487}
1488
nethercote85a456f2004-11-16 17:31:56 +00001489PRE(sys_fstatfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00001490{
nethercotedc18c0a2004-11-14 20:06:27 +00001491 PRINT("sys_fstatfs ( %d, %p )",arg1,arg2);
1492 PRE_REG_READ2(long, "fstatfs",
1493 unsigned int, fd, struct statfs *, buf);
1494 PRE_MEM_WRITE( "fstatfs(buf)", arg2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001495}
1496
nethercote85a456f2004-11-16 17:31:56 +00001497POST(sys_fstatfs)
jsgf855d93d2003-10-13 22:26:55 +00001498{
nethercoteef0c7662004-11-06 15:38:43 +00001499 POST_MEM_WRITE( arg2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001500}
1501
nethercote85a456f2004-11-16 17:31:56 +00001502PRE(sys_fstatfs64, 0)
thughesa996d3b2004-09-24 22:57:17 +00001503{
nethercotedc18c0a2004-11-14 20:06:27 +00001504 PRINT("sys_fstatfs64 ( %d, %llu, %p )",arg1,(ULong)arg2,arg3);
1505 PRE_REG_READ3(long, "fstatfs64",
1506 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
1507 PRE_MEM_WRITE( "fstatfs64(buf)", arg3, arg2 );
thughesa996d3b2004-09-24 22:57:17 +00001508}
1509
nethercote85a456f2004-11-16 17:31:56 +00001510POST(sys_fstatfs64)
thughesa996d3b2004-09-24 22:57:17 +00001511{
nethercoteef0c7662004-11-06 15:38:43 +00001512 POST_MEM_WRITE( arg3, arg2 );
thughesa996d3b2004-09-24 22:57:17 +00001513}
1514
nethercote85a456f2004-11-16 17:31:56 +00001515PRE(sys_getsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00001516{
nethercote5b653bc2004-11-15 14:32:12 +00001517 PRINT("sys_getsid ( %d )", arg1);
1518 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001519}
1520
nethercoteac866b92004-11-15 20:23:15 +00001521// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001522PRE(sys_pread64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001523{
nethercoteac866b92004-11-15 20:23:15 +00001524 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
nethercoteef0c7662004-11-06 15:38:43 +00001525 arg1, arg2, (ULong)arg3, LOHI64(arg4,arg5));
nethercoteac866b92004-11-15 20:23:15 +00001526 PRE_REG_READ5(ssize_t, "pread64",
1527 unsigned int, fd, char *, buf, vki_size_t, count,
1528 vki_u32, offset_low32, vki_u32, offset_high32);
1529 PRE_MEM_WRITE( "pread64(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001530}
1531
nethercote85a456f2004-11-16 17:31:56 +00001532POST(sys_pread64)
jsgf855d93d2003-10-13 22:26:55 +00001533{
jsgf855d93d2003-10-13 22:26:55 +00001534 if (res > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001535 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001536 }
1537}
1538
nethercote85a456f2004-11-16 17:31:56 +00001539PRE(sys_mknod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001540{
nethercotec6851dd2004-11-11 18:00:47 +00001541 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", arg1, arg2, arg3 );
1542 PRE_REG_READ3(long, "mknod",
1543 const char *, pathname, int, mode, unsigned, dev);
nethercoteef0c7662004-11-06 15:38:43 +00001544 PRE_MEM_RASCIIZ( "mknod(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001545}
1546
nethercote85a456f2004-11-16 17:31:56 +00001547PRE(sys_flock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001548{
nethercote06c7bd72004-11-14 19:11:56 +00001549 PRINT("sys_flock ( %d, %d )", arg1, arg2 );
1550 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
jsgf855d93d2003-10-13 22:26:55 +00001551}
1552
nethercote85a456f2004-11-16 17:31:56 +00001553PRE(sys_init_module, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001554{
nethercote0eafe552004-11-15 16:40:40 +00001555 PRINT("sys_init_module ( %p, %llu, %p )", arg1, (ULong)arg2, arg3 );
1556 PRE_REG_READ3(long, "init_module",
1557 void *, umod, unsigned long, len, const char *, uargs);
1558 PRE_MEM_READ( "init_module(umod)", arg1, arg2 );
1559 PRE_MEM_RASCIIZ( "init_module(uargs)", arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001560}
1561
nethercote85a456f2004-11-16 17:31:56 +00001562PRE(sys_capget, 0)
jsgf855d93d2003-10-13 22:26:55 +00001563{
nethercoteac866b92004-11-15 20:23:15 +00001564 PRINT("sys_capget ( %p, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00001565 PRE_REG_READ2(long, "capget",
1566 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00001567 PRE_MEM_READ( "capget(header)", arg1,
nethercote73b526f2004-10-31 18:48:21 +00001568 sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00001569 PRE_MEM_WRITE( "capget(data)", arg2,
nethercote73b526f2004-10-31 18:48:21 +00001570 sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001571}
1572
nethercote85a456f2004-11-16 17:31:56 +00001573POST(sys_capget)
jsgf855d93d2003-10-13 22:26:55 +00001574{
1575 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001576 POST_MEM_WRITE( arg2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001577}
1578
nethercote85a456f2004-11-16 17:31:56 +00001579PRE(sys_capset, 0)
jsgf855d93d2003-10-13 22:26:55 +00001580{
nethercote5b653bc2004-11-15 14:32:12 +00001581 PRINT("sys_capset ( %p, %p )", arg1, arg2 );
1582 PRE_REG_READ2(long, "capset",
1583 vki_cap_user_header_t, header,
1584 const vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00001585 PRE_MEM_READ( "capset(header)",
nethercote73b526f2004-10-31 18:48:21 +00001586 arg1, sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00001587 PRE_MEM_READ( "capset(data)",
nethercote73b526f2004-10-31 18:48:21 +00001588 arg2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001589}
1590
nethercotea81e9162004-02-12 14:34:14 +00001591// Pre_read a char** argument.
1592void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
1593{
1594 while (True) {
1595 Addr a_deref = deref_Addr( tid, a, s1 );
1596 if (0 == a_deref)
1597 break;
nethercoteef0c7662004-11-06 15:38:43 +00001598 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00001599 a += sizeof(char*);
1600 }
1601}
1602
nethercote7310afb2004-11-12 15:41:06 +00001603// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
1604// but it seems to work nonetheless...
nethercote85a456f2004-11-16 17:31:56 +00001605PRE(sys_execve, Special)
jsgf855d93d2003-10-13 22:26:55 +00001606{
nethercote7310afb2004-11-12 15:41:06 +00001607 PRINT("sys_execve ( %p(%s), %p, %p )", arg1, arg1, arg2, arg3);
1608 PRE_REG_READ3(vki_off_t, "execve",
1609 char *, filename, char **, argv, char **, envp);
nethercoteef0c7662004-11-06 15:38:43 +00001610 PRE_MEM_RASCIIZ( "execve(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00001611 if (arg2 != 0)
thughes7f72d012004-07-21 16:23:38 +00001612 pre_argv_envp( arg2, tid, "execve(argv)", "execve(argv[i])" );
nethercote163c5e82004-11-17 18:42:20 +00001613 if (arg3 != 0)
thughes4b9e0152004-06-19 13:02:34 +00001614 pre_argv_envp( arg3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00001615
1616 /* Erk. If the exec fails, then the following will have made a
1617 mess of things which makes it hard for us to continue. The
1618 right thing to do is piece everything together again in
1619 POST(execve), but that's hard work. Instead, we make an effort
1620 to check that the execve will work before actually calling
1621 exec. */
1622 {
1623 struct vki_stat st;
1624 Int ret = VG_(stat)((Char *)arg1, &st);
1625
1626 if (ret < 0) {
nethercote35122912004-10-18 17:00:30 +00001627 set_result( ret );
fitzhardingee1c06d82003-10-30 07:21:44 +00001628 return;
1629 }
thughes90efa302004-09-25 16:13:55 +00001630 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00001631 XXX do proper permissions check?
1632 */
thughes90efa302004-09-25 16:13:55 +00001633 if ((st.st_mode & 0100111) == 0100000) {
nethercote35122912004-10-18 17:00:30 +00001634 set_result( -VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00001635 return;
1636 }
1637 }
1638
1639 /* Resistance is futile. Nuke all other threads. POSIX mandates
1640 this. (Really, nuke them all, since the new process will make
1641 its own new thread.) */
1642 VG_(nuke_all_threads_except)( VG_INVALID_THREADID );
1643
fitzhardinge5408c062004-01-04 23:52:59 +00001644 {
nethercote60a96c52004-08-03 13:08:31 +00001645 // Remove the valgrind-specific stuff from the environment so the
1646 // child doesn't get our libpthread and other stuff. This is
1647 // done unconditionally, since if we are tracing the child,
1648 // stage1/2 will set up the appropriate client environment.
jsgf855d93d2003-10-13 22:26:55 +00001649 Char** envp = (Char**)arg3;
fitzhardinge98abfc72003-12-16 02:05:15 +00001650
1651 if (envp != NULL) {
nethercote60a96c52004-08-03 13:08:31 +00001652 VG_(env_remove_valgrind_env_stuff)( envp );
jsgf855d93d2003-10-13 22:26:55 +00001653 }
fitzhardinge5408c062004-01-04 23:52:59 +00001654 }
1655
1656 if (VG_(clo_trace_children)) {
nethercotef6a1d502004-08-09 12:21:57 +00001657 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)arg1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00001658
nethercotef6a1d502004-08-09 12:21:57 +00001659 // Set VALGRINDCLO and VALGRINDLIB in arg3 (the environment)
1660 VG_(env_setenv)( (Char***)&arg3, VALGRINDCLO, optvar);
1661 VG_(env_setenv)( (Char***)&arg3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00001662
nethercotef6a1d502004-08-09 12:21:57 +00001663 // Create executable name: "/proc/self/fd/<vgexecfd>", update arg1
nethercotea8c1e922004-10-26 10:57:24 +00001664 arg1 = (Addr)VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00001665 }
1666
1667 if (0) {
1668 Char **cpp;
1669
1670 VG_(printf)("exec: %s\n", (Char *)arg1);
1671 for(cpp = (Char **)arg2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00001672 VG_(printf)("argv: %s\n", *cpp);
fitzhardinge98abfc72003-12-16 02:05:15 +00001673 for(cpp = (Char **)arg3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00001674 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00001675 }
jsgf855d93d2003-10-13 22:26:55 +00001676
fitzhardingef0dd7e12004-01-16 02:17:30 +00001677 /* Set our real sigmask to match the client's sigmask so that the
1678 exec'd child will get the right mask. First we need to clear
1679 out any pending signals so they they don't get delivered, which
1680 would confuse things.
1681
1682 XXX This is a bug - the signals should remain pending, and be
1683 delivered to the new process after exec. There's also a
1684 race-condition, since if someone delivers us a signal between
1685 the sigprocmask and the execve, we'll still get the signal. Oh
1686 well.
1687 */
1688 {
nethercote73b526f2004-10-31 18:48:21 +00001689 vki_sigset_t allsigs;
1690 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00001691 static const struct vki_timespec zero = { 0, 0 };
1692
nethercote73b526f2004-10-31 18:48:21 +00001693 VG_(sigfillset)(&allsigs);
1694 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
fitzhardingef0dd7e12004-01-16 02:17:30 +00001695 ;
1696
nethercote73b526f2004-10-31 18:48:21 +00001697 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00001698 }
1699
fitzhardingeb50068f2004-02-24 23:42:55 +00001700 /* restore the DATA rlimit for the child */
1701 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1702
nethercote35122912004-10-18 17:00:30 +00001703 set_result( VG_(do_syscall)(__NR_execve, arg1, arg2, arg3) );
fitzhardingee1c06d82003-10-30 07:21:44 +00001704
1705 /* If we got here, then the execve failed. We've already made too much of a mess
1706 of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00001707 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
fitzhardingee1c06d82003-10-30 07:21:44 +00001708 arg1, arg1, arg2, arg3, -res);
1709 VG_(core_panic)("EXEC FAILED: I can't recover from execve() failing, so I'm dying.\n"
1710 "Add more stringent tests in PRE(execve), or work out how to recover.");
jsgf855d93d2003-10-13 22:26:55 +00001711}
1712
nethercote85a456f2004-11-16 17:31:56 +00001713PRE(sys_access, 0)
jsgf855d93d2003-10-13 22:26:55 +00001714{
nethercote9a3beb92004-11-12 17:07:26 +00001715 PRINT("sys_access ( %p(%s), %d )", arg1,arg1,arg2);
1716 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00001717 PRE_MEM_RASCIIZ( "access(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001718}
1719
nethercote85a456f2004-11-16 17:31:56 +00001720PRE(sys_alarm, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00001721{
nethercote9a3beb92004-11-12 17:07:26 +00001722 PRINT("sys_alarm ( %d )", arg1);
1723 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00001724}
1725
nethercote85a456f2004-11-16 17:31:56 +00001726PRE(sys_brk, Special)
jsgf855d93d2003-10-13 22:26:55 +00001727{
fitzhardinge98abfc72003-12-16 02:05:15 +00001728 Addr brk_limit = VG_(brk_limit);
1729
jsgf855d93d2003-10-13 22:26:55 +00001730 /* libc says: int brk(void *end_data_segment);
1731 kernel says: void* brk(void* end_data_segment); (more or less)
1732
1733 libc returns 0 on success, and -1 (and sets errno) on failure.
1734 Nb: if you ask to shrink the dataseg end below what it
1735 currently is, that always succeeds, even if the dataseg end
1736 doesn't actually change (eg. brk(0)). Unless it seg faults.
1737
1738 Kernel returns the new dataseg end. If the brk() failed, this
1739 will be unchanged from the old one. That's why calling (kernel)
1740 brk(0) gives the current dataseg end (libc brk() just returns
1741 zero in that case).
1742
1743 Both will seg fault if you shrink it back into a text segment.
1744 */
nethercote9c311eb2004-11-12 18:20:12 +00001745 PRINT("sys_brk ( %p )", arg1);
1746 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00001747
nethercote35122912004-10-18 17:00:30 +00001748 set_result( do_brk(arg1) );
fitzhardinge98abfc72003-12-16 02:05:15 +00001749
jsgf855d93d2003-10-13 22:26:55 +00001750 if (res == arg1) {
1751 /* brk() succeeded */
fitzhardinge98abfc72003-12-16 02:05:15 +00001752 if (res < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00001753 /* successfully shrunk the data segment. */
1754 VG_TRACK( die_mem_brk, (Addr)arg1,
fitzhardinge98abfc72003-12-16 02:05:15 +00001755 brk_limit-arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001756 } else
fitzhardinge98abfc72003-12-16 02:05:15 +00001757 if (res > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00001758 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00001759 VG_TRACK( new_mem_brk, brk_limit,
1760 arg1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00001761 }
jsgf855d93d2003-10-13 22:26:55 +00001762 } else {
1763 /* brk() failed */
fitzhardinge98abfc72003-12-16 02:05:15 +00001764 vg_assert(brk_limit == res);
jsgf855d93d2003-10-13 22:26:55 +00001765 }
1766}
1767
nethercote85a456f2004-11-16 17:31:56 +00001768PRE(sys_chdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00001769{
nethercotec6851dd2004-11-11 18:00:47 +00001770 PRINT("sys_chdir ( %p )", arg1);
1771 PRE_REG_READ1(long, "chdir", const char *, path);
nethercoteef0c7662004-11-06 15:38:43 +00001772 PRE_MEM_RASCIIZ( "chdir(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001773}
1774
nethercote85a456f2004-11-16 17:31:56 +00001775PRE(sys_chmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001776{
nethercotec6851dd2004-11-11 18:00:47 +00001777 PRINT("sys_chmod ( %p, %d )", arg1,arg2);
1778 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
nethercoteef0c7662004-11-06 15:38:43 +00001779 PRE_MEM_RASCIIZ( "chmod(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001780}
1781
nethercote85a456f2004-11-16 17:31:56 +00001782PRE(sys_chown16, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001783{
1784 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1785 PRE_REG_READ3(long, "chown16",
1786 const char *, path,
1787 vki_old_uid_t, owner, vki_old_gid_t, group);
1788 PRE_MEM_RASCIIZ( "chown16(path)", arg1 );
1789}
1790
nethercote85a456f2004-11-16 17:31:56 +00001791PRE(sys_chown, 0)
jsgf855d93d2003-10-13 22:26:55 +00001792{
1793 /* int chown(const char *path, uid_t owner, gid_t group); */
nethercote2e1c37d2004-11-13 13:57:12 +00001794 PRINT("sys_chown ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1795 PRE_REG_READ3(long, "chown",
1796 const char *, path, vki_uid_t, owner, vki_gid_t, group);
nethercoteef0c7662004-11-06 15:38:43 +00001797 PRE_MEM_RASCIIZ( "chown(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001798}
1799
nethercote85a456f2004-11-16 17:31:56 +00001800PRE(sys_lchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001801{
1802 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1803 PRE_REG_READ3(long, "lchown",
1804 const char *, path, vki_uid_t, owner, vki_gid_t, group);
1805 PRE_MEM_RASCIIZ( "lchown(path)", arg1 );
1806}
jsgf855d93d2003-10-13 22:26:55 +00001807
nethercote85a456f2004-11-16 17:31:56 +00001808PRE(sys_close, 0)
jsgf855d93d2003-10-13 22:26:55 +00001809{
nethercotec6851dd2004-11-11 18:00:47 +00001810 PRINT("sys_close ( %d )", arg1);
1811 PRE_REG_READ1(long, "close", unsigned int, fd);
1812
nethercotef8548672004-06-21 12:42:35 +00001813 /* Detect and negate attempts by the client to close Valgrind's log fd */
nethercote3d5e9102004-11-17 18:22:38 +00001814 if (!VG_(fd_allowed)(arg1, "close", tid, False))
nethercote35122912004-10-18 17:00:30 +00001815 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00001816}
1817
nethercote85a456f2004-11-16 17:31:56 +00001818POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00001819{
nethercotec6851dd2004-11-11 18:00:47 +00001820 if (VG_(clo_track_fds)) record_fd_close(tid, arg1);
rjwalshf5f536f2003-11-17 17:45:00 +00001821}
jsgf855d93d2003-10-13 22:26:55 +00001822
nethercote85a456f2004-11-16 17:31:56 +00001823PRE(sys_dup, 0)
jsgf855d93d2003-10-13 22:26:55 +00001824{
nethercote9a3beb92004-11-12 17:07:26 +00001825 PRINT("sys_dup ( %d )", arg1);
1826 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00001827}
1828
nethercote85a456f2004-11-16 17:31:56 +00001829POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00001830{
nethercote3d5e9102004-11-17 18:22:38 +00001831 if (!VG_(fd_allowed)(res, "dup", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00001832 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00001833 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00001834 } else {
nethercote9a3beb92004-11-12 17:07:26 +00001835 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001836 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
jsgf855d93d2003-10-13 22:26:55 +00001837 }
1838}
1839
nethercote85a456f2004-11-16 17:31:56 +00001840PRE(sys_dup2, 0)
jsgf855d93d2003-10-13 22:26:55 +00001841{
nethercote71f05f32004-11-12 18:49:27 +00001842 PRINT("sys_dup2 ( %d, %d )", arg1,arg2);
1843 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
nethercote3d5e9102004-11-17 18:22:38 +00001844 if (!VG_(fd_allowed)(arg2, "dup2", tid, True))
nethercote35122912004-10-18 17:00:30 +00001845 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00001846}
1847
nethercote85a456f2004-11-16 17:31:56 +00001848POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00001849{
nethercote71f05f32004-11-12 18:49:27 +00001850 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001851 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
jsgf855d93d2003-10-13 22:26:55 +00001852}
1853
nethercote85a456f2004-11-16 17:31:56 +00001854PRE(sys_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00001855{
nethercote5b653bc2004-11-15 14:32:12 +00001856 PRINT("sys_fchdir ( %d )", arg1);
1857 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001858}
1859
nethercote85a456f2004-11-16 17:31:56 +00001860PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001861{
nethercote2e1c37d2004-11-13 13:57:12 +00001862 PRINT("sys_fchown16 ( %d, %d, %d )", arg1,arg2,arg3);
1863 PRE_REG_READ3(long, "fchown16",
1864 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00001865}
1866
nethercote85a456f2004-11-16 17:31:56 +00001867PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001868{
1869 PRINT("sys_fchown ( %d, %d, %d )", arg1,arg2,arg3);
1870 PRE_REG_READ3(long, "fchown",
1871 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
1872}
jsgf855d93d2003-10-13 22:26:55 +00001873
nethercote85a456f2004-11-16 17:31:56 +00001874PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001875{
nethercoteac866b92004-11-15 20:23:15 +00001876 PRINT("sys_fchmod ( %d, %d )", arg1,arg2);
nethercotedc18c0a2004-11-14 20:06:27 +00001877 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00001878}
1879
njncfb8ad52004-11-23 14:57:49 +00001880void common_pre_fcntl(Bool is64, ThreadId tid, ThreadState* tst)
1881{
1882 switch (arg2) {
1883 // These ones ignore arg3.
1884 case VKI_F_GETFD:
1885 case VKI_F_GETFL:
1886 case VKI_F_GETOWN:
1887 case VKI_F_SETOWN:
1888 case VKI_F_GETSIG:
1889 case VKI_F_SETSIG:
1890 case VKI_F_GETLEASE:
1891 if (is64) {
1892 PRINT("sys_fcntl64 ( %d, %d )", arg1,arg2);
1893 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
1894 } else {
1895 PRINT("sys_fcntl ( %d, %d )", arg1,arg2);
1896 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1897 }
1898 break;
1899
1900 // These ones use arg3 as "arg".
1901 case VKI_F_DUPFD:
1902 case VKI_F_SETFD:
1903 case VKI_F_SETFL:
1904 case VKI_F_SETLEASE:
1905 case VKI_F_NOTIFY:
1906 if (is64) {
1907 PRINT("sys_fcntl64[arg3=='arg'] ( %d, %d, %d )", arg1,arg2,arg3);
1908 PRE_REG_READ3(long, "fcntl64",
1909 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1910 } else {
1911 PRINT("sys_fcntl[arg3=='arg'] ( %d, %d, %d )", arg1,arg2,arg3);
1912 PRE_REG_READ3(long, "fcntl",
1913 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1914 }
1915 break;
1916
1917 // These ones use arg3 as "lock".
1918 case VKI_F_GETLK:
1919 case VKI_F_SETLK:
1920 case VKI_F_SETLKW:
1921 case VKI_F_GETLK64:
1922 case VKI_F_SETLK64:
1923 case VKI_F_SETLKW64:
1924 if (is64) {
1925 PRINT("sys_fcntl64[arg3=='lock'] ( %d, %d, %p )", arg1,arg2,arg3);
1926 PRE_REG_READ3(long, "fcntl64",
1927 unsigned int, fd, unsigned int, cmd,
1928 struct flock64 *, lock);
1929 } else {
1930 PRINT("sys_fcntl[arg3=='lock'] ( %d, %d, %p )", arg1,arg2,arg3);
1931 PRE_REG_READ3(long, "fcntl",
1932 unsigned int, fd, unsigned int, cmd,
1933 struct flock64 *, lock);
1934 }
1935 break;
1936 }
1937}
1938
1939PRE(sys_fcntl, 0)
1940{
1941 common_pre_fcntl(/*is64*/False, tid, tst);
1942
1943 if (arg2 == VKI_F_SETLKW)
1944 tst->sys_flags |= MayBlock;
1945}
1946
1947POST(sys_fcntl)
1948{
1949 if (arg2 == VKI_F_DUPFD) {
1950 if (!VG_(fd_allowed)(res, "fcntl(DUPFD)", tid, True)) {
1951 VG_(close)(res);
1952 set_result( -VKI_EMFILE );
1953 } else {
1954 if (VG_(clo_track_fds))
1955 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
1956 }
1957 }
1958}
1959
nethercote06c7bd72004-11-14 19:11:56 +00001960// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00001961PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00001962{
njncfb8ad52004-11-23 14:57:49 +00001963 common_pre_fcntl(/*is64*/True, tid, tst);
1964
thughesd4b51a62004-07-29 21:20:11 +00001965 if (arg2 == VKI_F_SETLKW || arg2 == VKI_F_SETLKW64)
1966 tst->sys_flags |= MayBlock;
rjwalshf5f536f2003-11-17 17:45:00 +00001967}
1968
nethercote85a456f2004-11-16 17:31:56 +00001969POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00001970{
nethercote493dd182004-02-24 23:57:47 +00001971 if (arg2 == VKI_F_DUPFD) {
nethercote3d5e9102004-11-17 18:22:38 +00001972 if (!VG_(fd_allowed)(res, "fcntl64(DUPFD)", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00001973 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00001974 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00001975 } else {
1976 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001977 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
nethercote493dd182004-02-24 23:57:47 +00001978 }
1979 }
jsgf855d93d2003-10-13 22:26:55 +00001980}
1981
nethercote85a456f2004-11-16 17:31:56 +00001982PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00001983{
nethercote2e1c37d2004-11-13 13:57:12 +00001984 PRINT("sys_newfstat ( %d, %p )", arg1,arg2);
1985 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
1986 PRE_MEM_WRITE( "fstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00001987}
1988
nethercote85a456f2004-11-16 17:31:56 +00001989POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00001990{
nethercoteef0c7662004-11-06 15:38:43 +00001991 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00001992}
1993
nethercote73b526f2004-10-31 18:48:21 +00001994static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00001995
nethercote75a8c982004-11-11 19:03:34 +00001996// In Linux, the sys_fork() function varies across architectures, but we
1997// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00001998PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00001999{
nethercote73b526f2004-10-31 18:48:21 +00002000 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002001
nethercote75a8c982004-11-11 19:03:34 +00002002 PRINT("sys_fork ( )");
2003 PRE_REG_READ0(long, "fork");
2004
jsgf855d93d2003-10-13 22:26:55 +00002005 vg_assert(VG_(gettid)() == VG_(main_pid));
2006
2007 /* Block all signals during fork, so that we can fix things up in
2008 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002009 VG_(sigfillset)(&mask);
2010 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002011
jsgf855d93d2003-10-13 22:26:55 +00002012 do_atfork_pre(tid);
2013}
2014
nethercote85a456f2004-11-16 17:31:56 +00002015POST(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002016{
2017 if (res == 0) {
2018 do_atfork_child(tid);
2019
2020 /* I am the child. Nuke all other threads which I might
2021 have inherited from my parent. POSIX mandates this. */
2022 VG_(nuke_all_threads_except)( tid );
2023
2024 /* XXX TODO: tid 1 is special, and is presumed to be present.
2025 We should move this TID to 1 in the child. */
2026
2027 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002028 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002029 } else {
nethercoteef0c7662004-11-06 15:38:43 +00002030 PRINT(" fork: process %d created child %d\n", VG_(main_pid), res);
jsgf855d93d2003-10-13 22:26:55 +00002031
2032 do_atfork_parent(tid);
2033
2034 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002035 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002036 }
2037}
2038
nethercote85a456f2004-11-16 17:31:56 +00002039PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002040{
nethercote5a945af2004-11-14 18:37:07 +00002041 PRINT("sys_ftruncate ( %d, %lld )", arg1,(ULong)arg2);
2042 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002043}
2044
nethercote85a456f2004-11-16 17:31:56 +00002045PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002046{
nethercote5a945af2004-11-14 18:37:07 +00002047 PRINT("sys_truncate ( %p(%s), %d )", arg1,arg1,arg2);
2048 PRE_REG_READ2(long, "truncate",
2049 const char *, path, unsigned long, length);
2050 PRE_MEM_RASCIIZ( "truncate(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00002051}
2052
nethercote5a945af2004-11-14 18:37:07 +00002053// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002054PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002055{
2056 PRINT("sys_ftruncate64 ( %d, %lld )", arg1, LOHI64(arg2,arg3));
2057 PRE_REG_READ3(long, "ftruncate64",
2058 unsigned int, fd,
2059 vki_u32, length_low32, vki_u32, length_high32);
2060}
2061
2062// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002063PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002064{
2065 PRINT("sys_truncate64 ( %p, %lld )", arg1, LOHI64(arg2, arg3));
2066 PRE_REG_READ3(long, "truncate64",
2067 const char *, path,
2068 vki_u32, length_low32, vki_u32, length_high32);
2069 PRE_MEM_RASCIIZ( "truncate64(path)", arg1 );
2070}
2071
2072
nethercote85a456f2004-11-16 17:31:56 +00002073PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002074{
nethercote06c7bd72004-11-14 19:11:56 +00002075 PRINT("sys_getdents ( %d, %p, %d )", arg1,arg2,arg3);
2076 PRE_REG_READ3(long, "getdents",
2077 unsigned int, fd, struct linux_dirent *, dirp,
2078 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002079 PRE_MEM_WRITE( "getdents(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002080}
2081
nethercote85a456f2004-11-16 17:31:56 +00002082POST(sys_getdents)
jsgf855d93d2003-10-13 22:26:55 +00002083{
2084 if (res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002085 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00002086}
2087
nethercote85a456f2004-11-16 17:31:56 +00002088PRE(sys_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002089{
nethercoteac866b92004-11-15 20:23:15 +00002090 PRINT("sys_getdents64 ( %d, %p, %d )",arg1,arg2,arg3);
nethercote06c7bd72004-11-14 19:11:56 +00002091 PRE_REG_READ3(long, "getdents64",
2092 unsigned int, fd, struct linux_dirent64 *, dirp,
2093 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002094 PRE_MEM_WRITE( "getdents64(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002095}
2096
nethercote85a456f2004-11-16 17:31:56 +00002097POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002098{
2099 if (res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002100 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00002101}
2102
nethercote85a456f2004-11-16 17:31:56 +00002103PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002104{
nethercote686b5db2004-11-14 13:42:51 +00002105 PRINT("sys_getgroups16 ( %d, %p )", arg1, arg2);
2106 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2107 if (arg1 > 0)
2108 PRE_MEM_WRITE( "getgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
2109}
2110
nethercote85a456f2004-11-16 17:31:56 +00002111POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002112{
2113 if (arg1 > 0 && res > 0)
2114 POST_MEM_WRITE( arg2, res * sizeof(vki_old_gid_t) );
2115}
2116
nethercote85a456f2004-11-16 17:31:56 +00002117PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002118{
nethercoteac866b92004-11-15 20:23:15 +00002119 PRINT("sys_getgroups ( %d, %p )", arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00002120 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00002121 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002122 PRE_MEM_WRITE( "getgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002123}
2124
nethercote85a456f2004-11-16 17:31:56 +00002125POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002126{
2127 if (arg1 > 0 && res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002128 POST_MEM_WRITE( arg2, res * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002129}
2130
nethercote85a456f2004-11-16 17:31:56 +00002131PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002132{
nethercoteac866b92004-11-15 20:23:15 +00002133 // Note that the kernel version of getcwd() behaves quite differently to
2134 // the glibc one.
2135 PRINT("sys_getcwd ( %p, %llu )", arg1,(ULong)arg2);
2136 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
nethercoteef0c7662004-11-06 15:38:43 +00002137 PRE_MEM_WRITE( "getcwd(buf)", arg1, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00002138}
2139
nethercote85a456f2004-11-16 17:31:56 +00002140POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002141{
2142 if (res != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00002143 POST_MEM_WRITE( arg1, res );
jsgf855d93d2003-10-13 22:26:55 +00002144}
2145
nethercote85a456f2004-11-16 17:31:56 +00002146PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002147{
nethercote0df495a2004-11-11 16:38:21 +00002148 PRINT("sys_geteuid16 ( )");
2149 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002150}
2151
nethercote85a456f2004-11-16 17:31:56 +00002152PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002153{
nethercote0df495a2004-11-11 16:38:21 +00002154 PRINT("sys_geteuid ( )");
2155 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002156}
2157
nethercote85a456f2004-11-16 17:31:56 +00002158PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002159{
nethercote0df495a2004-11-11 16:38:21 +00002160 PRINT("sys_getegid16 ( )");
2161 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002162}
2163
nethercote85a456f2004-11-16 17:31:56 +00002164PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002165{
nethercote0df495a2004-11-11 16:38:21 +00002166 PRINT("sys_getegid ( )");
2167 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002168}
2169
nethercote85a456f2004-11-16 17:31:56 +00002170PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002171{
nethercote0df495a2004-11-11 16:38:21 +00002172 PRINT("sys_getgid16 ( )");
2173 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002174}
2175
nethercote85a456f2004-11-16 17:31:56 +00002176PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002177{
nethercote0df495a2004-11-11 16:38:21 +00002178 PRINT("sys_getgid ( )");
2179 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002180}
2181
nethercote85a456f2004-11-16 17:31:56 +00002182PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002183{
nethercote4e632c22004-11-09 16:45:33 +00002184 PRINT("sys_getpid ()");
2185 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002186}
2187
nethercote85a456f2004-11-16 17:31:56 +00002188PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002189{
nethercote5b653bc2004-11-15 14:32:12 +00002190 PRINT("sys_getpgid ( %d )", arg1);
2191 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002192}
2193
nethercote85a456f2004-11-16 17:31:56 +00002194PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002195{
nethercote0df495a2004-11-11 16:38:21 +00002196 PRINT("sys_getpgrp ()");
2197 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002198}
2199
nethercote85a456f2004-11-16 17:31:56 +00002200PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002201{
nethercote4e632c22004-11-09 16:45:33 +00002202 PRINT("sys_getppid ()");
2203 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002204}
2205
njncf45fd42004-11-24 16:30:22 +00002206static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002207{
nethercote620154f2004-11-12 21:21:07 +00002208 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002209
nethercote620154f2004-11-12 21:21:07 +00002210 switch (a1) {
2211 case VKI_RLIMIT_NOFILE:
2212 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2213 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2214 break;
nethercote535f03b2004-02-15 15:32:51 +00002215
nethercote620154f2004-11-12 21:21:07 +00002216 case VKI_RLIMIT_DATA:
2217 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2218 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002219
nethercote620154f2004-11-12 21:21:07 +00002220 case VKI_RLIMIT_STACK:
2221 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2222 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002223 }
jsgf855d93d2003-10-13 22:26:55 +00002224}
2225
nethercote85a456f2004-11-16 17:31:56 +00002226PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002227{
2228 PRINT("sys_old_getrlimit ( %d, %p )", arg1,arg2);
2229 PRE_REG_READ2(long, "old_getrlimit",
2230 unsigned int, resource, struct rlimit *, rlim);
2231 PRE_MEM_WRITE( "old_getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2232}
2233
nethercote85a456f2004-11-16 17:31:56 +00002234POST(sys_old_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002235{
njncf45fd42004-11-24 16:30:22 +00002236 common_post_getrlimit(tid, arg1, arg2);
nethercote620154f2004-11-12 21:21:07 +00002237}
2238
nethercote85a456f2004-11-16 17:31:56 +00002239PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002240{
2241 PRINT("sys_getrlimit ( %d, %p )", arg1,arg2);
2242 PRE_REG_READ2(long, "getrlimit",
2243 unsigned int, resource, struct rlimit *, rlim);
2244 PRE_MEM_WRITE( "getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2245}
2246
nethercote85a456f2004-11-16 17:31:56 +00002247POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002248{
njncf45fd42004-11-24 16:30:22 +00002249 common_post_getrlimit(tid, arg1, arg2);
nethercote620154f2004-11-12 21:21:07 +00002250}
jsgf855d93d2003-10-13 22:26:55 +00002251
nethercote85a456f2004-11-16 17:31:56 +00002252PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00002253{
2254 /* int getrusage (int who, struct rusage *usage); */
nethercotef1049bf2004-11-14 17:03:47 +00002255 PRINT("sys_getrusage ( %d, %p )", arg1,arg2);
2256 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
nethercoteef0c7662004-11-06 15:38:43 +00002257 PRE_MEM_WRITE( "getrusage(usage)", arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002258}
2259
nethercote85a456f2004-11-16 17:31:56 +00002260POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00002261{
2262 if (res == 0)
njncf45fd42004-11-24 16:30:22 +00002263 POST_MEM_WRITE( arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002264}
2265
nethercote85a456f2004-11-16 17:31:56 +00002266PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00002267{
nethercote686b5db2004-11-14 13:42:51 +00002268 PRINT("sys_gettimeofday ( %p, %p )", arg1,arg2);
2269 PRE_REG_READ2(long, "gettimeofday",
2270 struct timeval *, tv, struct timezone *, tz);
nethercoteef0c7662004-11-06 15:38:43 +00002271 PRE_MEM_WRITE( "gettimeofday(tv)", arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002272 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002273 PRE_MEM_WRITE( "gettimeofday(tz)", arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002274}
2275
nethercote85a456f2004-11-16 17:31:56 +00002276POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002277{
2278 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002279 POST_MEM_WRITE( arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002280 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002281 POST_MEM_WRITE( arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002282 }
2283}
2284
nethercote85a456f2004-11-16 17:31:56 +00002285PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00002286{
2287 PRINT("sys_settimeofday ( %p, %p )", arg1,arg2);
2288 PRE_REG_READ2(long, "settimeofday",
2289 struct timeval *, tv, struct timezone *, tz);
2290 PRE_MEM_READ( "settimeofday(tv)", arg1, sizeof(struct vki_timeval) );
2291 if (arg2 != 0) {
2292 PRE_MEM_READ( "settimeofday(tz)", arg2, sizeof(struct vki_timezone) );
2293 /* maybe should warn if tz->tz_dsttime is non-zero? */
2294 }
2295}
2296
nethercote85a456f2004-11-16 17:31:56 +00002297PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002298{
nethercote0df495a2004-11-11 16:38:21 +00002299 PRINT("sys_getuid16 ( )");
2300 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00002301}
2302
nethercote85a456f2004-11-16 17:31:56 +00002303PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002304{
nethercote0df495a2004-11-11 16:38:21 +00002305 PRINT("sys_getuid ( )");
2306 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00002307}
2308
nethercote7f7e4d12004-11-15 12:28:58 +00002309// XXX: x86-specific
2310// XXX: should use the constants here (eg. SHMAT), not the numbers directly!
nethercote85a456f2004-11-16 17:31:56 +00002311PRE(sys_ipc, 0)
jsgf855d93d2003-10-13 22:26:55 +00002312{
nethercote7f7e4d12004-11-15 12:28:58 +00002313 PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", arg1,arg2,arg3,arg4,arg5,arg6);
2314 // XXX: this is simplistic -- some args are not used in all circumstances.
2315 PRE_REG_READ6(int, "ipc",
2316 vki_uint, call, int, first, int, second, int, third,
2317 void *, ptr, long, fifth)
2318
jsgf855d93d2003-10-13 22:26:55 +00002319 switch (arg1 /* call */) {
2320 case 1: /* IPCOP_semop */
nethercoteef0c7662004-11-06 15:38:43 +00002321 PRE_MEM_READ( "semop(sops)", arg5, arg3 * sizeof(struct vki_sembuf) );
thughes024f25d2004-07-29 22:40:07 +00002322 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002323 break;
2324 case 2: /* IPCOP_semget */
jsgf855d93d2003-10-13 22:26:55 +00002325 break;
thughes60797102004-08-13 22:21:51 +00002326 case 3: /* IPCOP_semctl */
2327 {
nethercote73b526f2004-10-31 18:48:21 +00002328 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002329 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002330 case VKI_IPC_INFO:
2331 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002332 {
2333 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002334 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002335 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002336 break;
2337 }
nethercote73b526f2004-10-31 18:48:21 +00002338 case VKI_IPC_STAT:
2339 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002340 {
2341 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002342 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002343 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002344 break;
2345 }
nethercote73b526f2004-10-31 18:48:21 +00002346 case VKI_IPC_SET:
thughes60797102004-08-13 22:21:51 +00002347 {
2348 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002349 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002350 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002351 break;
2352 }
nethercote73b526f2004-10-31 18:48:21 +00002353 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002354 {
2355 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2356 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002357 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002358 sizeof(short) * nsems );
2359 break;
2360 }
nethercote73b526f2004-10-31 18:48:21 +00002361 case VKI_SETALL:
thughes60797102004-08-13 22:21:51 +00002362 {
2363 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2364 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002365 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002366 sizeof(short) * nsems );
2367 break;
2368 }
nethercote73b526f2004-10-31 18:48:21 +00002369 case VKI_SETVAL:
thughes60797102004-08-13 22:21:51 +00002370 {
nethercoteef0c7662004-11-06 15:38:43 +00002371 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002372 (Addr)&arg->val, sizeof(arg->val) );
2373 break;
2374 }
nethercote73b526f2004-10-31 18:48:21 +00002375 case VKI_IPC_INFO|VKI_IPC_64:
2376 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002377 {
2378 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002379 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002380 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002381 break;
2382 }
nethercote73b526f2004-10-31 18:48:21 +00002383 case VKI_IPC_STAT|VKI_IPC_64:
2384 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002385 {
2386 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002387 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002388 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002389 break;
2390 }
nethercote73b526f2004-10-31 18:48:21 +00002391 case VKI_IPC_SET|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002392 {
2393 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002394 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002395 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002396 break;
2397 }
nethercote73b526f2004-10-31 18:48:21 +00002398 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002399 {
2400 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2401 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002402 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002403 sizeof(short) * nsems );
2404 break;
2405 }
nethercote73b526f2004-10-31 18:48:21 +00002406 case VKI_SETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002407 {
2408 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2409 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002410 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002411 sizeof(short) * nsems );
2412 break;
2413 }
nethercote73b526f2004-10-31 18:48:21 +00002414 case VKI_SETVAL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002415 {
nethercoteef0c7662004-11-06 15:38:43 +00002416 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002417 (Addr)&arg->val, sizeof(arg->val) );
2418 break;
2419 }
thughes60797102004-08-13 22:21:51 +00002420 default:
2421 break;
2422 }
2423 break;
2424 }
thughes03766282004-06-13 14:23:00 +00002425 case 4: /* IPCOP_semtimedop */
nethercoteef0c7662004-11-06 15:38:43 +00002426 PRE_MEM_READ( "semtimedop(sops)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002427 arg3 * sizeof(struct vki_sembuf) );
nethercote163c5e82004-11-17 18:42:20 +00002428 if (arg6 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002429 PRE_MEM_READ( "semtimedop(timeout)", arg6,
nethercote73b526f2004-10-31 18:48:21 +00002430 sizeof(struct vki_timespec) );
thughes024f25d2004-07-29 22:40:07 +00002431 tst->sys_flags |= MayBlock;
thughes03766282004-06-13 14:23:00 +00002432 break;
jsgf855d93d2003-10-13 22:26:55 +00002433 case 11: /* IPCOP_msgsnd */
2434 {
nethercote73b526f2004-10-31 18:48:21 +00002435 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg5;
jsgf855d93d2003-10-13 22:26:55 +00002436 Int msgsz = arg3;
2437
nethercoteef0c7662004-11-06 15:38:43 +00002438 PRE_MEM_READ( "msgsnd(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002439 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002440 PRE_MEM_READ( "msgsnd(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002441 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002442
2443 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2444 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002445 break;
2446 }
2447 case 12: /* IPCOP_msgrcv */
2448 {
nethercote73b526f2004-10-31 18:48:21 +00002449 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002450 Int msgsz = arg3;
2451
nethercote73b526f2004-10-31 18:48:21 +00002452 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2453 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002454 "msgrcv(msgp)" );
2455
nethercoteef0c7662004-11-06 15:38:43 +00002456 PRE_MEM_WRITE( "msgrcv(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002457 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002458 PRE_MEM_WRITE( "msgrcv(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002459 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002460
2461 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2462 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002463 break;
2464 }
2465 case 13: /* IPCOP_msgget */
2466 break;
2467 case 14: /* IPCOP_msgctl */
2468 {
2469 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002470 case VKI_IPC_INFO:
2471 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002472 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002473 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002474 break;
nethercote73b526f2004-10-31 18:48:21 +00002475 case VKI_IPC_STAT:
2476 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002477 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002478 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002479 break;
nethercote73b526f2004-10-31 18:48:21 +00002480 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002481 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002482 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002483 break;
nethercote73b526f2004-10-31 18:48:21 +00002484 case VKI_IPC_INFO|VKI_IPC_64:
2485 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002486 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002487 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002488 break;
nethercote73b526f2004-10-31 18:48:21 +00002489 case VKI_IPC_STAT|VKI_IPC_64:
2490 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002491 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002492 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002493 break;
nethercote73b526f2004-10-31 18:48:21 +00002494 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002495 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002496 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002497 break;
jsgf855d93d2003-10-13 22:26:55 +00002498 default:
2499 break;
2500 }
2501 break;
2502 }
2503 case 21: /* IPCOP_shmat */
2504 {
fitzhardinge98abfc72003-12-16 02:05:15 +00002505 UInt shmid = arg2;
2506 UInt segmentSize = get_shm_size ( shmid );
2507
2508 /* If they didn't ask for a particular address, then place it
2509 like an mmap. */
2510 if (arg5 == 0)
2511 arg5 = VG_(find_map_space)(0, segmentSize, True);
nethercote8ff888f2004-11-17 17:11:45 +00002512 else if (!VG_(valid_client_addr)(arg5, segmentSize, tid, "shmat"))
nethercote35122912004-10-18 17:00:30 +00002513 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002514 break;
2515 }
2516 case 22: /* IPCOP_shmdt */
nethercote8ff888f2004-11-17 17:11:45 +00002517 if (!VG_(valid_client_addr)(arg5, 1, tid, "shmdt"))
nethercote35122912004-10-18 17:00:30 +00002518 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002519 break;
2520 case 23: /* IPCOP_shmget */
2521 break;
2522 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002523 {
thughes60797102004-08-13 22:21:51 +00002524 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002525 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002526 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002527 sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002528 break;
nethercote73b526f2004-10-31 18:48:21 +00002529 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002530 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002531 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002532 break;
nethercote73b526f2004-10-31 18:48:21 +00002533 case VKI_IPC_STAT:
2534 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002535 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002536 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002537 break;
nethercote73b526f2004-10-31 18:48:21 +00002538 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002539 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002540 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002541 break;
nethercote73b526f2004-10-31 18:48:21 +00002542 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002543 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002544 sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002545 break;
nethercote73b526f2004-10-31 18:48:21 +00002546 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002547 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002548 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002549 break;
nethercote73b526f2004-10-31 18:48:21 +00002550 case VKI_IPC_STAT|VKI_IPC_64:
2551 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002552 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002553 sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002554 break;
nethercote73b526f2004-10-31 18:48:21 +00002555 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002556 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002557 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002558 break;
thughes60797102004-08-13 22:21:51 +00002559 default:
2560 break;
jsgf855d93d2003-10-13 22:26:55 +00002561 }
thughes60797102004-08-13 22:21:51 +00002562 break;
jsgf855d93d2003-10-13 22:26:55 +00002563 }
jsgf855d93d2003-10-13 22:26:55 +00002564 default:
2565 VG_(message)(Vg_DebugMsg,
2566 "FATAL: unhandled syscall(ipc) %d",
2567 arg1 );
2568 VG_(core_panic)("... bye!\n");
2569 break; /*NOTREACHED*/
2570 }
2571}
2572
nethercote85a456f2004-11-16 17:31:56 +00002573POST(sys_ipc)
jsgf855d93d2003-10-13 22:26:55 +00002574{
2575 switch (arg1 /* call */) {
2576 case 1: /* IPCOP_semop */
jsgf855d93d2003-10-13 22:26:55 +00002577 case 2: /* IPCOP_semget */
thughes60797102004-08-13 22:21:51 +00002578 break;
jsgf855d93d2003-10-13 22:26:55 +00002579 case 3: /* IPCOP_semctl */
thughes60797102004-08-13 22:21:51 +00002580 {
nethercote73b526f2004-10-31 18:48:21 +00002581 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002582 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002583 case VKI_IPC_INFO:
2584 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002585 {
2586 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002587 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002588 break;
2589 }
nethercote73b526f2004-10-31 18:48:21 +00002590 case VKI_IPC_STAT:
2591 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002592 {
2593 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002594 POST_MEM_WRITE( buf, sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002595 break;
2596 }
nethercote73b526f2004-10-31 18:48:21 +00002597 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002598 {
2599 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2600 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002601 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002602 break;
2603 }
nethercote73b526f2004-10-31 18:48:21 +00002604 case VKI_IPC_INFO|VKI_IPC_64:
2605 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002606 {
2607 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002608 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002609 break;
2610 }
nethercote73b526f2004-10-31 18:48:21 +00002611 case VKI_IPC_STAT|VKI_IPC_64:
2612 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002613 {
2614 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002615 POST_MEM_WRITE( buf, sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002616 break;
2617 }
nethercote73b526f2004-10-31 18:48:21 +00002618 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002619 {
2620 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2621 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002622 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002623 break;
2624 }
thughes60797102004-08-13 22:21:51 +00002625 default:
2626 break;
2627 }
2628 break;
2629 }
thughes03766282004-06-13 14:23:00 +00002630 case 4: /* IPCOP_semtimedop */
jsgf855d93d2003-10-13 22:26:55 +00002631 break;
2632 case 11: /* IPCOP_msgsnd */
2633 break;
2634 case 12: /* IPCOP_msgrcv */
2635 {
nethercote73b526f2004-10-31 18:48:21 +00002636 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002637
nethercote73b526f2004-10-31 18:48:21 +00002638 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2639 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002640 "msgrcv(msgp)" );
2641 if ( res > 0 ) {
nethercoteef0c7662004-11-06 15:38:43 +00002642 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2643 POST_MEM_WRITE( (Addr)msgp->mtext, res );
jsgf855d93d2003-10-13 22:26:55 +00002644 }
2645 break;
2646 }
2647 case 13: /* IPCOP_msgget */
2648 break;
2649 case 14: /* IPCOP_msgctl */
2650 {
2651 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002652 case VKI_IPC_INFO:
2653 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002654 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002655 break;
nethercote73b526f2004-10-31 18:48:21 +00002656 case VKI_IPC_STAT:
2657 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002658 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002659 break;
nethercote73b526f2004-10-31 18:48:21 +00002660 case VKI_IPC_SET:
jsgf855d93d2003-10-13 22:26:55 +00002661 break;
nethercote73b526f2004-10-31 18:48:21 +00002662 case VKI_IPC_INFO|VKI_IPC_64:
2663 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002664 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
jsgf855d93d2003-10-13 22:26:55 +00002665 break;
nethercote73b526f2004-10-31 18:48:21 +00002666 case VKI_IPC_STAT|VKI_IPC_64:
2667 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002668 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid64_ds) );
thughes60797102004-08-13 22:21:51 +00002669 break;
nethercote73b526f2004-10-31 18:48:21 +00002670 case VKI_IPC_SET|VKI_IPC_64:
jsgf855d93d2003-10-13 22:26:55 +00002671 break;
jsgf855d93d2003-10-13 22:26:55 +00002672 default:
2673 break;
2674 }
2675 break;
2676 }
2677 case 21: /* IPCOP_shmat */
2678 {
2679 Int shmid = arg2;
fitzhardinge98abfc72003-12-16 02:05:15 +00002680 Int shmflag = arg3;
jsgf855d93d2003-10-13 22:26:55 +00002681 Addr addr;
2682
jsgf855d93d2003-10-13 22:26:55 +00002683 /* force readability. before the syscall it is
2684 * indeed uninitialized, as can be seen in
2685 * glibc/sysdeps/unix/sysv/linux/shmat.c */
nethercoteef0c7662004-11-06 15:38:43 +00002686 POST_MEM_WRITE( arg4, sizeof( ULong ) );
jsgf855d93d2003-10-13 22:26:55 +00002687
2688 addr = deref_Addr ( tid, arg4, "shmat(addr)" );
2689 if ( addr > 0 ) {
2690 UInt segmentSize = get_shm_size ( shmid );
2691 if ( segmentSize > 0 ) {
nethercote27ea8bc2004-07-10 17:21:14 +00002692 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
jsgf855d93d2003-10-13 22:26:55 +00002693 /* we don't distinguish whether it's read-only or
2694 * read-write -- it doesn't matter really. */
nethercote071c84a2004-07-10 17:30:07 +00002695 VG_TRACK( new_mem_mmap, addr, segmentSize, True, True, False );
fitzhardinge98abfc72003-12-16 02:05:15 +00002696
fitzhardinge98abfc72003-12-16 02:05:15 +00002697 if (!(shmflag & 010000)) /* = SHM_RDONLY */
2698 prot &= ~VKI_PROT_WRITE;
nethercote27ea8bc2004-07-10 17:21:14 +00002699 VG_(map_segment)(addr, segmentSize, prot, SF_SHARED|SF_SHM);
jsgf855d93d2003-10-13 22:26:55 +00002700 }
2701 }
2702 break;
2703 }
2704 case 22: /* IPCOP_shmdt */
fitzhardinge98abfc72003-12-16 02:05:15 +00002705 {
fitzhardinged25e8a22004-02-25 00:07:10 +00002706 Segment *s = VG_(find_segment)(arg5);
fitzhardinge98abfc72003-12-16 02:05:15 +00002707
fitzhardinged25e8a22004-02-25 00:07:10 +00002708 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg5, 1)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00002709 VG_TRACK( die_mem_munmap, s->addr, s->len );
2710 VG_(unmap_range)(s->addr, s->len);
2711 }
jsgf855d93d2003-10-13 22:26:55 +00002712 break;
fitzhardinge98abfc72003-12-16 02:05:15 +00002713 }
jsgf855d93d2003-10-13 22:26:55 +00002714 case 23: /* IPCOP_shmget */
2715 break;
2716 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002717 {
thughes60797102004-08-13 22:21:51 +00002718 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002719 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002720 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002721 break;
nethercote73b526f2004-10-31 18:48:21 +00002722 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002723 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002724 break;
nethercote73b526f2004-10-31 18:48:21 +00002725 case VKI_IPC_STAT:
2726 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002727 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002728 break;
nethercote73b526f2004-10-31 18:48:21 +00002729 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002730 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002731 break;
nethercote73b526f2004-10-31 18:48:21 +00002732 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002733 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002734 break;
nethercote73b526f2004-10-31 18:48:21 +00002735 case VKI_IPC_STAT|VKI_IPC_64:
2736 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002737 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002738 break;
thughes60797102004-08-13 22:21:51 +00002739 default:
2740 break;
jsgf855d93d2003-10-13 22:26:55 +00002741 }
thughes60797102004-08-13 22:21:51 +00002742 break;
jsgf855d93d2003-10-13 22:26:55 +00002743 }
jsgf855d93d2003-10-13 22:26:55 +00002744 default:
2745 VG_(message)(Vg_DebugMsg,
2746 "FATAL: unhandled syscall(ipc) %d",
2747 arg1 );
2748 VG_(core_panic)("... bye!\n");
2749 break; /*NOTREACHED*/
2750 }
2751}
2752
nethercote2e1c37d2004-11-13 13:57:12 +00002753// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00002754PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002755{
nethercote9c311eb2004-11-12 18:20:12 +00002756 PRINT("sys_ioctl ( %d, 0x%x, %p )",arg1,arg2,arg3);
2757 PRE_REG_READ3(long, "ioctl",
2758 unsigned int, fd, unsigned int, request, unsigned long, arg);
2759
jsgf855d93d2003-10-13 22:26:55 +00002760 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00002761 case VKI_TCSETS:
2762 case VKI_TCSETSW:
2763 case VKI_TCSETSF:
nethercote11e07d32004-11-06 16:17:52 +00002764 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002765 break;
nethercote73b526f2004-10-31 18:48:21 +00002766 case VKI_TCGETS:
nethercote11e07d32004-11-06 16:17:52 +00002767 PRE_MEM_WRITE( "ioctl(TCGETS)", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002768 break;
nethercote73b526f2004-10-31 18:48:21 +00002769 case VKI_TCSETA:
2770 case VKI_TCSETAW:
2771 case VKI_TCSETAF:
nethercote11e07d32004-11-06 16:17:52 +00002772 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002773 break;
nethercote73b526f2004-10-31 18:48:21 +00002774 case VKI_TCGETA:
nethercote11e07d32004-11-06 16:17:52 +00002775 PRE_MEM_WRITE( "ioctl(TCGETA)", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002776 break;
nethercote73b526f2004-10-31 18:48:21 +00002777 case VKI_TCSBRK:
2778 case VKI_TCXONC:
2779 case VKI_TCSBRKP:
2780 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00002781 /* These just take an int by value */
2782 break;
nethercote73b526f2004-10-31 18:48:21 +00002783 case VKI_TIOCGWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002784 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002785 break;
nethercote73b526f2004-10-31 18:48:21 +00002786 case VKI_TIOCSWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002787 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002788 break;
nethercote73b526f2004-10-31 18:48:21 +00002789 case VKI_TIOCMBIS:
nethercote11e07d32004-11-06 16:17:52 +00002790 PRE_MEM_READ( "ioctl(TIOCMBIS)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002791 break;
nethercote73b526f2004-10-31 18:48:21 +00002792 case VKI_TIOCMBIC:
nethercote11e07d32004-11-06 16:17:52 +00002793 PRE_MEM_READ( "ioctl(TIOCMBIC)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002794 break;
nethercote73b526f2004-10-31 18:48:21 +00002795 case VKI_TIOCMSET:
nethercote11e07d32004-11-06 16:17:52 +00002796 PRE_MEM_READ( "ioctl(TIOCMSET)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002797 break;
nethercote73b526f2004-10-31 18:48:21 +00002798 case VKI_TIOCLINUX:
nethercote11e07d32004-11-06 16:17:52 +00002799 PRE_MEM_READ( "ioctl(TIOCLINUX)", arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002800 if (*(char *)arg3 == 11) {
nethercote11e07d32004-11-06 16:17:52 +00002801 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", arg3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002802 }
2803 break;
nethercote73b526f2004-10-31 18:48:21 +00002804 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002805 /* Get process group ID for foreground processing group. */
nethercote11e07d32004-11-06 16:17:52 +00002806 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002807 break;
nethercote73b526f2004-10-31 18:48:21 +00002808 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002809 /* Set a process group ID? */
nethercote11e07d32004-11-06 16:17:52 +00002810 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002811 break;
nethercote73b526f2004-10-31 18:48:21 +00002812 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercote11e07d32004-11-06 16:17:52 +00002813 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002814 break;
nethercote73b526f2004-10-31 18:48:21 +00002815 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00002816 /* Just takes an int value. */
2817 break;
nethercote73b526f2004-10-31 18:48:21 +00002818 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
nethercote11e07d32004-11-06 16:17:52 +00002819 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002820 break;
nethercote73b526f2004-10-31 18:48:21 +00002821 case VKI_FIONBIO:
nethercote11e07d32004-11-06 16:17:52 +00002822 PRE_MEM_READ( "ioctl(FIONBIO)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002823 break;
nethercote73b526f2004-10-31 18:48:21 +00002824 case VKI_FIOASYNC:
nethercote11e07d32004-11-06 16:17:52 +00002825 PRE_MEM_READ( "ioctl(FIOASYNC)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002826 break;
nethercote73b526f2004-10-31 18:48:21 +00002827 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercote11e07d32004-11-06 16:17:52 +00002828 PRE_MEM_WRITE( "ioctl(FIONREAD)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002829 break;
2830
nethercote73b526f2004-10-31 18:48:21 +00002831 case VKI_SG_SET_COMMAND_Q:
nethercote11e07d32004-11-06 16:17:52 +00002832 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002833 break;
nethercote73b526f2004-10-31 18:48:21 +00002834 case VKI_SG_IO:
nethercote11e07d32004-11-06 16:17:52 +00002835 PRE_MEM_WRITE( "ioctl(SG_IO)", arg3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00002836 break;
nethercote73b526f2004-10-31 18:48:21 +00002837 case VKI_SG_GET_SCSI_ID:
nethercote11e07d32004-11-06 16:17:52 +00002838 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", arg3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00002839 break;
nethercote73b526f2004-10-31 18:48:21 +00002840 case VKI_SG_SET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002841 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002842 break;
nethercote73b526f2004-10-31 18:48:21 +00002843 case VKI_SG_SET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002844 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002845 break;
nethercote73b526f2004-10-31 18:48:21 +00002846 case VKI_SG_GET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002847 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002848 break;
nethercote73b526f2004-10-31 18:48:21 +00002849 case VKI_SG_GET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002850 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002851 break;
nethercote73b526f2004-10-31 18:48:21 +00002852 case VKI_SG_GET_VERSION_NUM:
nethercote11e07d32004-11-06 16:17:52 +00002853 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002854 break;
nethercote73b526f2004-10-31 18:48:21 +00002855 case VKI_SG_EMULATED_HOST: /* 0x2203 */
nethercote11e07d32004-11-06 16:17:52 +00002856 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002857 break;
nethercote73b526f2004-10-31 18:48:21 +00002858 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
nethercote11e07d32004-11-06 16:17:52 +00002859 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002860 break;
jsgf855d93d2003-10-13 22:26:55 +00002861
muellera4b153a2003-11-19 22:07:14 +00002862 case VKI_IIOCGETCPS:
nethercoteef0c7662004-11-06 15:38:43 +00002863 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", arg3,
nethercote95a97862004-11-06 16:31:43 +00002864 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00002865 break;
muellera4b153a2003-11-19 22:07:14 +00002866 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00002867 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
nethercote73b526f2004-10-31 18:48:21 +00002868 (Addr)&((vki_isdn_net_ioctl_phone *)arg3)->name,
2869 sizeof(((vki_isdn_net_ioctl_phone *)arg3)->name) );
nethercoteef0c7662004-11-06 15:38:43 +00002870 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00002871 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00002872 break;
2873
2874 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00002875 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00002876 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
nethercote73b526f2004-10-31 18:48:21 +00002877 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002878 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00002879 break;
nethercote73b526f2004-10-31 18:48:21 +00002880 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00002881 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00002882 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002883 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002884 break;
nethercote73b526f2004-10-31 18:48:21 +00002885 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00002886 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002887 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002888 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002889 break;
nethercote73b526f2004-10-31 18:48:21 +00002890 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00002891 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00002892 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002893 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002894 break;
nethercote73b526f2004-10-31 18:48:21 +00002895 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002896 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002897 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002898 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002899 break;
nethercote73b526f2004-10-31 18:48:21 +00002900 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00002901 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
nethercote73b526f2004-10-31 18:48:21 +00002902 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002903 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002904 break;
nethercote73b526f2004-10-31 18:48:21 +00002905 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00002906 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00002907 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002908 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002909 break;
nethercote73b526f2004-10-31 18:48:21 +00002910 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002911 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00002912 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002913 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002914 break;
nethercote73b526f2004-10-31 18:48:21 +00002915 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002916 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00002917 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002918 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002919 break;
nethercote73b526f2004-10-31 18:48:21 +00002920 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002921 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002922 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002923 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002924 break;
nethercote73b526f2004-10-31 18:48:21 +00002925 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002926 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002927 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002928 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002929 break;
nethercote73b526f2004-10-31 18:48:21 +00002930 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00002931 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
nethercote73b526f2004-10-31 18:48:21 +00002932 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
2933 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
nethercote11e07d32004-11-06 16:17:52 +00002934 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002935 break;
nethercote73b526f2004-10-31 18:48:21 +00002936 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00002937 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
nethercote73b526f2004-10-31 18:48:21 +00002938 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002939 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002940 break;
nethercote73b526f2004-10-31 18:48:21 +00002941 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00002942 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002943 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002944 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002945 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
2946 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00002947 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002948 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
2949 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00002950 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00002951 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002952 break;
nethercote73b526f2004-10-31 18:48:21 +00002953 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00002954 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00002955 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002956 KERNEL_DO_SYSCALL(tid,res);
2957 if (!VG_(is_kerror)(res) && res == 0)
njncf45fd42004-11-24 16:30:22 +00002958 POST_MEM_WRITE(arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002959 */
nethercoteef0c7662004-11-06 15:38:43 +00002960 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct vki_ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002961 if ( arg3 ) {
2962 // TODO len must be readable and writable
2963 // buf pointer only needs to be readable
nethercote73b526f2004-10-31 18:48:21 +00002964 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00002965 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00002966 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00002967 }
2968 break;
nethercote73b526f2004-10-31 18:48:21 +00002969 case VKI_SIOCGSTAMP:
nethercote11e07d32004-11-06 16:17:52 +00002970 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", arg3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00002971 break;
2972 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
2973 the number of bytes currently in that socket's send buffer.
2974 It writes this value as an int to the memory location
2975 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00002976 case VKI_SIOCOUTQ:
nethercote11e07d32004-11-06 16:17:52 +00002977 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00002978 break;
nethercote73b526f2004-10-31 18:48:21 +00002979 case VKI_SIOCGRARP: /* get RARP table entry */
2980 case VKI_SIOCGARP: /* get ARP table entry */
nethercote11e07d32004-11-06 16:17:52 +00002981 PRE_MEM_WRITE( "ioctl(SIOCGARP)", arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00002982 break;
2983
nethercote73b526f2004-10-31 18:48:21 +00002984 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00002985 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00002986 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002987 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00002988 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
2989 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00002990 break;
nethercote73b526f2004-10-31 18:48:21 +00002991 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002992 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00002993 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002994 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00002995 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
2996 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00002997 break;
nethercote73b526f2004-10-31 18:48:21 +00002998 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002999 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003000 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003001 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003002 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3003 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003004 break;
nethercote73b526f2004-10-31 18:48:21 +00003005 case VKI_SIOCSIFADDR: /* set PA address */
3006 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3007 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3008 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003009 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003010 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003011 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003012 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3013 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003014 break;
nethercote73b526f2004-10-31 18:48:21 +00003015 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003016 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003017 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003018 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003019 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3020 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003021 break;
nethercote73b526f2004-10-31 18:48:21 +00003022 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003023 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003024 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003025 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003026 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3027 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003028 break;
nethercote73b526f2004-10-31 18:48:21 +00003029 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003030 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003031 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003032 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003033 (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3034 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003035 break;
nethercote73b526f2004-10-31 18:48:21 +00003036 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003037 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003038 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003039 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003040 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3041 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003042 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003043 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
3044 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003045 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003046 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in,
3047 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003048 break;
jsgf855d93d2003-10-13 22:26:55 +00003049 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003050 case VKI_SIOCADDRT: /* add routing table entry */
3051 case VKI_SIOCDELRT: /* delete routing table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003052 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", arg3,
3053 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003054 break;
3055
3056 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003057 case VKI_SIOCDRARP: /* delete RARP table entry */
3058 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003059 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003060 case VKI_SIOCSARP: /* set ARP table entry */
3061 case VKI_SIOCDARP: /* delete ARP table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003062 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003063 break;
3064
nethercote73b526f2004-10-31 18:48:21 +00003065 case VKI_SIOCGPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003066 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003067 break;
nethercote73b526f2004-10-31 18:48:21 +00003068 case VKI_SIOCSPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003069 PRE_MEM_READ( "ioctl(SIOCSPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003070 tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003071 break;
3072
3073 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003074 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3075 case VKI_SNDCTL_SEQ_GETINCOUNT:
3076 case VKI_SNDCTL_SEQ_PERCMODE:
3077 case VKI_SNDCTL_SEQ_TESTMIDI:
3078 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3079 case VKI_SNDCTL_SEQ_NRSYNTHS:
3080 case VKI_SNDCTL_SEQ_NRMIDIS:
3081 case VKI_SNDCTL_SEQ_GETTIME:
3082 case VKI_SNDCTL_DSP_GETFMTS:
3083 case VKI_SNDCTL_DSP_GETTRIGGER:
3084 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003085 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003086 case VKI_SNDCTL_DSP_GETCAPS:
3087 case VKI_SOUND_PCM_READ_RATE:
3088 case VKI_SOUND_PCM_READ_CHANNELS:
3089 case VKI_SOUND_PCM_READ_BITS:
3090 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3091 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003092 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
3093 arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003094 break;
nethercote73b526f2004-10-31 18:48:21 +00003095 case VKI_SNDCTL_SEQ_CTRLRATE:
3096 case VKI_SNDCTL_DSP_SPEED:
3097 case VKI_SNDCTL_DSP_STEREO:
3098 case VKI_SNDCTL_DSP_GETBLKSIZE:
3099 case VKI_SNDCTL_DSP_CHANNELS:
3100 case VKI_SOUND_PCM_WRITE_FILTER:
3101 case VKI_SNDCTL_DSP_SUBDIVIDE:
3102 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003103 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003104 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003105 case VKI_SNDCTL_TMR_TIMEBASE:
3106 case VKI_SNDCTL_TMR_TEMPO:
3107 case VKI_SNDCTL_TMR_SOURCE:
3108 case VKI_SNDCTL_MIDI_PRETIME:
3109 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003110 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003111 arg3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003112 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003113 arg3, sizeof(int));
3114 break;
nethercote73b526f2004-10-31 18:48:21 +00003115 case VKI_SNDCTL_DSP_GETOSPACE:
3116 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003117 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
3118 arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003119 break;
nethercote73b526f2004-10-31 18:48:21 +00003120 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003121 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
jsgf855d93d2003-10-13 22:26:55 +00003122 arg3, sizeof(int));
3123 break;
3124
nethercote73b526f2004-10-31 18:48:21 +00003125 case VKI_SNDCTL_DSP_POST:
3126 case VKI_SNDCTL_DSP_RESET:
3127 case VKI_SNDCTL_DSP_SYNC:
3128 case VKI_SNDCTL_DSP_SETSYNCRO:
3129 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003130 break;
3131
3132 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003133 case VKI_RTC_UIE_ON:
3134 case VKI_RTC_UIE_OFF:
3135 case VKI_RTC_AIE_ON:
3136 case VKI_RTC_AIE_OFF:
3137 case VKI_RTC_PIE_ON:
3138 case VKI_RTC_PIE_OFF:
3139 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003140 break;
nethercote73b526f2004-10-31 18:48:21 +00003141 case VKI_RTC_RD_TIME:
3142 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003143 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
nethercote73b526f2004-10-31 18:48:21 +00003144 arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003145 break;
nethercote73b526f2004-10-31 18:48:21 +00003146 case VKI_RTC_ALM_SET:
nethercote11e07d32004-11-06 16:17:52 +00003147 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003148 break;
nethercote73b526f2004-10-31 18:48:21 +00003149 case VKI_RTC_IRQP_READ:
nethercote11e07d32004-11-06 16:17:52 +00003150 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003151 break;
jsgf855d93d2003-10-13 22:26:55 +00003152
nethercote95a97862004-11-06 16:31:43 +00003153 case VKI_BLKGETSIZE:
nethercote11e07d32004-11-06 16:17:52 +00003154 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003155 break;
jsgf855d93d2003-10-13 22:26:55 +00003156
thughesacbbc322004-06-19 12:12:01 +00003157 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003158 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
nethercoteef0c7662004-11-06 15:38:43 +00003159 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003160 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003161 break;
3162
jsgf855d93d2003-10-13 22:26:55 +00003163 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003164 case VKI_CDROM_GET_MCN:
nethercoteef0c7662004-11-06 15:38:43 +00003165 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003166 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003167 break;
nethercote73b526f2004-10-31 18:48:21 +00003168 case VKI_CDROM_SEND_PACKET:
nethercoteef0c7662004-11-06 15:38:43 +00003169 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003170 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003171 break;
nethercote73b526f2004-10-31 18:48:21 +00003172 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003173 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
3174 (Addr) &(((struct vki_cdrom_subchnl*) arg3)->cdsc_format),
3175 sizeof(((struct vki_cdrom_subchnl*) arg3)->cdsc_format));
3176 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003177 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003178 break;
nethercote73b526f2004-10-31 18:48:21 +00003179 case VKI_CDROMREADMODE2:
nethercote11e07d32004-11-06 16:17:52 +00003180 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", arg3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003181 break;
nethercote73b526f2004-10-31 18:48:21 +00003182 case VKI_CDROMREADTOCHDR:
nethercote11e07d32004-11-06 16:17:52 +00003183 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003184 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003185 break;
nethercote73b526f2004-10-31 18:48:21 +00003186 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003187 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
3188 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_format),
3189 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_format));
3190 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
3191 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_track),
3192 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_track));
3193 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003194 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003195 break;
nethercote73b526f2004-10-31 18:48:21 +00003196 case VKI_CDROMMULTISESSION: /* 0x5310 */
nethercoteef0c7662004-11-06 15:38:43 +00003197 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003198 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003199 break;
nethercote73b526f2004-10-31 18:48:21 +00003200 case VKI_CDROMVOLREAD: /* 0x5313 */
nethercoteef0c7662004-11-06 15:38:43 +00003201 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003202 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003203 break;
nethercote73b526f2004-10-31 18:48:21 +00003204 case VKI_CDROMREADAUDIO: /* 0x530e */
nethercoteef0c7662004-11-06 15:38:43 +00003205 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003206 sizeof (struct vki_cdrom_read_audio));
thughes5b788fb2004-09-11 15:07:14 +00003207 if ( arg3 ) {
3208 /* ToDo: don't do any of the following if the structure is invalid */
nethercote73b526f2004-10-31 18:48:21 +00003209 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003210 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3211 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003212 }
3213 break;
nethercote73b526f2004-10-31 18:48:21 +00003214 case VKI_CDROMPLAYMSF:
nethercote11e07d32004-11-06 16:17:52 +00003215 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", arg3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003216 break;
3217 /* The following two are probably bogus (should check args
3218 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003219 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3220 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003221 break;
thughes66d80092004-06-19 12:41:05 +00003222
nethercote73b526f2004-10-31 18:48:21 +00003223 case VKI_FIGETBSZ:
nethercote11e07d32004-11-06 16:17:52 +00003224 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003225 break;
nethercote73b526f2004-10-31 18:48:21 +00003226 case VKI_FIBMAP:
nethercote11e07d32004-11-06 16:17:52 +00003227 PRE_MEM_READ( "ioctl(FIBMAP)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003228 break;
3229
nethercote73b526f2004-10-31 18:48:21 +00003230 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
nethercoteef0c7662004-11-06 15:38:43 +00003231 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003232 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003233 break;
nethercote73b526f2004-10-31 18:48:21 +00003234 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
nethercoteef0c7662004-11-06 15:38:43 +00003235 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003236 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003237 break;
jsgf855d93d2003-10-13 22:26:55 +00003238
nethercote73b526f2004-10-31 18:48:21 +00003239 case VKI_PPCLAIM:
3240 case VKI_PPEXCL:
3241 case VKI_PPYIELD:
3242 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003243 break;
nethercote73b526f2004-10-31 18:48:21 +00003244 case VKI_PPSETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003245 PRE_MEM_READ( "ioctl(PPSETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003246 break;
nethercote73b526f2004-10-31 18:48:21 +00003247 case VKI_PPGETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003248 PRE_MEM_WRITE( "ioctl(PPGETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003249 break;
nethercote73b526f2004-10-31 18:48:21 +00003250 case VKI_PPSETPHASE:
nethercote11e07d32004-11-06 16:17:52 +00003251 PRE_MEM_READ( "ioctl(PPSETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003252 break;
nethercote73b526f2004-10-31 18:48:21 +00003253 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003254 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003255 break;
nethercote73b526f2004-10-31 18:48:21 +00003256 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003257 PRE_MEM_WRITE( "ioctl(PPGETMODES)", arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003258 break;
nethercote73b526f2004-10-31 18:48:21 +00003259 case VKI_PPSETFLAGS:
nethercote11e07d32004-11-06 16:17:52 +00003260 PRE_MEM_READ( "ioctl(PPSETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003261 break;
nethercote73b526f2004-10-31 18:48:21 +00003262 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003263 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003264 break;
nethercote73b526f2004-10-31 18:48:21 +00003265 case VKI_PPRSTATUS:
nethercote11e07d32004-11-06 16:17:52 +00003266 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003267 break;
nethercote73b526f2004-10-31 18:48:21 +00003268 case VKI_PPRDATA:
nethercote11e07d32004-11-06 16:17:52 +00003269 PRE_MEM_WRITE( "ioctl(PPRDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003270 break;
nethercote73b526f2004-10-31 18:48:21 +00003271 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003272 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003273 break;
nethercote73b526f2004-10-31 18:48:21 +00003274 case VKI_PPWDATA:
nethercote11e07d32004-11-06 16:17:52 +00003275 PRE_MEM_READ( "ioctl(PPWDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003276 break;
nethercote73b526f2004-10-31 18:48:21 +00003277 case VKI_PPWCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003278 PRE_MEM_READ( "ioctl(PPWCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003279 break;
nethercote73b526f2004-10-31 18:48:21 +00003280 case VKI_PPFCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003281 PRE_MEM_READ( "ioctl(PPFCONTROL)", arg3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003282 break;
nethercote73b526f2004-10-31 18:48:21 +00003283 case VKI_PPDATADIR:
nethercote11e07d32004-11-06 16:17:52 +00003284 PRE_MEM_READ( "ioctl(PPDATADIR)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003285 break;
nethercote73b526f2004-10-31 18:48:21 +00003286 case VKI_PPNEGOT:
nethercote11e07d32004-11-06 16:17:52 +00003287 PRE_MEM_READ( "ioctl(PPNEGOT)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003288 break;
nethercote73b526f2004-10-31 18:48:21 +00003289 case VKI_PPWCTLONIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003290 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003291 break;
nethercote73b526f2004-10-31 18:48:21 +00003292 case VKI_PPCLRIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003293 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003294 break;
nethercote73b526f2004-10-31 18:48:21 +00003295 case VKI_PPSETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003296 PRE_MEM_READ( "ioctl(PPSETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003297 break;
nethercote73b526f2004-10-31 18:48:21 +00003298 case VKI_PPGETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003299 PRE_MEM_WRITE( "ioctl(PPGETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003300 break;
3301
thughesb3d3bcf2004-11-13 00:36:15 +00003302 case VKI_GIO_FONT:
3303 PRE_MEM_WRITE( "ioctl(GIO_FONT)", arg3, 32 * 256 );
3304 break;
3305 case VKI_PIO_FONT:
3306 PRE_MEM_READ( "ioctl(PIO_FONT)", arg3, 32 * 256 );
3307 break;
3308
3309 case VKI_GIO_FONTX:
3310 PRE_MEM_READ( "ioctl(GIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3311 if ( arg3 ) {
3312 /* ToDo: don't do any of the following if the structure is invalid */
3313 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3314 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3315 32 * cfd->charcount );
3316 }
3317 break;
3318 case VKI_PIO_FONTX:
3319 PRE_MEM_READ( "ioctl(PIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3320 if ( arg3 ) {
3321 /* ToDo: don't do any of the following if the structure is invalid */
3322 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3323 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3324 32 * cfd->charcount );
3325 }
3326 break;
3327
3328 case VKI_PIO_FONTRESET:
3329 break;
3330
3331 case VKI_GIO_CMAP:
3332 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", arg3, 16 * 3 );
3333 break;
3334 case VKI_PIO_CMAP:
3335 PRE_MEM_READ( "ioctl(PIO_CMAP)", arg3, 16 * 3 );
3336 break;
3337
3338 case VKI_KIOCSOUND:
3339 case VKI_KDMKTONE:
3340 break;
3341
3342 case VKI_KDGETLED:
3343 PRE_MEM_WRITE( "ioctl(KDGETLED)", arg3, sizeof(char) );
3344 break;
3345 case VKI_KDSETLED:
3346 break;
3347
3348 case VKI_KDGKBTYPE:
3349 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", arg3, sizeof(char) );
3350 break;
3351
3352 case VKI_KDADDIO:
3353 case VKI_KDDELIO:
3354 case VKI_KDENABIO:
3355 case VKI_KDDISABIO:
3356 break;
3357
3358 case VKI_KDSETMODE:
3359 break;
3360 case VKI_KDGETMODE:
3361 PRE_MEM_WRITE( "ioctl(KDGETMODE)", arg3, sizeof(int) );
3362 break;
3363
3364 case VKI_KDMAPDISP:
3365 case VKI_KDUNMAPDISP:
3366 break;
3367
3368 case VKI_GIO_SCRNMAP:
3369 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3370 break;
3371 case VKI_PIO_SCRNMAP:
3372 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3373 break;
3374 case VKI_GIO_UNISCRNMAP:
3375 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", arg3,
3376 VKI_E_TABSZ * sizeof(unsigned short) );
3377 break;
3378 case VKI_PIO_UNISCRNMAP:
3379 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", arg3,
3380 VKI_E_TABSZ * sizeof(unsigned short) );
3381 break;
3382
3383 case VKI_KDGKBMODE:
3384 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", arg3, sizeof(int) );
3385 break;
3386 case VKI_KDSKBMODE:
3387 break;
3388
3389 case VKI_KDGKBMETA:
3390 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", arg3, sizeof(int) );
3391 break;
3392 case VKI_KDSKBMETA:
3393 break;
3394
3395 case VKI_KDGKBLED:
3396 PRE_MEM_WRITE( "ioctl(KDGKBLED)", arg3, sizeof(char) );
3397 break;
3398 case VKI_KDSKBLED:
3399 break;
3400
3401 case VKI_KDGKBENT:
3402 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
3403 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3404 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3405 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
3406 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3407 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3408 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
3409 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3410 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3411 break;
3412 case VKI_KDSKBENT:
3413 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
3414 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3415 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3416 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
3417 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3418 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3419 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
3420 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3421 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3422 break;
3423
3424 case VKI_KDGKBSENT:
3425 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
3426 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3427 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3428 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
3429 (Addr)((struct vki_kbsentry *)arg3)->kb_string,
3430 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
3431 break;
3432 case VKI_KDSKBSENT:
3433 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
3434 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3435 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3436 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
3437 (Addr)((struct vki_kbsentry *)arg3)->kb_string );
3438 break;
3439
3440 case VKI_KDGKBDIACR:
3441 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3442 break;
3443 case VKI_KDSKBDIACR:
3444 PRE_MEM_READ( "ioctl(KDSKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3445 break;
3446
3447 case VKI_KDGETKEYCODE:
3448 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
3449 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3450 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3451 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
3452 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3453 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3454 break;
3455 case VKI_KDSETKEYCODE:
3456 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
3457 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3458 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3459 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
3460 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3461 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3462 break;
3463
3464 case VKI_KDSIGACCEPT:
3465 break;
3466
3467 case VKI_KDKBDREP:
3468 PRE_MEM_READ( "ioctl(KBKBDREP)", arg3, sizeof(struct vki_kbd_repeat) );
3469 break;
3470
jsgf855d93d2003-10-13 22:26:55 +00003471 /* We don't have any specific information on it, so
3472 try to do something reasonable based on direction and
3473 size bits. The encoding scheme is described in
3474 /usr/include/asm/ioctl.h.
3475
3476 According to Simon Hausmann, _IOC_READ means the kernel
3477 writes a value to the ioctl value passed from the user
3478 space and the other way around with _IOC_WRITE. */
3479 default: {
nethercote73b526f2004-10-31 18:48:21 +00003480 UInt dir = _VKI_IOC_DIR(arg2);
3481 UInt size = _VKI_IOC_SIZE(arg2);
jsgf855d93d2003-10-13 22:26:55 +00003482 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3483 /*
3484 * Be very lax about ioctl handling; the only
3485 * assumption is that the size is correct. Doesn't
3486 * require the full buffer to be initialized when
3487 * writing. Without this, using some device
3488 * drivers with a large number of strange ioctl
3489 * commands becomes very tiresome.
3490 */
nethercote73b526f2004-10-31 18:48:21 +00003491 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003492 static Int moans = 3;
3493 if (moans > 0) {
3494 moans--;
3495 VG_(message)(Vg_UserMsg,
3496 "Warning: noted but unhandled ioctl 0x%x"
3497 " with no size/direction hints",
3498 arg2);
3499 VG_(message)(Vg_UserMsg,
3500 " This could cause spurious value errors"
3501 " to appear.");
3502 VG_(message)(Vg_UserMsg,
3503 " See README_MISSING_SYSCALL_OR_IOCTL for "
3504 "guidance on writing a proper wrapper." );
3505 }
3506 } else {
nethercote73b526f2004-10-31 18:48:21 +00003507 if ((dir & _VKI_IOC_WRITE) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003508 PRE_MEM_READ( "ioctl(generic)", arg3, size);
nethercote73b526f2004-10-31 18:48:21 +00003509 if ((dir & _VKI_IOC_READ) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003510 PRE_MEM_WRITE( "ioctl(generic)", arg3, size);
jsgf855d93d2003-10-13 22:26:55 +00003511 }
3512 break;
3513 }
3514 }
3515}
3516
nethercote85a456f2004-11-16 17:31:56 +00003517POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003518{
jsgf855d93d2003-10-13 22:26:55 +00003519 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003520 case VKI_TCSETS:
3521 case VKI_TCSETSW:
3522 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003523 break;
nethercote73b526f2004-10-31 18:48:21 +00003524 case VKI_TCGETS:
nethercoteef0c7662004-11-06 15:38:43 +00003525 POST_MEM_WRITE( arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003526 break;
nethercote73b526f2004-10-31 18:48:21 +00003527 case VKI_TCSETA:
3528 case VKI_TCSETAW:
3529 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003530 break;
nethercote73b526f2004-10-31 18:48:21 +00003531 case VKI_TCGETA:
nethercoteef0c7662004-11-06 15:38:43 +00003532 POST_MEM_WRITE( arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003533 break;
nethercote73b526f2004-10-31 18:48:21 +00003534 case VKI_TCSBRK:
3535 case VKI_TCXONC:
3536 case VKI_TCSBRKP:
3537 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003538 break;
nethercote73b526f2004-10-31 18:48:21 +00003539 case VKI_TIOCGWINSZ:
nethercoteef0c7662004-11-06 15:38:43 +00003540 POST_MEM_WRITE( arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003541 break;
nethercote73b526f2004-10-31 18:48:21 +00003542 case VKI_TIOCSWINSZ:
3543 case VKI_TIOCMBIS:
3544 case VKI_TIOCMBIC:
3545 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003546 break;
nethercote73b526f2004-10-31 18:48:21 +00003547 case VKI_TIOCLINUX:
nethercoteef0c7662004-11-06 15:38:43 +00003548 POST_MEM_WRITE( arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003549 break;
nethercote73b526f2004-10-31 18:48:21 +00003550 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003551 /* Get process group ID for foreground processing group. */
nethercoteef0c7662004-11-06 15:38:43 +00003552 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003553 break;
nethercote73b526f2004-10-31 18:48:21 +00003554 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003555 /* Set a process group ID? */
nethercoteef0c7662004-11-06 15:38:43 +00003556 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003557 break;
nethercote73b526f2004-10-31 18:48:21 +00003558 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercoteef0c7662004-11-06 15:38:43 +00003559 POST_MEM_WRITE( arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003560 break;
nethercote73b526f2004-10-31 18:48:21 +00003561 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003562 break;
nethercote73b526f2004-10-31 18:48:21 +00003563 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003564 break;
nethercote73b526f2004-10-31 18:48:21 +00003565 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003566 break;
nethercote73b526f2004-10-31 18:48:21 +00003567 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003568 break;
nethercote73b526f2004-10-31 18:48:21 +00003569 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercoteef0c7662004-11-06 15:38:43 +00003570 POST_MEM_WRITE( arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003571 break;
3572
nethercote73b526f2004-10-31 18:48:21 +00003573 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003574 break;
nethercote73b526f2004-10-31 18:48:21 +00003575 case VKI_SG_IO:
njncf45fd42004-11-24 16:30:22 +00003576 POST_MEM_WRITE(arg3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003577 break;
nethercote73b526f2004-10-31 18:48:21 +00003578 case VKI_SG_GET_SCSI_ID:
njncf45fd42004-11-24 16:30:22 +00003579 POST_MEM_WRITE(arg3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003580 break;
nethercote73b526f2004-10-31 18:48:21 +00003581 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003582 break;
nethercote73b526f2004-10-31 18:48:21 +00003583 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003584 break;
nethercote73b526f2004-10-31 18:48:21 +00003585 case VKI_SG_GET_RESERVED_SIZE:
njncf45fd42004-11-24 16:30:22 +00003586 POST_MEM_WRITE(arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003587 break;
nethercote73b526f2004-10-31 18:48:21 +00003588 case VKI_SG_GET_TIMEOUT:
njncf45fd42004-11-24 16:30:22 +00003589 POST_MEM_WRITE(arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003590 break;
nethercote73b526f2004-10-31 18:48:21 +00003591 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003592 break;
nethercote73b526f2004-10-31 18:48:21 +00003593 case VKI_SG_EMULATED_HOST:
njncf45fd42004-11-24 16:30:22 +00003594 POST_MEM_WRITE(arg3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003595 break;
nethercote73b526f2004-10-31 18:48:21 +00003596 case VKI_SG_GET_SG_TABLESIZE:
njncf45fd42004-11-24 16:30:22 +00003597 POST_MEM_WRITE(arg3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003598 break;
jsgf855d93d2003-10-13 22:26:55 +00003599
muellera4b153a2003-11-19 22:07:14 +00003600 case VKI_IIOCGETCPS:
nethercote95a97862004-11-06 16:31:43 +00003601 POST_MEM_WRITE( arg3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003602 break;
muellera4b153a2003-11-19 22:07:14 +00003603 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003604 POST_MEM_WRITE( arg3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003605 break;
3606
3607 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003608 case VKI_SIOCGIFINDEX: /* get iface index */
njncf45fd42004-11-24 16:30:22 +00003609 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
3610 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003611 break;
nethercote73b526f2004-10-31 18:48:21 +00003612 case VKI_SIOCGIFFLAGS: /* get flags */
njncf45fd42004-11-24 16:30:22 +00003613 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
3614 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003615 break;
nethercote73b526f2004-10-31 18:48:21 +00003616 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njncf45fd42004-11-24 16:30:22 +00003617 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3618 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003619 break;
nethercote73b526f2004-10-31 18:48:21 +00003620 case VKI_SIOCGIFMTU: /* get MTU size */
njncf45fd42004-11-24 16:30:22 +00003621 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3622 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003623 break;
nethercote73b526f2004-10-31 18:48:21 +00003624 case VKI_SIOCGIFADDR: /* get PA address */
3625 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3626 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3627 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003628 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003629 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3630 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003631 break;
nethercote73b526f2004-10-31 18:48:21 +00003632 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003633 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003634 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3635 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003636 break;
nethercote73b526f2004-10-31 18:48:21 +00003637 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003638 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003639 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
3640 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003641 break;
3642 break;
nethercote73b526f2004-10-31 18:48:21 +00003643 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003644 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003645 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3646 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003647 break;
nethercote73b526f2004-10-31 18:48:21 +00003648 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003649 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003650 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_name,
3651 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003652 break;
nethercote73b526f2004-10-31 18:48:21 +00003653 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003654 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003655 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3656 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003657 break;
nethercote73b526f2004-10-31 18:48:21 +00003658 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003659 POST_MEM_WRITE(
nethercote73b526f2004-10-31 18:48:21 +00003660 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out,
3661 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003662 break;
nethercote73b526f2004-10-31 18:48:21 +00003663 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003664 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00003665 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003666 KERNEL_DO_SYSCALL(tid,res);
3667 if (!VG_(is_kerror)(res) && res == 0)
njncf45fd42004-11-24 16:30:22 +00003668 POST_MEM_WRITE(arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003669 */
3670 if (res == 0 && arg3 ) {
nethercote73b526f2004-10-31 18:48:21 +00003671 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
3672 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003673 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003674 }
3675 break;
nethercote73b526f2004-10-31 18:48:21 +00003676 case VKI_SIOCGSTAMP:
njncf45fd42004-11-24 16:30:22 +00003677 POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003678 break;
3679 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3680 the number of bytes currently in that socket's send buffer.
3681 It writes this value as an int to the memory location
3682 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003683 case VKI_SIOCOUTQ:
njncf45fd42004-11-24 16:30:22 +00003684 POST_MEM_WRITE(arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003685 break;
nethercote73b526f2004-10-31 18:48:21 +00003686 case VKI_SIOCGRARP: /* get RARP table entry */
3687 case VKI_SIOCGARP: /* get ARP table entry */
njncf45fd42004-11-24 16:30:22 +00003688 POST_MEM_WRITE(arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003689 break;
3690
nethercote73b526f2004-10-31 18:48:21 +00003691 case VKI_SIOCSIFFLAGS: /* set flags */
3692 case VKI_SIOCSIFMAP: /* Set device parameters */
3693 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3694 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3695 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3696 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3697 case VKI_SIOCSIFMETRIC: /* set metric */
3698 case VKI_SIOCSIFADDR: /* set PA address */
3699 case VKI_SIOCSIFMTU: /* set MTU size */
3700 case VKI_SIOCSIFHWADDR: /* set hardware address */
3701 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003702 break;
3703 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003704 case VKI_SIOCADDRT: /* add routing table entry */
3705 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003706 break;
3707
3708 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003709 case VKI_SIOCDRARP: /* delete RARP table entry */
3710 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003711 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003712 case VKI_SIOCSARP: /* set ARP table entry */
3713 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003714 break;
3715
nethercote73b526f2004-10-31 18:48:21 +00003716 case VKI_SIOCGPGRP:
njncf45fd42004-11-24 16:30:22 +00003717 POST_MEM_WRITE(arg3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00003718 break;
nethercote73b526f2004-10-31 18:48:21 +00003719 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003720 break;
3721
3722 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003723 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3724 case VKI_SNDCTL_SEQ_GETINCOUNT:
3725 case VKI_SNDCTL_SEQ_PERCMODE:
3726 case VKI_SNDCTL_SEQ_TESTMIDI:
3727 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3728 case VKI_SNDCTL_SEQ_NRSYNTHS:
3729 case VKI_SNDCTL_SEQ_NRMIDIS:
3730 case VKI_SNDCTL_SEQ_GETTIME:
3731 case VKI_SNDCTL_DSP_GETFMTS:
3732 case VKI_SNDCTL_DSP_GETTRIGGER:
3733 case VKI_SNDCTL_DSP_GETODELAY:
3734 case VKI_SNDCTL_DSP_GETSPDIF:
3735 case VKI_SNDCTL_DSP_GETCAPS:
3736 case VKI_SOUND_PCM_READ_RATE:
3737 case VKI_SOUND_PCM_READ_CHANNELS:
3738 case VKI_SOUND_PCM_READ_BITS:
3739 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3740 case VKI_SOUND_PCM_READ_FILTER:
njncf45fd42004-11-24 16:30:22 +00003741 POST_MEM_WRITE(arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003742 break;
nethercote73b526f2004-10-31 18:48:21 +00003743 case VKI_SNDCTL_SEQ_CTRLRATE:
3744 case VKI_SNDCTL_DSP_SPEED:
3745 case VKI_SNDCTL_DSP_STEREO:
3746 case VKI_SNDCTL_DSP_GETBLKSIZE:
3747 case VKI_SNDCTL_DSP_CHANNELS:
3748 case VKI_SOUND_PCM_WRITE_FILTER:
3749 case VKI_SNDCTL_DSP_SUBDIVIDE:
3750 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003751 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003752 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003753 case VKI_SNDCTL_TMR_TIMEBASE:
3754 case VKI_SNDCTL_TMR_TEMPO:
3755 case VKI_SNDCTL_TMR_SOURCE:
3756 case VKI_SNDCTL_MIDI_PRETIME:
3757 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00003758 break;
nethercote73b526f2004-10-31 18:48:21 +00003759 case VKI_SNDCTL_DSP_GETOSPACE:
3760 case VKI_SNDCTL_DSP_GETISPACE:
njncf45fd42004-11-24 16:30:22 +00003761 POST_MEM_WRITE(arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003762 break;
nethercote73b526f2004-10-31 18:48:21 +00003763 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00003764 break;
3765
nethercote73b526f2004-10-31 18:48:21 +00003766 case VKI_SNDCTL_DSP_POST:
3767 case VKI_SNDCTL_DSP_RESET:
3768 case VKI_SNDCTL_DSP_SYNC:
3769 case VKI_SNDCTL_DSP_SETSYNCRO:
3770 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003771 break;
3772
3773 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003774 case VKI_RTC_UIE_ON:
3775 case VKI_RTC_UIE_OFF:
3776 case VKI_RTC_AIE_ON:
3777 case VKI_RTC_AIE_OFF:
3778 case VKI_RTC_PIE_ON:
3779 case VKI_RTC_PIE_OFF:
3780 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003781 break;
nethercote73b526f2004-10-31 18:48:21 +00003782 case VKI_RTC_RD_TIME:
3783 case VKI_RTC_ALM_READ:
njncf45fd42004-11-24 16:30:22 +00003784 POST_MEM_WRITE(arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003785 break;
nethercote73b526f2004-10-31 18:48:21 +00003786 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00003787 break;
nethercote73b526f2004-10-31 18:48:21 +00003788 case VKI_RTC_IRQP_READ:
njncf45fd42004-11-24 16:30:22 +00003789 POST_MEM_WRITE(arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003790 break;
jsgf855d93d2003-10-13 22:26:55 +00003791
nethercote95a97862004-11-06 16:31:43 +00003792 case VKI_BLKGETSIZE:
njncf45fd42004-11-24 16:30:22 +00003793 POST_MEM_WRITE(arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003794 break;
jsgf855d93d2003-10-13 22:26:55 +00003795
thughesacbbc322004-06-19 12:12:01 +00003796 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003797 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njncf45fd42004-11-24 16:30:22 +00003798 POST_MEM_WRITE(arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003799 break;
3800
jsgf855d93d2003-10-13 22:26:55 +00003801 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003802 case VKI_CDROMSUBCHNL:
njncf45fd42004-11-24 16:30:22 +00003803 POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003804 break;
nethercote73b526f2004-10-31 18:48:21 +00003805 case VKI_CDROMREADTOCHDR:
njncf45fd42004-11-24 16:30:22 +00003806 POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003807 break;
nethercote73b526f2004-10-31 18:48:21 +00003808 case VKI_CDROMREADTOCENTRY:
njncf45fd42004-11-24 16:30:22 +00003809 POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003810 break;
nethercote73b526f2004-10-31 18:48:21 +00003811 case VKI_CDROMMULTISESSION:
njncf45fd42004-11-24 16:30:22 +00003812 POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003813 break;
nethercote73b526f2004-10-31 18:48:21 +00003814 case VKI_CDROMVOLREAD:
njncf45fd42004-11-24 16:30:22 +00003815 POST_MEM_WRITE(arg3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003816 break;
nethercote73b526f2004-10-31 18:48:21 +00003817 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00003818 {
nethercote73b526f2004-10-31 18:48:21 +00003819 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003820 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003821 break;
3822 }
3823
nethercote73b526f2004-10-31 18:48:21 +00003824 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00003825 break;
3826 /* The following two are probably bogus (should check args
3827 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003828 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3829 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003830 break;
3831
nethercote73b526f2004-10-31 18:48:21 +00003832 case VKI_FIGETBSZ:
njncf45fd42004-11-24 16:30:22 +00003833 POST_MEM_WRITE(arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003834 break;
nethercote73b526f2004-10-31 18:48:21 +00003835 case VKI_FIBMAP:
njncf45fd42004-11-24 16:30:22 +00003836 POST_MEM_WRITE(arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003837 break;
3838
nethercote73b526f2004-10-31 18:48:21 +00003839 case VKI_FBIOGET_VSCREENINFO: //0x4600
njncf45fd42004-11-24 16:30:22 +00003840 POST_MEM_WRITE(arg3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003841 break;
nethercote73b526f2004-10-31 18:48:21 +00003842 case VKI_FBIOGET_FSCREENINFO: //0x4602
njncf45fd42004-11-24 16:30:22 +00003843 POST_MEM_WRITE(arg3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003844 break;
3845
nethercote73b526f2004-10-31 18:48:21 +00003846 case VKI_PPCLAIM:
3847 case VKI_PPEXCL:
3848 case VKI_PPYIELD:
3849 case VKI_PPRELEASE:
3850 case VKI_PPSETMODE:
3851 case VKI_PPSETPHASE:
3852 case VKI_PPSETFLAGS:
3853 case VKI_PPWDATA:
3854 case VKI_PPWCONTROL:
3855 case VKI_PPFCONTROL:
3856 case VKI_PPDATADIR:
3857 case VKI_PPNEGOT:
3858 case VKI_PPWCTLONIRQ:
3859 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00003860 break;
nethercote73b526f2004-10-31 18:48:21 +00003861 case VKI_PPGETMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003862 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003863 break;
nethercote73b526f2004-10-31 18:48:21 +00003864 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003865 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003866 break;
nethercote73b526f2004-10-31 18:48:21 +00003867 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003868 POST_MEM_WRITE( arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003869 break;
nethercote73b526f2004-10-31 18:48:21 +00003870 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003871 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003872 break;
nethercote73b526f2004-10-31 18:48:21 +00003873 case VKI_PPRSTATUS:
nethercoteef0c7662004-11-06 15:38:43 +00003874 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003875 break;
nethercote73b526f2004-10-31 18:48:21 +00003876 case VKI_PPRDATA:
nethercoteef0c7662004-11-06 15:38:43 +00003877 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003878 break;
nethercote73b526f2004-10-31 18:48:21 +00003879 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003880 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003881 break;
nethercote73b526f2004-10-31 18:48:21 +00003882 case VKI_PPCLRIRQ:
nethercoteef0c7662004-11-06 15:38:43 +00003883 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003884 break;
nethercote73b526f2004-10-31 18:48:21 +00003885 case VKI_PPGETTIME:
nethercoteef0c7662004-11-06 15:38:43 +00003886 POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003887 break;
3888
thughesc3b842d2004-11-13 10:38:04 +00003889 case VKI_GIO_FONT:
3890 POST_MEM_WRITE( arg3, 32 * 256 );
3891 break;
3892 case VKI_PIO_FONT:
3893 break;
3894
3895 case VKI_GIO_FONTX:
3896 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)arg3)->chardata,
3897 32 * ((struct vki_consolefontdesc *)arg3)->charcount );
3898 break;
3899 case VKI_PIO_FONTX:
3900 break;
3901
3902 case VKI_PIO_FONTRESET:
3903 break;
3904
3905 case VKI_GIO_CMAP:
3906 POST_MEM_WRITE( arg3, 16 * 3 );
3907 break;
3908 case VKI_PIO_CMAP:
3909 break;
3910
3911 case VKI_KIOCSOUND:
3912 case VKI_KDMKTONE:
3913 break;
3914
3915 case VKI_KDGETLED:
3916 POST_MEM_WRITE( arg3, sizeof(char) );
3917 break;
3918 case VKI_KDSETLED:
3919 break;
3920
3921 case VKI_KDGKBTYPE:
3922 POST_MEM_WRITE( arg3, sizeof(char) );
3923 break;
3924
3925 case VKI_KDADDIO:
3926 case VKI_KDDELIO:
3927 case VKI_KDENABIO:
3928 case VKI_KDDISABIO:
3929 break;
3930
3931 case VKI_KDSETMODE:
3932 break;
3933 case VKI_KDGETMODE:
3934 POST_MEM_WRITE( arg3, sizeof(int) );
3935 break;
3936
3937 case VKI_KDMAPDISP:
3938 case VKI_KDUNMAPDISP:
3939 break;
3940
3941 case VKI_GIO_SCRNMAP:
3942 POST_MEM_WRITE( arg3, VKI_E_TABSZ );
3943 break;
3944 case VKI_PIO_SCRNMAP:
3945 break;
3946 case VKI_GIO_UNISCRNMAP:
3947 POST_MEM_WRITE( arg3, VKI_E_TABSZ * sizeof(unsigned short) );
3948 break;
3949 case VKI_PIO_UNISCRNMAP:
3950 break;
3951
3952 case VKI_KDGKBMODE:
3953 POST_MEM_WRITE( arg3, sizeof(int) );
3954 break;
3955 case VKI_KDSKBMODE:
3956 break;
3957
3958 case VKI_KDGKBMETA:
3959 POST_MEM_WRITE( arg3, sizeof(int) );
3960 break;
3961 case VKI_KDSKBMETA:
3962 break;
3963
3964 case VKI_KDGKBLED:
3965 POST_MEM_WRITE( arg3, sizeof(char) );
3966 break;
3967 case VKI_KDSKBLED:
3968 break;
3969
3970 case VKI_KDGKBENT:
3971 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3972 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3973 break;
3974 case VKI_KDSKBENT:
3975 break;
3976
3977 case VKI_KDGKBSENT:
3978 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)arg3)->kb_string,
3979 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
3980 break;
3981 case VKI_KDSKBSENT:
3982 break;
3983
3984 case VKI_KDGKBDIACR:
3985 POST_MEM_WRITE( arg3, sizeof(struct vki_kbdiacrs) );
3986 break;
3987 case VKI_KDSKBDIACR:
3988 break;
3989
3990 case VKI_KDGETKEYCODE:
3991 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3992 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3993 break;
3994 case VKI_KDSETKEYCODE:
3995 break;
3996
3997 case VKI_KDSIGACCEPT:
3998 break;
3999
4000 case VKI_KDKBDREP:
4001 break;
4002
jsgf855d93d2003-10-13 22:26:55 +00004003 /* We don't have any specific information on it, so
4004 try to do something reasonable based on direction and
4005 size bits. The encoding scheme is described in
4006 /usr/include/asm/ioctl.h.
4007
4008 According to Simon Hausmann, _IOC_READ means the kernel
4009 writes a value to the ioctl value passed from the user
4010 space and the other way around with _IOC_WRITE. */
4011 default: {
nethercote73b526f2004-10-31 18:48:21 +00004012 UInt dir = _VKI_IOC_DIR(arg2);
4013 UInt size = _VKI_IOC_SIZE(arg2);
4014 if (size > 0 && (dir & _VKI_IOC_READ)
jsgf855d93d2003-10-13 22:26:55 +00004015 && res == 0
4016 && arg3 != (Addr)NULL)
njncf45fd42004-11-24 16:30:22 +00004017 POST_MEM_WRITE(arg3, size);
jsgf855d93d2003-10-13 22:26:55 +00004018 break;
4019 }
4020 }
4021}
4022
nethercote85a456f2004-11-16 17:31:56 +00004023PRE(sys_kill, 0)
jsgf855d93d2003-10-13 22:26:55 +00004024{
4025 /* int kill(pid_t pid, int sig); */
nethercote9a3beb92004-11-12 17:07:26 +00004026 PRINT("sys_kill ( %d, %d )", arg1,arg2);
4027 PRE_REG_READ2(long, "kill", int, pid, int, sig);
jsgf855d93d2003-10-13 22:26:55 +00004028 if (arg2 == VKI_SIGVGINT || arg2 == VKI_SIGVGKILL)
nethercote35122912004-10-18 17:00:30 +00004029 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004030}
4031
nethercote85a456f2004-11-16 17:31:56 +00004032POST(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004033{
4034 /* If this was a self-kill then wait for a signal to be
4035 delivered to any thread before claiming the kill is done. */
nethercote9a3beb92004-11-12 17:07:26 +00004036 if (res >= 0 && // if it was successful and
4037 arg2 != 0 && // if a real signal and
4038 !VG_(is_sig_ign)(arg2) && // that isn't ignored and
4039 !VG_(sigismember)(&tst->eff_sig_mask, arg2) && // we're not blocking it
4040 (arg1 == VG_(getpid)() || // directed at us or
4041 arg1 == -1 || // directed at everyone or
4042 arg1 == 0 || // directed at whole group or
4043 -arg1 == VG_(getpgrp)())) { // directed at our group...
jsgf855d93d2003-10-13 22:26:55 +00004044 /* ...then wait for that signal to be delivered to someone
nethercote9a3beb92004-11-12 17:07:26 +00004045 (might be us, might be someone else who doesn't have it blocked) */
jsgf855d93d2003-10-13 22:26:55 +00004046 VG_(proxy_waitsig)();
4047 }
4048}
4049
nethercote85a456f2004-11-16 17:31:56 +00004050PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004051{
nethercotec6851dd2004-11-11 18:00:47 +00004052 PRINT("sys_link ( %p, %p)", arg1, arg2);
4053 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004054 PRE_MEM_RASCIIZ( "link(oldpath)", arg1);
4055 PRE_MEM_RASCIIZ( "link(newpath)", arg2);
jsgf855d93d2003-10-13 22:26:55 +00004056}
4057
nethercote85a456f2004-11-16 17:31:56 +00004058PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00004059{
nethercotec6851dd2004-11-11 18:00:47 +00004060 PRINT("sys_lseek ( %d, %d, %d )", arg1,arg2,arg3);
4061 PRE_REG_READ3(vki_off_t, "lseek",
4062 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004063}
4064
nethercote85a456f2004-11-16 17:31:56 +00004065PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004066{
nethercote2e1c37d2004-11-13 13:57:12 +00004067 PRINT("sys_newlstat ( %p(%s), %p )", arg1,arg1,arg2);
4068 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004069 PRE_MEM_RASCIIZ( "lstat(file_name)", arg1 );
4070 PRE_MEM_WRITE( "lstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004071}
4072
nethercote85a456f2004-11-16 17:31:56 +00004073POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00004074{
4075 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004076 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004077 }
4078}
4079
nethercote85a456f2004-11-16 17:31:56 +00004080PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004081{
nethercoteac866b92004-11-15 20:23:15 +00004082 PRINT("sys_lstat64 ( %p(%s), %p )",arg1,arg1,arg2);
nethercote2e1c37d2004-11-13 13:57:12 +00004083 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004084 PRE_MEM_RASCIIZ( "lstat64(file_name)", arg1 );
4085 PRE_MEM_WRITE( "lstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004086}
4087
nethercote85a456f2004-11-16 17:31:56 +00004088POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004089{
4090 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004091 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004092 }
4093}
4094
nethercote85a456f2004-11-16 17:31:56 +00004095PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004096{
nethercote9a3beb92004-11-12 17:07:26 +00004097 PRINT("sys_mkdir ( %p, %d )", arg1,arg2);
4098 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004099 PRE_MEM_RASCIIZ( "mkdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004100}
4101
nethercote85a456f2004-11-16 17:31:56 +00004102PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004103{
nethercote151effa2004-11-15 12:57:39 +00004104 /* struct mmap_arg_struct {
4105 unsigned long addr;
4106 unsigned long len;
4107 unsigned long prot;
4108 unsigned long flags;
4109 unsigned long fd;
4110 unsigned long offset;
4111 }; */
jsgf855d93d2003-10-13 22:26:55 +00004112 UInt a1, a2, a3, a4, a5, a6;
4113
nethercote151effa2004-11-15 12:57:39 +00004114 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
nethercote6456ab12004-10-18 14:47:48 +00004115 PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004116
nethercote151effa2004-11-15 12:57:39 +00004117 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4118 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004119
fitzhardinge98abfc72003-12-16 02:05:15 +00004120 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004121 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004122 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
4123 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004124 }
4125 } else {
nethercote6456ab12004-10-18 14:47:48 +00004126 a1 = VG_(find_map_space)(a1, a2, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00004127 if (a1 == 0)
nethercote151effa2004-11-15 12:57:39 +00004128 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004129 else
nethercote151effa2004-11-15 12:57:39 +00004130 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004131 }
jsgf855d93d2003-10-13 22:26:55 +00004132
fitzhardinge98abfc72003-12-16 02:05:15 +00004133 if (res != -VKI_ENOMEM) {
nethercote6456ab12004-10-18 14:47:48 +00004134 PLATFORM_DO_MMAP(res, a1, a2, a3, a4, a5, a6);
fitzhardingec2d65072004-01-07 08:44:43 +00004135
4136 if (!VG_(is_kerror)(res)) {
nethercote8ff888f2004-11-17 17:11:45 +00004137 vg_assert(VG_(valid_client_addr)(res, a2, tid, "old_mmap"));
nethercoteb4250ae2004-07-10 16:50:09 +00004138 mmap_segment( (Addr)res, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004139 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004140 }
jsgf855d93d2003-10-13 22:26:55 +00004141}
4142
nethercote3d5e9102004-11-17 18:22:38 +00004143PRE(sys_mmap2, 0)
4144{
4145 // Exactly like old_mmap() except:
4146 // - all 6 args are passed in regs, rather than in a memory-block.
4147 // - the file offset is specified in pagesize units rather than bytes,
4148 // so that it can be used for files bigger than 2^32 bytes.
4149 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
4150 arg1, (ULong)arg2, arg3, arg4, arg5, arg6 );
4151 PRE_REG_READ6(long, "mmap2",
4152 unsigned long, start, unsigned long, length,
4153 unsigned long, prot, unsigned long, flags,
4154 unsigned long, fd, unsigned long, offset);
4155
4156 if (arg4 & VKI_MAP_FIXED) {
4157 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mmap2"))
4158 set_result( -VKI_ENOMEM );
4159 } else {
4160 arg1 = VG_(find_map_space)(arg1, arg2, True);
4161 if (arg1 == 0)
4162 set_result( -VKI_ENOMEM );
4163 else
4164 arg4 |= VKI_MAP_FIXED;
4165 }
4166}
4167
4168POST(sys_mmap2)
4169{
4170 vg_assert(VG_(valid_client_addr)(res, arg2, tid, "mmap2"));
4171 mmap_segment( (Addr)res, arg2, arg3, arg4, arg5,
4172 arg6 * (ULong)VKI_PAGE_SIZE );
4173}
4174
nethercote85a456f2004-11-16 17:31:56 +00004175PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004176{
nethercote06c7bd72004-11-14 19:11:56 +00004177 PRINT("sys_mprotect ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
4178 PRE_REG_READ3(long, "mprotect",
4179 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004180
nethercote8ff888f2004-11-17 17:11:45 +00004181 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mprotect"))
nethercote35122912004-10-18 17:00:30 +00004182 set_result( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004183}
4184
nethercote85a456f2004-11-16 17:31:56 +00004185POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004186{
nethercote27ea8bc2004-07-10 17:21:14 +00004187 Addr a = arg1;
nethercote928a5f72004-11-03 18:10:37 +00004188 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004189 Int prot = arg3;
4190 Bool rr = prot & VKI_PROT_READ;
4191 Bool ww = prot & VKI_PROT_WRITE;
4192 Bool xx = prot & VKI_PROT_EXEC;
4193
nethercote27ea8bc2004-07-10 17:21:14 +00004194 mash_addr_and_len(&a, &len);
4195 VG_(mprotect_range)(a, len, prot);
4196 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004197}
4198
nethercote85a456f2004-11-16 17:31:56 +00004199PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004200{
nethercote06c7bd72004-11-14 19:11:56 +00004201 PRINT("sys_munmap ( %p, %llu )", arg1,(ULong)arg2);
4202 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004203
nethercote8ff888f2004-11-17 17:11:45 +00004204 if (!VG_(valid_client_addr)(arg1, arg2, tid, "munmap"))
nethercote35122912004-10-18 17:00:30 +00004205 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004206}
4207
nethercote85a456f2004-11-16 17:31:56 +00004208POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004209{
nethercote928a5f72004-11-03 18:10:37 +00004210 Addr a = arg1;
4211 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004212
4213 mash_addr_and_len(&a, &len);
4214 VG_(unmap_range)(a, len);
4215 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004216}
4217
nethercote85a456f2004-11-16 17:31:56 +00004218PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004219{
nethercoteac866b92004-11-15 20:23:15 +00004220 PRINT("sys_mincore ( %p, %llu, %p )", arg1,(ULong)arg2,arg3);
4221 PRE_REG_READ3(long, "mincore",
4222 unsigned long, start, vki_size_t, length,
4223 unsigned char *, vec);
nethercoteef0c7662004-11-06 15:38:43 +00004224 PRE_MEM_WRITE( "mincore(vec)", arg3, (arg2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004225}
4226
nethercote85a456f2004-11-16 17:31:56 +00004227POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004228{
nethercoteef0c7662004-11-06 15:38:43 +00004229 POST_MEM_WRITE( arg3, (arg2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004230}
4231
nethercote85a456f2004-11-16 17:31:56 +00004232PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004233{
nethercoteac866b92004-11-15 20:23:15 +00004234 PRINT("sys_nanosleep ( %p, %p )", arg1,arg2);
nethercote5b653bc2004-11-15 14:32:12 +00004235 PRE_REG_READ2(long, "nanosleep",
4236 struct timespec *, req, struct timespec *, rem);
nethercoteef0c7662004-11-06 15:38:43 +00004237 PRE_MEM_READ( "nanosleep(req)", arg1, sizeof(struct vki_timespec) );
nethercote163c5e82004-11-17 18:42:20 +00004238 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00004239 PRE_MEM_WRITE( "nanosleep(rem)", arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004240}
4241
nethercote85a456f2004-11-16 17:31:56 +00004242POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004243{
nethercote163c5e82004-11-17 18:42:20 +00004244 if (arg2 != 0 && res == -VKI_EINTR)
nethercoteef0c7662004-11-06 15:38:43 +00004245 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004246}
4247
nethercote85a456f2004-11-16 17:31:56 +00004248PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004249{
nethercotee70bd7d2004-08-18 14:37:17 +00004250 if (arg2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004251 // 3-arg version
4252 PRINT("sys_open ( %p(%s), %d, %d )",arg1,arg1,arg2,arg3);
4253 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004254 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004255 } else {
nethercotee824cc42004-11-09 16:20:46 +00004256 // 2-arg version
4257 PRINT("sys_open ( %p(%s), %d )",arg1,arg1,arg2);
4258 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004259 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004260 }
nethercotee824cc42004-11-09 16:20:46 +00004261 PRE_MEM_RASCIIZ( "open(filename)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004262}
4263
nethercote85a456f2004-11-16 17:31:56 +00004264POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004265{
nethercote3d5e9102004-11-17 18:22:38 +00004266 if (!VG_(fd_allowed)(res, "open", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004267 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004268 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004269 } else {
nethercote493dd182004-02-24 23:57:47 +00004270 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004271 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004272 }
jsgf855d93d2003-10-13 22:26:55 +00004273}
4274
nethercote85a456f2004-11-16 17:31:56 +00004275PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004276{
nethercote8b76fe52004-11-08 19:20:09 +00004277 PRINT("sys_read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4278 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004279 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004280
nethercote3d5e9102004-11-17 18:22:38 +00004281 if (!VG_(fd_allowed)(arg1, "read", tid, False))
nethercote35122912004-10-18 17:00:30 +00004282 set_result( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004283 else
nethercoteef0c7662004-11-06 15:38:43 +00004284 PRE_MEM_WRITE( "read(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004285}
4286
nethercote85a456f2004-11-16 17:31:56 +00004287POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004288{
nethercoteef0c7662004-11-06 15:38:43 +00004289 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004290}
4291
nethercote85a456f2004-11-16 17:31:56 +00004292PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004293{
nethercote8b76fe52004-11-08 19:20:09 +00004294 PRINT("sys_write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4295 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004296 unsigned int, fd, const char *, buf, vki_size_t, count);
nethercote3d5e9102004-11-17 18:22:38 +00004297 if (!VG_(fd_allowed)(arg1, "write", tid, False))
nethercote35122912004-10-18 17:00:30 +00004298 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004299 else
nethercoteef0c7662004-11-06 15:38:43 +00004300 PRE_MEM_READ( "write(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004301}
4302
nethercote85a456f2004-11-16 17:31:56 +00004303PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004304{
nethercotec6851dd2004-11-11 18:00:47 +00004305 PRINT("sys_creat ( %p(%s), %d )", arg1,arg1,arg2);
4306 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004307 PRE_MEM_RASCIIZ( "creat(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004308}
4309
nethercote85a456f2004-11-16 17:31:56 +00004310POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004311{
nethercote3d5e9102004-11-17 18:22:38 +00004312 if (!VG_(fd_allowed)(res, "creat", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004313 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004314 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004315 } else {
nethercote493dd182004-02-24 23:57:47 +00004316 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004317 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004318 }
jsgf855d93d2003-10-13 22:26:55 +00004319}
4320
nethercote9a3beb92004-11-12 17:07:26 +00004321// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004322PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004323{
nethercote9a3beb92004-11-12 17:07:26 +00004324 PRINT("sys_pipe ( %p )", arg1);
4325 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
4326 PRE_MEM_WRITE( "pipe(filedes)", arg1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004327}
4328
nethercote85a456f2004-11-16 17:31:56 +00004329POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004330{
nethercote9a3beb92004-11-12 17:07:26 +00004331 // XXX: use of Int here -- 32-bit-specific?
jsgf855d93d2003-10-13 22:26:55 +00004332 Int *p = (Int *)arg1;
4333
nethercote3d5e9102004-11-17 18:22:38 +00004334 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4335 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004336 VG_(close)(p[0]);
4337 VG_(close)(p[1]);
nethercote35122912004-10-18 17:00:30 +00004338 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004339 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004340 POST_MEM_WRITE( arg1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004341 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004342 VG_(record_fd_open)(tid, p[0], NULL);
4343 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004344 }
4345 }
jsgf855d93d2003-10-13 22:26:55 +00004346}
4347
nethercotef90953e2004-11-15 14:50:02 +00004348// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004349PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004350{
4351 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004352 int fd; -- file descriptor
4353 short events; -- requested events
4354 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004355 };
nethercoteeb0592d2004-11-05 12:02:27 +00004356 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004357 */
nethercoteeb0592d2004-11-05 12:02:27 +00004358 UInt i;
4359 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
nethercotef90953e2004-11-15 14:50:02 +00004360 PRINT("sys_poll ( %p, %d, %d )\n", arg1,arg2,arg3);
4361 PRE_REG_READ3(long, "poll",
4362 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004363
nethercoteeb0592d2004-11-05 12:02:27 +00004364 for (i = 0; i < arg2; i++) {
4365 // 'fd' and 'events' field are inputs; 'revents' is output.
4366 // XXX: this is x86 specific -- the pollfd struct varies across
4367 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004368 PRE_MEM_READ( "poll(ufds)",
4369 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4370 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4371 }
jsgf855d93d2003-10-13 22:26:55 +00004372}
4373
nethercote85a456f2004-11-16 17:31:56 +00004374POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004375{
4376 if (res > 0) {
4377 UInt i;
nethercoteeb0592d2004-11-05 12:02:27 +00004378 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
4379 // XXX: again, this is x86-specific
jsgf855d93d2003-10-13 22:26:55 +00004380 for (i = 0; i < arg2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004381 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004382 }
4383}
4384
rjwalsh17d85302004-11-18 22:56:09 +00004385PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004386{
rjwalsh093047d2004-11-19 02:11:56 +00004387 int saved = SYSNO;
nethercote5a945af2004-11-14 18:37:07 +00004388 PRINT("sys_readlink ( %p, %p, %llu )", arg1,arg2,(ULong)arg3);
4389 PRE_REG_READ3(long, "readlink",
4390 const char *, path, char *, buf, int, bufsiz);
nethercoteef0c7662004-11-06 15:38:43 +00004391 PRE_MEM_RASCIIZ( "readlink(path)", arg1 );
4392 PRE_MEM_WRITE( "readlink(buf)", arg2,arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004393
rjwalsh17d85302004-11-18 22:56:09 +00004394 /*
rjwalsh093047d2004-11-19 02:11:56 +00004395 * Handle the case where readlink is looking at /proc/self/exe or
4396 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004397 */
4398
rjwalsh093047d2004-11-19 02:11:56 +00004399 set_result( VG_(do_syscall)(saved, arg1, arg2, arg3));
4400 if ((Int)res == -2) {
4401 char name[25];
4402
4403 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004404
rjwalsh093047d2004-11-19 02:11:56 +00004405 if (VG_(strcmp)((Char *)arg1, name) == 0 ||
4406 VG_(strcmp)((Char *)arg1, "/proc/self/exe") == 0) {
4407 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
4408 set_result( VG_(do_syscall)(saved, name, arg2, arg3));
4409 }
rjwalsh17d85302004-11-18 22:56:09 +00004410 }
4411
rjwalsh093047d2004-11-19 02:11:56 +00004412 if ((Int)res > 0)
rjwalsh17d85302004-11-18 22:56:09 +00004413 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004414}
4415
nethercote85a456f2004-11-16 17:31:56 +00004416PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004417{
jsgf855d93d2003-10-13 22:26:55 +00004418 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004419 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00004420 PRINT("sys_readv ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
4421 PRE_REG_READ3(ssize_t, "readv",
4422 unsigned long, fd, const struct iovec *, vector,
4423 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00004424 if (!VG_(fd_allowed)(arg1, "readv", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00004425 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004426 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004427 PRE_MEM_READ( "readv(vector)", arg2, arg3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004428
nethercote163c5e82004-11-17 18:42:20 +00004429 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004430 /* ToDo: don't do any of the following if the vector is invalid */
4431 vec = (struct vki_iovec *)arg2;
4432 for (i = 0; i < (Int)arg3; i++)
4433 PRE_MEM_WRITE( "readv(vector[...])",
4434 (Addr)vec[i].iov_base, vec[i].iov_len );
4435 }
jsgf855d93d2003-10-13 22:26:55 +00004436 }
4437}
4438
nethercote85a456f2004-11-16 17:31:56 +00004439POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004440{
4441 if (res > 0) {
4442 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004443 struct vki_iovec * vec = (struct vki_iovec *)arg2;
jsgf855d93d2003-10-13 22:26:55 +00004444 Int remains = res;
4445
4446 /* res holds the number of bytes read. */
4447 for (i = 0; i < (Int)arg3; i++) {
4448 Int nReadThisBuf = vec[i].iov_len;
4449 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004450 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004451 remains -= nReadThisBuf;
4452 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4453 }
4454 }
4455}
4456
nethercote85a456f2004-11-16 17:31:56 +00004457PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004458{
nethercote9a3beb92004-11-12 17:07:26 +00004459 PRINT("sys_rename ( %p, %p )", arg1, arg2 );
4460 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004461 PRE_MEM_RASCIIZ( "rename(oldpath)", arg1 );
4462 PRE_MEM_RASCIIZ( "rename(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00004463}
4464
nethercote85a456f2004-11-16 17:31:56 +00004465PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004466{
nethercote9a3beb92004-11-12 17:07:26 +00004467 PRINT("sys_rmdir ( %p )", arg1);
4468 PRE_REG_READ1(long, "rmdir", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00004469 PRE_MEM_RASCIIZ( "rmdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004470}
4471
nethercote85a456f2004-11-16 17:31:56 +00004472PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004473{
nethercoteef0c7662004-11-06 15:38:43 +00004474 PRINT("sched_setparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004475 PRE_REG_READ2(long, "sched_setparam",
4476 vki_pid_t, pid, struct sched_param *, p);
4477 PRE_MEM_READ( "sched_setparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004478}
4479
nethercote85a456f2004-11-16 17:31:56 +00004480POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004481{
nethercoteef0c7662004-11-06 15:38:43 +00004482 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004483}
4484
nethercote85a456f2004-11-16 17:31:56 +00004485PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004486{
nethercoteef0c7662004-11-06 15:38:43 +00004487 PRINT("sched_getparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004488 PRE_REG_READ2(long, "sched_getparam",
4489 vki_pid_t, pid, struct sched_param *, p);
4490 PRE_MEM_WRITE( "sched_getparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004491}
4492
nethercote85a456f2004-11-16 17:31:56 +00004493POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004494{
nethercoteef0c7662004-11-06 15:38:43 +00004495 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004496}
4497
nethercote85a456f2004-11-16 17:31:56 +00004498PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004499{
4500 PRINT("sys_select ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
4501 PRE_REG_READ5(long, "select",
4502 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4503 vki_fd_set *, exceptfds, struct timeval *, timeout);
4504 // XXX: this possibly understates how much memory is read.
4505 if (arg2 != 0)
4506 PRE_MEM_READ( "select(readfds)",
4507 arg2, arg1/8 /* __FD_SETSIZE/8 */ );
4508 if (arg3 != 0)
4509 PRE_MEM_READ( "select(writefds)",
4510 arg3, arg1/8 /* __FD_SETSIZE/8 */ );
4511 if (arg4 != 0)
4512 PRE_MEM_READ( "select(exceptfds)",
4513 arg4, arg1/8 /* __FD_SETSIZE/8 */ );
4514 if (arg5 != 0)
4515 PRE_MEM_READ( "select(timeout)", arg5, sizeof(struct vki_timeval) );
4516}
4517
nethercote85a456f2004-11-16 17:31:56 +00004518PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004519{
nethercote9c311eb2004-11-12 18:20:12 +00004520 PRINT("sys_setgid16 ( %d )", arg1);
4521 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4522}
4523
nethercote85a456f2004-11-16 17:31:56 +00004524PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004525{
4526 PRINT("sys_setgid ( %d )", arg1);
4527 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004528}
4529
nethercote85a456f2004-11-16 17:31:56 +00004530PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004531{
nethercote0df495a2004-11-11 16:38:21 +00004532 PRINT("sys_setsid ( )");
4533 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004534}
4535
nethercote85a456f2004-11-16 17:31:56 +00004536PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004537{
nethercote686b5db2004-11-14 13:42:51 +00004538 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)arg1, arg2);
4539 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
4540 if (arg1 > 0)
4541 PRE_MEM_READ( "setgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
4542}
4543
nethercote85a456f2004-11-16 17:31:56 +00004544PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004545{
nethercoteef0c7662004-11-06 15:38:43 +00004546 PRINT("setgroups ( %llu, %p )", (ULong)arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00004547 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00004548 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00004549 PRE_MEM_READ( "setgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004550}
4551
nethercote85a456f2004-11-16 17:31:56 +00004552PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004553{
nethercoteef0c7662004-11-06 15:38:43 +00004554 PRINT("setpgid ( %d, %d )", arg1, arg2);
nethercote9c311eb2004-11-12 18:20:12 +00004555 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004556}
4557
nethercote85a456f2004-11-16 17:31:56 +00004558POST(sys_setpgid)
jsgf855d93d2003-10-13 22:26:55 +00004559{
4560 VG_(main_pgrp) = VG_(getpgrp)();
4561}
4562
nethercote85a456f2004-11-16 17:31:56 +00004563PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004564{
nethercote17258dc2004-11-12 19:55:08 +00004565 PRINT("sys_setregid ( %d, %d )", arg1, arg2);
4566 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004567}
4568
nethercote85a456f2004-11-16 17:31:56 +00004569PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004570{
nethercote17258dc2004-11-12 19:55:08 +00004571 PRINT("setreuid16 ( 0x%x, 0x%x )", arg1, arg2);
4572 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4573}
4574
nethercote85a456f2004-11-16 17:31:56 +00004575PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004576{
4577 PRINT("sys_setreuid ( 0x%x, 0x%x )", arg1, arg2);
4578 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004579}
4580
nethercote85a456f2004-11-16 17:31:56 +00004581PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004582{
nethercote17258dc2004-11-12 19:55:08 +00004583 PRINT("sys_setrlimit ( %d, %p )", arg1,arg2);
4584 PRE_REG_READ2(long, "setrlimit",
4585 unsigned int, resource, struct rlimit *, rlim);
nethercoteef0c7662004-11-06 15:38:43 +00004586 PRE_MEM_READ( "setrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004587
thughesad1c9562004-06-26 11:27:52 +00004588 if (arg1 == VKI_RLIMIT_NOFILE) {
nethercote73b526f2004-10-31 18:48:21 +00004589 if (((struct vki_rlimit *)arg2)->rlim_cur > VG_(fd_hard_limit) ||
4590 ((struct vki_rlimit *)arg2)->rlim_max != VG_(fd_hard_limit)) {
nethercote35122912004-10-18 17:00:30 +00004591 set_result( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004592 }
4593 else {
nethercote73b526f2004-10-31 18:48:21 +00004594 VG_(fd_soft_limit) = ((struct vki_rlimit *)arg2)->rlim_cur;
nethercote35122912004-10-18 17:00:30 +00004595 set_result( 0 );
thughesad1c9562004-06-26 11:27:52 +00004596 }
4597 }
4598 else if (arg1 == VKI_RLIMIT_DATA) {
nethercote73b526f2004-10-31 18:48:21 +00004599 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4600 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004601 set_result( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004602 }
4603 else {
nethercote73b526f2004-10-31 18:48:21 +00004604 VG_(client_rlimit_data) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004605 set_result( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004606 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004607 }
thughesc37184f2004-09-11 14:16:57 +00004608 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
nethercote73b526f2004-10-31 18:48:21 +00004609 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4610 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004611 set_result( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004612 }
4613 else {
nethercote73b526f2004-10-31 18:48:21 +00004614 VG_(threads)[tid].stack_size = ((struct vki_rlimit *)arg2)->rlim_cur;
4615 VG_(client_rlimit_stack) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004616 set_result( 0 );
thughesc37184f2004-09-11 14:16:57 +00004617 }
4618 }
jsgf855d93d2003-10-13 22:26:55 +00004619}
4620
nethercote85a456f2004-11-16 17:31:56 +00004621PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004622{
nethercotec6851dd2004-11-11 18:00:47 +00004623 PRINT("sys_setuid16 ( %d )", arg1);
4624 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004625}
4626
nethercote85a456f2004-11-16 17:31:56 +00004627PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00004628{
4629 PRINT("sys_setuid ( %d )", arg1);
4630 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4631}
jsgf855d93d2003-10-13 22:26:55 +00004632
nethercote85a456f2004-11-16 17:31:56 +00004633PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004634{
nethercotedc18c0a2004-11-14 20:06:27 +00004635 PRINT("sys_socketcall ( %d, %p )",arg1,arg2);
4636 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4637
jsgf855d93d2003-10-13 22:26:55 +00004638 switch (arg1 /* request */) {
4639
nethercote73b526f2004-10-31 18:48:21 +00004640 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00004641 /* int socketpair(int d, int type, int protocol, int sv[2]); */
nethercoteef0c7662004-11-06 15:38:43 +00004642 PRE_MEM_READ( "socketcall.socketpair(args)", arg2, 4*sizeof(Addr) );
4643 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
nethercotef1d810d2004-11-04 19:57:03 +00004644 ((UWord*)arg2)[3], 2*sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004645 break;
4646
nethercote73b526f2004-10-31 18:48:21 +00004647 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00004648 /* int socket(int domain, int type, int protocol); */
nethercoteef0c7662004-11-06 15:38:43 +00004649 PRE_MEM_READ( "socketcall.socket(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004650 break;
4651
nethercote73b526f2004-10-31 18:48:21 +00004652 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004653 /* int bind(int sockfd, struct sockaddr *my_addr,
4654 int addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004655 PRE_MEM_READ( "socketcall.bind(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004656 pre_mem_read_sockaddr( tid, "socketcall.bind(my_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004657 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004658 break;
4659
nethercote73b526f2004-10-31 18:48:21 +00004660 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004661 /* int listen(int s, int backlog); */
nethercoteef0c7662004-11-06 15:38:43 +00004662 PRE_MEM_READ( "socketcall.listen(args)", arg2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004663 break;
4664
nethercote73b526f2004-10-31 18:48:21 +00004665 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004666 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004667 PRE_MEM_READ( "socketcall.accept(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004668 {
nethercotef1d810d2004-11-04 19:57:03 +00004669 Addr addr_p = ((UWord*)arg2)[1];
4670 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004671 if (addr_p != (Addr)NULL)
4672 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
4673 "socketcall.accept(addr)",
4674 "socketcall.accept(addrlen_in)" );
4675 }
4676 break;
4677 }
4678
nethercote73b526f2004-10-31 18:48:21 +00004679 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004680 /* int sendto(int s, const void *msg, int len,
4681 unsigned int flags,
4682 const struct sockaddr *to, int tolen); */
nethercoteef0c7662004-11-06 15:38:43 +00004683 PRE_MEM_READ( "socketcall.sendto(args)", arg2, 6*sizeof(Addr) );
4684 PRE_MEM_READ( "socketcall.sendto(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004685 ((UWord*)arg2)[1], /* msg */
4686 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004687 pre_mem_read_sockaddr( tid, "socketcall.sendto(to.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004688 (struct vki_sockaddr *) (((UWord*)arg2)[4]), ((UWord*)arg2)[5]);
jsgf855d93d2003-10-13 22:26:55 +00004689 break;
4690
nethercote73b526f2004-10-31 18:48:21 +00004691 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004692 /* int send(int s, const void *msg, size_t len, int flags); */
nethercoteef0c7662004-11-06 15:38:43 +00004693 PRE_MEM_READ( "socketcall.send(args)", arg2, 4*sizeof(Addr) );
4694 PRE_MEM_READ( "socketcall.send(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004695 ((UWord*)arg2)[1], /* msg */
4696 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004697 break;
4698
nethercote73b526f2004-10-31 18:48:21 +00004699 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004700 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4701 struct sockaddr *from, int *fromlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004702 PRE_MEM_READ( "socketcall.recvfrom(args)", arg2, 6*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004703 {
nethercotef1d810d2004-11-04 19:57:03 +00004704 Addr buf_p = ((UWord*)arg2)[1];
4705 Int len = ((UWord*)arg2)[2];
4706 Addr from_p = ((UWord*)arg2)[4];
4707 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004708
nethercoteef0c7662004-11-06 15:38:43 +00004709 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004710 if (from_p != (Addr)NULL)
4711 buf_and_len_pre_check ( tid, from_p, fromlen_p,
4712 "socketcall.recvfrom(from)",
4713 "socketcall.recvfrom(fromlen_in)" );
4714 }
4715 break;
4716
nethercote73b526f2004-10-31 18:48:21 +00004717 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00004718 /* int recv(int s, void *buf, int len, unsigned int flags); */
4719 /* man 2 recv says:
4720 The recv call is normally used only on a connected socket
4721 (see connect(2)) and is identical to recvfrom with a NULL
4722 from parameter.
4723 */
nethercoteef0c7662004-11-06 15:38:43 +00004724 PRE_MEM_READ( "socketcall.recv(args)", arg2, 4*sizeof(Addr) );
4725 PRE_MEM_WRITE( "socketcall.recv(buf)",
nethercotef1d810d2004-11-04 19:57:03 +00004726 ((UWord*)arg2)[1], /* buf */
4727 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004728 break;
4729
nethercote73b526f2004-10-31 18:48:21 +00004730 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004731 /* int connect(int sockfd,
4732 struct sockaddr *serv_addr, int addrlen ); */
nethercoteef0c7662004-11-06 15:38:43 +00004733 PRE_MEM_READ( "socketcall.connect(args)", arg2, 3*sizeof(Addr) );
4734 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
nethercotef1d810d2004-11-04 19:57:03 +00004735 ((UWord*)arg2)[1], /* serv_addr */
nethercote73b526f2004-10-31 18:48:21 +00004736 sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +00004737 pre_mem_read_sockaddr( tid,
4738 "socketcall.connect(serv_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004739 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004740 break;
4741
nethercote73b526f2004-10-31 18:48:21 +00004742 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004743 /* int setsockopt(int s, int level, int optname,
4744 const void *optval, int optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004745 PRE_MEM_READ( "socketcall.setsockopt(args)", arg2, 5*sizeof(Addr) );
4746 PRE_MEM_READ( "socketcall.setsockopt(optval)",
nethercotef1d810d2004-11-04 19:57:03 +00004747 ((UWord*)arg2)[3], /* optval */
4748 ((UWord*)arg2)[4] /* optlen */ );
jsgf855d93d2003-10-13 22:26:55 +00004749 break;
4750
nethercote73b526f2004-10-31 18:48:21 +00004751 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004752 /* int setsockopt(int s, int level, int optname,
4753 void *optval, socklen_t *optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004754 PRE_MEM_READ( "socketcall.getsockopt(args)", arg2, 5*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004755 {
nethercotef1d810d2004-11-04 19:57:03 +00004756 Addr optval_p = ((UWord*)arg2)[3];
4757 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00004758 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
4759 if (optval_p != (Addr)NULL)
4760 buf_and_len_pre_check ( tid, optval_p, optlen_p,
4761 "socketcall.getsockopt(optval)",
4762 "socketcall.getsockopt(optlen)" );
4763 }
4764 break;
4765
nethercote73b526f2004-10-31 18:48:21 +00004766 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004767 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004768 PRE_MEM_READ( "socketcall.getsockname(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004769 {
nethercotef1d810d2004-11-04 19:57:03 +00004770 Addr name_p = ((UWord*)arg2)[1];
4771 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004772
4773 /* Nb: name_p cannot be NULL */
4774 buf_and_len_pre_check ( tid, name_p, namelen_p,
4775 "socketcall.getsockname(name)",
4776 "socketcall.getsockname(namelen_in)" );
4777 }
4778 break;
4779
nethercote73b526f2004-10-31 18:48:21 +00004780 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004781 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004782 PRE_MEM_READ( "socketcall.getpeername(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004783 {
nethercotef1d810d2004-11-04 19:57:03 +00004784 Addr name_p = ((UWord*)arg2)[1];
4785 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004786
4787 /* Nb: name_p cannot be NULL */
4788 buf_and_len_pre_check ( tid, name_p, namelen_p,
4789 "socketcall.getpeername(name)",
4790 "socketcall.getpeername(namelen_in)" );
4791 }
4792 break;
4793
nethercote73b526f2004-10-31 18:48:21 +00004794 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004795 /* int shutdown(int s, int how); */
nethercoteef0c7662004-11-06 15:38:43 +00004796 PRE_MEM_READ( "socketcall.shutdown(args)", arg2, 2*sizeof(Addr) );
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 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4801
4802 /* this causes warnings, and I don't get why. glibc bug?
4803 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004804 PRE_MEM_READ( "socketcall.sendmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004805 */
4806
nethercote22208362004-11-04 20:00:44 +00004807 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004808 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
4809
4810 break;
4811 }
4812
nethercote73b526f2004-10-31 18:48:21 +00004813 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004814 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4815
4816 /* this causes warnings, and I don't get why. glibc bug?
4817 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004818 PRE_MEM_READ("socketcall.recvmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004819 */
4820
nethercote22208362004-11-04 20:00:44 +00004821 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004822 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
4823
4824 break;
4825 }
4826
4827 default:
jsgf17059e02003-10-19 16:46:06 +00004828 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",arg1);
nethercote35122912004-10-18 17:00:30 +00004829 set_result( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00004830 break;
jsgf855d93d2003-10-13 22:26:55 +00004831 }
4832}
4833
nethercote85a456f2004-11-16 17:31:56 +00004834POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00004835{
jsgf855d93d2003-10-13 22:26:55 +00004836 switch (arg1 /* request */) {
4837
nethercote73b526f2004-10-31 18:48:21 +00004838 case VKI_SYS_SOCKETPAIR: {
nethercotef1d810d2004-11-04 19:57:03 +00004839 Int fd1 = ((Int*)((UWord*)arg2)[3])[0];
4840 Int fd2 = ((Int*)((UWord*)arg2)[3])[1];
nethercoteef0c7662004-11-06 15:38:43 +00004841 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote3d5e9102004-11-17 18:22:38 +00004842 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
4843 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00004844 VG_(close)(fd1);
4845 VG_(close)(fd2);
nethercote35122912004-10-18 17:00:30 +00004846 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00004847 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004848 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004849 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004850 VG_(record_fd_open)(tid, fd1, NULL);
4851 VG_(record_fd_open)(tid, fd2, NULL);
nethercote493dd182004-02-24 23:57:47 +00004852 }
rjwalshf5f536f2003-11-17 17:45:00 +00004853 }
jsgf855d93d2003-10-13 22:26:55 +00004854 break;
nethercote493dd182004-02-24 23:57:47 +00004855 }
jsgf855d93d2003-10-13 22:26:55 +00004856
nethercote73b526f2004-10-31 18:48:21 +00004857 case VKI_SYS_SOCKET:
nethercote3d5e9102004-11-17 18:22:38 +00004858 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004859 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004860 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004861 } else {
nethercote493dd182004-02-24 23:57:47 +00004862 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004863 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004864 }
4865 break;
4866
nethercote73b526f2004-10-31 18:48:21 +00004867 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004868 /* int bind(int sockfd, struct sockaddr *my_addr,
4869 int addrlen); */
4870 break;
4871
nethercote73b526f2004-10-31 18:48:21 +00004872 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004873 /* int listen(int s, int backlog); */
4874 break;
4875
nethercote73b526f2004-10-31 18:48:21 +00004876 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004877 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercote3d5e9102004-11-17 18:22:38 +00004878 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004879 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004880 set_result( -VKI_EMFILE );
jsgf855d93d2003-10-13 22:26:55 +00004881 } else {
nethercotef1d810d2004-11-04 19:57:03 +00004882 Addr addr_p = ((UWord*)arg2)[1];
4883 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004884
4885 if (addr_p != (Addr)NULL)
4886 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
4887 "socketcall.accept(addrlen_out)" );
nethercote493dd182004-02-24 23:57:47 +00004888 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004889 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004890 }
4891 break;
4892 }
4893
nethercote73b526f2004-10-31 18:48:21 +00004894 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004895 break;
4896
nethercote73b526f2004-10-31 18:48:21 +00004897 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004898 break;
4899
nethercote73b526f2004-10-31 18:48:21 +00004900 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004901 {
nethercotef1d810d2004-11-04 19:57:03 +00004902 Addr buf_p = ((UWord*)arg2)[1];
4903 Int len = ((UWord*)arg2)[2];
4904 Addr from_p = ((UWord*)arg2)[4];
4905 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004906
4907 if (from_p != (Addr)NULL)
4908 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
4909 "socketcall.recvfrom(fromlen_out)" );
nethercoteef0c7662004-11-06 15:38:43 +00004910 POST_MEM_WRITE( buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004911 }
4912 break;
4913
nethercote73b526f2004-10-31 18:48:21 +00004914 case VKI_SYS_RECV:
nethercote163c5e82004-11-17 18:42:20 +00004915 if (res >= 0 && ((UWord*)arg2)[1] != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004916 POST_MEM_WRITE( ((UWord*)arg2)[1], /* buf */
4917 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004918 }
4919 break;
4920
nethercote73b526f2004-10-31 18:48:21 +00004921 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004922 break;
4923
nethercote73b526f2004-10-31 18:48:21 +00004924 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004925 break;
4926
nethercote73b526f2004-10-31 18:48:21 +00004927 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004928 {
nethercotef1d810d2004-11-04 19:57:03 +00004929 Addr optval_p = ((UWord*)arg2)[3];
4930 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00004931
4932 if (optval_p != (Addr)NULL)
4933 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
4934 "socketcall.getsockopt(optlen_out)" );
4935 }
4936 break;
4937
nethercote73b526f2004-10-31 18:48:21 +00004938 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004939 {
nethercotef1d810d2004-11-04 19:57:03 +00004940 Addr name_p = ((UWord*)arg2)[1];
4941 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004942
4943 buf_and_len_post_check ( tid, res, name_p, namelen_p,
4944 "socketcall.getsockname(namelen_out)" );
4945 }
4946 break;
4947
nethercote73b526f2004-10-31 18:48:21 +00004948 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004949 {
nethercotef1d810d2004-11-04 19:57:03 +00004950 Addr name_p = ((UWord*)arg2)[1];
4951 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004952
4953 buf_and_len_post_check ( tid, res, name_p, namelen_p,
4954 "socketcall.getpeername(namelen_out)" );
4955 }
4956 break;
4957
nethercote73b526f2004-10-31 18:48:21 +00004958 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004959 break;
4960
nethercote73b526f2004-10-31 18:48:21 +00004961 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00004962 break;
4963
nethercote73b526f2004-10-31 18:48:21 +00004964 case VKI_SYS_RECVMSG:
jsgf855d93d2003-10-13 22:26:55 +00004965 {
nethercote22208362004-11-04 20:00:44 +00004966 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004967
4968 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
rjwalshf5f536f2003-11-17 17:45:00 +00004969 check_cmsg_for_fds( tid, msg );
jsgf855d93d2003-10-13 22:26:55 +00004970
4971 break;
4972 }
4973
4974 default:
4975 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",arg1);
4976 VG_(core_panic)("... bye!\n");
4977 break; /*NOTREACHED*/
4978 }
4979}
4980
nethercote85a456f2004-11-16 17:31:56 +00004981PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004982{
nethercote2e1c37d2004-11-13 13:57:12 +00004983 PRINT("sys_newstat ( %p(%s), %p )", arg1,arg1,arg2);
4984 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004985 PRE_MEM_RASCIIZ( "stat(file_name)", arg1 );
4986 PRE_MEM_WRITE( "stat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004987}
4988
nethercote85a456f2004-11-16 17:31:56 +00004989POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00004990{
nethercoteef0c7662004-11-06 15:38:43 +00004991 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004992}
4993
nethercote85a456f2004-11-16 17:31:56 +00004994PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00004995{
nethercotedc18c0a2004-11-14 20:06:27 +00004996 PRINT("sys_statfs ( %p, %p )",arg1,arg2);
4997 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004998 PRE_MEM_RASCIIZ( "statfs(path)", arg1 );
4999 PRE_MEM_WRITE( "statfs(buf)", arg2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00005000}
5001
nethercote85a456f2004-11-16 17:31:56 +00005002POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00005003{
nethercoteef0c7662004-11-06 15:38:43 +00005004 POST_MEM_WRITE( arg2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00005005}
5006
nethercote85a456f2004-11-16 17:31:56 +00005007PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00005008{
nethercotedc18c0a2004-11-14 20:06:27 +00005009 PRINT("sys_statfs64 ( %p, %llu, %p )",arg1,(ULong)arg2,arg3);
5010 PRE_REG_READ3(long, "statfs64",
5011 const char *, path, vki_size_t, size, struct statfs64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005012 PRE_MEM_RASCIIZ( "statfs64(path)", arg1 );
5013 PRE_MEM_WRITE( "statfs64(buf)", arg3, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005014}
5015
nethercote85a456f2004-11-16 17:31:56 +00005016POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00005017{
nethercoteef0c7662004-11-06 15:38:43 +00005018 POST_MEM_WRITE( arg3, arg2 );
muellerd3502b62003-11-19 00:43:57 +00005019}
5020
nethercote85a456f2004-11-16 17:31:56 +00005021PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005022{
nethercote5a945af2004-11-14 18:37:07 +00005023 PRINT("sys_symlink ( %p, %p )",arg1,arg2);
5024 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00005025 PRE_MEM_RASCIIZ( "symlink(oldpath)", arg1 );
5026 PRE_MEM_RASCIIZ( "symlink(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005027}
5028
nethercote85a456f2004-11-16 17:31:56 +00005029PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005030{
nethercote2e1c37d2004-11-13 13:57:12 +00005031 PRINT("sys_stat64 ( %p, %p )",arg1,arg2);
5032 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005033 PRE_MEM_RASCIIZ( "stat64(file_name)", arg1 );
5034 PRE_MEM_WRITE( "stat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005035}
5036
nethercote85a456f2004-11-16 17:31:56 +00005037POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00005038{
nethercoteef0c7662004-11-06 15:38:43 +00005039 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005040}
5041
nethercote85a456f2004-11-16 17:31:56 +00005042PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005043{
nethercote2e1c37d2004-11-13 13:57:12 +00005044 PRINT("sys_fstat64 ( %d, %p )",arg1,arg2);
5045 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005046 PRE_MEM_WRITE( "fstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005047}
5048
nethercote85a456f2004-11-16 17:31:56 +00005049POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00005050{
nethercoteef0c7662004-11-06 15:38:43 +00005051 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005052}
5053
nethercote85a456f2004-11-16 17:31:56 +00005054PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00005055{
5056 /* time_t time(time_t *t); */
nethercotec6851dd2004-11-11 18:00:47 +00005057 PRINT("sys_time ( %p )",arg1);
5058 PRE_REG_READ1(long, "time", int *, t);
nethercote163c5e82004-11-17 18:42:20 +00005059 if (arg1 != 0) {
nethercotec6851dd2004-11-11 18:00:47 +00005060 PRE_MEM_WRITE( "time(t)", arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005061 }
5062}
5063
nethercote85a456f2004-11-16 17:31:56 +00005064POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005065{
nethercote163c5e82004-11-17 18:42:20 +00005066 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005067 POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005068 }
5069}
5070
nethercote85a456f2004-11-16 17:31:56 +00005071PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00005072{
nethercote9c311eb2004-11-12 18:20:12 +00005073 PRINT("sys_times ( %p )", arg1);
5074 PRE_REG_READ1(long, "times", struct tms *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005075 PRE_MEM_WRITE( "times(buf)", arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005076}
5077
nethercote85a456f2004-11-16 17:31:56 +00005078POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00005079{
nethercote163c5e82004-11-17 18:42:20 +00005080 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005081 POST_MEM_WRITE( arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005082 }
5083}
5084
nethercote85a456f2004-11-16 17:31:56 +00005085PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00005086{
nethercote9c311eb2004-11-12 18:20:12 +00005087 PRINT("sys_umask ( %d )", arg1);
5088 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00005089}
5090
nethercote85a456f2004-11-16 17:31:56 +00005091PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005092{
nethercotec6851dd2004-11-11 18:00:47 +00005093 PRINT("sys_unlink ( %p(%s) )", arg1,arg1);
5094 PRE_REG_READ1(long, "unlink", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00005095 PRE_MEM_RASCIIZ( "unlink(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00005096}
5097
nethercote85a456f2004-11-16 17:31:56 +00005098PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00005099{
nethercote1a1b9b72004-11-12 11:19:36 +00005100 PRINT("sys_newuname ( %p )", arg1);
5101 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005102 PRE_MEM_WRITE( "uname(buf)", arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005103}
5104
nethercote85a456f2004-11-16 17:31:56 +00005105POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005106{
nethercote163c5e82004-11-17 18:42:20 +00005107 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005108 POST_MEM_WRITE( arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005109 }
5110}
5111
nethercote85a456f2004-11-16 17:31:56 +00005112PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005113{
nethercote9a3beb92004-11-12 17:07:26 +00005114 PRINT("sys_utime ( %p, %p )", arg1,arg2);
5115 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005116 PRE_MEM_RASCIIZ( "utime(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005117 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005118 PRE_MEM_READ( "utime(buf)", arg2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00005119}
5120
nethercote85a456f2004-11-16 17:31:56 +00005121PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005122{
nethercotec6851dd2004-11-11 18:00:47 +00005123 PRINT("sys_waitpid ( %d, %p, %d )", arg1,arg2,arg3);
5124 PRE_REG_READ3(long, "waitpid",
5125 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005126
jsgf855d93d2003-10-13 22:26:55 +00005127 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005128 PRE_MEM_WRITE( "waitpid(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005129}
5130
nethercote85a456f2004-11-16 17:31:56 +00005131POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005132{
5133 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005134 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005135}
5136
nethercote85a456f2004-11-16 17:31:56 +00005137PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005138{
nethercote7f7e4d12004-11-15 12:28:58 +00005139 PRINT("sys_wait4 ( %d, %p, %d, %p )", arg1,arg2,arg3,arg4);
nethercote73b526f2004-10-31 18:48:21 +00005140 arg3 &= ~(__VKI_WCLONE | __VKI_WALL);
jsgf855d93d2003-10-13 22:26:55 +00005141
nethercote7f7e4d12004-11-15 12:28:58 +00005142 PRE_REG_READ4(long, "wait4",
5143 vki_pid_t, pid, unsigned int *, status, int, options,
5144 struct rusage *, rusage);
jsgf855d93d2003-10-13 22:26:55 +00005145 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005146 PRE_MEM_WRITE( "wait4(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005147 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005148 PRE_MEM_WRITE( "wait4(rusage)", arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005149}
5150
nethercote85a456f2004-11-16 17:31:56 +00005151POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005152{
5153 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005154 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005155 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005156 POST_MEM_WRITE( arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005157}
5158
nethercote85a456f2004-11-16 17:31:56 +00005159PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005160{
jsgf855d93d2003-10-13 22:26:55 +00005161 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005162 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00005163 PRINT("sys_writev ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
5164 PRE_REG_READ3(ssize_t, "writev",
5165 unsigned long, fd, const struct iovec *, vector,
5166 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00005167 if (!VG_(fd_allowed)(arg1, "writev", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005168 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005169 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005170 PRE_MEM_READ( "writev(vector)",
nethercote73b526f2004-10-31 18:48:21 +00005171 arg2, arg3 * sizeof(struct vki_iovec) );
nethercote163c5e82004-11-17 18:42:20 +00005172 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005173 /* ToDo: don't do any of the following if the vector is invalid */
5174 vec = (struct vki_iovec *)arg2;
5175 for (i = 0; i < (Int)arg3; i++)
5176 PRE_MEM_READ( "writev(vector[...])",
5177 (Addr)vec[i].iov_base, vec[i].iov_len );
5178 }
jsgf855d93d2003-10-13 22:26:55 +00005179 }
5180}
5181
nethercote85a456f2004-11-16 17:31:56 +00005182PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005183{
nethercoteac866b92004-11-15 20:23:15 +00005184 PRINT("sys_utimes ( %p, %p )", arg1,arg2);
nethercoteac866b92004-11-15 20:23:15 +00005185 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
nethercote38e0a9e2004-11-15 20:42:06 +00005186 PRE_MEM_RASCIIZ( "utimes(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005187 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005188 PRE_MEM_READ( "utimes(tvp)", arg2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005189}
5190
nethercote85a456f2004-11-16 17:31:56 +00005191PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005192{
nethercoteef0c7662004-11-06 15:38:43 +00005193 PRINT("sched_setaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005194 PRE_REG_READ3(long, "sched_setaffinity",
5195 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005196 PRE_MEM_READ( "sched_setaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005197}
5198
nethercote85a456f2004-11-16 17:31:56 +00005199PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005200{
nethercoteef0c7662004-11-06 15:38:43 +00005201 PRINT("sched_getaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005202 PRE_REG_READ3(long, "sched_getaffinity",
5203 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005204 PRE_MEM_WRITE( "sched_getaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005205}
5206
nethercote85a456f2004-11-16 17:31:56 +00005207POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005208{
njncf45fd42004-11-24 16:30:22 +00005209 POST_MEM_WRITE(arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005210}
5211
nethercote85a456f2004-11-16 17:31:56 +00005212PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005213{
nethercote2b0cae62004-11-12 14:57:34 +00005214 PRINT("sys_acct ( %p )", arg1);
5215 PRE_REG_READ1(long, "acct", const char *, filename);
nethercoteef0c7662004-11-06 15:38:43 +00005216 PRE_MEM_RASCIIZ( "acct(filename)", arg1 );
nethercote2bc5a212004-04-10 00:26:10 +00005217}
5218
nethercote85a456f2004-11-16 17:31:56 +00005219PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005220{
nethercote0df495a2004-11-11 16:38:21 +00005221 PRINT("sys_pause ( )");
5222 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005223}
5224
nethercotea3a2c142004-11-14 14:13:05 +00005225// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005226PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005227{
thughesc3e85df2004-11-15 09:27:24 +00005228 /* The C library interface to sigsuspend just takes a pointer to
5229 a signal mask but this system call has three arguments - the first
5230 two don't appear to be used by the kernel and are always passed as
5231 zero by glibc and the third is the first word of the signal mask
5232 so only 32 signals are supported.
5233
5234 In fact glibc normally uses rt_sigsuspend if it is available as
5235 that takes a pointer to the signal mask so supports more signals.
5236 */
thughesd8e00412004-11-14 19:44:25 +00005237 PRINT("sys_sigsuspend ( %d, %d, %d )", arg1,arg2,arg3 );
5238 PRE_REG_READ3(int, "sigsuspend",
5239 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005240 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005241}
5242
nethercotea3a2c142004-11-14 14:13:05 +00005243// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005244PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005245{
thughesc3e85df2004-11-15 09:27:24 +00005246 /* The C library interface to sigsuspend just takes a pointer to
5247 a signal mask but this system call has two arguments - a pointer
5248 to the mask and the number of bytes used by it. The kernel insists
5249 on the size being equal to sizeof(sigset_t) however and will just
5250 return EINVAL if it isn't.
5251 */
nethercotea3a2c142004-11-14 14:13:05 +00005252 PRINT("sys_rt_sigsuspend ( %p, %d )", arg1,arg2 );
5253 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
5254 if (arg1 != (Addr)NULL) {
5255 PRE_MEM_READ( "rt_sigsuspend(mask)", arg1, sizeof(vki_sigset_t) );
5256 }
5257}
jsgf855d93d2003-10-13 22:26:55 +00005258
nethercote85a456f2004-11-16 17:31:56 +00005259PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005260{
nethercoteac866b92004-11-15 20:23:15 +00005261 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
5262 arg1,arg2,arg3,(ULong)arg4);
5263 PRE_REG_READ4(long, "rt_sigtimedwait",
5264 const vki_sigset_t *, set, vki_siginfo_t *, info,
5265 const struct timespec *, timeout, vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005266 if (arg1 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005267 PRE_MEM_READ( "rt_sigtimedwait(set)", arg1, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005268 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005269 PRE_MEM_WRITE( "rt_sigtimedwait(info)", arg2, sizeof(vki_siginfo_t) );
5270 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
5271 arg4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005272}
5273
nethercote85a456f2004-11-16 17:31:56 +00005274POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005275{
nethercote163c5e82004-11-17 18:42:20 +00005276 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005277 POST_MEM_WRITE( arg2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005278}
5279
nethercote85a456f2004-11-16 17:31:56 +00005280PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005281{
nethercote92b2fd52004-11-16 16:15:41 +00005282 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", arg1, arg2, arg3);
5283 PRE_REG_READ3(long, "rt_sigqueueinfo",
5284 int, pid, int, sig, vki_siginfo_t *, uinfo);
nethercote163c5e82004-11-17 18:42:20 +00005285 if (arg2 != 0)
nethercote92b2fd52004-11-16 16:15:41 +00005286 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", arg3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005287}
5288
nethercote85a456f2004-11-16 17:31:56 +00005289POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005290{
5291 if (res >= 0 &&
5292 arg2 != 0 &&
5293 !VG_(is_sig_ign)(arg2) &&
nethercote73b526f2004-10-31 18:48:21 +00005294 !VG_(sigismember)(&tst->eff_sig_mask, arg2) &&
jsgf855d93d2003-10-13 22:26:55 +00005295 arg1 == VG_(getpid)()) {
5296 VG_(proxy_waitsig)();
5297 }
5298}
5299
nethercotec8734892004-11-10 18:57:37 +00005300#define SIGNAL_SIMULATION 1
5301
5302#if SIGNAL_SIMULATION
5303#define SIG_SIM Special
5304#else
5305#define SIG_SIM 0
5306#endif
5307
nethercoteb77dee62004-11-16 17:13:24 +00005308// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005309PRE(sys_sigaltstack, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005310{
5311 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
nethercoteef0c7662004-11-06 15:38:43 +00005312 PRINT("sigaltstack ( %p, %p )",arg1,arg2);
nethercoteb77dee62004-11-16 17:13:24 +00005313 PRE_REG_READ2(int, "sigaltstack",
5314 const vki_stack_t *, ss, vki_stack_t *, oss);
nethercote163c5e82004-11-17 18:42:20 +00005315 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005316 PRE_MEM_READ( "sigaltstack(ss)", arg1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005317 }
nethercote163c5e82004-11-17 18:42:20 +00005318 if (arg2 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005319 PRE_MEM_WRITE( "sigaltstack(oss)", arg2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005320 }
5321
5322 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005323 VG_(do_sys_sigaltstack) (tid);
jsgf855d93d2003-10-13 22:26:55 +00005324}
5325
nethercote85a456f2004-11-16 17:31:56 +00005326POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005327{
nethercote163c5e82004-11-17 18:42:20 +00005328 if (res == 0 && arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005329 POST_MEM_WRITE( arg2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005330}
5331
nethercote71f05f32004-11-12 18:49:27 +00005332// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005333PRE(sys_sigaction, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005334{
nethercote71f05f32004-11-12 18:49:27 +00005335 PRINT("sys_sigaction ( %d, %p, %p )", arg1,arg2,arg3);
5336 PRE_REG_READ3(int, "sigaction",
5337 int, signum, const struct old_sigaction *, act,
5338 struct old_sigaction *, oldact)
nethercote163c5e82004-11-17 18:42:20 +00005339 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005340 PRE_MEM_READ( "sigaction(act)", arg2, sizeof(struct vki_old_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005341 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005342 PRE_MEM_WRITE( "sigaction(oldact)", arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005343
5344 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005345 VG_(do_sys_sigaction)(tid);
jsgf855d93d2003-10-13 22:26:55 +00005346}
5347
nethercote85a456f2004-11-16 17:31:56 +00005348POST(sys_sigaction)
jsgf855d93d2003-10-13 22:26:55 +00005349{
nethercote163c5e82004-11-17 18:42:20 +00005350 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005351 POST_MEM_WRITE( arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005352}
5353
nethercote686b5db2004-11-14 13:42:51 +00005354// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005355PRE(sys_rt_sigaction, SIG_SIM)
nethercote686b5db2004-11-14 13:42:51 +00005356{
5357 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", arg1,arg2,arg3,arg4);
5358 PRE_REG_READ4(long, "rt_sigaction",
5359 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005360 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005361
nethercote163c5e82004-11-17 18:42:20 +00005362 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005363 PRE_MEM_READ( "rt_sigaction(act)", arg2, sizeof(struct vki_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005364 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005365 PRE_MEM_WRITE( "rt_sigaction(oldact)", arg3, sizeof(struct vki_sigaction));
5366
5367 // XXX: hmm... doesn't seem quite right...
5368 if (SIGNAL_SIMULATION)
5369 VG_(do_sys_sigaction)(tid);
5370}
5371
nethercote85a456f2004-11-16 17:31:56 +00005372POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005373{
nethercote163c5e82004-11-17 18:42:20 +00005374 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005375 POST_MEM_WRITE( arg3, sizeof(struct vki_sigaction));
5376}
jsgf855d93d2003-10-13 22:26:55 +00005377
nethercote85a456f2004-11-16 17:31:56 +00005378PRE(sys_sigprocmask, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005379{
nethercote7fbe08a2004-11-15 19:03:27 +00005380 PRINT("sys_sigprocmask ( %d, %p, %p )",arg1,arg2,arg3);
5381 PRE_REG_READ3(long, "sigprocmask",
5382 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
nethercote163c5e82004-11-17 18:42:20 +00005383 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005384 PRE_MEM_READ( "sigprocmask(set)", arg2, sizeof(vki_old_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005385 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005386 PRE_MEM_WRITE( "sigprocmask(oldset)", arg3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005387
nethercote7fbe08a2004-11-15 19:03:27 +00005388 if (SIGNAL_SIMULATION) {
5389 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5390 // vki_sigset_t params.
5391 vki_old_sigset_t* set = (vki_old_sigset_t*)arg2;
5392 vki_old_sigset_t* oldset = (vki_old_sigset_t*)arg3;
5393 vki_sigset_t bigger_set;
5394 vki_sigset_t bigger_oldset;
5395
5396 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5397 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
5398
5399 VG_(do_sys_sigprocmask) ( tid,
5400 arg1 /*how*/,
5401 &bigger_set,
5402 &bigger_oldset );
5403
thughes1112cab2004-11-16 12:08:45 +00005404 if (oldset)
nethercote330abb52004-11-16 12:58:04 +00005405 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005406 }
5407}
5408
nethercote85a456f2004-11-16 17:31:56 +00005409POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005410{
nethercote163c5e82004-11-17 18:42:20 +00005411 if (res == 0 && arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005412 POST_MEM_WRITE( arg3, sizeof(vki_old_sigset_t));
5413}
5414
nethercote85a456f2004-11-16 17:31:56 +00005415PRE(sys_rt_sigprocmask, SIG_SIM)
nethercote7fbe08a2004-11-15 19:03:27 +00005416{
5417 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",arg1,arg2,arg3,(ULong)arg4);
5418 PRE_REG_READ4(long, "rt_sigprocmask",
5419 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5420 vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005421 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005422 PRE_MEM_READ( "rt_sigprocmask(set)", arg2, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005423 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005424 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", arg3, sizeof(vki_sigset_t));
5425
5426 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
5427 if (sizeof(vki_sigset_t) != arg4)
5428 set_result( -VKI_EMFILE );
5429 else if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005430 VG_(do_sys_sigprocmask) ( tid,
jsgf855d93d2003-10-13 22:26:55 +00005431 arg1 /*how*/,
nethercote73b526f2004-10-31 18:48:21 +00005432 (vki_sigset_t*) arg2,
5433 (vki_sigset_t*) arg3 );
jsgf855d93d2003-10-13 22:26:55 +00005434}
5435
nethercote85a456f2004-11-16 17:31:56 +00005436POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005437{
nethercote163c5e82004-11-17 18:42:20 +00005438 if (res == 0 && arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005439 POST_MEM_WRITE( arg3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005440}
5441
nethercote85a456f2004-11-16 17:31:56 +00005442PRE(sys_sigpending, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00005443{
nethercote17258dc2004-11-12 19:55:08 +00005444 PRINT( "sys_sigpending ( %p )", arg1 );
5445 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
5446 PRE_MEM_WRITE( "sigpending(set)", arg1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005447}
5448
nethercote85a456f2004-11-16 17:31:56 +00005449POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005450{
nethercotea6395d12004-11-15 19:23:46 +00005451 POST_MEM_WRITE( arg1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005452}
5453
nethercote85a456f2004-11-16 17:31:56 +00005454PRE(sys_rt_sigpending, NBRunInLWP)
nethercotea6395d12004-11-15 19:23:46 +00005455{
nethercote38e0a9e2004-11-15 20:42:06 +00005456 PRINT( "sys_rt_sigpending ( %p )", arg1 );
nethercotea6395d12004-11-15 19:23:46 +00005457 PRE_REG_READ2(long, "rt_sigpending",
5458 vki_sigset_t *, set, vki_size_t, sigsetsize);
nethercote38e0a9e2004-11-15 20:42:06 +00005459 PRE_MEM_WRITE( "rt_sigpending(set)", arg1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005460}
5461
nethercote85a456f2004-11-16 17:31:56 +00005462POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005463{
5464 POST_MEM_WRITE( arg1, sizeof(vki_sigset_t) ) ;
5465}
jsgf855d93d2003-10-13 22:26:55 +00005466
nethercote85a456f2004-11-16 17:31:56 +00005467PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005468{
nethercote330abb52004-11-16 12:58:04 +00005469 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
5470 arg1,arg1,arg2,(ULong)arg3,arg4);
5471 PRE_REG_READ4(long, "mq_open",
5472 const char *, name, int, oflag, vki_mode_t, mode,
5473 struct mq_attr *, attr);
nethercoteef0c7662004-11-06 15:38:43 +00005474 PRE_MEM_RASCIIZ( "mq_open(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005475 if ((arg2 & VKI_O_CREAT) != 0 && arg4 != 0) {
5476 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg4;
nethercoteef0c7662004-11-06 15:38:43 +00005477 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005478 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005479 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005480 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5481 }
5482}
5483
nethercote85a456f2004-11-16 17:31:56 +00005484POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005485{
nethercote3d5e9102004-11-17 18:22:38 +00005486 if (!VG_(fd_allowed)(res, "mq_open", tid, True)) {
thughes8579b102004-08-14 18:52:27 +00005487 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00005488 set_result( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005489 } else {
5490 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00005491 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
thughes8579b102004-08-14 18:52:27 +00005492 }
thughes8579b102004-08-14 18:52:27 +00005493}
5494
nethercote85a456f2004-11-16 17:31:56 +00005495PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005496{
nethercote330abb52004-11-16 12:58:04 +00005497 PRINT("sys_mq_unlink ( %p(%s) )", arg1,arg1);
5498 PRE_REG_READ1(long, "mq_unlink", const char *, name);
nethercoteef0c7662004-11-06 15:38:43 +00005499 PRE_MEM_RASCIIZ( "mq_unlink(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005500}
5501
nethercote85a456f2004-11-16 17:31:56 +00005502PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005503{
nethercote330abb52004-11-16 12:58:04 +00005504 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
5505 arg1,arg2,(ULong)arg3,arg4,arg5);
5506 PRE_REG_READ5(long, "mq_timedsend",
5507 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5508 unsigned int, msg_prio, const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005509 if (!VG_(fd_allowed)(arg1, "mq_timedsend", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005510 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005511 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005512 PRE_MEM_READ( "mq_timedsend(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005513 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005514 PRE_MEM_READ( "mq_timedsend(abs_timeout)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00005515 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005516 }
5517}
5518
nethercote85a456f2004-11-16 17:31:56 +00005519PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005520{
nethercote330abb52004-11-16 12:58:04 +00005521 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
5522 arg1,arg2,(ULong)arg3,arg4,arg5);
5523 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5524 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5525 unsigned int *, msg_prio,
5526 const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005527 if (!VG_(fd_allowed)(arg1, "mq_timedreceive", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005528 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005529 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005530 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005531 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005532 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
thughes8579b102004-08-14 18:52:27 +00005533 arg4, sizeof(unsigned int) );
5534 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005535 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
nethercote73b526f2004-10-31 18:48:21 +00005536 arg5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005537 }
5538}
5539
nethercote85a456f2004-11-16 17:31:56 +00005540POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005541{
nethercoteef0c7662004-11-06 15:38:43 +00005542 POST_MEM_WRITE( arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005543 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005544 POST_MEM_WRITE( arg4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005545}
5546
nethercote85a456f2004-11-16 17:31:56 +00005547PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005548{
nethercote330abb52004-11-16 12:58:04 +00005549 PRINT("sys_mq_notify( %d, %p )", arg1,arg2 );
5550 PRE_REG_READ2(long, "mq_notify",
5551 vki_mqd_t, mqdes, const struct sigevent *, notification);
nethercote3d5e9102004-11-17 18:22:38 +00005552 if (!VG_(fd_allowed)(arg1, "mq_notify", tid, False))
nethercote35122912004-10-18 17:00:30 +00005553 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005554 else if (arg2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005555 PRE_MEM_READ( "mq_notify(notification)",
5556 arg2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005557}
5558
nethercote85a456f2004-11-16 17:31:56 +00005559PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005560{
nethercote330abb52004-11-16 12:58:04 +00005561 PRINT("sys_mq_getsetattr( %d, %p, %p )", arg1,arg2,arg3 );
5562 PRE_REG_READ3(long, "mq_getsetattr",
5563 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5564 struct mq_attr *, omqstat);
nethercote3d5e9102004-11-17 18:22:38 +00005565 if (!VG_(fd_allowed)(arg1, "mq_getsetattr", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005566 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005567 } else {
5568 if (arg2 != 0) {
5569 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg2;
nethercoteef0c7662004-11-06 15:38:43 +00005570 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005571 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5572 }
5573 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005574 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", arg3,
thughes8579b102004-08-14 18:52:27 +00005575 sizeof(struct vki_mq_attr) );
5576 }
5577}
5578
nethercote85a456f2004-11-16 17:31:56 +00005579POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005580{
5581 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005582 POST_MEM_WRITE( arg3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005583}
5584
nethercote85a456f2004-11-16 17:31:56 +00005585PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005586{
nethercote92b2fd52004-11-16 16:15:41 +00005587 PRINT("sys_timer_create( %d, %p, %p )", arg1,arg2,arg3);
5588 PRE_REG_READ3(long, "timer_create",
5589 vki_clockid_t, clockid, struct sigevent *, evp,
5590 vki_timer_t *, timerid);
thughese1a925d2004-08-30 19:50:02 +00005591 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005592 PRE_MEM_READ( "timer_create(evp)", arg2, sizeof(struct vki_sigevent) );
5593 PRE_MEM_WRITE( "timer_create(timerid)", arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005594}
5595
nethercote85a456f2004-11-16 17:31:56 +00005596POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005597{
nethercoteef0c7662004-11-06 15:38:43 +00005598 POST_MEM_WRITE( arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005599}
5600
nethercote85a456f2004-11-16 17:31:56 +00005601PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005602{
nethercote92b2fd52004-11-16 16:15:41 +00005603 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)arg1,arg2,arg3,arg4);
5604 PRE_REG_READ4(long, "timer_settime",
5605 vki_timer_t, timerid, int, flags,
5606 const struct itimerspec *, value,
5607 struct itimerspec *, ovalue);
nethercoteef0c7662004-11-06 15:38:43 +00005608 PRE_MEM_READ( "timer_settime(value)", arg3,
thughese1a925d2004-08-30 19:50:02 +00005609 sizeof(struct vki_itimerspec) );
5610 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005611 PRE_MEM_WRITE( "timer_settime(ovalue)", arg4,
thughese1a925d2004-08-30 19:50:02 +00005612 sizeof(struct vki_itimerspec) );
5613}
5614
nethercote85a456f2004-11-16 17:31:56 +00005615POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005616{
5617 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005618 POST_MEM_WRITE( arg4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005619}
5620
nethercote85a456f2004-11-16 17:31:56 +00005621PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005622{
nethercote92b2fd52004-11-16 16:15:41 +00005623 PRINT("sys_timer_gettime( %lld, %p )", (ULong)arg1,arg2);
5624 PRE_REG_READ2(long, "timer_gettime",
5625 vki_timer_t, timerid, struct itimerspec *, value);
nethercoteef0c7662004-11-06 15:38:43 +00005626 PRE_MEM_WRITE( "timer_gettime(value)", arg2,
thughese1a925d2004-08-30 19:50:02 +00005627 sizeof(struct vki_itimerspec));
5628}
5629
nethercote85a456f2004-11-16 17:31:56 +00005630POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005631{
nethercoteef0c7662004-11-06 15:38:43 +00005632 POST_MEM_WRITE( arg2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005633}
5634
nethercote85a456f2004-11-16 17:31:56 +00005635PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005636{
nethercote92b2fd52004-11-16 16:15:41 +00005637 PRINT("sys_timer_getoverrun( %p )", arg1);
5638 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005639}
5640
nethercote85a456f2004-11-16 17:31:56 +00005641PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005642{
nethercote92b2fd52004-11-16 16:15:41 +00005643 PRINT("sys_timer_delete( %p )", arg1);
5644 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005645}
5646
nethercote85a456f2004-11-16 17:31:56 +00005647PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005648{
nethercote92b2fd52004-11-16 16:15:41 +00005649 PRINT("sys_clock_settime( %d, %p )", arg1,arg2);
5650 PRE_REG_READ2(long, "clock_settime",
5651 vki_clockid_t, clk_id, const struct timespec *, tp);
5652 PRE_MEM_READ( "clock_settime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005653}
5654
nethercote85a456f2004-11-16 17:31:56 +00005655PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005656{
nethercote92b2fd52004-11-16 16:15:41 +00005657 PRINT("sys_clock_gettime( %d, %p )" , arg1,arg2);
5658 PRE_REG_READ2(long, "clock_gettime",
5659 vki_clockid_t, clk_id, struct timespec *, tp);
5660 PRE_MEM_WRITE( "clock_gettime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005661}
5662
nethercote85a456f2004-11-16 17:31:56 +00005663POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005664{
nethercote92b2fd52004-11-16 16:15:41 +00005665 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005666}
5667
nethercote85a456f2004-11-16 17:31:56 +00005668PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005669{
nethercote92b2fd52004-11-16 16:15:41 +00005670 PRINT("sys_clock_getres( %d, %p )" , arg1,arg2);
5671 // Nb: we can't use "res" as the param name because that's a macro
5672 // defined above!
5673 PRE_REG_READ2(long, "clock_getres",
5674 vki_clockid_t, clk_id, struct timespec *, cres);
5675 PRE_MEM_WRITE( "clock_getres(cres)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005676}
5677
nethercote85a456f2004-11-16 17:31:56 +00005678POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005679{
nethercote92b2fd52004-11-16 16:15:41 +00005680 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005681}
5682
nethercote4fa681f2004-11-08 17:51:39 +00005683
5684/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005685 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005686 ------------------------------------------------------------------ */
5687
nethercote85a456f2004-11-16 17:31:56 +00005688static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005689static void bad_before(ThreadId tid, ThreadState *tst)
5690{
5691 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005692 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005693 if (VG_(clo_verbosity) > 1) {
5694 ExeContext *ec = VG_(get_ExeContext)(tid);
5695 VG_(pp_ExeContext)(ec);
5696 }
jsgf855d93d2003-10-13 22:26:55 +00005697 VG_(message)
5698 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5699 VG_(message)
5700 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5701
nethercote35122912004-10-18 17:00:30 +00005702 set_result( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005703}
5704
nethercote8ff888f2004-11-17 17:11:45 +00005705static const struct SyscallTableEntry bad_sys =
5706 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005707
nethercote4fa681f2004-11-08 17:51:39 +00005708
jsgf855d93d2003-10-13 22:26:55 +00005709Bool VG_(pre_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00005710{
sewardj018f7622002-05-15 21:13:39 +00005711 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005712 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005713 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00005714 Bool isSpecial = False;
5715 Bool mayBlock = False;
5716 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00005717 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00005718
njn25e49d8e72002-09-23 09:36:25 +00005719 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00005720
jsgf855d93d2003-10-13 22:26:55 +00005721 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00005722
jsgf855d93d2003-10-13 22:26:55 +00005723 /* Convert vfork to fork, since we can't handle it otherwise. */
nethercote427e9512004-08-23 16:36:09 +00005724 if (SYSNO == __NR_vfork)
5725 SYSNO = __NR_fork;
sewardjde4a1d02002-03-22 01:27:54 +00005726
nethercote44d9aaa2004-11-04 19:38:14 +00005727 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00005728
5729 if (tst->syscallno != -1)
5730 VG_(printf)("tid %d has syscall %d\n", tst->tid, tst->syscallno);
5731
nethercote1c2a3f52004-11-12 20:38:34 +00005732 vg_assert(tst->syscallno == -1); // should be no current syscall
5733 vg_assert(tst->status == VgTs_Runnable); // should be runnable */
jsgf855d93d2003-10-13 22:26:55 +00005734
5735 /* the syscall no is in %eax. For syscalls with <= 6 args,
5736 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
5737 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00005738 containing the args.
5739
5740 The result is returned in %eax. If this value >= 0, the call
5741 succeeded, and this is the return value. If < 0, it failed, and
5742 the negation of this value is errno. To be more specific,
5743 if res is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
5744 (kernel 2.4.9 sources, include/asm-i386/errno.h)
5745 then it indicates an error. Otherwise it doesn't.
5746
5747 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
5748 (inclusive?) indicate error returns. Not sure where the -4095
5749 comes from.
5750 */
5751
jsgf855d93d2003-10-13 22:26:55 +00005752 tst->syscallno = syscallno;
fitzhardingef0f911c2003-11-09 09:51:33 +00005753 vg_assert(tst->status == VgTs_Runnable);
sewardjde4a1d02002-03-22 01:27:54 +00005754
nethercote8ff888f2004-11-17 17:11:45 +00005755 if (syscallno < VGA_(syscall_table_size) &&
5756 VGA_(syscall_table)[syscallno].before != NULL)
5757 {
5758 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005759 } else {
5760 sys = &bad_sys;
nethercotec8734892004-11-10 18:57:37 +00005761 }
nethercote85a456f2004-11-16 17:31:56 +00005762 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00005763
nethercote1fe55d62004-11-12 11:02:00 +00005764 {
5765 Bool nbrunInLWP = ( flags & NBRunInLWP ? True : False );
5766 isSpecial = ( flags & Special ? True : False );
5767 mayBlock = ( flags & MayBlock ? True : False );
5768 runInLWP = mayBlock || nbrunInLWP;
5769 // At most one of these should be true
5770 vg_assert( isSpecial + mayBlock + nbrunInLWP <= 1 );
5771 }
nethercotec8734892004-11-10 18:57:37 +00005772
5773 tst->sys_flags = flags;
5774
jsgf855d93d2003-10-13 22:26:55 +00005775 /* Do any pre-syscall actions */
5776 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00005777 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00005778 TL_(pre_syscall)(tid, syscallno);
njn4be0a692004-11-22 18:10:36 +00005779 VGP_POPCC(VgpToolSysWrap);
jsgf855d93d2003-10-13 22:26:55 +00005780 }
5781
nethercoteef0c7662004-11-06 15:38:43 +00005782 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
5783 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00005784 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00005785 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00005786
nethercotec8734892004-11-10 18:57:37 +00005787 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00005788 /* "Special" syscalls are implemented by Valgrind internally,
5789 and do not generate real kernel calls. The expectation,
5790 therefore, is that the "before" function not only does the
5791 appropriate tests, but also performs the syscall itself and
5792 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00005793 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00005794
5795 (sys->before)(tst->tid, tst);
5796
nethercotec8734892004-11-10 18:57:37 +00005797 vg_assert(tst->sys_flags == flags);
thughesbaa46e52004-07-29 17:44:23 +00005798
nethercoteef0c7662004-11-06 15:38:43 +00005799 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005800 syscall_done = True;
5801 } else {
5802 (sys->before)(tst->tid, tst);
5803
nethercote44d9aaa2004-11-04 19:38:14 +00005804 if ((Word)res <= 0) {
jsgf855d93d2003-10-13 22:26:55 +00005805 /* "before" decided the syscall wasn't viable, so don't do
5806 anything - just pretend the syscall happened. */
nethercoteef0c7662004-11-06 15:38:43 +00005807 PRINT(" ==> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005808 syscall_done = True;
nethercote1fe55d62004-11-12 11:02:00 +00005809 } else if (runInLWP) {
fitzhardinge33730212003-11-10 21:21:00 +00005810 /* Issue to worker. If we're waiting on the syscall because
5811 it's in the hands of the ProxyLWP, then set the thread
5812 state to WaitSys. */
nethercoteef0c7662004-11-06 15:38:43 +00005813 PRINT(" --> ...\n");
fitzhardinge33730212003-11-10 21:21:00 +00005814 tst->status = VgTs_WaitSys;
jsgf855d93d2003-10-13 22:26:55 +00005815 VG_(sys_issue)(tid);
5816 } else {
5817 /* run the syscall directly */
nethercotea4670f62004-08-23 16:39:42 +00005818 res = VG_(do_syscall)(syscallno, arg1, arg2, arg3, arg4, arg5, arg6);
nethercoteef0c7662004-11-06 15:38:43 +00005819 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005820 syscall_done = True;
5821 }
5822 }
5823
5824 VGP_POPCC(VgpCoreSysWrap);
5825
fitzhardinge33730212003-11-10 21:21:00 +00005826 vg_assert(( syscall_done && tst->status == VgTs_Runnable) ||
5827 (!syscall_done && tst->status == VgTs_WaitSys ));
fitzhardingef0f911c2003-11-09 09:51:33 +00005828
jsgf855d93d2003-10-13 22:26:55 +00005829 return syscall_done;
5830}
5831
nethercote85cdd342004-08-01 22:36:40 +00005832static void restart_syscall(ThreadId tid)
5833{
5834 ThreadState* tst;
5835 tst = VG_(get_ThreadState)(tid);
5836
5837 vg_assert(tst != NULL);
5838 vg_assert(tst->status == VgTs_WaitSys);
5839 vg_assert(tst->syscallno != -1);
5840
nethercote427e9512004-08-23 16:36:09 +00005841 SYSNO = tst->syscallno;
nethercote41c75da2004-10-18 15:34:14 +00005842 VGA_(restart_syscall)(&tst->arch);
nethercote85cdd342004-08-01 22:36:40 +00005843}
jsgf855d93d2003-10-13 22:26:55 +00005844
fitzhardinge31ba9052004-01-16 02:15:23 +00005845void VG_(post_syscall) ( ThreadId tid, Bool restart )
jsgf855d93d2003-10-13 22:26:55 +00005846{
5847 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005848 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005849 const struct SyscallTableEntry *sys;
nethercotec8734892004-11-10 18:57:37 +00005850 Bool isSpecial = False;
fitzhardinge31ba9052004-01-16 02:15:23 +00005851 Bool restarted = False;
jsgf855d93d2003-10-13 22:26:55 +00005852
5853 VGP_PUSHCC(VgpCoreSysWrap);
5854
5855 tst = VG_(get_ThreadState)(tid);
nethercoteef0c7662004-11-06 15:38:43 +00005856 vg_assert(tst->tid == tid);
jsgf855d93d2003-10-13 22:26:55 +00005857
nethercote996901a2004-08-03 13:29:09 +00005858 /* Tell the tool about the syscall return value */
nethercote427e9512004-08-23 16:36:09 +00005859 SET_SYSCALL_RETVAL(tst->tid, res);
jsgf855d93d2003-10-13 22:26:55 +00005860
5861 syscallno = tst->syscallno;
jsgf855d93d2003-10-13 22:26:55 +00005862
5863 vg_assert(syscallno != -1); /* must be a current syscall */
jsgf855d93d2003-10-13 22:26:55 +00005864
nethercote8ff888f2004-11-17 17:11:45 +00005865 if (syscallno < VGA_(syscall_table_size) &&
5866 VGA_(syscall_table)[syscallno].before != NULL)
5867 {
5868 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005869 } else {
5870 sys = &bad_sys;
jsgf855d93d2003-10-13 22:26:55 +00005871 }
nethercote85a456f2004-11-16 17:31:56 +00005872 flags = *(sys->flags_ptr);
nethercotec8734892004-11-10 18:57:37 +00005873
5874 isSpecial = flags & Special;
fitzhardingef0f911c2003-11-09 09:51:33 +00005875
nethercote427e9512004-08-23 16:36:09 +00005876 if (res == -VKI_ERESTARTSYS) {
fitzhardinge31ba9052004-01-16 02:15:23 +00005877 /* Applications never expect to see this, so we should either
5878 restart the syscall or fail it with EINTR, depending on what
5879 our caller wants. Generally they'll want to restart, but if
5880 client set the signal state to not restart, then we fail with
5881 EINTR. Either way, ERESTARTSYS means the syscall made no
5882 progress, and so can be failed or restarted without
5883 consequence. */
5884 if (0)
5885 VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
5886 syscallno, restart);
5887
5888 if (restart) {
5889 restarted = True;
nethercote85cdd342004-08-01 22:36:40 +00005890 restart_syscall(tid);
fitzhardinge31ba9052004-01-16 02:15:23 +00005891 } else
nethercotea4670f62004-08-23 16:39:42 +00005892 res = -VKI_EINTR;
fitzhardinge31ba9052004-01-16 02:15:23 +00005893 }
5894
5895 if (!restarted) {
thughesbaa46e52004-07-29 17:44:23 +00005896 if (sys->after != NULL &&
nethercote427e9512004-08-23 16:36:09 +00005897 ((tst->sys_flags & PostOnFail) != 0 || !VG_(is_kerror)(res)))
fitzhardinge31ba9052004-01-16 02:15:23 +00005898 (sys->after)(tst->tid, tst);
5899
5900 /* Do any post-syscall actions
5901
5902 NOTE: this is only called if the syscall completed. If the
5903 syscall was restarted, then it will call the Tool's
5904 pre_syscall again, without calling post_syscall (ie, more
5905 pre's than post's)
5906 */
5907 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00005908 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00005909 TL_(post_syscall)(tid, syscallno, res);
njn4be0a692004-11-22 18:10:36 +00005910 VGP_POPCC(VgpToolSysWrap);
fitzhardinge31ba9052004-01-16 02:15:23 +00005911 }
fitzhardingee1c06d82003-10-30 07:21:44 +00005912 }
5913
jsgf855d93d2003-10-13 22:26:55 +00005914 tst->status = VgTs_Runnable; /* runnable again */
fitzhardinge31ba9052004-01-16 02:15:23 +00005915 tst->syscallno = -1; /* no current syscall */
sewardj2e93c502002-04-12 11:12:52 +00005916
njn25e49d8e72002-09-23 09:36:25 +00005917 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00005918}
5919
nethercote427e9512004-08-23 16:36:09 +00005920#undef SYSNO
5921#undef res
5922#undef arg1
5923#undef arg2
5924#undef arg3
5925#undef arg4
5926#undef arg5
5927#undef arg6
5928
sewardjde4a1d02002-03-22 01:27:54 +00005929/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00005930/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005931/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00005932