blob: c3701cf9f7525622d1c5e51ff4241e7a664db2ec [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) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000861 SK_(pre_mem_write) ( Vg_CoreSysCall,
862 tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000863 }
864 }
865}
866
867static
njn72718642003-07-24 08:45:32 +0000868void buf_and_len_post_check( ThreadId tid, Int res,
njn25e49d8e72002-09-23 09:36:25 +0000869 Addr buf_p, Addr buflen_p, Char* s )
870{
fitzhardinge98abfc72003-12-16 02:05:15 +0000871 if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000872 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000873 if (buflen_out > 0 && buf_p != (Addr)NULL) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000874 SK_(post_mem_write) ( buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000875 }
876 }
877}
878
879/* ---------------------------------------------------------------------
880 Data seg end, for brk()
881 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000882
fitzhardinge98abfc72003-12-16 02:05:15 +0000883static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000884{
fitzhardinge98abfc72003-12-16 02:05:15 +0000885 Addr ret = VG_(brk_limit);
886 static const Bool debug = False;
887 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000888 Addr current, newaddr;
889
fitzhardinge98abfc72003-12-16 02:05:15 +0000890
891 if (debug)
892 VG_(printf)("do_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
893 VG_(brk_base), VG_(brk_limit), newbrk);
894
895 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
896 return VG_(brk_limit);
897
898 /* brk isn't allowed to grow over anything else */
899 seg = VG_(find_segment)(VG_(brk_limit));
900
901 vg_assert(seg != NULL);
902
njn25e49d8e72002-09-23 09:36:25 +0000903 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000904 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
905 VG_(brk_limit), seg->addr, seg->addr+seg->len);
906 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit) <= (seg->addr + seg->len));
907
908 seg = VG_(next_segment)(seg);
909 if (seg != NULL && newbrk > seg->addr)
910 return VG_(brk_limit);
911
nethercotece471262004-08-25 13:43:44 +0000912 current = PGROUNDUP(VG_(brk_limit));
913 newaddr = PGROUNDUP(newbrk);
914 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000915
916 /* new brk in a new page - fix the mappings */
917 if (newbrk > VG_(brk_limit)) {
918
919 if (debug)
920 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
921 current, newaddr, newaddr-current);
922
923 if (newaddr == current) {
924 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000925 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
926 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
927 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
928 SF_FIXED|SF_BRK, -1, 0))
929 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000930 ret = newbrk;
931 }
932 } else {
933 vg_assert(newbrk < VG_(brk_limit));
934
935 if (debug)
936 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
937 current, newaddr, current-newaddr);
938
939 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000940 int res = VG_(munmap)((void *)newaddr, current - newaddr);
941 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000942 }
943 ret = newbrk;
944 }
945 } else
946 ret = newbrk;
947
948 VG_(brk_limit) = ret;
949
950 return ret;
951}
952
953
njn25e49d8e72002-09-23 09:36:25 +0000954/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000955 Vet file descriptors for sanity
956 ------------------------------------------------------------------ */
957
958/* Return true if we're allowed to use or create this fd */
nethercote3d5e9102004-11-17 18:22:38 +0000959Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000960{
thughesad1c9562004-06-26 11:27:52 +0000961 if (fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) {
jsewardd9320a42003-12-12 06:40:05 +0000962 VG_(message)(Vg_UserMsg,
963 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000964 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000965 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000966 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000967 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000968 if (VG_(clo_verbosity) > 1) {
969 ExeContext *ec = VG_(get_ExeContext)(tid);
970 VG_(pp_ExeContext)(ec);
971 }
972 return False;
973 }
thughesad1c9562004-06-26 11:27:52 +0000974 else if (soft && fd >= VG_(fd_soft_limit)) {
975 return False;
976 }
jsgf855d93d2003-10-13 22:26:55 +0000977 return True;
978}
979
980
981/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +0000982 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +0000983 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000984
nethercote4fa681f2004-11-08 17:51:39 +0000985/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +0000986 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +0000987 names like sys_write(); a few have names like old_mmap(). See the
nethercote8ff888f2004-11-17 17:11:45 +0000988 comment for VGA_(syscall_table)[] for important info about the __NR_foo
989 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +0000990
nethercote92b2fd52004-11-16 16:15:41 +0000991 Some notes about names used for syscalls and args:
992 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
993 ambiguity.
994
995 - For error messages, we generally use a somewhat generic name
996 for the syscall (eg. "write" rather than "sys_write"). This should be
997 good enough for the average user to understand what is happening,
998 without confusing them with names like "sys_write".
999
1000 - Also, for error messages the arg names are mostly taken from the man
1001 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001002 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001003 for the same reason -- a user presented with a "bogus foo(bar)" arg
1004 will most likely look at the "foo" man page to see which is the "bar"
1005 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001006
nethercote9c311eb2004-11-12 18:20:12 +00001007 Note that we use our own vki_* types. The one exception is in
1008 PRE_REG_READn calls, where pointer types haven't been changed, because
1009 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1010 be visible.
1011
nethercote4fa681f2004-11-08 17:51:39 +00001012 XXX: some of these are arch-specific, and should be factored out.
1013*/
1014
nethercotec8734892004-11-10 18:57:37 +00001015#define Special (1 << 0)
1016#define MayBlock (1 << 1)
nethercote1fe55d62004-11-12 11:02:00 +00001017#define NBRunInLWP (1 << 2) // non-blocking, but must run in LWP context
1018#define PostOnFail (1 << 3)
jsgf855d93d2003-10-13 22:26:55 +00001019
nethercote85a456f2004-11-16 17:31:56 +00001020#define PRE(x,f) \
nethercote8ff888f2004-11-17 17:11:45 +00001021 UInt VGA_(gen_##x##_flags) = f; \
1022 void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst)
nethercote85a456f2004-11-16 17:31:56 +00001023#define POST(x) \
nethercote8ff888f2004-11-17 17:11:45 +00001024 void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst)
jsgf855d93d2003-10-13 22:26:55 +00001025
nethercotebb4222b2004-09-10 17:42:11 +00001026#define SYSNO PLATFORM_SYSCALL_NUM(tst->arch) // in PRE(x)
1027#define res PLATFORM_SYSCALL_RET(tst->arch) // in POST(x)
1028#define arg1 PLATFORM_SYSCALL_ARG1(tst->arch)
1029#define arg2 PLATFORM_SYSCALL_ARG2(tst->arch)
1030#define arg3 PLATFORM_SYSCALL_ARG3(tst->arch)
1031#define arg4 PLATFORM_SYSCALL_ARG4(tst->arch)
1032#define arg5 PLATFORM_SYSCALL_ARG5(tst->arch)
1033#define arg6 PLATFORM_SYSCALL_ARG6(tst->arch)
jsgf855d93d2003-10-13 22:26:55 +00001034
nethercote35122912004-10-18 17:00:30 +00001035#define set_result(val) PLATFORM_SET_SYSCALL_RESULT(tst->arch, (val))
1036
nethercoteef0c7662004-11-06 15:38:43 +00001037#define PRINT(format, args...) \
1038 if (VG_(clo_trace_syscalls)) \
1039 VG_(printf)(format, ## args)
1040
1041// Combine two 32-bit values into a 64-bit value
1042#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1043
nethercote85a456f2004-11-16 17:31:56 +00001044PRE(sys_exit_group, Special)
jsgf855d93d2003-10-13 22:26:55 +00001045{
1046 VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1047}
1048
nethercote85a456f2004-11-16 17:31:56 +00001049PRE(sys_exit, Special)
jsgf855d93d2003-10-13 22:26:55 +00001050{
1051 VG_(core_panic)("syscall exit() not caught by the scheduler?!");
1052}
1053
nethercote85a456f2004-11-16 17:31:56 +00001054PRE(sys_sched_yield, Special)
nethercote5b653bc2004-11-15 14:32:12 +00001055{
1056 VG_(core_panic)("syscall sched_yield() not caught by the scheduler?!");
1057}
1058
nethercote85a456f2004-11-16 17:31:56 +00001059PRE(sys_ni_syscall, Special)
nethercoteeb1c7b72004-11-11 19:43:50 +00001060{
1061 PRINT("non-existent syscall! (ni_syscall)");
1062 PRE_REG_READ0(long, "ni_syscall");
1063 set_result( -VKI_ENOSYS );
1064}
1065
nethercote8ff888f2004-11-17 17:11:45 +00001066// XXX: I think this is x86/linux-specific... at least some of the entries
1067// are non-generic
nethercote9a3beb92004-11-12 17:07:26 +00001068// XXX: Why is the memory pointed to by arg3 never checked?
nethercote85a456f2004-11-16 17:31:56 +00001069PRE(sys_ptrace, 0)
jsgf855d93d2003-10-13 22:26:55 +00001070{
nethercote9a3beb92004-11-12 17:07:26 +00001071 PRINT("sys_ptrace ( %d, %d, %p, %p )", arg1,arg2,arg3,arg4);
1072 PRE_REG_READ4(int, "ptrace",
1073 long, request, long, pid, long, addr, long, data);
jsgf855d93d2003-10-13 22:26:55 +00001074 switch (arg1) {
1075 case 12: /* PTRACE_GETREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001076 PRE_MEM_WRITE( "ptrace(getregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001077 sizeof (struct vki_user_regs_struct));
jsgf855d93d2003-10-13 22:26:55 +00001078 break;
1079 case 14: /* PTRACE_GETFPREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001080 PRE_MEM_WRITE( "ptrace(getfpregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001081 sizeof (struct vki_user_i387_struct));
jsgf855d93d2003-10-13 22:26:55 +00001082 break;
1083 case 18: /* PTRACE_GETFPXREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001084 PRE_MEM_WRITE( "ptrace(getfpxregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001085 sizeof(struct vki_user_fxsr_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001086 break;
1087 case 1: case 2: case 3: /* PTRACE_PEEK{TEXT,DATA,USER} */
nethercoteef0c7662004-11-06 15:38:43 +00001088 PRE_MEM_WRITE( "ptrace(peek)", arg4,
jsgf855d93d2003-10-13 22:26:55 +00001089 sizeof (long));
1090 break;
1091 case 13: /* PTRACE_SETREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001092 PRE_MEM_READ( "ptrace(setregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001093 sizeof (struct vki_user_regs_struct));
jsgf855d93d2003-10-13 22:26:55 +00001094 break;
1095 case 15: /* PTRACE_SETFPREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001096 PRE_MEM_READ( "ptrace(setfpregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001097 sizeof (struct vki_user_i387_struct));
jsgf855d93d2003-10-13 22:26:55 +00001098 break;
1099 case 19: /* PTRACE_SETFPXREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001100 PRE_MEM_READ( "ptrace(setfpxregs)", arg4,
nethercote73b526f2004-10-31 18:48:21 +00001101 sizeof(struct vki_user_fxsr_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001102 break;
1103 default:
1104 break;
1105 }
1106}
1107
nethercote9a3beb92004-11-12 17:07:26 +00001108// XXX: I think this is x86/linux-specific
nethercote85a456f2004-11-16 17:31:56 +00001109POST(sys_ptrace)
jsgf855d93d2003-10-13 22:26:55 +00001110{
jsgf855d93d2003-10-13 22:26:55 +00001111 switch (arg1) {
1112 case 12: /* PTRACE_GETREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001113 POST_MEM_WRITE( arg4, sizeof (struct vki_user_regs_struct));
jsgf855d93d2003-10-13 22:26:55 +00001114 break;
1115 case 14: /* PTRACE_GETFPREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001116 POST_MEM_WRITE( arg4, sizeof (struct vki_user_i387_struct));
jsgf855d93d2003-10-13 22:26:55 +00001117 break;
1118 case 18: /* PTRACE_GETFPXREGS */
nethercoteef0c7662004-11-06 15:38:43 +00001119 POST_MEM_WRITE( arg4, sizeof(struct vki_user_fxsr_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001120 break;
1121 case 1: case 2: case 3: /* PTRACE_PEEK{TEXT,DATA,USER} */
nethercoteef0c7662004-11-06 15:38:43 +00001122 POST_MEM_WRITE( arg4, sizeof (long));
jsgf855d93d2003-10-13 22:26:55 +00001123 break;
1124 default:
1125 break;
1126 }
1127}
1128
nethercote85a456f2004-11-16 17:31:56 +00001129PRE(sys_set_tid_address, Special)
rjwalshcdf1cb52004-04-29 08:40:50 +00001130{
nethercote328b7692004-11-17 18:24:10 +00001131 // We don't let this syscall run, and don't do anything to simulate it
1132 // ourselves -- it becomes a no-op! Why? Tom says:
1133 //
1134 // I suspect this is deliberate given that all the user level threads
1135 // are running in the same kernel thread under valgrind so we probably
1136 // don't want to be calling the actual system call here.
1137 //
1138 // Hmm.
nethercote5b653bc2004-11-15 14:32:12 +00001139 PRINT("sys_set_tid_address ( %p )", arg1);
1140 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
rjwalshcdf1cb52004-04-29 08:40:50 +00001141}
1142
nethercote85a456f2004-11-16 17:31:56 +00001143PRE(sys_iopl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001144{
nethercote7f7e4d12004-11-15 12:28:58 +00001145 PRINT("sys_iopl ( %d )", arg1);
1146 PRE_REG_READ1(long, "iopl", unsigned long, level);
jsgf855d93d2003-10-13 22:26:55 +00001147}
1148
nethercote85a456f2004-11-16 17:31:56 +00001149PRE(sys_setxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001150{
nethercote2e1c37d2004-11-13 13:57:12 +00001151 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
nethercoteef0c7662004-11-06 15:38:43 +00001152 arg1, arg2, arg3, (ULong)arg4, arg5);
nethercote2e1c37d2004-11-13 13:57:12 +00001153 PRE_REG_READ5(long, "setxattr",
1154 char *, path, char *, name,
1155 void *, value, vki_size_t, size, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001156 PRE_MEM_RASCIIZ( "setxattr(path)", arg1 );
1157 PRE_MEM_RASCIIZ( "setxattr(name)", arg2 );
1158 PRE_MEM_READ( "setxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001159}
1160
nethercote85a456f2004-11-16 17:31:56 +00001161PRE(sys_lsetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001162{
nethercote2e1c37d2004-11-13 13:57:12 +00001163 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
nethercoteef0c7662004-11-06 15:38:43 +00001164 arg1, arg2, arg3, (ULong)arg4, arg5);
nethercote2e1c37d2004-11-13 13:57:12 +00001165 PRE_REG_READ5(long, "lsetxattr",
1166 char *, path, char *, name,
1167 void *, value, vki_size_t, size, int, flags);
1168 PRE_MEM_RASCIIZ( "lsetxattr(path)", arg1 );
1169 PRE_MEM_RASCIIZ( "lsetxattr(name)", arg2 );
1170 PRE_MEM_READ( "lsetxattr(value)", arg3, arg4 );
1171}
1172
nethercote85a456f2004-11-16 17:31:56 +00001173PRE(sys_fsetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001174{
1175 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
1176 arg1, arg2, arg3, (ULong)arg4, arg5);
1177 PRE_REG_READ5(long, "fsetxattr",
1178 int, fd, char *, name, void *, value,
1179 vki_size_t, size, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001180 PRE_MEM_RASCIIZ( "fsetxattr(name)", arg2 );
1181 PRE_MEM_READ( "fsetxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001182}
1183
nethercote85a456f2004-11-16 17:31:56 +00001184PRE(sys_getxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001185{
nethercote2e1c37d2004-11-13 13:57:12 +00001186 PRINT("sys_getxattr ( %p, %p, %p, %llu )", arg1,arg2,arg3, (ULong)arg4);
1187 PRE_REG_READ4(ssize_t, "getxattr",
1188 char *, path, char *, name, void *, value, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001189 PRE_MEM_RASCIIZ( "getxattr(path)", arg1 );
1190 PRE_MEM_RASCIIZ( "getxattr(name)", arg2 );
1191 PRE_MEM_WRITE( "getxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001192}
1193
nethercote85a456f2004-11-16 17:31:56 +00001194POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001195{
1196 if (res > 0 && arg3 != (Addr)NULL) {
nethercoteef0c7662004-11-06 15:38:43 +00001197 POST_MEM_WRITE( arg3, res );
jsgf855d93d2003-10-13 22:26:55 +00001198 }
1199}
1200
nethercote85a456f2004-11-16 17:31:56 +00001201PRE(sys_lgetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001202{
nethercote2e1c37d2004-11-13 13:57:12 +00001203 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", arg1,arg2,arg3, (ULong)arg4);
1204 PRE_REG_READ4(ssize_t, "lgetxattr",
1205 char *, path, char *, name, void *, value, vki_size_t, size);
1206 PRE_MEM_RASCIIZ( "lgetxattr(path)", arg1 );
1207 PRE_MEM_RASCIIZ( "lgetxattr(name)", arg2 );
1208 PRE_MEM_WRITE( "lgetxattr(value)", arg3, arg4 );
1209}
1210
nethercote85a456f2004-11-16 17:31:56 +00001211POST(sys_lgetxattr)
nethercote2e1c37d2004-11-13 13:57:12 +00001212{
1213 if (res > 0 && arg3 != (Addr)NULL) {
1214 POST_MEM_WRITE( arg3, res );
1215 }
1216}
1217
nethercote85a456f2004-11-16 17:31:56 +00001218PRE(sys_fgetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001219{
1220 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", arg1, arg2, arg3, (ULong)arg4);
1221 PRE_REG_READ4(ssize_t, "fgetxattr",
1222 int, fd, char *, name, void *, value, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001223 PRE_MEM_RASCIIZ( "fgetxattr(name)", arg2 );
1224 PRE_MEM_WRITE( "fgetxattr(value)", arg3, arg4 );
jsgf855d93d2003-10-13 22:26:55 +00001225}
1226
nethercote85a456f2004-11-16 17:31:56 +00001227POST(sys_fgetxattr)
jsgf855d93d2003-10-13 22:26:55 +00001228{
1229 if (res > 0 && arg3 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001230 POST_MEM_WRITE( arg3, res );
jsgf855d93d2003-10-13 22:26:55 +00001231}
1232
nethercote85a456f2004-11-16 17:31:56 +00001233PRE(sys_listxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001234{
nethercote2e1c37d2004-11-13 13:57:12 +00001235 PRINT("sys_listxattr ( %p, %p, %llu )", arg1, arg2, (ULong)arg3);
1236 PRE_REG_READ3(ssize_t, "listxattr",
1237 char *, path, char *, list, vki_size_t, size);
nethercoteef0c7662004-11-06 15:38:43 +00001238 PRE_MEM_RASCIIZ( "listxattr(path)", arg1 );
1239 PRE_MEM_WRITE( "listxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001240}
1241
nethercote85a456f2004-11-16 17:31:56 +00001242POST(sys_listxattr)
jsgf855d93d2003-10-13 22:26:55 +00001243{
1244 if (res > 0 && arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001245 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001246}
1247
nethercote85a456f2004-11-16 17:31:56 +00001248PRE(sys_llistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001249{
nethercote2e1c37d2004-11-13 13:57:12 +00001250 PRINT("sys_llistxattr ( %p, %p, %llu )", arg1, arg2, (ULong)arg3);
1251 PRE_REG_READ3(ssize_t, "llistxattr",
1252 char *, path, char *, list, vki_size_t, size);
1253 PRE_MEM_RASCIIZ( "llistxattr(path)", arg1 );
1254 PRE_MEM_WRITE( "llistxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001255}
1256
nethercote85a456f2004-11-16 17:31:56 +00001257POST(sys_llistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001258{
1259 if (res > 0 && arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001260 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001261}
1262
nethercote85a456f2004-11-16 17:31:56 +00001263PRE(sys_flistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001264{
nethercote2e1c37d2004-11-13 13:57:12 +00001265 PRINT("sys_flistxattr ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
1266 PRE_REG_READ3(ssize_t, "flistxattr",
1267 int, fd, char *, list, vki_size_t, size);
1268 PRE_MEM_WRITE( "flistxattr(list)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001269}
1270
nethercote85a456f2004-11-16 17:31:56 +00001271POST(sys_flistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001272{
nethercote2e1c37d2004-11-13 13:57:12 +00001273 if (res > 0 && arg2 != (Addr)NULL)
1274 POST_MEM_WRITE( arg2, res );
1275}
1276
nethercote85a456f2004-11-16 17:31:56 +00001277PRE(sys_removexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001278{
1279 PRINT("sys_removexattr ( %p, %p )", arg1, arg2);
1280 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
1281 PRE_MEM_RASCIIZ( "removexattr(path)", arg1 );
1282 PRE_MEM_RASCIIZ( "removexattr(name)", arg2 );
1283}
1284
nethercote85a456f2004-11-16 17:31:56 +00001285PRE(sys_lremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001286{
1287 PRINT("sys_lremovexattr ( %p, %p )", arg1, arg2);
1288 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
1289 PRE_MEM_RASCIIZ( "lremovexattr(path)", arg1 );
1290 PRE_MEM_RASCIIZ( "lremovexattr(name)", arg2 );
1291}
1292
nethercote85a456f2004-11-16 17:31:56 +00001293PRE(sys_fremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001294{
1295 PRINT("sys_fremovexattr ( %d, %p )", arg1, arg2);
1296 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
1297 PRE_MEM_RASCIIZ( "fremovexattr(name)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001298}
1299
nethercote85a456f2004-11-16 17:31:56 +00001300PRE(sys_quotactl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001301{
nethercote5b653bc2004-11-15 14:32:12 +00001302 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", arg1,arg2,arg3, arg4);
1303 PRE_REG_READ4(long, "quotactl",
1304 unsigned int, cmd, const char *, special, vki_qid_t, id,
1305 void *, addr);
nethercoteef0c7662004-11-06 15:38:43 +00001306 PRE_MEM_RASCIIZ( "quotactl(special)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001307}
1308
nethercote5a945af2004-11-14 18:37:07 +00001309// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00001310PRE(sys_lookup_dcookie, 0)
jsgf855d93d2003-10-13 22:26:55 +00001311{
nethercote660e4ee2004-11-12 13:29:24 +00001312 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(arg1,arg2), arg3, arg4);
1313 PRE_REG_READ4(long, "lookup_dcookie",
1314 vki_u32, cookie_low32, vki_u32, cookie_high32,
1315 char *, buf, vki_size_t, len);
nethercoteef0c7662004-11-06 15:38:43 +00001316 PRE_MEM_WRITE( "lookup_dcookie(buf)", arg3, arg4);
jsgf855d93d2003-10-13 22:26:55 +00001317}
1318
nethercote85a456f2004-11-16 17:31:56 +00001319POST(sys_lookup_dcookie)
jsgf855d93d2003-10-13 22:26:55 +00001320{
1321 if (arg3 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001322 POST_MEM_WRITE( arg3, res);
jsgf855d93d2003-10-13 22:26:55 +00001323}
1324
nethercote85a456f2004-11-16 17:31:56 +00001325PRE(sys_fsync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001326{
nethercotedc18c0a2004-11-14 20:06:27 +00001327 PRINT("sys_fsync ( %d )", arg1);
1328 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1329}
1330
nethercote85a456f2004-11-16 17:31:56 +00001331PRE(sys_fdatasync, MayBlock)
nethercotedc18c0a2004-11-14 20:06:27 +00001332{
1333 PRINT("sys_fdatasync ( %d )", arg1);
1334 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001335}
1336
nethercote85a456f2004-11-16 17:31:56 +00001337PRE(sys_msync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001338{
nethercote06c7bd72004-11-14 19:11:56 +00001339 PRINT("sys_msync ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
1340 PRE_REG_READ3(long, "msync",
1341 unsigned long, start, vki_size_t, length, int, flags);
nethercoteef0c7662004-11-06 15:38:43 +00001342 PRE_MEM_READ( "msync(start)", arg1, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00001343}
1344
nethercoteef0c7662004-11-06 15:38:43 +00001345// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1346// versions of LiS (Linux Streams). They are not part of the kernel.
1347// Therefore, we have to provide this type ourself, rather than getting it
1348// from the kernel sources.
nethercoteb77dee62004-11-16 17:13:24 +00001349struct vki_pmsg_strbuf {
jsgf855d93d2003-10-13 22:26:55 +00001350 int maxlen; /* no. of bytes in buffer */
1351 int len; /* no. of bytes returned */
nethercote73b526f2004-10-31 18:48:21 +00001352 vki_caddr_t buf; /* pointer to data */
jsgf855d93d2003-10-13 22:26:55 +00001353};
1354
nethercote85a456f2004-11-16 17:31:56 +00001355PRE(sys_getpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001356{
1357 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001358 struct vki_pmsg_strbuf *ctrl;
1359 struct vki_pmsg_strbuf *data;
1360 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
1361 PRE_REG_READ5(int, "getpmsg",
1362 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1363 int *, bandp, int *, flagsp);
1364 ctrl = (struct vki_pmsg_strbuf *)arg2;
1365 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001366 if (ctrl && ctrl->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001367 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001368 if (data && data->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001369 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001370 if (arg4)
nethercoteef0c7662004-11-06 15:38:43 +00001371 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)arg4, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001372 if (arg5)
nethercoteef0c7662004-11-06 15:38:43 +00001373 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)arg5, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001374}
1375
nethercote85a456f2004-11-16 17:31:56 +00001376POST(sys_getpmsg)
jsgf855d93d2003-10-13 22:26:55 +00001377{
nethercoteb77dee62004-11-16 17:13:24 +00001378 struct vki_pmsg_strbuf *ctrl;
1379 struct vki_pmsg_strbuf *data;
jsgf855d93d2003-10-13 22:26:55 +00001380
nethercoteb77dee62004-11-16 17:13:24 +00001381 ctrl = (struct vki_pmsg_strbuf *)arg2;
1382 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001383 if (res == 0 && ctrl && ctrl->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001384 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001385 }
1386 if (res == 0 && data && data->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001387 POST_MEM_WRITE( (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001388 }
1389}
1390
nethercote85a456f2004-11-16 17:31:56 +00001391PRE(sys_putpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001392{
1393 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001394 struct vki_pmsg_strbuf *ctrl;
1395 struct vki_pmsg_strbuf *data;
1396 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", arg1,arg2,arg3,arg4,arg5);
1397 PRE_REG_READ5(int, "putpmsg",
1398 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1399 int, band, int, flags);
1400 ctrl = (struct vki_pmsg_strbuf *)arg2;
1401 data = (struct vki_pmsg_strbuf *)arg3;
jsgf855d93d2003-10-13 22:26:55 +00001402 if (ctrl && ctrl->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001403 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00001404 if (data && data->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001405 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00001406}
1407
nethercote85a456f2004-11-16 17:31:56 +00001408PRE(sys_getitimer, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00001409{
nethercote5b653bc2004-11-15 14:32:12 +00001410 PRINT("sys_getitimer ( %d, %p )", arg1, arg2);
1411 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
1412 PRE_MEM_WRITE( "getitimer(value)", arg2, sizeof(struct vki_itimerval) );
jsgf855d93d2003-10-13 22:26:55 +00001413}
1414
nethercote85a456f2004-11-16 17:31:56 +00001415POST(sys_getitimer)
jsgf855d93d2003-10-13 22:26:55 +00001416{
1417 if (arg2 != (Addr)NULL) {
nethercote73b526f2004-10-31 18:48:21 +00001418 VG_TRACK( post_mem_write,arg2, sizeof(struct vki_itimerval));
jsgf855d93d2003-10-13 22:26:55 +00001419 }
1420}
1421
nethercote85a456f2004-11-16 17:31:56 +00001422PRE(sys_setitimer, NBRunInLWP)
nethercote5b653bc2004-11-15 14:32:12 +00001423{
1424 PRINT("sys_setitimer ( %d, %p, %p )", arg1,arg2,arg3);
1425 PRE_REG_READ3(long, "setitimer",
1426 int, which,
1427 struct itimerval *, value, struct itimerval *, ovalue);
1428 if (arg2 != (Addr)NULL)
1429 PRE_MEM_READ( "setitimer(value)", arg2, sizeof(struct vki_itimerval) );
1430 if (arg3 != (Addr)NULL)
1431 PRE_MEM_WRITE( "setitimer(ovalue)", arg3, sizeof(struct vki_itimerval));
1432}
1433
nethercote85a456f2004-11-16 17:31:56 +00001434POST(sys_setitimer)
nethercote5b653bc2004-11-15 14:32:12 +00001435{
1436 if (arg3 != (Addr)NULL) {
1437 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_itimerval));
1438 }
1439}
1440
nethercote85a456f2004-11-16 17:31:56 +00001441PRE(sys_chroot, 0)
jsgf855d93d2003-10-13 22:26:55 +00001442{
nethercote71f05f32004-11-12 18:49:27 +00001443 PRINT("sys_chroot ( %p )", arg1);
1444 PRE_REG_READ1(long, "chroot", const char *, path);
nethercoteef0c7662004-11-06 15:38:43 +00001445 PRE_MEM_RASCIIZ( "chroot(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001446}
1447
nethercote85a456f2004-11-16 17:31:56 +00001448PRE(sys_madvise, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001449{
nethercoteac866b92004-11-15 20:23:15 +00001450 PRINT("sys_madvise ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
1451 PRE_REG_READ3(long, "madvise",
1452 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00001453}
1454
nethercote85a456f2004-11-16 17:31:56 +00001455PRE(sys_mremap, Special)
jsgf855d93d2003-10-13 22:26:55 +00001456{
nethercote27ea8bc2004-07-10 17:21:14 +00001457 // Nb: this is different to the glibc version described in the man pages,
1458 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00001459 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
1460 arg1, (ULong)arg2, arg3, arg4, arg5);
1461 PRE_REG_READ5(unsigned long, "mremap",
1462 unsigned long, old_addr, unsigned long, old_size,
1463 unsigned long, new_size, unsigned long, flags,
1464 unsigned long, new_addr);
nethercote35122912004-10-18 17:00:30 +00001465 set_result( mremap_segment((Addr)arg1, arg2, (Addr)arg5, arg3, arg4, tid) );
jsgf855d93d2003-10-13 22:26:55 +00001466}
1467
nethercote85a456f2004-11-16 17:31:56 +00001468PRE(sys_nice, 0)
jsgf855d93d2003-10-13 22:26:55 +00001469{
nethercote9a3beb92004-11-12 17:07:26 +00001470 PRINT("sys_nice ( %d )", arg1);
1471 PRE_REG_READ1(long, "nice", int, inc);
jsgf855d93d2003-10-13 22:26:55 +00001472}
1473
nethercote85a456f2004-11-16 17:31:56 +00001474PRE(sys_sched_getscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001475{
nethercote5b653bc2004-11-15 14:32:12 +00001476 PRINT("sys_sched_getscheduler ( %d )", arg1);
1477 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001478}
1479
nethercote85a456f2004-11-16 17:31:56 +00001480PRE(sys_sched_setscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00001481{
nethercote5b653bc2004-11-15 14:32:12 +00001482 PRINT("sys_sched_setscheduler ( %d, %d, %p )", arg1,arg2,arg3);
1483 PRE_REG_READ3(long, "sched_setscheduler",
1484 vki_pid_t, pid, int, policy, struct sched_param *, p);
nethercote163c5e82004-11-17 18:42:20 +00001485 if (arg3 != 0)
nethercote5b653bc2004-11-15 14:32:12 +00001486 PRE_MEM_READ( "sched_setscheduler(p)",
nethercoteef0c7662004-11-06 15:38:43 +00001487 arg3, sizeof(struct vki_sched_param));
jsgf855d93d2003-10-13 22:26:55 +00001488}
1489
nethercote85a456f2004-11-16 17:31:56 +00001490PRE(sys_mlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001491{
nethercote06c7bd72004-11-14 19:11:56 +00001492 PRINT("sys_mlock ( %p, %llu )", arg1, (ULong)arg2);
1493 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001494}
1495
nethercote85a456f2004-11-16 17:31:56 +00001496PRE(sys_munlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001497{
nethercote06c7bd72004-11-14 19:11:56 +00001498 PRINT("sys_munlock ( %p, %llu )", arg1, (ULong)arg2);
1499 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00001500}
1501
nethercote85a456f2004-11-16 17:31:56 +00001502PRE(sys_mlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001503{
nethercote06c7bd72004-11-14 19:11:56 +00001504 PRINT("sys_mlockall ( %x )", arg1);
1505 PRE_REG_READ1(long, "mlockall", int, flags);
jsgf855d93d2003-10-13 22:26:55 +00001506}
1507
nethercote85a456f2004-11-16 17:31:56 +00001508PRE(sys_munlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001509{
nethercote0df495a2004-11-11 16:38:21 +00001510 PRINT("sys_munlockall ( )");
1511 PRE_REG_READ0(long, "munlockall");
jsgf855d93d2003-10-13 22:26:55 +00001512}
1513
nethercote85a456f2004-11-16 17:31:56 +00001514PRE(sys_sched_get_priority_max, 0)
jsgf855d93d2003-10-13 22:26:55 +00001515{
nethercoteef0c7662004-11-06 15:38:43 +00001516 PRINT("sched_get_priority_max ( %d )", arg1);
nethercote5b653bc2004-11-15 14:32:12 +00001517 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001518}
1519
nethercote85a456f2004-11-16 17:31:56 +00001520PRE(sys_sched_get_priority_min, 0)
jsgf855d93d2003-10-13 22:26:55 +00001521{
nethercoteef0c7662004-11-06 15:38:43 +00001522 PRINT("sched_get_priority_min ( %d )", arg1);
nethercote5b653bc2004-11-15 14:32:12 +00001523 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00001524}
1525
nethercote85a456f2004-11-16 17:31:56 +00001526PRE(sys_setpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001527{
nethercotedc18c0a2004-11-14 20:06:27 +00001528 PRINT("sys_setpriority ( %d, %d, %d )", arg1, arg2, arg3);
1529 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
jsgf855d93d2003-10-13 22:26:55 +00001530}
1531
nethercote85a456f2004-11-16 17:31:56 +00001532PRE(sys_getpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00001533{
nethercotedc18c0a2004-11-14 20:06:27 +00001534 PRINT("sys_getpriority ( %d, %d )", arg1, arg2);
1535 PRE_REG_READ2(long, "getpriority", int, which, int, who);
jsgf855d93d2003-10-13 22:26:55 +00001536}
1537
nethercote85a456f2004-11-16 17:31:56 +00001538PRE(sys_setregid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001539{
nethercote17258dc2004-11-12 19:55:08 +00001540 PRINT("sys_setregid16 ( %d, %d )", arg1, arg2);
1541 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00001542}
1543
nethercoteac866b92004-11-15 20:23:15 +00001544// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001545PRE(sys_pwrite64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001546{
nethercoteac866b92004-11-15 20:23:15 +00001547 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
nethercoteef0c7662004-11-06 15:38:43 +00001548 arg1, arg2, (ULong)arg3, LOHI64(arg4,arg5));
nethercoteac866b92004-11-15 20:23:15 +00001549 PRE_REG_READ5(ssize_t, "pwrite64",
1550 unsigned int, fd, const char *, buf, vki_size_t, count,
1551 vki_u32, offset_low32, vki_u32, offset_high32);
nethercoteef0c7662004-11-06 15:38:43 +00001552 PRE_MEM_READ( "pwrite64(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001553}
1554
nethercote85a456f2004-11-16 17:31:56 +00001555PRE(sys_sync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001556{
nethercote0df495a2004-11-11 16:38:21 +00001557 PRINT("sys_sync ( )");
1558 PRE_REG_READ0(long, "sync");
jsgf855d93d2003-10-13 22:26:55 +00001559}
1560
nethercote85a456f2004-11-16 17:31:56 +00001561PRE(sys_fstatfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00001562{
nethercotedc18c0a2004-11-14 20:06:27 +00001563 PRINT("sys_fstatfs ( %d, %p )",arg1,arg2);
1564 PRE_REG_READ2(long, "fstatfs",
1565 unsigned int, fd, struct statfs *, buf);
1566 PRE_MEM_WRITE( "fstatfs(buf)", arg2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001567}
1568
nethercote85a456f2004-11-16 17:31:56 +00001569POST(sys_fstatfs)
jsgf855d93d2003-10-13 22:26:55 +00001570{
nethercoteef0c7662004-11-06 15:38:43 +00001571 POST_MEM_WRITE( arg2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00001572}
1573
nethercote85a456f2004-11-16 17:31:56 +00001574PRE(sys_fstatfs64, 0)
thughesa996d3b2004-09-24 22:57:17 +00001575{
nethercotedc18c0a2004-11-14 20:06:27 +00001576 PRINT("sys_fstatfs64 ( %d, %llu, %p )",arg1,(ULong)arg2,arg3);
1577 PRE_REG_READ3(long, "fstatfs64",
1578 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
1579 PRE_MEM_WRITE( "fstatfs64(buf)", arg3, arg2 );
thughesa996d3b2004-09-24 22:57:17 +00001580}
1581
nethercote85a456f2004-11-16 17:31:56 +00001582POST(sys_fstatfs64)
thughesa996d3b2004-09-24 22:57:17 +00001583{
nethercoteef0c7662004-11-06 15:38:43 +00001584 POST_MEM_WRITE( arg3, arg2 );
thughesa996d3b2004-09-24 22:57:17 +00001585}
1586
nethercote85a456f2004-11-16 17:31:56 +00001587PRE(sys_getsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00001588{
nethercote5b653bc2004-11-15 14:32:12 +00001589 PRINT("sys_getsid ( %d )", arg1);
1590 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00001591}
1592
nethercoteac866b92004-11-15 20:23:15 +00001593// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00001594PRE(sys_pread64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001595{
nethercoteac866b92004-11-15 20:23:15 +00001596 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
nethercoteef0c7662004-11-06 15:38:43 +00001597 arg1, arg2, (ULong)arg3, LOHI64(arg4,arg5));
nethercoteac866b92004-11-15 20:23:15 +00001598 PRE_REG_READ5(ssize_t, "pread64",
1599 unsigned int, fd, char *, buf, vki_size_t, count,
1600 vki_u32, offset_low32, vki_u32, offset_high32);
1601 PRE_MEM_WRITE( "pread64(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001602}
1603
nethercote85a456f2004-11-16 17:31:56 +00001604POST(sys_pread64)
jsgf855d93d2003-10-13 22:26:55 +00001605{
jsgf855d93d2003-10-13 22:26:55 +00001606 if (res > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00001607 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00001608 }
1609}
1610
nethercote85a456f2004-11-16 17:31:56 +00001611PRE(sys_mknod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001612{
nethercotec6851dd2004-11-11 18:00:47 +00001613 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", arg1, arg2, arg3 );
1614 PRE_REG_READ3(long, "mknod",
1615 const char *, pathname, int, mode, unsigned, dev);
nethercoteef0c7662004-11-06 15:38:43 +00001616 PRE_MEM_RASCIIZ( "mknod(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001617}
1618
nethercote85a456f2004-11-16 17:31:56 +00001619PRE(sys_flock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001620{
nethercote06c7bd72004-11-14 19:11:56 +00001621 PRINT("sys_flock ( %d, %d )", arg1, arg2 );
1622 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
jsgf855d93d2003-10-13 22:26:55 +00001623}
1624
nethercote85a456f2004-11-16 17:31:56 +00001625PRE(sys_init_module, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001626{
nethercote0eafe552004-11-15 16:40:40 +00001627 PRINT("sys_init_module ( %p, %llu, %p )", arg1, (ULong)arg2, arg3 );
1628 PRE_REG_READ3(long, "init_module",
1629 void *, umod, unsigned long, len, const char *, uargs);
1630 PRE_MEM_READ( "init_module(umod)", arg1, arg2 );
1631 PRE_MEM_RASCIIZ( "init_module(uargs)", arg3 );
jsgf855d93d2003-10-13 22:26:55 +00001632}
1633
nethercote85a456f2004-11-16 17:31:56 +00001634PRE(sys_capget, 0)
jsgf855d93d2003-10-13 22:26:55 +00001635{
nethercoteac866b92004-11-15 20:23:15 +00001636 PRINT("sys_capget ( %p, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00001637 PRE_REG_READ2(long, "capget",
1638 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00001639 PRE_MEM_READ( "capget(header)", arg1,
nethercote73b526f2004-10-31 18:48:21 +00001640 sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00001641 PRE_MEM_WRITE( "capget(data)", arg2,
nethercote73b526f2004-10-31 18:48:21 +00001642 sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001643}
1644
nethercote85a456f2004-11-16 17:31:56 +00001645POST(sys_capget)
jsgf855d93d2003-10-13 22:26:55 +00001646{
1647 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00001648 POST_MEM_WRITE( arg2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001649}
1650
nethercote85a456f2004-11-16 17:31:56 +00001651PRE(sys_capset, 0)
jsgf855d93d2003-10-13 22:26:55 +00001652{
nethercote5b653bc2004-11-15 14:32:12 +00001653 PRINT("sys_capset ( %p, %p )", arg1, arg2 );
1654 PRE_REG_READ2(long, "capset",
1655 vki_cap_user_header_t, header,
1656 const vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00001657 PRE_MEM_READ( "capset(header)",
nethercote73b526f2004-10-31 18:48:21 +00001658 arg1, sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00001659 PRE_MEM_READ( "capset(data)",
nethercote73b526f2004-10-31 18:48:21 +00001660 arg2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00001661}
1662
nethercotea81e9162004-02-12 14:34:14 +00001663// Pre_read a char** argument.
1664void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
1665{
1666 while (True) {
1667 Addr a_deref = deref_Addr( tid, a, s1 );
1668 if (0 == a_deref)
1669 break;
nethercoteef0c7662004-11-06 15:38:43 +00001670 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00001671 a += sizeof(char*);
1672 }
1673}
1674
nethercote7310afb2004-11-12 15:41:06 +00001675// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
1676// but it seems to work nonetheless...
nethercote85a456f2004-11-16 17:31:56 +00001677PRE(sys_execve, Special)
jsgf855d93d2003-10-13 22:26:55 +00001678{
nethercote7310afb2004-11-12 15:41:06 +00001679 PRINT("sys_execve ( %p(%s), %p, %p )", arg1, arg1, arg2, arg3);
1680 PRE_REG_READ3(vki_off_t, "execve",
1681 char *, filename, char **, argv, char **, envp);
nethercoteef0c7662004-11-06 15:38:43 +00001682 PRE_MEM_RASCIIZ( "execve(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00001683 if (arg2 != 0)
thughes7f72d012004-07-21 16:23:38 +00001684 pre_argv_envp( arg2, tid, "execve(argv)", "execve(argv[i])" );
nethercote163c5e82004-11-17 18:42:20 +00001685 if (arg3 != 0)
thughes4b9e0152004-06-19 13:02:34 +00001686 pre_argv_envp( arg3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00001687
1688 /* Erk. If the exec fails, then the following will have made a
1689 mess of things which makes it hard for us to continue. The
1690 right thing to do is piece everything together again in
1691 POST(execve), but that's hard work. Instead, we make an effort
1692 to check that the execve will work before actually calling
1693 exec. */
1694 {
1695 struct vki_stat st;
1696 Int ret = VG_(stat)((Char *)arg1, &st);
1697
1698 if (ret < 0) {
nethercote35122912004-10-18 17:00:30 +00001699 set_result( ret );
fitzhardingee1c06d82003-10-30 07:21:44 +00001700 return;
1701 }
thughes90efa302004-09-25 16:13:55 +00001702 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00001703 XXX do proper permissions check?
1704 */
thughes90efa302004-09-25 16:13:55 +00001705 if ((st.st_mode & 0100111) == 0100000) {
nethercote35122912004-10-18 17:00:30 +00001706 set_result( -VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00001707 return;
1708 }
1709 }
1710
1711 /* Resistance is futile. Nuke all other threads. POSIX mandates
1712 this. (Really, nuke them all, since the new process will make
1713 its own new thread.) */
1714 VG_(nuke_all_threads_except)( VG_INVALID_THREADID );
1715
fitzhardinge5408c062004-01-04 23:52:59 +00001716 {
nethercote60a96c52004-08-03 13:08:31 +00001717 // Remove the valgrind-specific stuff from the environment so the
1718 // child doesn't get our libpthread and other stuff. This is
1719 // done unconditionally, since if we are tracing the child,
1720 // stage1/2 will set up the appropriate client environment.
jsgf855d93d2003-10-13 22:26:55 +00001721 Char** envp = (Char**)arg3;
fitzhardinge98abfc72003-12-16 02:05:15 +00001722
1723 if (envp != NULL) {
nethercote60a96c52004-08-03 13:08:31 +00001724 VG_(env_remove_valgrind_env_stuff)( envp );
jsgf855d93d2003-10-13 22:26:55 +00001725 }
fitzhardinge5408c062004-01-04 23:52:59 +00001726 }
1727
1728 if (VG_(clo_trace_children)) {
nethercotef6a1d502004-08-09 12:21:57 +00001729 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)arg1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00001730
nethercotef6a1d502004-08-09 12:21:57 +00001731 // Set VALGRINDCLO and VALGRINDLIB in arg3 (the environment)
1732 VG_(env_setenv)( (Char***)&arg3, VALGRINDCLO, optvar);
1733 VG_(env_setenv)( (Char***)&arg3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00001734
nethercotef6a1d502004-08-09 12:21:57 +00001735 // Create executable name: "/proc/self/fd/<vgexecfd>", update arg1
nethercotea8c1e922004-10-26 10:57:24 +00001736 arg1 = (Addr)VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00001737 }
1738
1739 if (0) {
1740 Char **cpp;
1741
1742 VG_(printf)("exec: %s\n", (Char *)arg1);
1743 for(cpp = (Char **)arg2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00001744 VG_(printf)("argv: %s\n", *cpp);
fitzhardinge98abfc72003-12-16 02:05:15 +00001745 for(cpp = (Char **)arg3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00001746 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00001747 }
jsgf855d93d2003-10-13 22:26:55 +00001748
fitzhardingef0dd7e12004-01-16 02:17:30 +00001749 /* Set our real sigmask to match the client's sigmask so that the
1750 exec'd child will get the right mask. First we need to clear
1751 out any pending signals so they they don't get delivered, which
1752 would confuse things.
1753
1754 XXX This is a bug - the signals should remain pending, and be
1755 delivered to the new process after exec. There's also a
1756 race-condition, since if someone delivers us a signal between
1757 the sigprocmask and the execve, we'll still get the signal. Oh
1758 well.
1759 */
1760 {
nethercote73b526f2004-10-31 18:48:21 +00001761 vki_sigset_t allsigs;
1762 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00001763 static const struct vki_timespec zero = { 0, 0 };
1764
nethercote73b526f2004-10-31 18:48:21 +00001765 VG_(sigfillset)(&allsigs);
1766 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
fitzhardingef0dd7e12004-01-16 02:17:30 +00001767 ;
1768
nethercote73b526f2004-10-31 18:48:21 +00001769 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00001770 }
1771
fitzhardingeb50068f2004-02-24 23:42:55 +00001772 /* restore the DATA rlimit for the child */
1773 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1774
nethercote35122912004-10-18 17:00:30 +00001775 set_result( VG_(do_syscall)(__NR_execve, arg1, arg2, arg3) );
fitzhardingee1c06d82003-10-30 07:21:44 +00001776
1777 /* If we got here, then the execve failed. We've already made too much of a mess
1778 of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00001779 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
fitzhardingee1c06d82003-10-30 07:21:44 +00001780 arg1, arg1, arg2, arg3, -res);
1781 VG_(core_panic)("EXEC FAILED: I can't recover from execve() failing, so I'm dying.\n"
1782 "Add more stringent tests in PRE(execve), or work out how to recover.");
jsgf855d93d2003-10-13 22:26:55 +00001783}
1784
nethercote85a456f2004-11-16 17:31:56 +00001785PRE(sys_access, 0)
jsgf855d93d2003-10-13 22:26:55 +00001786{
nethercote9a3beb92004-11-12 17:07:26 +00001787 PRINT("sys_access ( %p(%s), %d )", arg1,arg1,arg2);
1788 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00001789 PRE_MEM_RASCIIZ( "access(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001790}
1791
nethercote85a456f2004-11-16 17:31:56 +00001792PRE(sys_alarm, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00001793{
nethercote9a3beb92004-11-12 17:07:26 +00001794 PRINT("sys_alarm ( %d )", arg1);
1795 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00001796}
1797
nethercote85a456f2004-11-16 17:31:56 +00001798PRE(sys_brk, Special)
jsgf855d93d2003-10-13 22:26:55 +00001799{
fitzhardinge98abfc72003-12-16 02:05:15 +00001800 Addr brk_limit = VG_(brk_limit);
1801
jsgf855d93d2003-10-13 22:26:55 +00001802 /* libc says: int brk(void *end_data_segment);
1803 kernel says: void* brk(void* end_data_segment); (more or less)
1804
1805 libc returns 0 on success, and -1 (and sets errno) on failure.
1806 Nb: if you ask to shrink the dataseg end below what it
1807 currently is, that always succeeds, even if the dataseg end
1808 doesn't actually change (eg. brk(0)). Unless it seg faults.
1809
1810 Kernel returns the new dataseg end. If the brk() failed, this
1811 will be unchanged from the old one. That's why calling (kernel)
1812 brk(0) gives the current dataseg end (libc brk() just returns
1813 zero in that case).
1814
1815 Both will seg fault if you shrink it back into a text segment.
1816 */
nethercote9c311eb2004-11-12 18:20:12 +00001817 PRINT("sys_brk ( %p )", arg1);
1818 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00001819
nethercote35122912004-10-18 17:00:30 +00001820 set_result( do_brk(arg1) );
fitzhardinge98abfc72003-12-16 02:05:15 +00001821
jsgf855d93d2003-10-13 22:26:55 +00001822 if (res == arg1) {
1823 /* brk() succeeded */
fitzhardinge98abfc72003-12-16 02:05:15 +00001824 if (res < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00001825 /* successfully shrunk the data segment. */
1826 VG_TRACK( die_mem_brk, (Addr)arg1,
fitzhardinge98abfc72003-12-16 02:05:15 +00001827 brk_limit-arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001828 } else
fitzhardinge98abfc72003-12-16 02:05:15 +00001829 if (res > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00001830 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00001831 VG_TRACK( new_mem_brk, brk_limit,
1832 arg1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00001833 }
jsgf855d93d2003-10-13 22:26:55 +00001834 } else {
1835 /* brk() failed */
fitzhardinge98abfc72003-12-16 02:05:15 +00001836 vg_assert(brk_limit == res);
jsgf855d93d2003-10-13 22:26:55 +00001837 }
1838}
1839
nethercote85a456f2004-11-16 17:31:56 +00001840PRE(sys_chdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00001841{
nethercotec6851dd2004-11-11 18:00:47 +00001842 PRINT("sys_chdir ( %p )", arg1);
1843 PRE_REG_READ1(long, "chdir", const char *, path);
nethercoteef0c7662004-11-06 15:38:43 +00001844 PRE_MEM_RASCIIZ( "chdir(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001845}
1846
nethercote85a456f2004-11-16 17:31:56 +00001847PRE(sys_chmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001848{
nethercotec6851dd2004-11-11 18:00:47 +00001849 PRINT("sys_chmod ( %p, %d )", arg1,arg2);
1850 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
nethercoteef0c7662004-11-06 15:38:43 +00001851 PRE_MEM_RASCIIZ( "chmod(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001852}
1853
nethercote85a456f2004-11-16 17:31:56 +00001854PRE(sys_chown16, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001855{
1856 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1857 PRE_REG_READ3(long, "chown16",
1858 const char *, path,
1859 vki_old_uid_t, owner, vki_old_gid_t, group);
1860 PRE_MEM_RASCIIZ( "chown16(path)", arg1 );
1861}
1862
nethercote85a456f2004-11-16 17:31:56 +00001863PRE(sys_chown, 0)
jsgf855d93d2003-10-13 22:26:55 +00001864{
1865 /* int chown(const char *path, uid_t owner, gid_t group); */
nethercote2e1c37d2004-11-13 13:57:12 +00001866 PRINT("sys_chown ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1867 PRE_REG_READ3(long, "chown",
1868 const char *, path, vki_uid_t, owner, vki_gid_t, group);
nethercoteef0c7662004-11-06 15:38:43 +00001869 PRE_MEM_RASCIIZ( "chown(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00001870}
1871
nethercote85a456f2004-11-16 17:31:56 +00001872PRE(sys_lchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001873{
1874 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", arg1,arg2,arg3);
1875 PRE_REG_READ3(long, "lchown",
1876 const char *, path, vki_uid_t, owner, vki_gid_t, group);
1877 PRE_MEM_RASCIIZ( "lchown(path)", arg1 );
1878}
jsgf855d93d2003-10-13 22:26:55 +00001879
nethercote85a456f2004-11-16 17:31:56 +00001880PRE(sys_close, 0)
jsgf855d93d2003-10-13 22:26:55 +00001881{
nethercotec6851dd2004-11-11 18:00:47 +00001882 PRINT("sys_close ( %d )", arg1);
1883 PRE_REG_READ1(long, "close", unsigned int, fd);
1884
nethercotef8548672004-06-21 12:42:35 +00001885 /* Detect and negate attempts by the client to close Valgrind's log fd */
nethercote3d5e9102004-11-17 18:22:38 +00001886 if (!VG_(fd_allowed)(arg1, "close", tid, False))
nethercote35122912004-10-18 17:00:30 +00001887 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00001888}
1889
nethercote85a456f2004-11-16 17:31:56 +00001890POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00001891{
nethercotec6851dd2004-11-11 18:00:47 +00001892 if (VG_(clo_track_fds)) record_fd_close(tid, arg1);
rjwalshf5f536f2003-11-17 17:45:00 +00001893}
jsgf855d93d2003-10-13 22:26:55 +00001894
nethercote85a456f2004-11-16 17:31:56 +00001895PRE(sys_dup, 0)
jsgf855d93d2003-10-13 22:26:55 +00001896{
nethercote9a3beb92004-11-12 17:07:26 +00001897 PRINT("sys_dup ( %d )", arg1);
1898 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00001899}
1900
nethercote85a456f2004-11-16 17:31:56 +00001901POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00001902{
nethercote3d5e9102004-11-17 18:22:38 +00001903 if (!VG_(fd_allowed)(res, "dup", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00001904 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00001905 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00001906 } else {
nethercote9a3beb92004-11-12 17:07:26 +00001907 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001908 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
jsgf855d93d2003-10-13 22:26:55 +00001909 }
1910}
1911
nethercote85a456f2004-11-16 17:31:56 +00001912PRE(sys_dup2, 0)
jsgf855d93d2003-10-13 22:26:55 +00001913{
nethercote71f05f32004-11-12 18:49:27 +00001914 PRINT("sys_dup2 ( %d, %d )", arg1,arg2);
1915 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
nethercote3d5e9102004-11-17 18:22:38 +00001916 if (!VG_(fd_allowed)(arg2, "dup2", tid, True))
nethercote35122912004-10-18 17:00:30 +00001917 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00001918}
1919
nethercote85a456f2004-11-16 17:31:56 +00001920POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00001921{
nethercote71f05f32004-11-12 18:49:27 +00001922 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001923 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
jsgf855d93d2003-10-13 22:26:55 +00001924}
1925
nethercote85a456f2004-11-16 17:31:56 +00001926PRE(sys_fcntl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001927{
nethercote9c311eb2004-11-12 18:20:12 +00001928 PRINT("sys_fcntl ( %d, %d, %d )", arg1,arg2,arg3);
1929 PRE_REG_READ3(long, "fcntl",
1930 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
thughesd4b51a62004-07-29 21:20:11 +00001931 if (arg2 == VKI_F_SETLKW)
1932 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00001933}
1934
nethercote85a456f2004-11-16 17:31:56 +00001935POST(sys_fcntl)
rjwalshf5f536f2003-11-17 17:45:00 +00001936{
nethercote493dd182004-02-24 23:57:47 +00001937 if (arg2 == VKI_F_DUPFD) {
nethercote3d5e9102004-11-17 18:22:38 +00001938 if (!VG_(fd_allowed)(res, "fcntl(DUPFD)", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00001939 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00001940 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00001941 } else {
1942 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001943 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
nethercote493dd182004-02-24 23:57:47 +00001944 }
1945 }
rjwalshf5f536f2003-11-17 17:45:00 +00001946}
1947
nethercote85a456f2004-11-16 17:31:56 +00001948PRE(sys_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00001949{
nethercote5b653bc2004-11-15 14:32:12 +00001950 PRINT("sys_fchdir ( %d )", arg1);
1951 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001952}
1953
nethercote85a456f2004-11-16 17:31:56 +00001954PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001955{
nethercote2e1c37d2004-11-13 13:57:12 +00001956 PRINT("sys_fchown16 ( %d, %d, %d )", arg1,arg2,arg3);
1957 PRE_REG_READ3(long, "fchown16",
1958 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00001959}
1960
nethercote85a456f2004-11-16 17:31:56 +00001961PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001962{
1963 PRINT("sys_fchown ( %d, %d, %d )", arg1,arg2,arg3);
1964 PRE_REG_READ3(long, "fchown",
1965 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
1966}
jsgf855d93d2003-10-13 22:26:55 +00001967
nethercote85a456f2004-11-16 17:31:56 +00001968PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001969{
nethercoteac866b92004-11-15 20:23:15 +00001970 PRINT("sys_fchmod ( %d, %d )", arg1,arg2);
nethercotedc18c0a2004-11-14 20:06:27 +00001971 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00001972}
1973
nethercote06c7bd72004-11-14 19:11:56 +00001974// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00001975PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00001976{
nethercote06c7bd72004-11-14 19:11:56 +00001977 PRINT("sys_fcntl64 ( %d, %d, %d )", arg1,arg2,arg3);
1978 PRE_REG_READ3(long, "fcntl64",
1979 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
thughesd4b51a62004-07-29 21:20:11 +00001980 if (arg2 == VKI_F_SETLKW || arg2 == VKI_F_SETLKW64)
1981 tst->sys_flags |= MayBlock;
rjwalshf5f536f2003-11-17 17:45:00 +00001982}
1983
nethercote85a456f2004-11-16 17:31:56 +00001984POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00001985{
nethercote493dd182004-02-24 23:57:47 +00001986 if (arg2 == VKI_F_DUPFD) {
nethercote3d5e9102004-11-17 18:22:38 +00001987 if (!VG_(fd_allowed)(res, "fcntl64(DUPFD)", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00001988 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00001989 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00001990 } else {
1991 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00001992 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
nethercote493dd182004-02-24 23:57:47 +00001993 }
1994 }
jsgf855d93d2003-10-13 22:26:55 +00001995}
1996
nethercote85a456f2004-11-16 17:31:56 +00001997PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00001998{
nethercote2e1c37d2004-11-13 13:57:12 +00001999 PRINT("sys_newfstat ( %d, %p )", arg1,arg2);
2000 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
2001 PRE_MEM_WRITE( "fstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002002}
2003
nethercote85a456f2004-11-16 17:31:56 +00002004POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00002005{
nethercoteef0c7662004-11-06 15:38:43 +00002006 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002007}
2008
nethercote73b526f2004-10-31 18:48:21 +00002009static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002010
nethercote75a8c982004-11-11 19:03:34 +00002011// In Linux, the sys_fork() function varies across architectures, but we
2012// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00002013PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00002014{
nethercote73b526f2004-10-31 18:48:21 +00002015 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002016
nethercote75a8c982004-11-11 19:03:34 +00002017 PRINT("sys_fork ( )");
2018 PRE_REG_READ0(long, "fork");
2019
jsgf855d93d2003-10-13 22:26:55 +00002020 vg_assert(VG_(gettid)() == VG_(main_pid));
2021
2022 /* Block all signals during fork, so that we can fix things up in
2023 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002024 VG_(sigfillset)(&mask);
2025 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002026
jsgf855d93d2003-10-13 22:26:55 +00002027 do_atfork_pre(tid);
2028}
2029
nethercote85a456f2004-11-16 17:31:56 +00002030POST(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002031{
2032 if (res == 0) {
2033 do_atfork_child(tid);
2034
2035 /* I am the child. Nuke all other threads which I might
2036 have inherited from my parent. POSIX mandates this. */
2037 VG_(nuke_all_threads_except)( tid );
2038
2039 /* XXX TODO: tid 1 is special, and is presumed to be present.
2040 We should move this TID to 1 in the child. */
2041
2042 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002043 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002044 } else {
nethercoteef0c7662004-11-06 15:38:43 +00002045 PRINT(" fork: process %d created child %d\n", VG_(main_pid), res);
jsgf855d93d2003-10-13 22:26:55 +00002046
2047 do_atfork_parent(tid);
2048
2049 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002050 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002051 }
2052}
2053
nethercote85a456f2004-11-16 17:31:56 +00002054PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002055{
nethercote5a945af2004-11-14 18:37:07 +00002056 PRINT("sys_ftruncate ( %d, %lld )", arg1,(ULong)arg2);
2057 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002058}
2059
nethercote85a456f2004-11-16 17:31:56 +00002060PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002061{
nethercote5a945af2004-11-14 18:37:07 +00002062 PRINT("sys_truncate ( %p(%s), %d )", arg1,arg1,arg2);
2063 PRE_REG_READ2(long, "truncate",
2064 const char *, path, unsigned long, length);
2065 PRE_MEM_RASCIIZ( "truncate(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00002066}
2067
nethercote5a945af2004-11-14 18:37:07 +00002068// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002069PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002070{
2071 PRINT("sys_ftruncate64 ( %d, %lld )", arg1, LOHI64(arg2,arg3));
2072 PRE_REG_READ3(long, "ftruncate64",
2073 unsigned int, fd,
2074 vki_u32, length_low32, vki_u32, length_high32);
2075}
2076
2077// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002078PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002079{
2080 PRINT("sys_truncate64 ( %p, %lld )", arg1, LOHI64(arg2, arg3));
2081 PRE_REG_READ3(long, "truncate64",
2082 const char *, path,
2083 vki_u32, length_low32, vki_u32, length_high32);
2084 PRE_MEM_RASCIIZ( "truncate64(path)", arg1 );
2085}
2086
2087
nethercote85a456f2004-11-16 17:31:56 +00002088PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002089{
nethercote06c7bd72004-11-14 19:11:56 +00002090 PRINT("sys_getdents ( %d, %p, %d )", arg1,arg2,arg3);
2091 PRE_REG_READ3(long, "getdents",
2092 unsigned int, fd, struct linux_dirent *, dirp,
2093 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002094 PRE_MEM_WRITE( "getdents(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002095}
2096
nethercote85a456f2004-11-16 17:31:56 +00002097POST(sys_getdents)
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_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002104{
nethercoteac866b92004-11-15 20:23:15 +00002105 PRINT("sys_getdents64 ( %d, %p, %d )",arg1,arg2,arg3);
nethercote06c7bd72004-11-14 19:11:56 +00002106 PRE_REG_READ3(long, "getdents64",
2107 unsigned int, fd, struct linux_dirent64 *, dirp,
2108 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002109 PRE_MEM_WRITE( "getdents64(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002110}
2111
nethercote85a456f2004-11-16 17:31:56 +00002112POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002113{
2114 if (res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002115 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00002116}
2117
nethercote85a456f2004-11-16 17:31:56 +00002118PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002119{
nethercote686b5db2004-11-14 13:42:51 +00002120 PRINT("sys_getgroups16 ( %d, %p )", arg1, arg2);
2121 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2122 if (arg1 > 0)
2123 PRE_MEM_WRITE( "getgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
2124}
2125
nethercote85a456f2004-11-16 17:31:56 +00002126POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002127{
2128 if (arg1 > 0 && res > 0)
2129 POST_MEM_WRITE( arg2, res * sizeof(vki_old_gid_t) );
2130}
2131
nethercote85a456f2004-11-16 17:31:56 +00002132PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002133{
nethercoteac866b92004-11-15 20:23:15 +00002134 PRINT("sys_getgroups ( %d, %p )", arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00002135 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00002136 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002137 PRE_MEM_WRITE( "getgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002138}
2139
nethercote85a456f2004-11-16 17:31:56 +00002140POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002141{
2142 if (arg1 > 0 && res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002143 POST_MEM_WRITE( arg2, res * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002144}
2145
nethercote85a456f2004-11-16 17:31:56 +00002146PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002147{
nethercoteac866b92004-11-15 20:23:15 +00002148 // Note that the kernel version of getcwd() behaves quite differently to
2149 // the glibc one.
2150 PRINT("sys_getcwd ( %p, %llu )", arg1,(ULong)arg2);
2151 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
nethercoteef0c7662004-11-06 15:38:43 +00002152 PRE_MEM_WRITE( "getcwd(buf)", arg1, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00002153}
2154
nethercote85a456f2004-11-16 17:31:56 +00002155POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002156{
2157 if (res != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00002158 POST_MEM_WRITE( arg1, res );
jsgf855d93d2003-10-13 22:26:55 +00002159}
2160
nethercote85a456f2004-11-16 17:31:56 +00002161PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002162{
nethercote0df495a2004-11-11 16:38:21 +00002163 PRINT("sys_geteuid16 ( )");
2164 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002165}
2166
nethercote85a456f2004-11-16 17:31:56 +00002167PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002168{
nethercote0df495a2004-11-11 16:38:21 +00002169 PRINT("sys_geteuid ( )");
2170 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002171}
2172
nethercote85a456f2004-11-16 17:31:56 +00002173PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002174{
nethercote0df495a2004-11-11 16:38:21 +00002175 PRINT("sys_getegid16 ( )");
2176 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002177}
2178
nethercote85a456f2004-11-16 17:31:56 +00002179PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002180{
nethercote0df495a2004-11-11 16:38:21 +00002181 PRINT("sys_getegid ( )");
2182 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002183}
2184
nethercote85a456f2004-11-16 17:31:56 +00002185PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002186{
nethercote0df495a2004-11-11 16:38:21 +00002187 PRINT("sys_getgid16 ( )");
2188 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002189}
2190
nethercote85a456f2004-11-16 17:31:56 +00002191PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002192{
nethercote0df495a2004-11-11 16:38:21 +00002193 PRINT("sys_getgid ( )");
2194 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002195}
2196
nethercote85a456f2004-11-16 17:31:56 +00002197PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002198{
nethercote4e632c22004-11-09 16:45:33 +00002199 PRINT("sys_getpid ()");
2200 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002201}
2202
nethercote85a456f2004-11-16 17:31:56 +00002203PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002204{
nethercote5b653bc2004-11-15 14:32:12 +00002205 PRINT("sys_getpgid ( %d )", arg1);
2206 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002207}
2208
nethercote85a456f2004-11-16 17:31:56 +00002209PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002210{
nethercote0df495a2004-11-11 16:38:21 +00002211 PRINT("sys_getpgrp ()");
2212 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002213}
2214
nethercote85a456f2004-11-16 17:31:56 +00002215PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002216{
nethercote4e632c22004-11-09 16:45:33 +00002217 PRINT("sys_getppid ()");
2218 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002219}
2220
nethercote620154f2004-11-12 21:21:07 +00002221static void common_post_getrlimit(UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002222{
nethercote620154f2004-11-12 21:21:07 +00002223 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002224
nethercote620154f2004-11-12 21:21:07 +00002225 switch (a1) {
2226 case VKI_RLIMIT_NOFILE:
2227 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2228 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2229 break;
nethercote535f03b2004-02-15 15:32:51 +00002230
nethercote620154f2004-11-12 21:21:07 +00002231 case VKI_RLIMIT_DATA:
2232 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2233 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002234
nethercote620154f2004-11-12 21:21:07 +00002235 case VKI_RLIMIT_STACK:
2236 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2237 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002238 }
jsgf855d93d2003-10-13 22:26:55 +00002239}
2240
nethercote85a456f2004-11-16 17:31:56 +00002241PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002242{
2243 PRINT("sys_old_getrlimit ( %d, %p )", arg1,arg2);
2244 PRE_REG_READ2(long, "old_getrlimit",
2245 unsigned int, resource, struct rlimit *, rlim);
2246 PRE_MEM_WRITE( "old_getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2247}
2248
nethercote85a456f2004-11-16 17:31:56 +00002249POST(sys_old_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002250{
2251 common_post_getrlimit(arg1, arg2);
2252}
2253
nethercote85a456f2004-11-16 17:31:56 +00002254PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002255{
2256 PRINT("sys_getrlimit ( %d, %p )", arg1,arg2);
2257 PRE_REG_READ2(long, "getrlimit",
2258 unsigned int, resource, struct rlimit *, rlim);
2259 PRE_MEM_WRITE( "getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2260}
2261
nethercote85a456f2004-11-16 17:31:56 +00002262POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002263{
2264 common_post_getrlimit(arg1, arg2);
2265}
jsgf855d93d2003-10-13 22:26:55 +00002266
nethercote85a456f2004-11-16 17:31:56 +00002267PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00002268{
2269 /* int getrusage (int who, struct rusage *usage); */
nethercotef1049bf2004-11-14 17:03:47 +00002270 PRINT("sys_getrusage ( %d, %p )", arg1,arg2);
2271 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
nethercoteef0c7662004-11-06 15:38:43 +00002272 PRE_MEM_WRITE( "getrusage(usage)", arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002273}
2274
nethercote85a456f2004-11-16 17:31:56 +00002275POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00002276{
2277 if (res == 0)
nethercotef1049bf2004-11-14 17:03:47 +00002278 VG_TRACK( post_mem_write, arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002279}
2280
nethercote85a456f2004-11-16 17:31:56 +00002281PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00002282{
nethercote686b5db2004-11-14 13:42:51 +00002283 PRINT("sys_gettimeofday ( %p, %p )", arg1,arg2);
2284 PRE_REG_READ2(long, "gettimeofday",
2285 struct timeval *, tv, struct timezone *, tz);
nethercoteef0c7662004-11-06 15:38:43 +00002286 PRE_MEM_WRITE( "gettimeofday(tv)", arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002287 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002288 PRE_MEM_WRITE( "gettimeofday(tz)", arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002289}
2290
nethercote85a456f2004-11-16 17:31:56 +00002291POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002292{
2293 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002294 POST_MEM_WRITE( arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002295 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002296 POST_MEM_WRITE( arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002297 }
2298}
2299
nethercote85a456f2004-11-16 17:31:56 +00002300PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00002301{
2302 PRINT("sys_settimeofday ( %p, %p )", arg1,arg2);
2303 PRE_REG_READ2(long, "settimeofday",
2304 struct timeval *, tv, struct timezone *, tz);
2305 PRE_MEM_READ( "settimeofday(tv)", arg1, sizeof(struct vki_timeval) );
2306 if (arg2 != 0) {
2307 PRE_MEM_READ( "settimeofday(tz)", arg2, sizeof(struct vki_timezone) );
2308 /* maybe should warn if tz->tz_dsttime is non-zero? */
2309 }
2310}
2311
nethercote85a456f2004-11-16 17:31:56 +00002312PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002313{
nethercote0df495a2004-11-11 16:38:21 +00002314 PRINT("sys_getuid16 ( )");
2315 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00002316}
2317
nethercote85a456f2004-11-16 17:31:56 +00002318PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002319{
nethercote0df495a2004-11-11 16:38:21 +00002320 PRINT("sys_getuid ( )");
2321 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00002322}
2323
nethercote7f7e4d12004-11-15 12:28:58 +00002324// XXX: x86-specific
2325// XXX: should use the constants here (eg. SHMAT), not the numbers directly!
nethercote85a456f2004-11-16 17:31:56 +00002326PRE(sys_ipc, 0)
jsgf855d93d2003-10-13 22:26:55 +00002327{
nethercote7f7e4d12004-11-15 12:28:58 +00002328 PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", arg1,arg2,arg3,arg4,arg5,arg6);
2329 // XXX: this is simplistic -- some args are not used in all circumstances.
2330 PRE_REG_READ6(int, "ipc",
2331 vki_uint, call, int, first, int, second, int, third,
2332 void *, ptr, long, fifth)
2333
jsgf855d93d2003-10-13 22:26:55 +00002334 switch (arg1 /* call */) {
2335 case 1: /* IPCOP_semop */
nethercoteef0c7662004-11-06 15:38:43 +00002336 PRE_MEM_READ( "semop(sops)", arg5, arg3 * sizeof(struct vki_sembuf) );
thughes024f25d2004-07-29 22:40:07 +00002337 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002338 break;
2339 case 2: /* IPCOP_semget */
jsgf855d93d2003-10-13 22:26:55 +00002340 break;
thughes60797102004-08-13 22:21:51 +00002341 case 3: /* IPCOP_semctl */
2342 {
nethercote73b526f2004-10-31 18:48:21 +00002343 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002344 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002345 case VKI_IPC_INFO:
2346 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002347 {
2348 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002349 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002350 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002351 break;
2352 }
nethercote73b526f2004-10-31 18:48:21 +00002353 case VKI_IPC_STAT:
2354 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002355 {
2356 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002357 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002358 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002359 break;
2360 }
nethercote73b526f2004-10-31 18:48:21 +00002361 case VKI_IPC_SET:
thughes60797102004-08-13 22:21:51 +00002362 {
2363 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002364 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002365 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002366 break;
2367 }
nethercote73b526f2004-10-31 18:48:21 +00002368 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002369 {
2370 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2371 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002372 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002373 sizeof(short) * nsems );
2374 break;
2375 }
nethercote73b526f2004-10-31 18:48:21 +00002376 case VKI_SETALL:
thughes60797102004-08-13 22:21:51 +00002377 {
2378 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2379 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002380 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002381 sizeof(short) * nsems );
2382 break;
2383 }
nethercote73b526f2004-10-31 18:48:21 +00002384 case VKI_SETVAL:
thughes60797102004-08-13 22:21:51 +00002385 {
nethercoteef0c7662004-11-06 15:38:43 +00002386 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002387 (Addr)&arg->val, sizeof(arg->val) );
2388 break;
2389 }
nethercote73b526f2004-10-31 18:48:21 +00002390 case VKI_IPC_INFO|VKI_IPC_64:
2391 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002392 {
2393 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002394 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002395 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002396 break;
2397 }
nethercote73b526f2004-10-31 18:48:21 +00002398 case VKI_IPC_STAT|VKI_IPC_64:
2399 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002400 {
2401 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002402 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002403 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002404 break;
2405 }
nethercote73b526f2004-10-31 18:48:21 +00002406 case VKI_IPC_SET|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002407 {
2408 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002409 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002410 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002411 break;
2412 }
nethercote73b526f2004-10-31 18:48:21 +00002413 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002414 {
2415 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2416 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002417 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002418 sizeof(short) * nsems );
2419 break;
2420 }
nethercote73b526f2004-10-31 18:48:21 +00002421 case VKI_SETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002422 {
2423 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2424 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002425 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002426 sizeof(short) * nsems );
2427 break;
2428 }
nethercote73b526f2004-10-31 18:48:21 +00002429 case VKI_SETVAL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002430 {
nethercoteef0c7662004-11-06 15:38:43 +00002431 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002432 (Addr)&arg->val, sizeof(arg->val) );
2433 break;
2434 }
thughes60797102004-08-13 22:21:51 +00002435 default:
2436 break;
2437 }
2438 break;
2439 }
thughes03766282004-06-13 14:23:00 +00002440 case 4: /* IPCOP_semtimedop */
nethercoteef0c7662004-11-06 15:38:43 +00002441 PRE_MEM_READ( "semtimedop(sops)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002442 arg3 * sizeof(struct vki_sembuf) );
nethercote163c5e82004-11-17 18:42:20 +00002443 if (arg6 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002444 PRE_MEM_READ( "semtimedop(timeout)", arg6,
nethercote73b526f2004-10-31 18:48:21 +00002445 sizeof(struct vki_timespec) );
thughes024f25d2004-07-29 22:40:07 +00002446 tst->sys_flags |= MayBlock;
thughes03766282004-06-13 14:23:00 +00002447 break;
jsgf855d93d2003-10-13 22:26:55 +00002448 case 11: /* IPCOP_msgsnd */
2449 {
nethercote73b526f2004-10-31 18:48:21 +00002450 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg5;
jsgf855d93d2003-10-13 22:26:55 +00002451 Int msgsz = arg3;
2452
nethercoteef0c7662004-11-06 15:38:43 +00002453 PRE_MEM_READ( "msgsnd(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002454 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002455 PRE_MEM_READ( "msgsnd(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002456 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002457
2458 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2459 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002460 break;
2461 }
2462 case 12: /* IPCOP_msgrcv */
2463 {
nethercote73b526f2004-10-31 18:48:21 +00002464 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002465 Int msgsz = arg3;
2466
nethercote73b526f2004-10-31 18:48:21 +00002467 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2468 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002469 "msgrcv(msgp)" );
2470
nethercoteef0c7662004-11-06 15:38:43 +00002471 PRE_MEM_WRITE( "msgrcv(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002472 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002473 PRE_MEM_WRITE( "msgrcv(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002474 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002475
2476 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2477 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002478 break;
2479 }
2480 case 13: /* IPCOP_msgget */
2481 break;
2482 case 14: /* IPCOP_msgctl */
2483 {
2484 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002485 case VKI_IPC_INFO:
2486 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002487 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002488 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002489 break;
nethercote73b526f2004-10-31 18:48:21 +00002490 case VKI_IPC_STAT:
2491 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002492 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002493 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002494 break;
nethercote73b526f2004-10-31 18:48:21 +00002495 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002496 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002497 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002498 break;
nethercote73b526f2004-10-31 18:48:21 +00002499 case VKI_IPC_INFO|VKI_IPC_64:
2500 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002501 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002502 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002503 break;
nethercote73b526f2004-10-31 18:48:21 +00002504 case VKI_IPC_STAT|VKI_IPC_64:
2505 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002506 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002507 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002508 break;
nethercote73b526f2004-10-31 18:48:21 +00002509 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002510 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002511 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002512 break;
jsgf855d93d2003-10-13 22:26:55 +00002513 default:
2514 break;
2515 }
2516 break;
2517 }
2518 case 21: /* IPCOP_shmat */
2519 {
fitzhardinge98abfc72003-12-16 02:05:15 +00002520 UInt shmid = arg2;
2521 UInt segmentSize = get_shm_size ( shmid );
2522
2523 /* If they didn't ask for a particular address, then place it
2524 like an mmap. */
2525 if (arg5 == 0)
2526 arg5 = VG_(find_map_space)(0, segmentSize, True);
nethercote8ff888f2004-11-17 17:11:45 +00002527 else if (!VG_(valid_client_addr)(arg5, segmentSize, tid, "shmat"))
nethercote35122912004-10-18 17:00:30 +00002528 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002529 break;
2530 }
2531 case 22: /* IPCOP_shmdt */
nethercote8ff888f2004-11-17 17:11:45 +00002532 if (!VG_(valid_client_addr)(arg5, 1, tid, "shmdt"))
nethercote35122912004-10-18 17:00:30 +00002533 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002534 break;
2535 case 23: /* IPCOP_shmget */
2536 break;
2537 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002538 {
thughes60797102004-08-13 22:21:51 +00002539 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002540 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002541 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002542 sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002543 break;
nethercote73b526f2004-10-31 18:48:21 +00002544 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002545 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002546 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002547 break;
nethercote73b526f2004-10-31 18:48:21 +00002548 case VKI_IPC_STAT:
2549 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002550 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002551 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002552 break;
nethercote73b526f2004-10-31 18:48:21 +00002553 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002554 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002555 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002556 break;
nethercote73b526f2004-10-31 18:48:21 +00002557 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002558 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002559 sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002560 break;
nethercote73b526f2004-10-31 18:48:21 +00002561 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002562 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002563 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002564 break;
nethercote73b526f2004-10-31 18:48:21 +00002565 case VKI_IPC_STAT|VKI_IPC_64:
2566 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002567 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002568 sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002569 break;
nethercote73b526f2004-10-31 18:48:21 +00002570 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002571 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002572 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002573 break;
thughes60797102004-08-13 22:21:51 +00002574 default:
2575 break;
jsgf855d93d2003-10-13 22:26:55 +00002576 }
thughes60797102004-08-13 22:21:51 +00002577 break;
jsgf855d93d2003-10-13 22:26:55 +00002578 }
jsgf855d93d2003-10-13 22:26:55 +00002579 default:
2580 VG_(message)(Vg_DebugMsg,
2581 "FATAL: unhandled syscall(ipc) %d",
2582 arg1 );
2583 VG_(core_panic)("... bye!\n");
2584 break; /*NOTREACHED*/
2585 }
2586}
2587
nethercote85a456f2004-11-16 17:31:56 +00002588POST(sys_ipc)
jsgf855d93d2003-10-13 22:26:55 +00002589{
2590 switch (arg1 /* call */) {
2591 case 1: /* IPCOP_semop */
jsgf855d93d2003-10-13 22:26:55 +00002592 case 2: /* IPCOP_semget */
thughes60797102004-08-13 22:21:51 +00002593 break;
jsgf855d93d2003-10-13 22:26:55 +00002594 case 3: /* IPCOP_semctl */
thughes60797102004-08-13 22:21:51 +00002595 {
nethercote73b526f2004-10-31 18:48:21 +00002596 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002597 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002598 case VKI_IPC_INFO:
2599 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002600 {
2601 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002602 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002603 break;
2604 }
nethercote73b526f2004-10-31 18:48:21 +00002605 case VKI_IPC_STAT:
2606 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002607 {
2608 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002609 POST_MEM_WRITE( buf, sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002610 break;
2611 }
nethercote73b526f2004-10-31 18:48:21 +00002612 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002613 {
2614 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2615 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002616 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002617 break;
2618 }
nethercote73b526f2004-10-31 18:48:21 +00002619 case VKI_IPC_INFO|VKI_IPC_64:
2620 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002621 {
2622 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002623 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002624 break;
2625 }
nethercote73b526f2004-10-31 18:48:21 +00002626 case VKI_IPC_STAT|VKI_IPC_64:
2627 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002628 {
2629 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002630 POST_MEM_WRITE( buf, sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002631 break;
2632 }
nethercote73b526f2004-10-31 18:48:21 +00002633 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002634 {
2635 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2636 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002637 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002638 break;
2639 }
thughes60797102004-08-13 22:21:51 +00002640 default:
2641 break;
2642 }
2643 break;
2644 }
thughes03766282004-06-13 14:23:00 +00002645 case 4: /* IPCOP_semtimedop */
jsgf855d93d2003-10-13 22:26:55 +00002646 break;
2647 case 11: /* IPCOP_msgsnd */
2648 break;
2649 case 12: /* IPCOP_msgrcv */
2650 {
nethercote73b526f2004-10-31 18:48:21 +00002651 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002652
nethercote73b526f2004-10-31 18:48:21 +00002653 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2654 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002655 "msgrcv(msgp)" );
2656 if ( res > 0 ) {
nethercoteef0c7662004-11-06 15:38:43 +00002657 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2658 POST_MEM_WRITE( (Addr)msgp->mtext, res );
jsgf855d93d2003-10-13 22:26:55 +00002659 }
2660 break;
2661 }
2662 case 13: /* IPCOP_msgget */
2663 break;
2664 case 14: /* IPCOP_msgctl */
2665 {
2666 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002667 case VKI_IPC_INFO:
2668 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002669 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002670 break;
nethercote73b526f2004-10-31 18:48:21 +00002671 case VKI_IPC_STAT:
2672 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002673 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002674 break;
nethercote73b526f2004-10-31 18:48:21 +00002675 case VKI_IPC_SET:
jsgf855d93d2003-10-13 22:26:55 +00002676 break;
nethercote73b526f2004-10-31 18:48:21 +00002677 case VKI_IPC_INFO|VKI_IPC_64:
2678 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002679 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
jsgf855d93d2003-10-13 22:26:55 +00002680 break;
nethercote73b526f2004-10-31 18:48:21 +00002681 case VKI_IPC_STAT|VKI_IPC_64:
2682 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002683 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid64_ds) );
thughes60797102004-08-13 22:21:51 +00002684 break;
nethercote73b526f2004-10-31 18:48:21 +00002685 case VKI_IPC_SET|VKI_IPC_64:
jsgf855d93d2003-10-13 22:26:55 +00002686 break;
jsgf855d93d2003-10-13 22:26:55 +00002687 default:
2688 break;
2689 }
2690 break;
2691 }
2692 case 21: /* IPCOP_shmat */
2693 {
2694 Int shmid = arg2;
fitzhardinge98abfc72003-12-16 02:05:15 +00002695 Int shmflag = arg3;
jsgf855d93d2003-10-13 22:26:55 +00002696 Addr addr;
2697
jsgf855d93d2003-10-13 22:26:55 +00002698 /* force readability. before the syscall it is
2699 * indeed uninitialized, as can be seen in
2700 * glibc/sysdeps/unix/sysv/linux/shmat.c */
nethercoteef0c7662004-11-06 15:38:43 +00002701 POST_MEM_WRITE( arg4, sizeof( ULong ) );
jsgf855d93d2003-10-13 22:26:55 +00002702
2703 addr = deref_Addr ( tid, arg4, "shmat(addr)" );
2704 if ( addr > 0 ) {
2705 UInt segmentSize = get_shm_size ( shmid );
2706 if ( segmentSize > 0 ) {
nethercote27ea8bc2004-07-10 17:21:14 +00002707 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
jsgf855d93d2003-10-13 22:26:55 +00002708 /* we don't distinguish whether it's read-only or
2709 * read-write -- it doesn't matter really. */
nethercote071c84a2004-07-10 17:30:07 +00002710 VG_TRACK( new_mem_mmap, addr, segmentSize, True, True, False );
fitzhardinge98abfc72003-12-16 02:05:15 +00002711
fitzhardinge98abfc72003-12-16 02:05:15 +00002712 if (!(shmflag & 010000)) /* = SHM_RDONLY */
2713 prot &= ~VKI_PROT_WRITE;
nethercote27ea8bc2004-07-10 17:21:14 +00002714 VG_(map_segment)(addr, segmentSize, prot, SF_SHARED|SF_SHM);
jsgf855d93d2003-10-13 22:26:55 +00002715 }
2716 }
2717 break;
2718 }
2719 case 22: /* IPCOP_shmdt */
fitzhardinge98abfc72003-12-16 02:05:15 +00002720 {
fitzhardinged25e8a22004-02-25 00:07:10 +00002721 Segment *s = VG_(find_segment)(arg5);
fitzhardinge98abfc72003-12-16 02:05:15 +00002722
fitzhardinged25e8a22004-02-25 00:07:10 +00002723 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg5, 1)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00002724 VG_TRACK( die_mem_munmap, s->addr, s->len );
2725 VG_(unmap_range)(s->addr, s->len);
2726 }
jsgf855d93d2003-10-13 22:26:55 +00002727 break;
fitzhardinge98abfc72003-12-16 02:05:15 +00002728 }
jsgf855d93d2003-10-13 22:26:55 +00002729 case 23: /* IPCOP_shmget */
2730 break;
2731 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002732 {
thughes60797102004-08-13 22:21:51 +00002733 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002734 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002735 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002736 break;
nethercote73b526f2004-10-31 18:48:21 +00002737 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002738 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002739 break;
nethercote73b526f2004-10-31 18:48:21 +00002740 case VKI_IPC_STAT:
2741 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002742 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002743 break;
nethercote73b526f2004-10-31 18:48:21 +00002744 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002745 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002746 break;
nethercote73b526f2004-10-31 18:48:21 +00002747 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002748 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002749 break;
nethercote73b526f2004-10-31 18:48:21 +00002750 case VKI_IPC_STAT|VKI_IPC_64:
2751 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002752 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002753 break;
thughes60797102004-08-13 22:21:51 +00002754 default:
2755 break;
jsgf855d93d2003-10-13 22:26:55 +00002756 }
thughes60797102004-08-13 22:21:51 +00002757 break;
jsgf855d93d2003-10-13 22:26:55 +00002758 }
jsgf855d93d2003-10-13 22:26:55 +00002759 default:
2760 VG_(message)(Vg_DebugMsg,
2761 "FATAL: unhandled syscall(ipc) %d",
2762 arg1 );
2763 VG_(core_panic)("... bye!\n");
2764 break; /*NOTREACHED*/
2765 }
2766}
2767
nethercote2e1c37d2004-11-13 13:57:12 +00002768// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00002769PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002770{
nethercote9c311eb2004-11-12 18:20:12 +00002771 PRINT("sys_ioctl ( %d, 0x%x, %p )",arg1,arg2,arg3);
2772 PRE_REG_READ3(long, "ioctl",
2773 unsigned int, fd, unsigned int, request, unsigned long, arg);
2774
jsgf855d93d2003-10-13 22:26:55 +00002775 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00002776 case VKI_TCSETS:
2777 case VKI_TCSETSW:
2778 case VKI_TCSETSF:
nethercote11e07d32004-11-06 16:17:52 +00002779 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002780 break;
nethercote73b526f2004-10-31 18:48:21 +00002781 case VKI_TCGETS:
nethercote11e07d32004-11-06 16:17:52 +00002782 PRE_MEM_WRITE( "ioctl(TCGETS)", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002783 break;
nethercote73b526f2004-10-31 18:48:21 +00002784 case VKI_TCSETA:
2785 case VKI_TCSETAW:
2786 case VKI_TCSETAF:
nethercote11e07d32004-11-06 16:17:52 +00002787 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002788 break;
nethercote73b526f2004-10-31 18:48:21 +00002789 case VKI_TCGETA:
nethercote11e07d32004-11-06 16:17:52 +00002790 PRE_MEM_WRITE( "ioctl(TCGETA)", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002791 break;
nethercote73b526f2004-10-31 18:48:21 +00002792 case VKI_TCSBRK:
2793 case VKI_TCXONC:
2794 case VKI_TCSBRKP:
2795 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00002796 /* These just take an int by value */
2797 break;
nethercote73b526f2004-10-31 18:48:21 +00002798 case VKI_TIOCGWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002799 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002800 break;
nethercote73b526f2004-10-31 18:48:21 +00002801 case VKI_TIOCSWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002802 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002803 break;
nethercote73b526f2004-10-31 18:48:21 +00002804 case VKI_TIOCMBIS:
nethercote11e07d32004-11-06 16:17:52 +00002805 PRE_MEM_READ( "ioctl(TIOCMBIS)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002806 break;
nethercote73b526f2004-10-31 18:48:21 +00002807 case VKI_TIOCMBIC:
nethercote11e07d32004-11-06 16:17:52 +00002808 PRE_MEM_READ( "ioctl(TIOCMBIC)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002809 break;
nethercote73b526f2004-10-31 18:48:21 +00002810 case VKI_TIOCMSET:
nethercote11e07d32004-11-06 16:17:52 +00002811 PRE_MEM_READ( "ioctl(TIOCMSET)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002812 break;
nethercote73b526f2004-10-31 18:48:21 +00002813 case VKI_TIOCLINUX:
nethercote11e07d32004-11-06 16:17:52 +00002814 PRE_MEM_READ( "ioctl(TIOCLINUX)", arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002815 if (*(char *)arg3 == 11) {
nethercote11e07d32004-11-06 16:17:52 +00002816 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", arg3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002817 }
2818 break;
nethercote73b526f2004-10-31 18:48:21 +00002819 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002820 /* Get process group ID for foreground processing group. */
nethercote11e07d32004-11-06 16:17:52 +00002821 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002822 break;
nethercote73b526f2004-10-31 18:48:21 +00002823 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002824 /* Set a process group ID? */
nethercote11e07d32004-11-06 16:17:52 +00002825 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002826 break;
nethercote73b526f2004-10-31 18:48:21 +00002827 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercote11e07d32004-11-06 16:17:52 +00002828 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002829 break;
nethercote73b526f2004-10-31 18:48:21 +00002830 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00002831 /* Just takes an int value. */
2832 break;
nethercote73b526f2004-10-31 18:48:21 +00002833 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
nethercote11e07d32004-11-06 16:17:52 +00002834 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002835 break;
nethercote73b526f2004-10-31 18:48:21 +00002836 case VKI_FIONBIO:
nethercote11e07d32004-11-06 16:17:52 +00002837 PRE_MEM_READ( "ioctl(FIONBIO)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002838 break;
nethercote73b526f2004-10-31 18:48:21 +00002839 case VKI_FIOASYNC:
nethercote11e07d32004-11-06 16:17:52 +00002840 PRE_MEM_READ( "ioctl(FIOASYNC)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002841 break;
nethercote73b526f2004-10-31 18:48:21 +00002842 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercote11e07d32004-11-06 16:17:52 +00002843 PRE_MEM_WRITE( "ioctl(FIONREAD)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002844 break;
2845
nethercote73b526f2004-10-31 18:48:21 +00002846 case VKI_SG_SET_COMMAND_Q:
nethercote11e07d32004-11-06 16:17:52 +00002847 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002848 break;
nethercote73b526f2004-10-31 18:48:21 +00002849 case VKI_SG_IO:
nethercote11e07d32004-11-06 16:17:52 +00002850 PRE_MEM_WRITE( "ioctl(SG_IO)", arg3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00002851 break;
nethercote73b526f2004-10-31 18:48:21 +00002852 case VKI_SG_GET_SCSI_ID:
nethercote11e07d32004-11-06 16:17:52 +00002853 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", arg3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00002854 break;
nethercote73b526f2004-10-31 18:48:21 +00002855 case VKI_SG_SET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002856 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002857 break;
nethercote73b526f2004-10-31 18:48:21 +00002858 case VKI_SG_SET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002859 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002860 break;
nethercote73b526f2004-10-31 18:48:21 +00002861 case VKI_SG_GET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002862 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002863 break;
nethercote73b526f2004-10-31 18:48:21 +00002864 case VKI_SG_GET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002865 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002866 break;
nethercote73b526f2004-10-31 18:48:21 +00002867 case VKI_SG_GET_VERSION_NUM:
nethercote11e07d32004-11-06 16:17:52 +00002868 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002869 break;
nethercote73b526f2004-10-31 18:48:21 +00002870 case VKI_SG_EMULATED_HOST: /* 0x2203 */
nethercote11e07d32004-11-06 16:17:52 +00002871 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002872 break;
nethercote73b526f2004-10-31 18:48:21 +00002873 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
nethercote11e07d32004-11-06 16:17:52 +00002874 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002875 break;
jsgf855d93d2003-10-13 22:26:55 +00002876
muellera4b153a2003-11-19 22:07:14 +00002877 case VKI_IIOCGETCPS:
nethercoteef0c7662004-11-06 15:38:43 +00002878 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", arg3,
nethercote95a97862004-11-06 16:31:43 +00002879 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00002880 break;
muellera4b153a2003-11-19 22:07:14 +00002881 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00002882 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
nethercote73b526f2004-10-31 18:48:21 +00002883 (Addr)&((vki_isdn_net_ioctl_phone *)arg3)->name,
2884 sizeof(((vki_isdn_net_ioctl_phone *)arg3)->name) );
nethercoteef0c7662004-11-06 15:38:43 +00002885 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00002886 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00002887 break;
2888
2889 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00002890 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00002891 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
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(SIOCGIFINDEX)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00002894 break;
nethercote73b526f2004-10-31 18:48:21 +00002895 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00002896 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
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(SIOCGIFFLAGS)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002899 break;
nethercote73b526f2004-10-31 18:48:21 +00002900 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00002901 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
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(SIOCGIFHWADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002904 break;
nethercote73b526f2004-10-31 18:48:21 +00002905 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00002906 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
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(SIOCGIFMTU)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002909 break;
nethercote73b526f2004-10-31 18:48:21 +00002910 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002911 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
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(SIOCGIFADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002914 break;
nethercote73b526f2004-10-31 18:48:21 +00002915 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00002916 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
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(SIOCGIFNETMASK)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002919 break;
nethercote73b526f2004-10-31 18:48:21 +00002920 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00002921 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
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(SIOCGIFMETRIC)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002924 break;
nethercote73b526f2004-10-31 18:48:21 +00002925 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002926 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
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(SIOCGIFMAP)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002929 break;
nethercote73b526f2004-10-31 18:48:21 +00002930 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002931 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00002932 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002933 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002934 break;
nethercote73b526f2004-10-31 18:48:21 +00002935 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002936 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002937 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002938 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002939 break;
nethercote73b526f2004-10-31 18:48:21 +00002940 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002941 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002942 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002943 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002944 break;
nethercote73b526f2004-10-31 18:48:21 +00002945 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00002946 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
nethercote73b526f2004-10-31 18:48:21 +00002947 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
2948 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
nethercote11e07d32004-11-06 16:17:52 +00002949 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002950 break;
nethercote73b526f2004-10-31 18:48:21 +00002951 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00002952 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
nethercote73b526f2004-10-31 18:48:21 +00002953 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002954 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002955 break;
nethercote73b526f2004-10-31 18:48:21 +00002956 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00002957 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002958 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00002959 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002960 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
2961 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00002962 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00002963 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
2964 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00002965 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00002966 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002967 break;
nethercote73b526f2004-10-31 18:48:21 +00002968 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00002969 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00002970 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002971 KERNEL_DO_SYSCALL(tid,res);
2972 if (!VG_(is_kerror)(res) && res == 0)
2973 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
2974 */
nethercoteef0c7662004-11-06 15:38:43 +00002975 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct vki_ifconf));
jsgf855d93d2003-10-13 22:26:55 +00002976 if ( arg3 ) {
2977 // TODO len must be readable and writable
2978 // buf pointer only needs to be readable
nethercote73b526f2004-10-31 18:48:21 +00002979 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00002980 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00002981 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00002982 }
2983 break;
nethercote73b526f2004-10-31 18:48:21 +00002984 case VKI_SIOCGSTAMP:
nethercote11e07d32004-11-06 16:17:52 +00002985 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", arg3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00002986 break;
2987 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
2988 the number of bytes currently in that socket's send buffer.
2989 It writes this value as an int to the memory location
2990 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00002991 case VKI_SIOCOUTQ:
nethercote11e07d32004-11-06 16:17:52 +00002992 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00002993 break;
nethercote73b526f2004-10-31 18:48:21 +00002994 case VKI_SIOCGRARP: /* get RARP table entry */
2995 case VKI_SIOCGARP: /* get ARP table entry */
nethercote11e07d32004-11-06 16:17:52 +00002996 PRE_MEM_WRITE( "ioctl(SIOCGARP)", arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00002997 break;
2998
nethercote73b526f2004-10-31 18:48:21 +00002999 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003000 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00003001 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003002 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00003003 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
3004 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003005 break;
nethercote73b526f2004-10-31 18:48:21 +00003006 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003007 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00003008 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003009 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00003010 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
3011 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003012 break;
nethercote73b526f2004-10-31 18:48:21 +00003013 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003014 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003015 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003016 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003017 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3018 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003019 break;
nethercote73b526f2004-10-31 18:48:21 +00003020 case VKI_SIOCSIFADDR: /* set PA address */
3021 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3022 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3023 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003024 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003025 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003026 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003027 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3028 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003029 break;
nethercote73b526f2004-10-31 18:48:21 +00003030 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003031 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003032 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003033 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003034 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3035 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003036 break;
nethercote73b526f2004-10-31 18:48:21 +00003037 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003038 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003039 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003040 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003041 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3042 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003043 break;
nethercote73b526f2004-10-31 18:48:21 +00003044 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003045 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003046 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003047 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003048 (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3049 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003050 break;
nethercote73b526f2004-10-31 18:48:21 +00003051 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003052 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003053 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003054 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003055 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3056 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003057 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003058 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
3059 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003060 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003061 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in,
3062 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003063 break;
jsgf855d93d2003-10-13 22:26:55 +00003064 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003065 case VKI_SIOCADDRT: /* add routing table entry */
3066 case VKI_SIOCDELRT: /* delete routing table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003067 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", arg3,
3068 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003069 break;
3070
3071 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003072 case VKI_SIOCDRARP: /* delete RARP table entry */
3073 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003074 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003075 case VKI_SIOCSARP: /* set ARP table entry */
3076 case VKI_SIOCDARP: /* delete ARP table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003077 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003078 break;
3079
nethercote73b526f2004-10-31 18:48:21 +00003080 case VKI_SIOCGPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003081 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003082 break;
nethercote73b526f2004-10-31 18:48:21 +00003083 case VKI_SIOCSPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003084 PRE_MEM_READ( "ioctl(SIOCSPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003085 tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003086 break;
3087
3088 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003089 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3090 case VKI_SNDCTL_SEQ_GETINCOUNT:
3091 case VKI_SNDCTL_SEQ_PERCMODE:
3092 case VKI_SNDCTL_SEQ_TESTMIDI:
3093 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3094 case VKI_SNDCTL_SEQ_NRSYNTHS:
3095 case VKI_SNDCTL_SEQ_NRMIDIS:
3096 case VKI_SNDCTL_SEQ_GETTIME:
3097 case VKI_SNDCTL_DSP_GETFMTS:
3098 case VKI_SNDCTL_DSP_GETTRIGGER:
3099 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003100 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003101 case VKI_SNDCTL_DSP_GETCAPS:
3102 case VKI_SOUND_PCM_READ_RATE:
3103 case VKI_SOUND_PCM_READ_CHANNELS:
3104 case VKI_SOUND_PCM_READ_BITS:
3105 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3106 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003107 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
3108 arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003109 break;
nethercote73b526f2004-10-31 18:48:21 +00003110 case VKI_SNDCTL_SEQ_CTRLRATE:
3111 case VKI_SNDCTL_DSP_SPEED:
3112 case VKI_SNDCTL_DSP_STEREO:
3113 case VKI_SNDCTL_DSP_GETBLKSIZE:
3114 case VKI_SNDCTL_DSP_CHANNELS:
3115 case VKI_SOUND_PCM_WRITE_FILTER:
3116 case VKI_SNDCTL_DSP_SUBDIVIDE:
3117 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003118 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003119 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003120 case VKI_SNDCTL_TMR_TIMEBASE:
3121 case VKI_SNDCTL_TMR_TEMPO:
3122 case VKI_SNDCTL_TMR_SOURCE:
3123 case VKI_SNDCTL_MIDI_PRETIME:
3124 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003125 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003126 arg3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003127 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003128 arg3, sizeof(int));
3129 break;
nethercote73b526f2004-10-31 18:48:21 +00003130 case VKI_SNDCTL_DSP_GETOSPACE:
3131 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003132 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
3133 arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003134 break;
nethercote73b526f2004-10-31 18:48:21 +00003135 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003136 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
jsgf855d93d2003-10-13 22:26:55 +00003137 arg3, sizeof(int));
3138 break;
3139
nethercote73b526f2004-10-31 18:48:21 +00003140 case VKI_SNDCTL_DSP_POST:
3141 case VKI_SNDCTL_DSP_RESET:
3142 case VKI_SNDCTL_DSP_SYNC:
3143 case VKI_SNDCTL_DSP_SETSYNCRO:
3144 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003145 break;
3146
3147 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003148 case VKI_RTC_UIE_ON:
3149 case VKI_RTC_UIE_OFF:
3150 case VKI_RTC_AIE_ON:
3151 case VKI_RTC_AIE_OFF:
3152 case VKI_RTC_PIE_ON:
3153 case VKI_RTC_PIE_OFF:
3154 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003155 break;
nethercote73b526f2004-10-31 18:48:21 +00003156 case VKI_RTC_RD_TIME:
3157 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003158 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
nethercote73b526f2004-10-31 18:48:21 +00003159 arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003160 break;
nethercote73b526f2004-10-31 18:48:21 +00003161 case VKI_RTC_ALM_SET:
nethercote11e07d32004-11-06 16:17:52 +00003162 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003163 break;
nethercote73b526f2004-10-31 18:48:21 +00003164 case VKI_RTC_IRQP_READ:
nethercote11e07d32004-11-06 16:17:52 +00003165 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003166 break;
jsgf855d93d2003-10-13 22:26:55 +00003167
nethercote95a97862004-11-06 16:31:43 +00003168 case VKI_BLKGETSIZE:
nethercote11e07d32004-11-06 16:17:52 +00003169 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003170 break;
jsgf855d93d2003-10-13 22:26:55 +00003171
thughesacbbc322004-06-19 12:12:01 +00003172 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003173 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
nethercoteef0c7662004-11-06 15:38:43 +00003174 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003175 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003176 break;
3177
jsgf855d93d2003-10-13 22:26:55 +00003178 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003179 case VKI_CDROM_GET_MCN:
nethercoteef0c7662004-11-06 15:38:43 +00003180 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003181 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003182 break;
nethercote73b526f2004-10-31 18:48:21 +00003183 case VKI_CDROM_SEND_PACKET:
nethercoteef0c7662004-11-06 15:38:43 +00003184 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003185 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003186 break;
nethercote73b526f2004-10-31 18:48:21 +00003187 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003188 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
3189 (Addr) &(((struct vki_cdrom_subchnl*) arg3)->cdsc_format),
3190 sizeof(((struct vki_cdrom_subchnl*) arg3)->cdsc_format));
3191 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003192 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003193 break;
nethercote73b526f2004-10-31 18:48:21 +00003194 case VKI_CDROMREADMODE2:
nethercote11e07d32004-11-06 16:17:52 +00003195 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", arg3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003196 break;
nethercote73b526f2004-10-31 18:48:21 +00003197 case VKI_CDROMREADTOCHDR:
nethercote11e07d32004-11-06 16:17:52 +00003198 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003199 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003200 break;
nethercote73b526f2004-10-31 18:48:21 +00003201 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003202 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
3203 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_format),
3204 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_format));
3205 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
3206 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_track),
3207 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_track));
3208 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003209 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003210 break;
nethercote73b526f2004-10-31 18:48:21 +00003211 case VKI_CDROMMULTISESSION: /* 0x5310 */
nethercoteef0c7662004-11-06 15:38:43 +00003212 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003213 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003214 break;
nethercote73b526f2004-10-31 18:48:21 +00003215 case VKI_CDROMVOLREAD: /* 0x5313 */
nethercoteef0c7662004-11-06 15:38:43 +00003216 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003217 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003218 break;
nethercote73b526f2004-10-31 18:48:21 +00003219 case VKI_CDROMREADAUDIO: /* 0x530e */
nethercoteef0c7662004-11-06 15:38:43 +00003220 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003221 sizeof (struct vki_cdrom_read_audio));
thughes5b788fb2004-09-11 15:07:14 +00003222 if ( arg3 ) {
3223 /* ToDo: don't do any of the following if the structure is invalid */
nethercote73b526f2004-10-31 18:48:21 +00003224 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003225 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3226 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003227 }
3228 break;
nethercote73b526f2004-10-31 18:48:21 +00003229 case VKI_CDROMPLAYMSF:
nethercote11e07d32004-11-06 16:17:52 +00003230 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", arg3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003231 break;
3232 /* The following two are probably bogus (should check args
3233 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003234 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3235 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003236 break;
thughes66d80092004-06-19 12:41:05 +00003237
nethercote73b526f2004-10-31 18:48:21 +00003238 case VKI_FIGETBSZ:
nethercote11e07d32004-11-06 16:17:52 +00003239 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003240 break;
nethercote73b526f2004-10-31 18:48:21 +00003241 case VKI_FIBMAP:
nethercote11e07d32004-11-06 16:17:52 +00003242 PRE_MEM_READ( "ioctl(FIBMAP)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003243 break;
3244
nethercote73b526f2004-10-31 18:48:21 +00003245 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
nethercoteef0c7662004-11-06 15:38:43 +00003246 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003247 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003248 break;
nethercote73b526f2004-10-31 18:48:21 +00003249 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
nethercoteef0c7662004-11-06 15:38:43 +00003250 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003251 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003252 break;
jsgf855d93d2003-10-13 22:26:55 +00003253
nethercote73b526f2004-10-31 18:48:21 +00003254 case VKI_PPCLAIM:
3255 case VKI_PPEXCL:
3256 case VKI_PPYIELD:
3257 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003258 break;
nethercote73b526f2004-10-31 18:48:21 +00003259 case VKI_PPSETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003260 PRE_MEM_READ( "ioctl(PPSETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003261 break;
nethercote73b526f2004-10-31 18:48:21 +00003262 case VKI_PPGETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003263 PRE_MEM_WRITE( "ioctl(PPGETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003264 break;
nethercote73b526f2004-10-31 18:48:21 +00003265 case VKI_PPSETPHASE:
nethercote11e07d32004-11-06 16:17:52 +00003266 PRE_MEM_READ( "ioctl(PPSETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003267 break;
nethercote73b526f2004-10-31 18:48:21 +00003268 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003269 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003270 break;
nethercote73b526f2004-10-31 18:48:21 +00003271 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003272 PRE_MEM_WRITE( "ioctl(PPGETMODES)", arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003273 break;
nethercote73b526f2004-10-31 18:48:21 +00003274 case VKI_PPSETFLAGS:
nethercote11e07d32004-11-06 16:17:52 +00003275 PRE_MEM_READ( "ioctl(PPSETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003276 break;
nethercote73b526f2004-10-31 18:48:21 +00003277 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003278 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003279 break;
nethercote73b526f2004-10-31 18:48:21 +00003280 case VKI_PPRSTATUS:
nethercote11e07d32004-11-06 16:17:52 +00003281 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003282 break;
nethercote73b526f2004-10-31 18:48:21 +00003283 case VKI_PPRDATA:
nethercote11e07d32004-11-06 16:17:52 +00003284 PRE_MEM_WRITE( "ioctl(PPRDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003285 break;
nethercote73b526f2004-10-31 18:48:21 +00003286 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003287 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003288 break;
nethercote73b526f2004-10-31 18:48:21 +00003289 case VKI_PPWDATA:
nethercote11e07d32004-11-06 16:17:52 +00003290 PRE_MEM_READ( "ioctl(PPWDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003291 break;
nethercote73b526f2004-10-31 18:48:21 +00003292 case VKI_PPWCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003293 PRE_MEM_READ( "ioctl(PPWCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003294 break;
nethercote73b526f2004-10-31 18:48:21 +00003295 case VKI_PPFCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003296 PRE_MEM_READ( "ioctl(PPFCONTROL)", arg3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003297 break;
nethercote73b526f2004-10-31 18:48:21 +00003298 case VKI_PPDATADIR:
nethercote11e07d32004-11-06 16:17:52 +00003299 PRE_MEM_READ( "ioctl(PPDATADIR)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003300 break;
nethercote73b526f2004-10-31 18:48:21 +00003301 case VKI_PPNEGOT:
nethercote11e07d32004-11-06 16:17:52 +00003302 PRE_MEM_READ( "ioctl(PPNEGOT)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003303 break;
nethercote73b526f2004-10-31 18:48:21 +00003304 case VKI_PPWCTLONIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003305 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003306 break;
nethercote73b526f2004-10-31 18:48:21 +00003307 case VKI_PPCLRIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003308 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003309 break;
nethercote73b526f2004-10-31 18:48:21 +00003310 case VKI_PPSETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003311 PRE_MEM_READ( "ioctl(PPSETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003312 break;
nethercote73b526f2004-10-31 18:48:21 +00003313 case VKI_PPGETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003314 PRE_MEM_WRITE( "ioctl(PPGETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003315 break;
3316
thughesb3d3bcf2004-11-13 00:36:15 +00003317 case VKI_GIO_FONT:
3318 PRE_MEM_WRITE( "ioctl(GIO_FONT)", arg3, 32 * 256 );
3319 break;
3320 case VKI_PIO_FONT:
3321 PRE_MEM_READ( "ioctl(PIO_FONT)", arg3, 32 * 256 );
3322 break;
3323
3324 case VKI_GIO_FONTX:
3325 PRE_MEM_READ( "ioctl(GIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3326 if ( arg3 ) {
3327 /* ToDo: don't do any of the following if the structure is invalid */
3328 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3329 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3330 32 * cfd->charcount );
3331 }
3332 break;
3333 case VKI_PIO_FONTX:
3334 PRE_MEM_READ( "ioctl(PIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3335 if ( arg3 ) {
3336 /* ToDo: don't do any of the following if the structure is invalid */
3337 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3338 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3339 32 * cfd->charcount );
3340 }
3341 break;
3342
3343 case VKI_PIO_FONTRESET:
3344 break;
3345
3346 case VKI_GIO_CMAP:
3347 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", arg3, 16 * 3 );
3348 break;
3349 case VKI_PIO_CMAP:
3350 PRE_MEM_READ( "ioctl(PIO_CMAP)", arg3, 16 * 3 );
3351 break;
3352
3353 case VKI_KIOCSOUND:
3354 case VKI_KDMKTONE:
3355 break;
3356
3357 case VKI_KDGETLED:
3358 PRE_MEM_WRITE( "ioctl(KDGETLED)", arg3, sizeof(char) );
3359 break;
3360 case VKI_KDSETLED:
3361 break;
3362
3363 case VKI_KDGKBTYPE:
3364 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", arg3, sizeof(char) );
3365 break;
3366
3367 case VKI_KDADDIO:
3368 case VKI_KDDELIO:
3369 case VKI_KDENABIO:
3370 case VKI_KDDISABIO:
3371 break;
3372
3373 case VKI_KDSETMODE:
3374 break;
3375 case VKI_KDGETMODE:
3376 PRE_MEM_WRITE( "ioctl(KDGETMODE)", arg3, sizeof(int) );
3377 break;
3378
3379 case VKI_KDMAPDISP:
3380 case VKI_KDUNMAPDISP:
3381 break;
3382
3383 case VKI_GIO_SCRNMAP:
3384 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3385 break;
3386 case VKI_PIO_SCRNMAP:
3387 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3388 break;
3389 case VKI_GIO_UNISCRNMAP:
3390 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", arg3,
3391 VKI_E_TABSZ * sizeof(unsigned short) );
3392 break;
3393 case VKI_PIO_UNISCRNMAP:
3394 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", arg3,
3395 VKI_E_TABSZ * sizeof(unsigned short) );
3396 break;
3397
3398 case VKI_KDGKBMODE:
3399 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", arg3, sizeof(int) );
3400 break;
3401 case VKI_KDSKBMODE:
3402 break;
3403
3404 case VKI_KDGKBMETA:
3405 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", arg3, sizeof(int) );
3406 break;
3407 case VKI_KDSKBMETA:
3408 break;
3409
3410 case VKI_KDGKBLED:
3411 PRE_MEM_WRITE( "ioctl(KDGKBLED)", arg3, sizeof(char) );
3412 break;
3413 case VKI_KDSKBLED:
3414 break;
3415
3416 case VKI_KDGKBENT:
3417 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
3418 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3419 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3420 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
3421 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3422 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3423 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
3424 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3425 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3426 break;
3427 case VKI_KDSKBENT:
3428 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
3429 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3430 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3431 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
3432 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3433 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3434 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
3435 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3436 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3437 break;
3438
3439 case VKI_KDGKBSENT:
3440 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
3441 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3442 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3443 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
3444 (Addr)((struct vki_kbsentry *)arg3)->kb_string,
3445 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
3446 break;
3447 case VKI_KDSKBSENT:
3448 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
3449 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3450 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3451 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
3452 (Addr)((struct vki_kbsentry *)arg3)->kb_string );
3453 break;
3454
3455 case VKI_KDGKBDIACR:
3456 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3457 break;
3458 case VKI_KDSKBDIACR:
3459 PRE_MEM_READ( "ioctl(KDSKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3460 break;
3461
3462 case VKI_KDGETKEYCODE:
3463 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
3464 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3465 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3466 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
3467 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3468 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3469 break;
3470 case VKI_KDSETKEYCODE:
3471 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
3472 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3473 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3474 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
3475 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3476 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3477 break;
3478
3479 case VKI_KDSIGACCEPT:
3480 break;
3481
3482 case VKI_KDKBDREP:
3483 PRE_MEM_READ( "ioctl(KBKBDREP)", arg3, sizeof(struct vki_kbd_repeat) );
3484 break;
3485
jsgf855d93d2003-10-13 22:26:55 +00003486 /* We don't have any specific information on it, so
3487 try to do something reasonable based on direction and
3488 size bits. The encoding scheme is described in
3489 /usr/include/asm/ioctl.h.
3490
3491 According to Simon Hausmann, _IOC_READ means the kernel
3492 writes a value to the ioctl value passed from the user
3493 space and the other way around with _IOC_WRITE. */
3494 default: {
nethercote73b526f2004-10-31 18:48:21 +00003495 UInt dir = _VKI_IOC_DIR(arg2);
3496 UInt size = _VKI_IOC_SIZE(arg2);
jsgf855d93d2003-10-13 22:26:55 +00003497 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3498 /*
3499 * Be very lax about ioctl handling; the only
3500 * assumption is that the size is correct. Doesn't
3501 * require the full buffer to be initialized when
3502 * writing. Without this, using some device
3503 * drivers with a large number of strange ioctl
3504 * commands becomes very tiresome.
3505 */
nethercote73b526f2004-10-31 18:48:21 +00003506 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003507 static Int moans = 3;
3508 if (moans > 0) {
3509 moans--;
3510 VG_(message)(Vg_UserMsg,
3511 "Warning: noted but unhandled ioctl 0x%x"
3512 " with no size/direction hints",
3513 arg2);
3514 VG_(message)(Vg_UserMsg,
3515 " This could cause spurious value errors"
3516 " to appear.");
3517 VG_(message)(Vg_UserMsg,
3518 " See README_MISSING_SYSCALL_OR_IOCTL for "
3519 "guidance on writing a proper wrapper." );
3520 }
3521 } else {
nethercote73b526f2004-10-31 18:48:21 +00003522 if ((dir & _VKI_IOC_WRITE) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003523 PRE_MEM_READ( "ioctl(generic)", arg3, size);
nethercote73b526f2004-10-31 18:48:21 +00003524 if ((dir & _VKI_IOC_READ) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003525 PRE_MEM_WRITE( "ioctl(generic)", arg3, size);
jsgf855d93d2003-10-13 22:26:55 +00003526 }
3527 break;
3528 }
3529 }
3530}
3531
nethercote85a456f2004-11-16 17:31:56 +00003532POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003533{
jsgf855d93d2003-10-13 22:26:55 +00003534 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003535 case VKI_TCSETS:
3536 case VKI_TCSETSW:
3537 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003538 break;
nethercote73b526f2004-10-31 18:48:21 +00003539 case VKI_TCGETS:
nethercoteef0c7662004-11-06 15:38:43 +00003540 POST_MEM_WRITE( arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003541 break;
nethercote73b526f2004-10-31 18:48:21 +00003542 case VKI_TCSETA:
3543 case VKI_TCSETAW:
3544 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003545 break;
nethercote73b526f2004-10-31 18:48:21 +00003546 case VKI_TCGETA:
nethercoteef0c7662004-11-06 15:38:43 +00003547 POST_MEM_WRITE( arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003548 break;
nethercote73b526f2004-10-31 18:48:21 +00003549 case VKI_TCSBRK:
3550 case VKI_TCXONC:
3551 case VKI_TCSBRKP:
3552 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003553 break;
nethercote73b526f2004-10-31 18:48:21 +00003554 case VKI_TIOCGWINSZ:
nethercoteef0c7662004-11-06 15:38:43 +00003555 POST_MEM_WRITE( arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003556 break;
nethercote73b526f2004-10-31 18:48:21 +00003557 case VKI_TIOCSWINSZ:
3558 case VKI_TIOCMBIS:
3559 case VKI_TIOCMBIC:
3560 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003561 break;
nethercote73b526f2004-10-31 18:48:21 +00003562 case VKI_TIOCLINUX:
nethercoteef0c7662004-11-06 15:38:43 +00003563 POST_MEM_WRITE( arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003564 break;
nethercote73b526f2004-10-31 18:48:21 +00003565 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003566 /* Get process group ID for foreground processing group. */
nethercoteef0c7662004-11-06 15:38:43 +00003567 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003568 break;
nethercote73b526f2004-10-31 18:48:21 +00003569 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003570 /* Set a process group ID? */
nethercoteef0c7662004-11-06 15:38:43 +00003571 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003572 break;
nethercote73b526f2004-10-31 18:48:21 +00003573 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercoteef0c7662004-11-06 15:38:43 +00003574 POST_MEM_WRITE( arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003575 break;
nethercote73b526f2004-10-31 18:48:21 +00003576 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003577 break;
nethercote73b526f2004-10-31 18:48:21 +00003578 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003579 break;
nethercote73b526f2004-10-31 18:48:21 +00003580 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003581 break;
nethercote73b526f2004-10-31 18:48:21 +00003582 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003583 break;
nethercote73b526f2004-10-31 18:48:21 +00003584 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercoteef0c7662004-11-06 15:38:43 +00003585 POST_MEM_WRITE( arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003586 break;
3587
nethercote73b526f2004-10-31 18:48:21 +00003588 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003589 break;
nethercote73b526f2004-10-31 18:48:21 +00003590 case VKI_SG_IO:
3591 VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003592 break;
nethercote73b526f2004-10-31 18:48:21 +00003593 case VKI_SG_GET_SCSI_ID:
3594 VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003595 break;
nethercote73b526f2004-10-31 18:48:21 +00003596 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003597 break;
nethercote73b526f2004-10-31 18:48:21 +00003598 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003599 break;
nethercote73b526f2004-10-31 18:48:21 +00003600 case VKI_SG_GET_RESERVED_SIZE:
thughes64326692004-09-11 15:14:59 +00003601 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003602 break;
nethercote73b526f2004-10-31 18:48:21 +00003603 case VKI_SG_GET_TIMEOUT:
thughes64326692004-09-11 15:14:59 +00003604 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003605 break;
nethercote73b526f2004-10-31 18:48:21 +00003606 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003607 break;
nethercote73b526f2004-10-31 18:48:21 +00003608 case VKI_SG_EMULATED_HOST:
thughes5b788fb2004-09-11 15:07:14 +00003609 VG_TRACK( post_mem_write,arg3, sizeof(int));
3610 break;
nethercote73b526f2004-10-31 18:48:21 +00003611 case VKI_SG_GET_SG_TABLESIZE:
thughes5b788fb2004-09-11 15:07:14 +00003612 VG_TRACK( post_mem_write,arg3, sizeof(int));
3613 break;
jsgf855d93d2003-10-13 22:26:55 +00003614
muellera4b153a2003-11-19 22:07:14 +00003615 case VKI_IIOCGETCPS:
nethercote95a97862004-11-06 16:31:43 +00003616 POST_MEM_WRITE( arg3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003617 break;
muellera4b153a2003-11-19 22:07:14 +00003618 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003619 POST_MEM_WRITE( arg3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003620 break;
3621
3622 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003623 case VKI_SIOCGIFINDEX: /* get iface index */
thughes64326692004-09-11 15:14:59 +00003624 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003625 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
3626 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003627 break;
nethercote73b526f2004-10-31 18:48:21 +00003628 case VKI_SIOCGIFFLAGS: /* get flags */
thughes64326692004-09-11 15:14:59 +00003629 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003630 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
3631 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003632 break;
nethercote73b526f2004-10-31 18:48:21 +00003633 case VKI_SIOCGIFHWADDR: /* Get hardware address */
thughes64326692004-09-11 15:14:59 +00003634 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003635 (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3636 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003637 break;
nethercote73b526f2004-10-31 18:48:21 +00003638 case VKI_SIOCGIFMTU: /* get MTU size */
thughes64326692004-09-11 15:14:59 +00003639 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003640 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3641 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003642 break;
nethercote73b526f2004-10-31 18:48:21 +00003643 case VKI_SIOCGIFADDR: /* get PA address */
3644 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3645 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3646 case VKI_SIOCGIFNETMASK: /* get network PA mask */
thughes64326692004-09-11 15:14:59 +00003647 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003648 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3649 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003650 break;
nethercote73b526f2004-10-31 18:48:21 +00003651 case VKI_SIOCGIFMETRIC: /* get metric */
thughes64326692004-09-11 15:14:59 +00003652 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003653 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3654 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003655 break;
nethercote73b526f2004-10-31 18:48:21 +00003656 case VKI_SIOCGIFMAP: /* Get device parameters */
thughes64326692004-09-11 15:14:59 +00003657 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003658 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
3659 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003660 break;
3661 break;
nethercote73b526f2004-10-31 18:48:21 +00003662 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
thughes64326692004-09-11 15:14:59 +00003663 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003664 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3665 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003666 break;
nethercote73b526f2004-10-31 18:48:21 +00003667 case VKI_SIOCGIFNAME: /* get iface name */
thughes64326692004-09-11 15:14:59 +00003668 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003669 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_name,
3670 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003671 break;
nethercote73b526f2004-10-31 18:48:21 +00003672 case VKI_SIOCGMIIPHY: /* get hardware entry */
thughes64326692004-09-11 15:14:59 +00003673 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003674 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3675 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003676 break;
nethercote73b526f2004-10-31 18:48:21 +00003677 case VKI_SIOCGMIIREG: /* get hardware entry registers */
thughes64326692004-09-11 15:14:59 +00003678 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003679 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out,
3680 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003681 break;
nethercote73b526f2004-10-31 18:48:21 +00003682 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003683 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00003684 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003685 KERNEL_DO_SYSCALL(tid,res);
3686 if (!VG_(is_kerror)(res) && res == 0)
3687 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
3688 */
3689 if (res == 0 && arg3 ) {
nethercote73b526f2004-10-31 18:48:21 +00003690 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
3691 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003692 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003693 }
3694 break;
nethercote73b526f2004-10-31 18:48:21 +00003695 case VKI_SIOCGSTAMP:
3696 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003697 break;
3698 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3699 the number of bytes currently in that socket's send buffer.
3700 It writes this value as an int to the memory location
3701 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003702 case VKI_SIOCOUTQ:
thughes64326692004-09-11 15:14:59 +00003703 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003704 break;
nethercote73b526f2004-10-31 18:48:21 +00003705 case VKI_SIOCGRARP: /* get RARP table entry */
3706 case VKI_SIOCGARP: /* get ARP table entry */
3707 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003708 break;
3709
nethercote73b526f2004-10-31 18:48:21 +00003710 case VKI_SIOCSIFFLAGS: /* set flags */
3711 case VKI_SIOCSIFMAP: /* Set device parameters */
3712 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3713 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3714 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3715 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3716 case VKI_SIOCSIFMETRIC: /* set metric */
3717 case VKI_SIOCSIFADDR: /* set PA address */
3718 case VKI_SIOCSIFMTU: /* set MTU size */
3719 case VKI_SIOCSIFHWADDR: /* set hardware address */
3720 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003721 break;
3722 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003723 case VKI_SIOCADDRT: /* add routing table entry */
3724 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003725 break;
3726
3727 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003728 case VKI_SIOCDRARP: /* delete RARP table entry */
3729 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003730 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003731 case VKI_SIOCSARP: /* set ARP table entry */
3732 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003733 break;
3734
nethercote73b526f2004-10-31 18:48:21 +00003735 case VKI_SIOCGPGRP:
thughes1174fed2004-09-11 15:33:17 +00003736 VG_TRACK( post_mem_write,arg3, sizeof(int));
3737 break;
nethercote73b526f2004-10-31 18:48:21 +00003738 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003739 break;
3740
3741 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003742 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3743 case VKI_SNDCTL_SEQ_GETINCOUNT:
3744 case VKI_SNDCTL_SEQ_PERCMODE:
3745 case VKI_SNDCTL_SEQ_TESTMIDI:
3746 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3747 case VKI_SNDCTL_SEQ_NRSYNTHS:
3748 case VKI_SNDCTL_SEQ_NRMIDIS:
3749 case VKI_SNDCTL_SEQ_GETTIME:
3750 case VKI_SNDCTL_DSP_GETFMTS:
3751 case VKI_SNDCTL_DSP_GETTRIGGER:
3752 case VKI_SNDCTL_DSP_GETODELAY:
3753 case VKI_SNDCTL_DSP_GETSPDIF:
3754 case VKI_SNDCTL_DSP_GETCAPS:
3755 case VKI_SOUND_PCM_READ_RATE:
3756 case VKI_SOUND_PCM_READ_CHANNELS:
3757 case VKI_SOUND_PCM_READ_BITS:
3758 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3759 case VKI_SOUND_PCM_READ_FILTER:
thughes64326692004-09-11 15:14:59 +00003760 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003761 break;
nethercote73b526f2004-10-31 18:48:21 +00003762 case VKI_SNDCTL_SEQ_CTRLRATE:
3763 case VKI_SNDCTL_DSP_SPEED:
3764 case VKI_SNDCTL_DSP_STEREO:
3765 case VKI_SNDCTL_DSP_GETBLKSIZE:
3766 case VKI_SNDCTL_DSP_CHANNELS:
3767 case VKI_SOUND_PCM_WRITE_FILTER:
3768 case VKI_SNDCTL_DSP_SUBDIVIDE:
3769 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003770 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003771 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003772 case VKI_SNDCTL_TMR_TIMEBASE:
3773 case VKI_SNDCTL_TMR_TEMPO:
3774 case VKI_SNDCTL_TMR_SOURCE:
3775 case VKI_SNDCTL_MIDI_PRETIME:
3776 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00003777 break;
nethercote73b526f2004-10-31 18:48:21 +00003778 case VKI_SNDCTL_DSP_GETOSPACE:
3779 case VKI_SNDCTL_DSP_GETISPACE:
3780 VG_TRACK( post_mem_write,arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003781 break;
nethercote73b526f2004-10-31 18:48:21 +00003782 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00003783 break;
3784
nethercote73b526f2004-10-31 18:48:21 +00003785 case VKI_SNDCTL_DSP_POST:
3786 case VKI_SNDCTL_DSP_RESET:
3787 case VKI_SNDCTL_DSP_SYNC:
3788 case VKI_SNDCTL_DSP_SETSYNCRO:
3789 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003790 break;
3791
3792 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003793 case VKI_RTC_UIE_ON:
3794 case VKI_RTC_UIE_OFF:
3795 case VKI_RTC_AIE_ON:
3796 case VKI_RTC_AIE_OFF:
3797 case VKI_RTC_PIE_ON:
3798 case VKI_RTC_PIE_OFF:
3799 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003800 break;
nethercote73b526f2004-10-31 18:48:21 +00003801 case VKI_RTC_RD_TIME:
3802 case VKI_RTC_ALM_READ:
3803 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003804 break;
nethercote73b526f2004-10-31 18:48:21 +00003805 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00003806 break;
nethercote73b526f2004-10-31 18:48:21 +00003807 case VKI_RTC_IRQP_READ:
thughes64326692004-09-11 15:14:59 +00003808 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003809 break;
jsgf855d93d2003-10-13 22:26:55 +00003810
nethercote95a97862004-11-06 16:31:43 +00003811 case VKI_BLKGETSIZE:
thughes64326692004-09-11 15:14:59 +00003812 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003813 break;
jsgf855d93d2003-10-13 22:26:55 +00003814
thughesacbbc322004-06-19 12:12:01 +00003815 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003816 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
3817 VG_TRACK( post_mem_write,arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003818 break;
3819
jsgf855d93d2003-10-13 22:26:55 +00003820 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003821 case VKI_CDROMSUBCHNL:
3822 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003823 break;
nethercote73b526f2004-10-31 18:48:21 +00003824 case VKI_CDROMREADTOCHDR:
3825 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003826 break;
nethercote73b526f2004-10-31 18:48:21 +00003827 case VKI_CDROMREADTOCENTRY:
3828 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003829 break;
nethercote73b526f2004-10-31 18:48:21 +00003830 case VKI_CDROMMULTISESSION:
3831 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003832 break;
nethercote73b526f2004-10-31 18:48:21 +00003833 case VKI_CDROMVOLREAD:
3834 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003835 break;
nethercote73b526f2004-10-31 18:48:21 +00003836 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00003837 {
nethercote73b526f2004-10-31 18:48:21 +00003838 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003839 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003840 break;
3841 }
3842
nethercote73b526f2004-10-31 18:48:21 +00003843 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00003844 break;
3845 /* The following two are probably bogus (should check args
3846 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003847 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3848 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003849 break;
3850
nethercote73b526f2004-10-31 18:48:21 +00003851 case VKI_FIGETBSZ:
thughes64326692004-09-11 15:14:59 +00003852 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003853 break;
nethercote73b526f2004-10-31 18:48:21 +00003854 case VKI_FIBMAP:
thughes64326692004-09-11 15:14:59 +00003855 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003856 break;
3857
nethercote73b526f2004-10-31 18:48:21 +00003858 case VKI_FBIOGET_VSCREENINFO: //0x4600
3859 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003860 break;
nethercote73b526f2004-10-31 18:48:21 +00003861 case VKI_FBIOGET_FSCREENINFO: //0x4602
3862 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003863 break;
3864
nethercote73b526f2004-10-31 18:48:21 +00003865 case VKI_PPCLAIM:
3866 case VKI_PPEXCL:
3867 case VKI_PPYIELD:
3868 case VKI_PPRELEASE:
3869 case VKI_PPSETMODE:
3870 case VKI_PPSETPHASE:
3871 case VKI_PPSETFLAGS:
3872 case VKI_PPWDATA:
3873 case VKI_PPWCONTROL:
3874 case VKI_PPFCONTROL:
3875 case VKI_PPDATADIR:
3876 case VKI_PPNEGOT:
3877 case VKI_PPWCTLONIRQ:
3878 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00003879 break;
nethercote73b526f2004-10-31 18:48:21 +00003880 case VKI_PPGETMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003881 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003882 break;
nethercote73b526f2004-10-31 18:48:21 +00003883 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003884 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003885 break;
nethercote73b526f2004-10-31 18:48:21 +00003886 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003887 POST_MEM_WRITE( arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003888 break;
nethercote73b526f2004-10-31 18:48:21 +00003889 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003890 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003891 break;
nethercote73b526f2004-10-31 18:48:21 +00003892 case VKI_PPRSTATUS:
nethercoteef0c7662004-11-06 15:38:43 +00003893 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003894 break;
nethercote73b526f2004-10-31 18:48:21 +00003895 case VKI_PPRDATA:
nethercoteef0c7662004-11-06 15:38:43 +00003896 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003897 break;
nethercote73b526f2004-10-31 18:48:21 +00003898 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003899 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003900 break;
nethercote73b526f2004-10-31 18:48:21 +00003901 case VKI_PPCLRIRQ:
nethercoteef0c7662004-11-06 15:38:43 +00003902 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003903 break;
nethercote73b526f2004-10-31 18:48:21 +00003904 case VKI_PPGETTIME:
nethercoteef0c7662004-11-06 15:38:43 +00003905 POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003906 break;
3907
thughesc3b842d2004-11-13 10:38:04 +00003908 case VKI_GIO_FONT:
3909 POST_MEM_WRITE( arg3, 32 * 256 );
3910 break;
3911 case VKI_PIO_FONT:
3912 break;
3913
3914 case VKI_GIO_FONTX:
3915 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)arg3)->chardata,
3916 32 * ((struct vki_consolefontdesc *)arg3)->charcount );
3917 break;
3918 case VKI_PIO_FONTX:
3919 break;
3920
3921 case VKI_PIO_FONTRESET:
3922 break;
3923
3924 case VKI_GIO_CMAP:
3925 POST_MEM_WRITE( arg3, 16 * 3 );
3926 break;
3927 case VKI_PIO_CMAP:
3928 break;
3929
3930 case VKI_KIOCSOUND:
3931 case VKI_KDMKTONE:
3932 break;
3933
3934 case VKI_KDGETLED:
3935 POST_MEM_WRITE( arg3, sizeof(char) );
3936 break;
3937 case VKI_KDSETLED:
3938 break;
3939
3940 case VKI_KDGKBTYPE:
3941 POST_MEM_WRITE( arg3, sizeof(char) );
3942 break;
3943
3944 case VKI_KDADDIO:
3945 case VKI_KDDELIO:
3946 case VKI_KDENABIO:
3947 case VKI_KDDISABIO:
3948 break;
3949
3950 case VKI_KDSETMODE:
3951 break;
3952 case VKI_KDGETMODE:
3953 POST_MEM_WRITE( arg3, sizeof(int) );
3954 break;
3955
3956 case VKI_KDMAPDISP:
3957 case VKI_KDUNMAPDISP:
3958 break;
3959
3960 case VKI_GIO_SCRNMAP:
3961 POST_MEM_WRITE( arg3, VKI_E_TABSZ );
3962 break;
3963 case VKI_PIO_SCRNMAP:
3964 break;
3965 case VKI_GIO_UNISCRNMAP:
3966 POST_MEM_WRITE( arg3, VKI_E_TABSZ * sizeof(unsigned short) );
3967 break;
3968 case VKI_PIO_UNISCRNMAP:
3969 break;
3970
3971 case VKI_KDGKBMODE:
3972 POST_MEM_WRITE( arg3, sizeof(int) );
3973 break;
3974 case VKI_KDSKBMODE:
3975 break;
3976
3977 case VKI_KDGKBMETA:
3978 POST_MEM_WRITE( arg3, sizeof(int) );
3979 break;
3980 case VKI_KDSKBMETA:
3981 break;
3982
3983 case VKI_KDGKBLED:
3984 POST_MEM_WRITE( arg3, sizeof(char) );
3985 break;
3986 case VKI_KDSKBLED:
3987 break;
3988
3989 case VKI_KDGKBENT:
3990 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3991 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3992 break;
3993 case VKI_KDSKBENT:
3994 break;
3995
3996 case VKI_KDGKBSENT:
3997 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)arg3)->kb_string,
3998 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
3999 break;
4000 case VKI_KDSKBSENT:
4001 break;
4002
4003 case VKI_KDGKBDIACR:
4004 POST_MEM_WRITE( arg3, sizeof(struct vki_kbdiacrs) );
4005 break;
4006 case VKI_KDSKBDIACR:
4007 break;
4008
4009 case VKI_KDGETKEYCODE:
4010 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)arg3)->keycode,
4011 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
4012 break;
4013 case VKI_KDSETKEYCODE:
4014 break;
4015
4016 case VKI_KDSIGACCEPT:
4017 break;
4018
4019 case VKI_KDKBDREP:
4020 break;
4021
jsgf855d93d2003-10-13 22:26:55 +00004022 /* We don't have any specific information on it, so
4023 try to do something reasonable based on direction and
4024 size bits. The encoding scheme is described in
4025 /usr/include/asm/ioctl.h.
4026
4027 According to Simon Hausmann, _IOC_READ means the kernel
4028 writes a value to the ioctl value passed from the user
4029 space and the other way around with _IOC_WRITE. */
4030 default: {
nethercote73b526f2004-10-31 18:48:21 +00004031 UInt dir = _VKI_IOC_DIR(arg2);
4032 UInt size = _VKI_IOC_SIZE(arg2);
4033 if (size > 0 && (dir & _VKI_IOC_READ)
jsgf855d93d2003-10-13 22:26:55 +00004034 && res == 0
4035 && arg3 != (Addr)NULL)
4036 VG_TRACK( post_mem_write,arg3, size);
4037 break;
4038 }
4039 }
4040}
4041
nethercote85a456f2004-11-16 17:31:56 +00004042PRE(sys_kill, 0)
jsgf855d93d2003-10-13 22:26:55 +00004043{
4044 /* int kill(pid_t pid, int sig); */
nethercote9a3beb92004-11-12 17:07:26 +00004045 PRINT("sys_kill ( %d, %d )", arg1,arg2);
4046 PRE_REG_READ2(long, "kill", int, pid, int, sig);
jsgf855d93d2003-10-13 22:26:55 +00004047 if (arg2 == VKI_SIGVGINT || arg2 == VKI_SIGVGKILL)
nethercote35122912004-10-18 17:00:30 +00004048 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004049}
4050
nethercote85a456f2004-11-16 17:31:56 +00004051POST(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004052{
4053 /* If this was a self-kill then wait for a signal to be
4054 delivered to any thread before claiming the kill is done. */
nethercote9a3beb92004-11-12 17:07:26 +00004055 if (res >= 0 && // if it was successful and
4056 arg2 != 0 && // if a real signal and
4057 !VG_(is_sig_ign)(arg2) && // that isn't ignored and
4058 !VG_(sigismember)(&tst->eff_sig_mask, arg2) && // we're not blocking it
4059 (arg1 == VG_(getpid)() || // directed at us or
4060 arg1 == -1 || // directed at everyone or
4061 arg1 == 0 || // directed at whole group or
4062 -arg1 == VG_(getpgrp)())) { // directed at our group...
jsgf855d93d2003-10-13 22:26:55 +00004063 /* ...then wait for that signal to be delivered to someone
nethercote9a3beb92004-11-12 17:07:26 +00004064 (might be us, might be someone else who doesn't have it blocked) */
jsgf855d93d2003-10-13 22:26:55 +00004065 VG_(proxy_waitsig)();
4066 }
4067}
4068
nethercote85a456f2004-11-16 17:31:56 +00004069PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004070{
nethercotec6851dd2004-11-11 18:00:47 +00004071 PRINT("sys_link ( %p, %p)", arg1, arg2);
4072 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004073 PRE_MEM_RASCIIZ( "link(oldpath)", arg1);
4074 PRE_MEM_RASCIIZ( "link(newpath)", arg2);
jsgf855d93d2003-10-13 22:26:55 +00004075}
4076
nethercote85a456f2004-11-16 17:31:56 +00004077PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00004078{
nethercotec6851dd2004-11-11 18:00:47 +00004079 PRINT("sys_lseek ( %d, %d, %d )", arg1,arg2,arg3);
4080 PRE_REG_READ3(vki_off_t, "lseek",
4081 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004082}
4083
nethercote85a456f2004-11-16 17:31:56 +00004084PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004085{
nethercote2e1c37d2004-11-13 13:57:12 +00004086 PRINT("sys_newlstat ( %p(%s), %p )", arg1,arg1,arg2);
4087 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004088 PRE_MEM_RASCIIZ( "lstat(file_name)", arg1 );
4089 PRE_MEM_WRITE( "lstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004090}
4091
nethercote85a456f2004-11-16 17:31:56 +00004092POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00004093{
4094 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004095 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004096 }
4097}
4098
nethercote85a456f2004-11-16 17:31:56 +00004099PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004100{
nethercoteac866b92004-11-15 20:23:15 +00004101 PRINT("sys_lstat64 ( %p(%s), %p )",arg1,arg1,arg2);
nethercote2e1c37d2004-11-13 13:57:12 +00004102 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004103 PRE_MEM_RASCIIZ( "lstat64(file_name)", arg1 );
4104 PRE_MEM_WRITE( "lstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004105}
4106
nethercote85a456f2004-11-16 17:31:56 +00004107POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004108{
4109 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004110 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004111 }
4112}
4113
nethercote85a456f2004-11-16 17:31:56 +00004114PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004115{
nethercote9a3beb92004-11-12 17:07:26 +00004116 PRINT("sys_mkdir ( %p, %d )", arg1,arg2);
4117 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004118 PRE_MEM_RASCIIZ( "mkdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004119}
4120
nethercote85a456f2004-11-16 17:31:56 +00004121PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004122{
nethercote151effa2004-11-15 12:57:39 +00004123 /* struct mmap_arg_struct {
4124 unsigned long addr;
4125 unsigned long len;
4126 unsigned long prot;
4127 unsigned long flags;
4128 unsigned long fd;
4129 unsigned long offset;
4130 }; */
jsgf855d93d2003-10-13 22:26:55 +00004131 UInt a1, a2, a3, a4, a5, a6;
4132
nethercote151effa2004-11-15 12:57:39 +00004133 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
nethercote6456ab12004-10-18 14:47:48 +00004134 PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004135
nethercote151effa2004-11-15 12:57:39 +00004136 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4137 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004138
fitzhardinge98abfc72003-12-16 02:05:15 +00004139 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004140 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004141 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
4142 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004143 }
4144 } else {
nethercote6456ab12004-10-18 14:47:48 +00004145 a1 = VG_(find_map_space)(a1, a2, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00004146 if (a1 == 0)
nethercote151effa2004-11-15 12:57:39 +00004147 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004148 else
nethercote151effa2004-11-15 12:57:39 +00004149 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004150 }
jsgf855d93d2003-10-13 22:26:55 +00004151
fitzhardinge98abfc72003-12-16 02:05:15 +00004152 if (res != -VKI_ENOMEM) {
nethercote6456ab12004-10-18 14:47:48 +00004153 PLATFORM_DO_MMAP(res, a1, a2, a3, a4, a5, a6);
fitzhardingec2d65072004-01-07 08:44:43 +00004154
4155 if (!VG_(is_kerror)(res)) {
nethercote8ff888f2004-11-17 17:11:45 +00004156 vg_assert(VG_(valid_client_addr)(res, a2, tid, "old_mmap"));
nethercoteb4250ae2004-07-10 16:50:09 +00004157 mmap_segment( (Addr)res, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004158 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004159 }
jsgf855d93d2003-10-13 22:26:55 +00004160}
4161
nethercote3d5e9102004-11-17 18:22:38 +00004162PRE(sys_mmap2, 0)
4163{
4164 // Exactly like old_mmap() except:
4165 // - all 6 args are passed in regs, rather than in a memory-block.
4166 // - the file offset is specified in pagesize units rather than bytes,
4167 // so that it can be used for files bigger than 2^32 bytes.
4168 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
4169 arg1, (ULong)arg2, arg3, arg4, arg5, arg6 );
4170 PRE_REG_READ6(long, "mmap2",
4171 unsigned long, start, unsigned long, length,
4172 unsigned long, prot, unsigned long, flags,
4173 unsigned long, fd, unsigned long, offset);
4174
4175 if (arg4 & VKI_MAP_FIXED) {
4176 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mmap2"))
4177 set_result( -VKI_ENOMEM );
4178 } else {
4179 arg1 = VG_(find_map_space)(arg1, arg2, True);
4180 if (arg1 == 0)
4181 set_result( -VKI_ENOMEM );
4182 else
4183 arg4 |= VKI_MAP_FIXED;
4184 }
4185}
4186
4187POST(sys_mmap2)
4188{
4189 vg_assert(VG_(valid_client_addr)(res, arg2, tid, "mmap2"));
4190 mmap_segment( (Addr)res, arg2, arg3, arg4, arg5,
4191 arg6 * (ULong)VKI_PAGE_SIZE );
4192}
4193
nethercote85a456f2004-11-16 17:31:56 +00004194PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004195{
nethercote06c7bd72004-11-14 19:11:56 +00004196 PRINT("sys_mprotect ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
4197 PRE_REG_READ3(long, "mprotect",
4198 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004199
nethercote8ff888f2004-11-17 17:11:45 +00004200 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mprotect"))
nethercote35122912004-10-18 17:00:30 +00004201 set_result( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004202}
4203
nethercote85a456f2004-11-16 17:31:56 +00004204POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004205{
nethercote27ea8bc2004-07-10 17:21:14 +00004206 Addr a = arg1;
nethercote928a5f72004-11-03 18:10:37 +00004207 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004208 Int prot = arg3;
4209 Bool rr = prot & VKI_PROT_READ;
4210 Bool ww = prot & VKI_PROT_WRITE;
4211 Bool xx = prot & VKI_PROT_EXEC;
4212
nethercote27ea8bc2004-07-10 17:21:14 +00004213 mash_addr_and_len(&a, &len);
4214 VG_(mprotect_range)(a, len, prot);
4215 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004216}
4217
nethercote85a456f2004-11-16 17:31:56 +00004218PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004219{
nethercote06c7bd72004-11-14 19:11:56 +00004220 PRINT("sys_munmap ( %p, %llu )", arg1,(ULong)arg2);
4221 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004222
nethercote8ff888f2004-11-17 17:11:45 +00004223 if (!VG_(valid_client_addr)(arg1, arg2, tid, "munmap"))
nethercote35122912004-10-18 17:00:30 +00004224 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004225}
4226
nethercote85a456f2004-11-16 17:31:56 +00004227POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004228{
nethercote928a5f72004-11-03 18:10:37 +00004229 Addr a = arg1;
4230 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004231
4232 mash_addr_and_len(&a, &len);
4233 VG_(unmap_range)(a, len);
4234 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004235}
4236
nethercote85a456f2004-11-16 17:31:56 +00004237PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004238{
nethercoteac866b92004-11-15 20:23:15 +00004239 PRINT("sys_mincore ( %p, %llu, %p )", arg1,(ULong)arg2,arg3);
4240 PRE_REG_READ3(long, "mincore",
4241 unsigned long, start, vki_size_t, length,
4242 unsigned char *, vec);
nethercoteef0c7662004-11-06 15:38:43 +00004243 PRE_MEM_WRITE( "mincore(vec)", arg3, (arg2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004244}
4245
nethercote85a456f2004-11-16 17:31:56 +00004246POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004247{
nethercoteef0c7662004-11-06 15:38:43 +00004248 POST_MEM_WRITE( arg3, (arg2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004249}
4250
nethercote85a456f2004-11-16 17:31:56 +00004251PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004252{
nethercoteac866b92004-11-15 20:23:15 +00004253 PRINT("sys_nanosleep ( %p, %p )", arg1,arg2);
nethercote5b653bc2004-11-15 14:32:12 +00004254 PRE_REG_READ2(long, "nanosleep",
4255 struct timespec *, req, struct timespec *, rem);
nethercoteef0c7662004-11-06 15:38:43 +00004256 PRE_MEM_READ( "nanosleep(req)", arg1, sizeof(struct vki_timespec) );
nethercote163c5e82004-11-17 18:42:20 +00004257 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00004258 PRE_MEM_WRITE( "nanosleep(rem)", arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004259}
4260
nethercote85a456f2004-11-16 17:31:56 +00004261POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004262{
nethercote163c5e82004-11-17 18:42:20 +00004263 if (arg2 != 0 && res == -VKI_EINTR)
nethercoteef0c7662004-11-06 15:38:43 +00004264 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004265}
4266
nethercote85a456f2004-11-16 17:31:56 +00004267PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004268{
nethercotee70bd7d2004-08-18 14:37:17 +00004269 if (arg2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004270 // 3-arg version
4271 PRINT("sys_open ( %p(%s), %d, %d )",arg1,arg1,arg2,arg3);
4272 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004273 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004274 } else {
nethercotee824cc42004-11-09 16:20:46 +00004275 // 2-arg version
4276 PRINT("sys_open ( %p(%s), %d )",arg1,arg1,arg2);
4277 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004278 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004279 }
nethercotee824cc42004-11-09 16:20:46 +00004280 PRE_MEM_RASCIIZ( "open(filename)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004281}
4282
nethercote85a456f2004-11-16 17:31:56 +00004283POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004284{
nethercote3d5e9102004-11-17 18:22:38 +00004285 if (!VG_(fd_allowed)(res, "open", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004286 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004287 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004288 } else {
nethercote493dd182004-02-24 23:57:47 +00004289 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004290 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004291 }
jsgf855d93d2003-10-13 22:26:55 +00004292}
4293
nethercote85a456f2004-11-16 17:31:56 +00004294PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004295{
nethercote8b76fe52004-11-08 19:20:09 +00004296 PRINT("sys_read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4297 PRE_REG_READ3(ssize_t, "read",
nethercote0df495a2004-11-11 16:38:21 +00004298 unsigned int, fd, char *, buf, size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004299
nethercote3d5e9102004-11-17 18:22:38 +00004300 if (!VG_(fd_allowed)(arg1, "read", tid, False))
nethercote35122912004-10-18 17:00:30 +00004301 set_result( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004302 else
nethercoteef0c7662004-11-06 15:38:43 +00004303 PRE_MEM_WRITE( "read(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004304}
4305
nethercote85a456f2004-11-16 17:31:56 +00004306POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004307{
nethercoteef0c7662004-11-06 15:38:43 +00004308 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004309}
4310
nethercote85a456f2004-11-16 17:31:56 +00004311PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004312{
nethercote8b76fe52004-11-08 19:20:09 +00004313 PRINT("sys_write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4314 PRE_REG_READ3(ssize_t, "write",
nethercote0df495a2004-11-11 16:38:21 +00004315 unsigned int, fd, const char *, buf, size_t, count);
nethercote3d5e9102004-11-17 18:22:38 +00004316 if (!VG_(fd_allowed)(arg1, "write", tid, False))
nethercote35122912004-10-18 17:00:30 +00004317 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004318 else
nethercoteef0c7662004-11-06 15:38:43 +00004319 PRE_MEM_READ( "write(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004320}
4321
nethercote85a456f2004-11-16 17:31:56 +00004322PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004323{
nethercotec6851dd2004-11-11 18:00:47 +00004324 PRINT("sys_creat ( %p(%s), %d )", arg1,arg1,arg2);
4325 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004326 PRE_MEM_RASCIIZ( "creat(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004327}
4328
nethercote85a456f2004-11-16 17:31:56 +00004329POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004330{
nethercote3d5e9102004-11-17 18:22:38 +00004331 if (!VG_(fd_allowed)(res, "creat", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004332 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004333 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004334 } else {
nethercote493dd182004-02-24 23:57:47 +00004335 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004336 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004337 }
jsgf855d93d2003-10-13 22:26:55 +00004338}
4339
nethercote9a3beb92004-11-12 17:07:26 +00004340// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004341PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004342{
nethercote9a3beb92004-11-12 17:07:26 +00004343 PRINT("sys_pipe ( %p )", arg1);
4344 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
4345 PRE_MEM_WRITE( "pipe(filedes)", arg1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004346}
4347
nethercote85a456f2004-11-16 17:31:56 +00004348POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004349{
nethercote9a3beb92004-11-12 17:07:26 +00004350 // XXX: use of Int here -- 32-bit-specific?
jsgf855d93d2003-10-13 22:26:55 +00004351 Int *p = (Int *)arg1;
4352
nethercote3d5e9102004-11-17 18:22:38 +00004353 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4354 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004355 VG_(close)(p[0]);
4356 VG_(close)(p[1]);
nethercote35122912004-10-18 17:00:30 +00004357 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004358 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004359 POST_MEM_WRITE( arg1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004360 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004361 VG_(record_fd_open)(tid, p[0], NULL);
4362 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004363 }
4364 }
jsgf855d93d2003-10-13 22:26:55 +00004365}
4366
nethercotef90953e2004-11-15 14:50:02 +00004367// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004368PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004369{
4370 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004371 int fd; -- file descriptor
4372 short events; -- requested events
4373 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004374 };
nethercoteeb0592d2004-11-05 12:02:27 +00004375 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004376 */
nethercoteeb0592d2004-11-05 12:02:27 +00004377 UInt i;
4378 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
nethercotef90953e2004-11-15 14:50:02 +00004379 PRINT("sys_poll ( %p, %d, %d )\n", arg1,arg2,arg3);
4380 PRE_REG_READ3(long, "poll",
4381 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004382
nethercoteeb0592d2004-11-05 12:02:27 +00004383 for (i = 0; i < arg2; i++) {
4384 // 'fd' and 'events' field are inputs; 'revents' is output.
4385 // XXX: this is x86 specific -- the pollfd struct varies across
4386 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004387 PRE_MEM_READ( "poll(ufds)",
4388 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4389 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4390 }
jsgf855d93d2003-10-13 22:26:55 +00004391}
4392
nethercote85a456f2004-11-16 17:31:56 +00004393POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004394{
4395 if (res > 0) {
4396 UInt i;
nethercoteeb0592d2004-11-05 12:02:27 +00004397 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
4398 // XXX: again, this is x86-specific
jsgf855d93d2003-10-13 22:26:55 +00004399 for (i = 0; i < arg2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004400 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004401 }
4402}
4403
rjwalsh17d85302004-11-18 22:56:09 +00004404PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004405{
rjwalsh093047d2004-11-19 02:11:56 +00004406 int saved = SYSNO;
nethercote5a945af2004-11-14 18:37:07 +00004407 PRINT("sys_readlink ( %p, %p, %llu )", arg1,arg2,(ULong)arg3);
4408 PRE_REG_READ3(long, "readlink",
4409 const char *, path, char *, buf, int, bufsiz);
nethercoteef0c7662004-11-06 15:38:43 +00004410 PRE_MEM_RASCIIZ( "readlink(path)", arg1 );
4411 PRE_MEM_WRITE( "readlink(buf)", arg2,arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004412
rjwalsh17d85302004-11-18 22:56:09 +00004413 /*
rjwalsh093047d2004-11-19 02:11:56 +00004414 * Handle the case where readlink is looking at /proc/self/exe or
4415 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004416 */
4417
rjwalsh093047d2004-11-19 02:11:56 +00004418 set_result( VG_(do_syscall)(saved, arg1, arg2, arg3));
4419 if ((Int)res == -2) {
4420 char name[25];
4421
4422 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004423
rjwalsh093047d2004-11-19 02:11:56 +00004424 if (VG_(strcmp)((Char *)arg1, name) == 0 ||
4425 VG_(strcmp)((Char *)arg1, "/proc/self/exe") == 0) {
4426 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
4427 set_result( VG_(do_syscall)(saved, name, arg2, arg3));
4428 }
rjwalsh17d85302004-11-18 22:56:09 +00004429 }
4430
rjwalsh093047d2004-11-19 02:11:56 +00004431 if ((Int)res > 0)
rjwalsh17d85302004-11-18 22:56:09 +00004432 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004433}
4434
nethercote85a456f2004-11-16 17:31:56 +00004435PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004436{
jsgf855d93d2003-10-13 22:26:55 +00004437 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004438 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00004439 PRINT("sys_readv ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
4440 PRE_REG_READ3(ssize_t, "readv",
4441 unsigned long, fd, const struct iovec *, vector,
4442 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00004443 if (!VG_(fd_allowed)(arg1, "readv", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00004444 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004445 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004446 PRE_MEM_READ( "readv(vector)", arg2, arg3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004447
nethercote163c5e82004-11-17 18:42:20 +00004448 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004449 /* ToDo: don't do any of the following if the vector is invalid */
4450 vec = (struct vki_iovec *)arg2;
4451 for (i = 0; i < (Int)arg3; i++)
4452 PRE_MEM_WRITE( "readv(vector[...])",
4453 (Addr)vec[i].iov_base, vec[i].iov_len );
4454 }
jsgf855d93d2003-10-13 22:26:55 +00004455 }
4456}
4457
nethercote85a456f2004-11-16 17:31:56 +00004458POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004459{
4460 if (res > 0) {
4461 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004462 struct vki_iovec * vec = (struct vki_iovec *)arg2;
jsgf855d93d2003-10-13 22:26:55 +00004463 Int remains = res;
4464
4465 /* res holds the number of bytes read. */
4466 for (i = 0; i < (Int)arg3; i++) {
4467 Int nReadThisBuf = vec[i].iov_len;
4468 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004469 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004470 remains -= nReadThisBuf;
4471 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4472 }
4473 }
4474}
4475
nethercote85a456f2004-11-16 17:31:56 +00004476PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004477{
nethercote9a3beb92004-11-12 17:07:26 +00004478 PRINT("sys_rename ( %p, %p )", arg1, arg2 );
4479 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004480 PRE_MEM_RASCIIZ( "rename(oldpath)", arg1 );
4481 PRE_MEM_RASCIIZ( "rename(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00004482}
4483
nethercote85a456f2004-11-16 17:31:56 +00004484PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004485{
nethercote9a3beb92004-11-12 17:07:26 +00004486 PRINT("sys_rmdir ( %p )", arg1);
4487 PRE_REG_READ1(long, "rmdir", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00004488 PRE_MEM_RASCIIZ( "rmdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004489}
4490
nethercote85a456f2004-11-16 17:31:56 +00004491PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004492{
nethercoteef0c7662004-11-06 15:38:43 +00004493 PRINT("sched_setparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004494 PRE_REG_READ2(long, "sched_setparam",
4495 vki_pid_t, pid, struct sched_param *, p);
4496 PRE_MEM_READ( "sched_setparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004497}
4498
nethercote85a456f2004-11-16 17:31:56 +00004499POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004500{
nethercoteef0c7662004-11-06 15:38:43 +00004501 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004502}
4503
nethercote85a456f2004-11-16 17:31:56 +00004504PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004505{
nethercoteef0c7662004-11-06 15:38:43 +00004506 PRINT("sched_getparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004507 PRE_REG_READ2(long, "sched_getparam",
4508 vki_pid_t, pid, struct sched_param *, p);
4509 PRE_MEM_WRITE( "sched_getparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004510}
4511
nethercote85a456f2004-11-16 17:31:56 +00004512POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004513{
nethercoteef0c7662004-11-06 15:38:43 +00004514 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004515}
4516
nethercote85a456f2004-11-16 17:31:56 +00004517PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004518{
4519 PRINT("sys_select ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
4520 PRE_REG_READ5(long, "select",
4521 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4522 vki_fd_set *, exceptfds, struct timeval *, timeout);
4523 // XXX: this possibly understates how much memory is read.
4524 if (arg2 != 0)
4525 PRE_MEM_READ( "select(readfds)",
4526 arg2, arg1/8 /* __FD_SETSIZE/8 */ );
4527 if (arg3 != 0)
4528 PRE_MEM_READ( "select(writefds)",
4529 arg3, arg1/8 /* __FD_SETSIZE/8 */ );
4530 if (arg4 != 0)
4531 PRE_MEM_READ( "select(exceptfds)",
4532 arg4, arg1/8 /* __FD_SETSIZE/8 */ );
4533 if (arg5 != 0)
4534 PRE_MEM_READ( "select(timeout)", arg5, sizeof(struct vki_timeval) );
4535}
4536
nethercote85a456f2004-11-16 17:31:56 +00004537PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004538{
nethercote9c311eb2004-11-12 18:20:12 +00004539 PRINT("sys_setgid16 ( %d )", arg1);
4540 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4541}
4542
nethercote85a456f2004-11-16 17:31:56 +00004543PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004544{
4545 PRINT("sys_setgid ( %d )", arg1);
4546 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004547}
4548
nethercote85a456f2004-11-16 17:31:56 +00004549PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004550{
nethercote0df495a2004-11-11 16:38:21 +00004551 PRINT("sys_setsid ( )");
4552 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004553}
4554
nethercote85a456f2004-11-16 17:31:56 +00004555PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004556{
nethercote686b5db2004-11-14 13:42:51 +00004557 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)arg1, arg2);
4558 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
4559 if (arg1 > 0)
4560 PRE_MEM_READ( "setgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
4561}
4562
nethercote85a456f2004-11-16 17:31:56 +00004563PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004564{
nethercoteef0c7662004-11-06 15:38:43 +00004565 PRINT("setgroups ( %llu, %p )", (ULong)arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00004566 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00004567 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00004568 PRE_MEM_READ( "setgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004569}
4570
nethercote85a456f2004-11-16 17:31:56 +00004571PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004572{
nethercoteef0c7662004-11-06 15:38:43 +00004573 PRINT("setpgid ( %d, %d )", arg1, arg2);
nethercote9c311eb2004-11-12 18:20:12 +00004574 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004575}
4576
nethercote85a456f2004-11-16 17:31:56 +00004577POST(sys_setpgid)
jsgf855d93d2003-10-13 22:26:55 +00004578{
4579 VG_(main_pgrp) = VG_(getpgrp)();
4580}
4581
nethercote85a456f2004-11-16 17:31:56 +00004582PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004583{
nethercote17258dc2004-11-12 19:55:08 +00004584 PRINT("sys_setregid ( %d, %d )", arg1, arg2);
4585 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004586}
4587
nethercote85a456f2004-11-16 17:31:56 +00004588PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004589{
nethercote17258dc2004-11-12 19:55:08 +00004590 PRINT("setreuid16 ( 0x%x, 0x%x )", arg1, arg2);
4591 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4592}
4593
nethercote85a456f2004-11-16 17:31:56 +00004594PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004595{
4596 PRINT("sys_setreuid ( 0x%x, 0x%x )", arg1, arg2);
4597 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004598}
4599
nethercote85a456f2004-11-16 17:31:56 +00004600PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004601{
nethercote17258dc2004-11-12 19:55:08 +00004602 PRINT("sys_setrlimit ( %d, %p )", arg1,arg2);
4603 PRE_REG_READ2(long, "setrlimit",
4604 unsigned int, resource, struct rlimit *, rlim);
nethercoteef0c7662004-11-06 15:38:43 +00004605 PRE_MEM_READ( "setrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004606
thughesad1c9562004-06-26 11:27:52 +00004607 if (arg1 == VKI_RLIMIT_NOFILE) {
nethercote73b526f2004-10-31 18:48:21 +00004608 if (((struct vki_rlimit *)arg2)->rlim_cur > VG_(fd_hard_limit) ||
4609 ((struct vki_rlimit *)arg2)->rlim_max != VG_(fd_hard_limit)) {
nethercote35122912004-10-18 17:00:30 +00004610 set_result( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004611 }
4612 else {
nethercote73b526f2004-10-31 18:48:21 +00004613 VG_(fd_soft_limit) = ((struct vki_rlimit *)arg2)->rlim_cur;
nethercote35122912004-10-18 17:00:30 +00004614 set_result( 0 );
thughesad1c9562004-06-26 11:27:52 +00004615 }
4616 }
4617 else if (arg1 == VKI_RLIMIT_DATA) {
nethercote73b526f2004-10-31 18:48:21 +00004618 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4619 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004620 set_result( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004621 }
4622 else {
nethercote73b526f2004-10-31 18:48:21 +00004623 VG_(client_rlimit_data) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004624 set_result( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004625 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004626 }
thughesc37184f2004-09-11 14:16:57 +00004627 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
nethercote73b526f2004-10-31 18:48:21 +00004628 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4629 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004630 set_result( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004631 }
4632 else {
nethercote73b526f2004-10-31 18:48:21 +00004633 VG_(threads)[tid].stack_size = ((struct vki_rlimit *)arg2)->rlim_cur;
4634 VG_(client_rlimit_stack) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004635 set_result( 0 );
thughesc37184f2004-09-11 14:16:57 +00004636 }
4637 }
jsgf855d93d2003-10-13 22:26:55 +00004638}
4639
nethercote85a456f2004-11-16 17:31:56 +00004640PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004641{
nethercotec6851dd2004-11-11 18:00:47 +00004642 PRINT("sys_setuid16 ( %d )", arg1);
4643 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004644}
4645
nethercote85a456f2004-11-16 17:31:56 +00004646PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00004647{
4648 PRINT("sys_setuid ( %d )", arg1);
4649 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4650}
jsgf855d93d2003-10-13 22:26:55 +00004651
nethercote85a456f2004-11-16 17:31:56 +00004652PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004653{
nethercotedc18c0a2004-11-14 20:06:27 +00004654 PRINT("sys_socketcall ( %d, %p )",arg1,arg2);
4655 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4656
jsgf855d93d2003-10-13 22:26:55 +00004657 switch (arg1 /* request */) {
4658
nethercote73b526f2004-10-31 18:48:21 +00004659 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00004660 /* int socketpair(int d, int type, int protocol, int sv[2]); */
nethercoteef0c7662004-11-06 15:38:43 +00004661 PRE_MEM_READ( "socketcall.socketpair(args)", arg2, 4*sizeof(Addr) );
4662 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
nethercotef1d810d2004-11-04 19:57:03 +00004663 ((UWord*)arg2)[3], 2*sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004664 break;
4665
nethercote73b526f2004-10-31 18:48:21 +00004666 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00004667 /* int socket(int domain, int type, int protocol); */
nethercoteef0c7662004-11-06 15:38:43 +00004668 PRE_MEM_READ( "socketcall.socket(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004669 break;
4670
nethercote73b526f2004-10-31 18:48:21 +00004671 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004672 /* int bind(int sockfd, struct sockaddr *my_addr,
4673 int addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004674 PRE_MEM_READ( "socketcall.bind(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004675 pre_mem_read_sockaddr( tid, "socketcall.bind(my_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004676 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004677 break;
4678
nethercote73b526f2004-10-31 18:48:21 +00004679 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004680 /* int listen(int s, int backlog); */
nethercoteef0c7662004-11-06 15:38:43 +00004681 PRE_MEM_READ( "socketcall.listen(args)", arg2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004682 break;
4683
nethercote73b526f2004-10-31 18:48:21 +00004684 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004685 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004686 PRE_MEM_READ( "socketcall.accept(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004687 {
nethercotef1d810d2004-11-04 19:57:03 +00004688 Addr addr_p = ((UWord*)arg2)[1];
4689 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004690 if (addr_p != (Addr)NULL)
4691 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
4692 "socketcall.accept(addr)",
4693 "socketcall.accept(addrlen_in)" );
4694 }
4695 break;
4696 }
4697
nethercote73b526f2004-10-31 18:48:21 +00004698 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004699 /* int sendto(int s, const void *msg, int len,
4700 unsigned int flags,
4701 const struct sockaddr *to, int tolen); */
nethercoteef0c7662004-11-06 15:38:43 +00004702 PRE_MEM_READ( "socketcall.sendto(args)", arg2, 6*sizeof(Addr) );
4703 PRE_MEM_READ( "socketcall.sendto(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004704 ((UWord*)arg2)[1], /* msg */
4705 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004706 pre_mem_read_sockaddr( tid, "socketcall.sendto(to.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004707 (struct vki_sockaddr *) (((UWord*)arg2)[4]), ((UWord*)arg2)[5]);
jsgf855d93d2003-10-13 22:26:55 +00004708 break;
4709
nethercote73b526f2004-10-31 18:48:21 +00004710 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004711 /* int send(int s, const void *msg, size_t len, int flags); */
nethercoteef0c7662004-11-06 15:38:43 +00004712 PRE_MEM_READ( "socketcall.send(args)", arg2, 4*sizeof(Addr) );
4713 PRE_MEM_READ( "socketcall.send(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004714 ((UWord*)arg2)[1], /* msg */
4715 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004716 break;
4717
nethercote73b526f2004-10-31 18:48:21 +00004718 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004719 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4720 struct sockaddr *from, int *fromlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004721 PRE_MEM_READ( "socketcall.recvfrom(args)", arg2, 6*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004722 {
nethercotef1d810d2004-11-04 19:57:03 +00004723 Addr buf_p = ((UWord*)arg2)[1];
4724 Int len = ((UWord*)arg2)[2];
4725 Addr from_p = ((UWord*)arg2)[4];
4726 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004727
nethercoteef0c7662004-11-06 15:38:43 +00004728 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004729 if (from_p != (Addr)NULL)
4730 buf_and_len_pre_check ( tid, from_p, fromlen_p,
4731 "socketcall.recvfrom(from)",
4732 "socketcall.recvfrom(fromlen_in)" );
4733 }
4734 break;
4735
nethercote73b526f2004-10-31 18:48:21 +00004736 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00004737 /* int recv(int s, void *buf, int len, unsigned int flags); */
4738 /* man 2 recv says:
4739 The recv call is normally used only on a connected socket
4740 (see connect(2)) and is identical to recvfrom with a NULL
4741 from parameter.
4742 */
nethercoteef0c7662004-11-06 15:38:43 +00004743 PRE_MEM_READ( "socketcall.recv(args)", arg2, 4*sizeof(Addr) );
4744 PRE_MEM_WRITE( "socketcall.recv(buf)",
nethercotef1d810d2004-11-04 19:57:03 +00004745 ((UWord*)arg2)[1], /* buf */
4746 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004747 break;
4748
nethercote73b526f2004-10-31 18:48:21 +00004749 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004750 /* int connect(int sockfd,
4751 struct sockaddr *serv_addr, int addrlen ); */
nethercoteef0c7662004-11-06 15:38:43 +00004752 PRE_MEM_READ( "socketcall.connect(args)", arg2, 3*sizeof(Addr) );
4753 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
nethercotef1d810d2004-11-04 19:57:03 +00004754 ((UWord*)arg2)[1], /* serv_addr */
nethercote73b526f2004-10-31 18:48:21 +00004755 sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +00004756 pre_mem_read_sockaddr( tid,
4757 "socketcall.connect(serv_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004758 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004759 break;
4760
nethercote73b526f2004-10-31 18:48:21 +00004761 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004762 /* int setsockopt(int s, int level, int optname,
4763 const void *optval, int optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004764 PRE_MEM_READ( "socketcall.setsockopt(args)", arg2, 5*sizeof(Addr) );
4765 PRE_MEM_READ( "socketcall.setsockopt(optval)",
nethercotef1d810d2004-11-04 19:57:03 +00004766 ((UWord*)arg2)[3], /* optval */
4767 ((UWord*)arg2)[4] /* optlen */ );
jsgf855d93d2003-10-13 22:26:55 +00004768 break;
4769
nethercote73b526f2004-10-31 18:48:21 +00004770 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004771 /* int setsockopt(int s, int level, int optname,
4772 void *optval, socklen_t *optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004773 PRE_MEM_READ( "socketcall.getsockopt(args)", arg2, 5*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004774 {
nethercotef1d810d2004-11-04 19:57:03 +00004775 Addr optval_p = ((UWord*)arg2)[3];
4776 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00004777 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
4778 if (optval_p != (Addr)NULL)
4779 buf_and_len_pre_check ( tid, optval_p, optlen_p,
4780 "socketcall.getsockopt(optval)",
4781 "socketcall.getsockopt(optlen)" );
4782 }
4783 break;
4784
nethercote73b526f2004-10-31 18:48:21 +00004785 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004786 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004787 PRE_MEM_READ( "socketcall.getsockname(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004788 {
nethercotef1d810d2004-11-04 19:57:03 +00004789 Addr name_p = ((UWord*)arg2)[1];
4790 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004791
4792 /* Nb: name_p cannot be NULL */
4793 buf_and_len_pre_check ( tid, name_p, namelen_p,
4794 "socketcall.getsockname(name)",
4795 "socketcall.getsockname(namelen_in)" );
4796 }
4797 break;
4798
nethercote73b526f2004-10-31 18:48:21 +00004799 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004800 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004801 PRE_MEM_READ( "socketcall.getpeername(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004802 {
nethercotef1d810d2004-11-04 19:57:03 +00004803 Addr name_p = ((UWord*)arg2)[1];
4804 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004805
4806 /* Nb: name_p cannot be NULL */
4807 buf_and_len_pre_check ( tid, name_p, namelen_p,
4808 "socketcall.getpeername(name)",
4809 "socketcall.getpeername(namelen_in)" );
4810 }
4811 break;
4812
nethercote73b526f2004-10-31 18:48:21 +00004813 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004814 /* int shutdown(int s, int how); */
nethercoteef0c7662004-11-06 15:38:43 +00004815 PRE_MEM_READ( "socketcall.shutdown(args)", arg2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004816 break;
4817
nethercote73b526f2004-10-31 18:48:21 +00004818 case VKI_SYS_SENDMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004819 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4820
4821 /* this causes warnings, and I don't get why. glibc bug?
4822 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004823 PRE_MEM_READ( "socketcall.sendmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004824 */
4825
nethercote22208362004-11-04 20:00:44 +00004826 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004827 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
4828
4829 break;
4830 }
4831
nethercote73b526f2004-10-31 18:48:21 +00004832 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004833 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4834
4835 /* this causes warnings, and I don't get why. glibc bug?
4836 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004837 PRE_MEM_READ("socketcall.recvmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004838 */
4839
nethercote22208362004-11-04 20:00:44 +00004840 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004841 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
4842
4843 break;
4844 }
4845
4846 default:
jsgf17059e02003-10-19 16:46:06 +00004847 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",arg1);
nethercote35122912004-10-18 17:00:30 +00004848 set_result( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00004849 break;
jsgf855d93d2003-10-13 22:26:55 +00004850 }
4851}
4852
nethercote85a456f2004-11-16 17:31:56 +00004853POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00004854{
jsgf855d93d2003-10-13 22:26:55 +00004855 switch (arg1 /* request */) {
4856
nethercote73b526f2004-10-31 18:48:21 +00004857 case VKI_SYS_SOCKETPAIR: {
nethercotef1d810d2004-11-04 19:57:03 +00004858 Int fd1 = ((Int*)((UWord*)arg2)[3])[0];
4859 Int fd2 = ((Int*)((UWord*)arg2)[3])[1];
nethercoteef0c7662004-11-06 15:38:43 +00004860 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote3d5e9102004-11-17 18:22:38 +00004861 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
4862 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00004863 VG_(close)(fd1);
4864 VG_(close)(fd2);
nethercote35122912004-10-18 17:00:30 +00004865 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00004866 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004867 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004868 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004869 VG_(record_fd_open)(tid, fd1, NULL);
4870 VG_(record_fd_open)(tid, fd2, NULL);
nethercote493dd182004-02-24 23:57:47 +00004871 }
rjwalshf5f536f2003-11-17 17:45:00 +00004872 }
jsgf855d93d2003-10-13 22:26:55 +00004873 break;
nethercote493dd182004-02-24 23:57:47 +00004874 }
jsgf855d93d2003-10-13 22:26:55 +00004875
nethercote73b526f2004-10-31 18:48:21 +00004876 case VKI_SYS_SOCKET:
nethercote3d5e9102004-11-17 18:22:38 +00004877 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004878 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004879 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004880 } else {
nethercote493dd182004-02-24 23:57:47 +00004881 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004882 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004883 }
4884 break;
4885
nethercote73b526f2004-10-31 18:48:21 +00004886 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004887 /* int bind(int sockfd, struct sockaddr *my_addr,
4888 int addrlen); */
4889 break;
4890
nethercote73b526f2004-10-31 18:48:21 +00004891 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004892 /* int listen(int s, int backlog); */
4893 break;
4894
nethercote73b526f2004-10-31 18:48:21 +00004895 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004896 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercote3d5e9102004-11-17 18:22:38 +00004897 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004898 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004899 set_result( -VKI_EMFILE );
jsgf855d93d2003-10-13 22:26:55 +00004900 } else {
nethercotef1d810d2004-11-04 19:57:03 +00004901 Addr addr_p = ((UWord*)arg2)[1];
4902 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004903
4904 if (addr_p != (Addr)NULL)
4905 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
4906 "socketcall.accept(addrlen_out)" );
nethercote493dd182004-02-24 23:57:47 +00004907 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004908 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004909 }
4910 break;
4911 }
4912
nethercote73b526f2004-10-31 18:48:21 +00004913 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004914 break;
4915
nethercote73b526f2004-10-31 18:48:21 +00004916 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004917 break;
4918
nethercote73b526f2004-10-31 18:48:21 +00004919 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004920 {
nethercotef1d810d2004-11-04 19:57:03 +00004921 Addr buf_p = ((UWord*)arg2)[1];
4922 Int len = ((UWord*)arg2)[2];
4923 Addr from_p = ((UWord*)arg2)[4];
4924 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004925
4926 if (from_p != (Addr)NULL)
4927 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
4928 "socketcall.recvfrom(fromlen_out)" );
nethercoteef0c7662004-11-06 15:38:43 +00004929 POST_MEM_WRITE( buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004930 }
4931 break;
4932
nethercote73b526f2004-10-31 18:48:21 +00004933 case VKI_SYS_RECV:
nethercote163c5e82004-11-17 18:42:20 +00004934 if (res >= 0 && ((UWord*)arg2)[1] != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004935 POST_MEM_WRITE( ((UWord*)arg2)[1], /* buf */
4936 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004937 }
4938 break;
4939
nethercote73b526f2004-10-31 18:48:21 +00004940 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004941 break;
4942
nethercote73b526f2004-10-31 18:48:21 +00004943 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004944 break;
4945
nethercote73b526f2004-10-31 18:48:21 +00004946 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004947 {
nethercotef1d810d2004-11-04 19:57:03 +00004948 Addr optval_p = ((UWord*)arg2)[3];
4949 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00004950
4951 if (optval_p != (Addr)NULL)
4952 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
4953 "socketcall.getsockopt(optlen_out)" );
4954 }
4955 break;
4956
nethercote73b526f2004-10-31 18:48:21 +00004957 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004958 {
nethercotef1d810d2004-11-04 19:57:03 +00004959 Addr name_p = ((UWord*)arg2)[1];
4960 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004961
4962 buf_and_len_post_check ( tid, res, name_p, namelen_p,
4963 "socketcall.getsockname(namelen_out)" );
4964 }
4965 break;
4966
nethercote73b526f2004-10-31 18:48:21 +00004967 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004968 {
nethercotef1d810d2004-11-04 19:57:03 +00004969 Addr name_p = ((UWord*)arg2)[1];
4970 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004971
4972 buf_and_len_post_check ( tid, res, name_p, namelen_p,
4973 "socketcall.getpeername(namelen_out)" );
4974 }
4975 break;
4976
nethercote73b526f2004-10-31 18:48:21 +00004977 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004978 break;
4979
nethercote73b526f2004-10-31 18:48:21 +00004980 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00004981 break;
4982
nethercote73b526f2004-10-31 18:48:21 +00004983 case VKI_SYS_RECVMSG:
jsgf855d93d2003-10-13 22:26:55 +00004984 {
nethercote22208362004-11-04 20:00:44 +00004985 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004986
4987 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
rjwalshf5f536f2003-11-17 17:45:00 +00004988 check_cmsg_for_fds( tid, msg );
jsgf855d93d2003-10-13 22:26:55 +00004989
4990 break;
4991 }
4992
4993 default:
4994 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",arg1);
4995 VG_(core_panic)("... bye!\n");
4996 break; /*NOTREACHED*/
4997 }
4998}
4999
nethercote85a456f2004-11-16 17:31:56 +00005000PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00005001{
nethercote2e1c37d2004-11-13 13:57:12 +00005002 PRINT("sys_newstat ( %p(%s), %p )", arg1,arg1,arg2);
5003 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005004 PRE_MEM_RASCIIZ( "stat(file_name)", arg1 );
5005 PRE_MEM_WRITE( "stat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005006}
5007
nethercote85a456f2004-11-16 17:31:56 +00005008POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00005009{
nethercoteef0c7662004-11-06 15:38:43 +00005010 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005011}
5012
nethercote85a456f2004-11-16 17:31:56 +00005013PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00005014{
nethercotedc18c0a2004-11-14 20:06:27 +00005015 PRINT("sys_statfs ( %p, %p )",arg1,arg2);
5016 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005017 PRE_MEM_RASCIIZ( "statfs(path)", arg1 );
5018 PRE_MEM_WRITE( "statfs(buf)", arg2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00005019}
5020
nethercote85a456f2004-11-16 17:31:56 +00005021POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00005022{
nethercoteef0c7662004-11-06 15:38:43 +00005023 POST_MEM_WRITE( arg2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00005024}
5025
nethercote85a456f2004-11-16 17:31:56 +00005026PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00005027{
nethercotedc18c0a2004-11-14 20:06:27 +00005028 PRINT("sys_statfs64 ( %p, %llu, %p )",arg1,(ULong)arg2,arg3);
5029 PRE_REG_READ3(long, "statfs64",
5030 const char *, path, vki_size_t, size, struct statfs64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005031 PRE_MEM_RASCIIZ( "statfs64(path)", arg1 );
5032 PRE_MEM_WRITE( "statfs64(buf)", arg3, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005033}
5034
nethercote85a456f2004-11-16 17:31:56 +00005035POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00005036{
nethercoteef0c7662004-11-06 15:38:43 +00005037 POST_MEM_WRITE( arg3, arg2 );
muellerd3502b62003-11-19 00:43:57 +00005038}
5039
nethercote85a456f2004-11-16 17:31:56 +00005040PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005041{
nethercote5a945af2004-11-14 18:37:07 +00005042 PRINT("sys_symlink ( %p, %p )",arg1,arg2);
5043 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00005044 PRE_MEM_RASCIIZ( "symlink(oldpath)", arg1 );
5045 PRE_MEM_RASCIIZ( "symlink(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005046}
5047
nethercote85a456f2004-11-16 17:31:56 +00005048PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005049{
nethercote2e1c37d2004-11-13 13:57:12 +00005050 PRINT("sys_stat64 ( %p, %p )",arg1,arg2);
5051 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005052 PRE_MEM_RASCIIZ( "stat64(file_name)", arg1 );
5053 PRE_MEM_WRITE( "stat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005054}
5055
nethercote85a456f2004-11-16 17:31:56 +00005056POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00005057{
nethercoteef0c7662004-11-06 15:38:43 +00005058 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005059}
5060
nethercote85a456f2004-11-16 17:31:56 +00005061PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005062{
nethercote2e1c37d2004-11-13 13:57:12 +00005063 PRINT("sys_fstat64 ( %d, %p )",arg1,arg2);
5064 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005065 PRE_MEM_WRITE( "fstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005066}
5067
nethercote85a456f2004-11-16 17:31:56 +00005068POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00005069{
nethercoteef0c7662004-11-06 15:38:43 +00005070 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005071}
5072
nethercote85a456f2004-11-16 17:31:56 +00005073PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00005074{
5075 /* time_t time(time_t *t); */
nethercotec6851dd2004-11-11 18:00:47 +00005076 PRINT("sys_time ( %p )",arg1);
5077 PRE_REG_READ1(long, "time", int *, t);
nethercote163c5e82004-11-17 18:42:20 +00005078 if (arg1 != 0) {
nethercotec6851dd2004-11-11 18:00:47 +00005079 PRE_MEM_WRITE( "time(t)", arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005080 }
5081}
5082
nethercote85a456f2004-11-16 17:31:56 +00005083POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005084{
nethercote163c5e82004-11-17 18:42:20 +00005085 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005086 POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005087 }
5088}
5089
nethercote85a456f2004-11-16 17:31:56 +00005090PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00005091{
nethercote9c311eb2004-11-12 18:20:12 +00005092 PRINT("sys_times ( %p )", arg1);
5093 PRE_REG_READ1(long, "times", struct tms *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005094 PRE_MEM_WRITE( "times(buf)", arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005095}
5096
nethercote85a456f2004-11-16 17:31:56 +00005097POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00005098{
nethercote163c5e82004-11-17 18:42:20 +00005099 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005100 POST_MEM_WRITE( arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005101 }
5102}
5103
nethercote85a456f2004-11-16 17:31:56 +00005104PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00005105{
nethercote9c311eb2004-11-12 18:20:12 +00005106 PRINT("sys_umask ( %d )", arg1);
5107 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00005108}
5109
nethercote85a456f2004-11-16 17:31:56 +00005110PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005111{
nethercotec6851dd2004-11-11 18:00:47 +00005112 PRINT("sys_unlink ( %p(%s) )", arg1,arg1);
5113 PRE_REG_READ1(long, "unlink", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00005114 PRE_MEM_RASCIIZ( "unlink(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00005115}
5116
nethercote85a456f2004-11-16 17:31:56 +00005117PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00005118{
nethercote1a1b9b72004-11-12 11:19:36 +00005119 PRINT("sys_newuname ( %p )", arg1);
5120 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005121 PRE_MEM_WRITE( "uname(buf)", arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005122}
5123
nethercote85a456f2004-11-16 17:31:56 +00005124POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005125{
nethercote163c5e82004-11-17 18:42:20 +00005126 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005127 POST_MEM_WRITE( arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005128 }
5129}
5130
nethercote85a456f2004-11-16 17:31:56 +00005131PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005132{
nethercote9a3beb92004-11-12 17:07:26 +00005133 PRINT("sys_utime ( %p, %p )", arg1,arg2);
5134 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005135 PRE_MEM_RASCIIZ( "utime(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005136 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005137 PRE_MEM_READ( "utime(buf)", arg2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00005138}
5139
nethercote85a456f2004-11-16 17:31:56 +00005140PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005141{
nethercotec6851dd2004-11-11 18:00:47 +00005142 PRINT("sys_waitpid ( %d, %p, %d )", arg1,arg2,arg3);
5143 PRE_REG_READ3(long, "waitpid",
5144 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005145
jsgf855d93d2003-10-13 22:26:55 +00005146 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005147 PRE_MEM_WRITE( "waitpid(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005148}
5149
nethercote85a456f2004-11-16 17:31:56 +00005150POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005151{
5152 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005153 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005154}
5155
nethercote85a456f2004-11-16 17:31:56 +00005156PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005157{
nethercote7f7e4d12004-11-15 12:28:58 +00005158 PRINT("sys_wait4 ( %d, %p, %d, %p )", arg1,arg2,arg3,arg4);
nethercote73b526f2004-10-31 18:48:21 +00005159 arg3 &= ~(__VKI_WCLONE | __VKI_WALL);
jsgf855d93d2003-10-13 22:26:55 +00005160
nethercote7f7e4d12004-11-15 12:28:58 +00005161 PRE_REG_READ4(long, "wait4",
5162 vki_pid_t, pid, unsigned int *, status, int, options,
5163 struct rusage *, rusage);
jsgf855d93d2003-10-13 22:26:55 +00005164 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005165 PRE_MEM_WRITE( "wait4(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005166 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005167 PRE_MEM_WRITE( "wait4(rusage)", arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005168}
5169
nethercote85a456f2004-11-16 17:31:56 +00005170POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005171{
5172 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005173 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005174 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005175 POST_MEM_WRITE( arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005176}
5177
nethercote85a456f2004-11-16 17:31:56 +00005178PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005179{
jsgf855d93d2003-10-13 22:26:55 +00005180 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005181 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00005182 PRINT("sys_writev ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
5183 PRE_REG_READ3(ssize_t, "writev",
5184 unsigned long, fd, const struct iovec *, vector,
5185 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00005186 if (!VG_(fd_allowed)(arg1, "writev", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005187 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005188 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005189 PRE_MEM_READ( "writev(vector)",
nethercote73b526f2004-10-31 18:48:21 +00005190 arg2, arg3 * sizeof(struct vki_iovec) );
nethercote163c5e82004-11-17 18:42:20 +00005191 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005192 /* ToDo: don't do any of the following if the vector is invalid */
5193 vec = (struct vki_iovec *)arg2;
5194 for (i = 0; i < (Int)arg3; i++)
5195 PRE_MEM_READ( "writev(vector[...])",
5196 (Addr)vec[i].iov_base, vec[i].iov_len );
5197 }
jsgf855d93d2003-10-13 22:26:55 +00005198 }
5199}
5200
nethercote85a456f2004-11-16 17:31:56 +00005201PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005202{
nethercoteac866b92004-11-15 20:23:15 +00005203 PRINT("sys_utimes ( %p, %p )", arg1,arg2);
nethercoteac866b92004-11-15 20:23:15 +00005204 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
nethercote38e0a9e2004-11-15 20:42:06 +00005205 PRE_MEM_RASCIIZ( "utimes(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005206 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005207 PRE_MEM_READ( "utimes(tvp)", arg2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005208}
5209
nethercote85a456f2004-11-16 17:31:56 +00005210PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005211{
nethercoteef0c7662004-11-06 15:38:43 +00005212 PRINT("sched_setaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005213 PRE_REG_READ3(long, "sched_setaffinity",
5214 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005215 PRE_MEM_READ( "sched_setaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005216}
5217
nethercote85a456f2004-11-16 17:31:56 +00005218PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005219{
nethercoteef0c7662004-11-06 15:38:43 +00005220 PRINT("sched_getaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005221 PRE_REG_READ3(long, "sched_getaffinity",
5222 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005223 PRE_MEM_WRITE( "sched_getaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005224}
5225
nethercote85a456f2004-11-16 17:31:56 +00005226POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005227{
5228 VG_TRACK(post_mem_write, arg3, arg2);
5229}
5230
nethercote85a456f2004-11-16 17:31:56 +00005231PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005232{
nethercote2b0cae62004-11-12 14:57:34 +00005233 PRINT("sys_acct ( %p )", arg1);
5234 PRE_REG_READ1(long, "acct", const char *, filename);
nethercoteef0c7662004-11-06 15:38:43 +00005235 PRE_MEM_RASCIIZ( "acct(filename)", arg1 );
nethercote2bc5a212004-04-10 00:26:10 +00005236}
5237
nethercote85a456f2004-11-16 17:31:56 +00005238PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005239{
nethercote0df495a2004-11-11 16:38:21 +00005240 PRINT("sys_pause ( )");
5241 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005242}
5243
nethercotea3a2c142004-11-14 14:13:05 +00005244// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005245PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005246{
thughesc3e85df2004-11-15 09:27:24 +00005247 /* The C library interface to sigsuspend just takes a pointer to
5248 a signal mask but this system call has three arguments - the first
5249 two don't appear to be used by the kernel and are always passed as
5250 zero by glibc and the third is the first word of the signal mask
5251 so only 32 signals are supported.
5252
5253 In fact glibc normally uses rt_sigsuspend if it is available as
5254 that takes a pointer to the signal mask so supports more signals.
5255 */
thughesd8e00412004-11-14 19:44:25 +00005256 PRINT("sys_sigsuspend ( %d, %d, %d )", arg1,arg2,arg3 );
5257 PRE_REG_READ3(int, "sigsuspend",
5258 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005259 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005260}
5261
nethercotea3a2c142004-11-14 14:13:05 +00005262// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005263PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005264{
thughesc3e85df2004-11-15 09:27:24 +00005265 /* The C library interface to sigsuspend just takes a pointer to
5266 a signal mask but this system call has two arguments - a pointer
5267 to the mask and the number of bytes used by it. The kernel insists
5268 on the size being equal to sizeof(sigset_t) however and will just
5269 return EINVAL if it isn't.
5270 */
nethercotea3a2c142004-11-14 14:13:05 +00005271 PRINT("sys_rt_sigsuspend ( %p, %d )", arg1,arg2 );
5272 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
5273 if (arg1 != (Addr)NULL) {
5274 PRE_MEM_READ( "rt_sigsuspend(mask)", arg1, sizeof(vki_sigset_t) );
5275 }
5276}
jsgf855d93d2003-10-13 22:26:55 +00005277
nethercote85a456f2004-11-16 17:31:56 +00005278PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005279{
nethercoteac866b92004-11-15 20:23:15 +00005280 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
5281 arg1,arg2,arg3,(ULong)arg4);
5282 PRE_REG_READ4(long, "rt_sigtimedwait",
5283 const vki_sigset_t *, set, vki_siginfo_t *, info,
5284 const struct timespec *, timeout, vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005285 if (arg1 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005286 PRE_MEM_READ( "rt_sigtimedwait(set)", arg1, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005287 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005288 PRE_MEM_WRITE( "rt_sigtimedwait(info)", arg2, sizeof(vki_siginfo_t) );
5289 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
5290 arg4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005291}
5292
nethercote85a456f2004-11-16 17:31:56 +00005293POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005294{
nethercote163c5e82004-11-17 18:42:20 +00005295 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005296 POST_MEM_WRITE( arg2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005297}
5298
nethercote85a456f2004-11-16 17:31:56 +00005299PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005300{
nethercote92b2fd52004-11-16 16:15:41 +00005301 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", arg1, arg2, arg3);
5302 PRE_REG_READ3(long, "rt_sigqueueinfo",
5303 int, pid, int, sig, vki_siginfo_t *, uinfo);
nethercote163c5e82004-11-17 18:42:20 +00005304 if (arg2 != 0)
nethercote92b2fd52004-11-16 16:15:41 +00005305 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", arg3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005306}
5307
nethercote85a456f2004-11-16 17:31:56 +00005308POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005309{
5310 if (res >= 0 &&
5311 arg2 != 0 &&
5312 !VG_(is_sig_ign)(arg2) &&
nethercote73b526f2004-10-31 18:48:21 +00005313 !VG_(sigismember)(&tst->eff_sig_mask, arg2) &&
jsgf855d93d2003-10-13 22:26:55 +00005314 arg1 == VG_(getpid)()) {
5315 VG_(proxy_waitsig)();
5316 }
5317}
5318
nethercotec8734892004-11-10 18:57:37 +00005319#define SIGNAL_SIMULATION 1
5320
5321#if SIGNAL_SIMULATION
5322#define SIG_SIM Special
5323#else
5324#define SIG_SIM 0
5325#endif
5326
nethercoteb77dee62004-11-16 17:13:24 +00005327// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005328PRE(sys_sigaltstack, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005329{
5330 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
nethercoteef0c7662004-11-06 15:38:43 +00005331 PRINT("sigaltstack ( %p, %p )",arg1,arg2);
nethercoteb77dee62004-11-16 17:13:24 +00005332 PRE_REG_READ2(int, "sigaltstack",
5333 const vki_stack_t *, ss, vki_stack_t *, oss);
nethercote163c5e82004-11-17 18:42:20 +00005334 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005335 PRE_MEM_READ( "sigaltstack(ss)", arg1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005336 }
nethercote163c5e82004-11-17 18:42:20 +00005337 if (arg2 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005338 PRE_MEM_WRITE( "sigaltstack(oss)", arg2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005339 }
5340
5341 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005342 VG_(do_sys_sigaltstack) (tid);
jsgf855d93d2003-10-13 22:26:55 +00005343}
5344
nethercote85a456f2004-11-16 17:31:56 +00005345POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005346{
nethercote163c5e82004-11-17 18:42:20 +00005347 if (res == 0 && arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005348 POST_MEM_WRITE( arg2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005349}
5350
nethercote71f05f32004-11-12 18:49:27 +00005351// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005352PRE(sys_sigaction, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005353{
nethercote71f05f32004-11-12 18:49:27 +00005354 PRINT("sys_sigaction ( %d, %p, %p )", arg1,arg2,arg3);
5355 PRE_REG_READ3(int, "sigaction",
5356 int, signum, const struct old_sigaction *, act,
5357 struct old_sigaction *, oldact)
nethercote163c5e82004-11-17 18:42:20 +00005358 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005359 PRE_MEM_READ( "sigaction(act)", arg2, sizeof(struct vki_old_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005360 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005361 PRE_MEM_WRITE( "sigaction(oldact)", arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005362
5363 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005364 VG_(do_sys_sigaction)(tid);
jsgf855d93d2003-10-13 22:26:55 +00005365}
5366
nethercote85a456f2004-11-16 17:31:56 +00005367POST(sys_sigaction)
jsgf855d93d2003-10-13 22:26:55 +00005368{
nethercote163c5e82004-11-17 18:42:20 +00005369 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005370 POST_MEM_WRITE( arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005371}
5372
nethercote686b5db2004-11-14 13:42:51 +00005373// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005374PRE(sys_rt_sigaction, SIG_SIM)
nethercote686b5db2004-11-14 13:42:51 +00005375{
5376 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", arg1,arg2,arg3,arg4);
5377 PRE_REG_READ4(long, "rt_sigaction",
5378 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005379 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005380
nethercote163c5e82004-11-17 18:42:20 +00005381 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005382 PRE_MEM_READ( "rt_sigaction(act)", arg2, sizeof(struct vki_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005383 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005384 PRE_MEM_WRITE( "rt_sigaction(oldact)", arg3, sizeof(struct vki_sigaction));
5385
5386 // XXX: hmm... doesn't seem quite right...
5387 if (SIGNAL_SIMULATION)
5388 VG_(do_sys_sigaction)(tid);
5389}
5390
nethercote85a456f2004-11-16 17:31:56 +00005391POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005392{
nethercote163c5e82004-11-17 18:42:20 +00005393 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005394 POST_MEM_WRITE( arg3, sizeof(struct vki_sigaction));
5395}
jsgf855d93d2003-10-13 22:26:55 +00005396
nethercote85a456f2004-11-16 17:31:56 +00005397PRE(sys_sigprocmask, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005398{
nethercote7fbe08a2004-11-15 19:03:27 +00005399 PRINT("sys_sigprocmask ( %d, %p, %p )",arg1,arg2,arg3);
5400 PRE_REG_READ3(long, "sigprocmask",
5401 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
nethercote163c5e82004-11-17 18:42:20 +00005402 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005403 PRE_MEM_READ( "sigprocmask(set)", arg2, sizeof(vki_old_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005404 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005405 PRE_MEM_WRITE( "sigprocmask(oldset)", arg3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005406
nethercote7fbe08a2004-11-15 19:03:27 +00005407 if (SIGNAL_SIMULATION) {
5408 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5409 // vki_sigset_t params.
5410 vki_old_sigset_t* set = (vki_old_sigset_t*)arg2;
5411 vki_old_sigset_t* oldset = (vki_old_sigset_t*)arg3;
5412 vki_sigset_t bigger_set;
5413 vki_sigset_t bigger_oldset;
5414
5415 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5416 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
5417
5418 VG_(do_sys_sigprocmask) ( tid,
5419 arg1 /*how*/,
5420 &bigger_set,
5421 &bigger_oldset );
5422
thughes1112cab2004-11-16 12:08:45 +00005423 if (oldset)
nethercote330abb52004-11-16 12:58:04 +00005424 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005425 }
5426}
5427
nethercote85a456f2004-11-16 17:31:56 +00005428POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005429{
nethercote163c5e82004-11-17 18:42:20 +00005430 if (res == 0 && arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005431 POST_MEM_WRITE( arg3, sizeof(vki_old_sigset_t));
5432}
5433
nethercote85a456f2004-11-16 17:31:56 +00005434PRE(sys_rt_sigprocmask, SIG_SIM)
nethercote7fbe08a2004-11-15 19:03:27 +00005435{
5436 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",arg1,arg2,arg3,(ULong)arg4);
5437 PRE_REG_READ4(long, "rt_sigprocmask",
5438 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5439 vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005440 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005441 PRE_MEM_READ( "rt_sigprocmask(set)", arg2, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005442 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005443 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", arg3, sizeof(vki_sigset_t));
5444
5445 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
5446 if (sizeof(vki_sigset_t) != arg4)
5447 set_result( -VKI_EMFILE );
5448 else if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005449 VG_(do_sys_sigprocmask) ( tid,
jsgf855d93d2003-10-13 22:26:55 +00005450 arg1 /*how*/,
nethercote73b526f2004-10-31 18:48:21 +00005451 (vki_sigset_t*) arg2,
5452 (vki_sigset_t*) arg3 );
jsgf855d93d2003-10-13 22:26:55 +00005453}
5454
nethercote85a456f2004-11-16 17:31:56 +00005455POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005456{
nethercote163c5e82004-11-17 18:42:20 +00005457 if (res == 0 && arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005458 POST_MEM_WRITE( arg3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005459}
5460
nethercote85a456f2004-11-16 17:31:56 +00005461PRE(sys_sigpending, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00005462{
nethercote17258dc2004-11-12 19:55:08 +00005463 PRINT( "sys_sigpending ( %p )", arg1 );
5464 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
5465 PRE_MEM_WRITE( "sigpending(set)", arg1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005466}
5467
nethercote85a456f2004-11-16 17:31:56 +00005468POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005469{
nethercotea6395d12004-11-15 19:23:46 +00005470 POST_MEM_WRITE( arg1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005471}
5472
nethercote85a456f2004-11-16 17:31:56 +00005473PRE(sys_rt_sigpending, NBRunInLWP)
nethercotea6395d12004-11-15 19:23:46 +00005474{
nethercote38e0a9e2004-11-15 20:42:06 +00005475 PRINT( "sys_rt_sigpending ( %p )", arg1 );
nethercotea6395d12004-11-15 19:23:46 +00005476 PRE_REG_READ2(long, "rt_sigpending",
5477 vki_sigset_t *, set, vki_size_t, sigsetsize);
nethercote38e0a9e2004-11-15 20:42:06 +00005478 PRE_MEM_WRITE( "rt_sigpending(set)", arg1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005479}
5480
nethercote85a456f2004-11-16 17:31:56 +00005481POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005482{
5483 POST_MEM_WRITE( arg1, sizeof(vki_sigset_t) ) ;
5484}
jsgf855d93d2003-10-13 22:26:55 +00005485
nethercote85a456f2004-11-16 17:31:56 +00005486PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005487{
nethercote330abb52004-11-16 12:58:04 +00005488 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
5489 arg1,arg1,arg2,(ULong)arg3,arg4);
5490 PRE_REG_READ4(long, "mq_open",
5491 const char *, name, int, oflag, vki_mode_t, mode,
5492 struct mq_attr *, attr);
nethercoteef0c7662004-11-06 15:38:43 +00005493 PRE_MEM_RASCIIZ( "mq_open(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005494 if ((arg2 & VKI_O_CREAT) != 0 && arg4 != 0) {
5495 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg4;
nethercoteef0c7662004-11-06 15:38:43 +00005496 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005497 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005498 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005499 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5500 }
5501}
5502
nethercote85a456f2004-11-16 17:31:56 +00005503POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005504{
nethercote3d5e9102004-11-17 18:22:38 +00005505 if (!VG_(fd_allowed)(res, "mq_open", tid, True)) {
thughes8579b102004-08-14 18:52:27 +00005506 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00005507 set_result( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005508 } else {
5509 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00005510 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
thughes8579b102004-08-14 18:52:27 +00005511 }
thughes8579b102004-08-14 18:52:27 +00005512}
5513
nethercote85a456f2004-11-16 17:31:56 +00005514PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005515{
nethercote330abb52004-11-16 12:58:04 +00005516 PRINT("sys_mq_unlink ( %p(%s) )", arg1,arg1);
5517 PRE_REG_READ1(long, "mq_unlink", const char *, name);
nethercoteef0c7662004-11-06 15:38:43 +00005518 PRE_MEM_RASCIIZ( "mq_unlink(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005519}
5520
nethercote85a456f2004-11-16 17:31:56 +00005521PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005522{
nethercote330abb52004-11-16 12:58:04 +00005523 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
5524 arg1,arg2,(ULong)arg3,arg4,arg5);
5525 PRE_REG_READ5(long, "mq_timedsend",
5526 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5527 unsigned int, msg_prio, const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005528 if (!VG_(fd_allowed)(arg1, "mq_timedsend", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005529 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005530 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005531 PRE_MEM_READ( "mq_timedsend(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005532 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005533 PRE_MEM_READ( "mq_timedsend(abs_timeout)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00005534 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005535 }
5536}
5537
nethercote85a456f2004-11-16 17:31:56 +00005538PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005539{
nethercote330abb52004-11-16 12:58:04 +00005540 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
5541 arg1,arg2,(ULong)arg3,arg4,arg5);
5542 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5543 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5544 unsigned int *, msg_prio,
5545 const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005546 if (!VG_(fd_allowed)(arg1, "mq_timedreceive", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005547 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005548 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005549 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005550 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005551 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
thughes8579b102004-08-14 18:52:27 +00005552 arg4, sizeof(unsigned int) );
5553 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005554 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
nethercote73b526f2004-10-31 18:48:21 +00005555 arg5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005556 }
5557}
5558
nethercote85a456f2004-11-16 17:31:56 +00005559POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005560{
nethercoteef0c7662004-11-06 15:38:43 +00005561 POST_MEM_WRITE( arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005562 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005563 POST_MEM_WRITE( arg4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005564}
5565
nethercote85a456f2004-11-16 17:31:56 +00005566PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005567{
nethercote330abb52004-11-16 12:58:04 +00005568 PRINT("sys_mq_notify( %d, %p )", arg1,arg2 );
5569 PRE_REG_READ2(long, "mq_notify",
5570 vki_mqd_t, mqdes, const struct sigevent *, notification);
nethercote3d5e9102004-11-17 18:22:38 +00005571 if (!VG_(fd_allowed)(arg1, "mq_notify", tid, False))
nethercote35122912004-10-18 17:00:30 +00005572 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005573 else if (arg2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005574 PRE_MEM_READ( "mq_notify(notification)",
5575 arg2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005576}
5577
nethercote85a456f2004-11-16 17:31:56 +00005578PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005579{
nethercote330abb52004-11-16 12:58:04 +00005580 PRINT("sys_mq_getsetattr( %d, %p, %p )", arg1,arg2,arg3 );
5581 PRE_REG_READ3(long, "mq_getsetattr",
5582 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5583 struct mq_attr *, omqstat);
nethercote3d5e9102004-11-17 18:22:38 +00005584 if (!VG_(fd_allowed)(arg1, "mq_getsetattr", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005585 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005586 } else {
5587 if (arg2 != 0) {
5588 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg2;
nethercoteef0c7662004-11-06 15:38:43 +00005589 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005590 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5591 }
5592 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005593 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", arg3,
thughes8579b102004-08-14 18:52:27 +00005594 sizeof(struct vki_mq_attr) );
5595 }
5596}
5597
nethercote85a456f2004-11-16 17:31:56 +00005598POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005599{
5600 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005601 POST_MEM_WRITE( arg3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005602}
5603
nethercote85a456f2004-11-16 17:31:56 +00005604PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005605{
nethercote92b2fd52004-11-16 16:15:41 +00005606 PRINT("sys_timer_create( %d, %p, %p )", arg1,arg2,arg3);
5607 PRE_REG_READ3(long, "timer_create",
5608 vki_clockid_t, clockid, struct sigevent *, evp,
5609 vki_timer_t *, timerid);
thughese1a925d2004-08-30 19:50:02 +00005610 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005611 PRE_MEM_READ( "timer_create(evp)", arg2, sizeof(struct vki_sigevent) );
5612 PRE_MEM_WRITE( "timer_create(timerid)", arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005613}
5614
nethercote85a456f2004-11-16 17:31:56 +00005615POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005616{
nethercoteef0c7662004-11-06 15:38:43 +00005617 POST_MEM_WRITE( arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005618}
5619
nethercote85a456f2004-11-16 17:31:56 +00005620PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005621{
nethercote92b2fd52004-11-16 16:15:41 +00005622 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)arg1,arg2,arg3,arg4);
5623 PRE_REG_READ4(long, "timer_settime",
5624 vki_timer_t, timerid, int, flags,
5625 const struct itimerspec *, value,
5626 struct itimerspec *, ovalue);
nethercoteef0c7662004-11-06 15:38:43 +00005627 PRE_MEM_READ( "timer_settime(value)", arg3,
thughese1a925d2004-08-30 19:50:02 +00005628 sizeof(struct vki_itimerspec) );
5629 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005630 PRE_MEM_WRITE( "timer_settime(ovalue)", arg4,
thughese1a925d2004-08-30 19:50:02 +00005631 sizeof(struct vki_itimerspec) );
5632}
5633
nethercote85a456f2004-11-16 17:31:56 +00005634POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005635{
5636 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005637 POST_MEM_WRITE( arg4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005638}
5639
nethercote85a456f2004-11-16 17:31:56 +00005640PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005641{
nethercote92b2fd52004-11-16 16:15:41 +00005642 PRINT("sys_timer_gettime( %lld, %p )", (ULong)arg1,arg2);
5643 PRE_REG_READ2(long, "timer_gettime",
5644 vki_timer_t, timerid, struct itimerspec *, value);
nethercoteef0c7662004-11-06 15:38:43 +00005645 PRE_MEM_WRITE( "timer_gettime(value)", arg2,
thughese1a925d2004-08-30 19:50:02 +00005646 sizeof(struct vki_itimerspec));
5647}
5648
nethercote85a456f2004-11-16 17:31:56 +00005649POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005650{
nethercoteef0c7662004-11-06 15:38:43 +00005651 POST_MEM_WRITE( arg2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005652}
5653
nethercote85a456f2004-11-16 17:31:56 +00005654PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005655{
nethercote92b2fd52004-11-16 16:15:41 +00005656 PRINT("sys_timer_getoverrun( %p )", arg1);
5657 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005658}
5659
nethercote85a456f2004-11-16 17:31:56 +00005660PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005661{
nethercote92b2fd52004-11-16 16:15:41 +00005662 PRINT("sys_timer_delete( %p )", arg1);
5663 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005664}
5665
nethercote85a456f2004-11-16 17:31:56 +00005666PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005667{
nethercote92b2fd52004-11-16 16:15:41 +00005668 PRINT("sys_clock_settime( %d, %p )", arg1,arg2);
5669 PRE_REG_READ2(long, "clock_settime",
5670 vki_clockid_t, clk_id, const struct timespec *, tp);
5671 PRE_MEM_READ( "clock_settime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005672}
5673
nethercote85a456f2004-11-16 17:31:56 +00005674PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005675{
nethercote92b2fd52004-11-16 16:15:41 +00005676 PRINT("sys_clock_gettime( %d, %p )" , arg1,arg2);
5677 PRE_REG_READ2(long, "clock_gettime",
5678 vki_clockid_t, clk_id, struct timespec *, tp);
5679 PRE_MEM_WRITE( "clock_gettime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005680}
5681
nethercote85a456f2004-11-16 17:31:56 +00005682POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005683{
nethercote92b2fd52004-11-16 16:15:41 +00005684 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005685}
5686
nethercote85a456f2004-11-16 17:31:56 +00005687PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005688{
nethercote92b2fd52004-11-16 16:15:41 +00005689 PRINT("sys_clock_getres( %d, %p )" , arg1,arg2);
5690 // Nb: we can't use "res" as the param name because that's a macro
5691 // defined above!
5692 PRE_REG_READ2(long, "clock_getres",
5693 vki_clockid_t, clk_id, struct timespec *, cres);
5694 PRE_MEM_WRITE( "clock_getres(cres)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005695}
5696
nethercote85a456f2004-11-16 17:31:56 +00005697POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005698{
nethercote92b2fd52004-11-16 16:15:41 +00005699 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005700}
5701
nethercote4fa681f2004-11-08 17:51:39 +00005702
5703/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005704 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005705 ------------------------------------------------------------------ */
5706
nethercote85a456f2004-11-16 17:31:56 +00005707static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005708static void bad_before(ThreadId tid, ThreadState *tst)
5709{
5710 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005711 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005712 if (VG_(clo_verbosity) > 1) {
5713 ExeContext *ec = VG_(get_ExeContext)(tid);
5714 VG_(pp_ExeContext)(ec);
5715 }
jsgf855d93d2003-10-13 22:26:55 +00005716 VG_(message)
5717 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5718 VG_(message)
5719 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5720
nethercote35122912004-10-18 17:00:30 +00005721 set_result( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005722}
5723
nethercote8ff888f2004-11-17 17:11:45 +00005724static const struct SyscallTableEntry bad_sys =
5725 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005726
nethercote4fa681f2004-11-08 17:51:39 +00005727
jsgf855d93d2003-10-13 22:26:55 +00005728Bool VG_(pre_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00005729{
sewardj018f7622002-05-15 21:13:39 +00005730 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005731 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005732 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00005733 Bool isSpecial = False;
5734 Bool mayBlock = False;
5735 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00005736 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00005737
njn25e49d8e72002-09-23 09:36:25 +00005738 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00005739
jsgf855d93d2003-10-13 22:26:55 +00005740 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00005741
jsgf855d93d2003-10-13 22:26:55 +00005742 /* Convert vfork to fork, since we can't handle it otherwise. */
nethercote427e9512004-08-23 16:36:09 +00005743 if (SYSNO == __NR_vfork)
5744 SYSNO = __NR_fork;
sewardjde4a1d02002-03-22 01:27:54 +00005745
nethercote44d9aaa2004-11-04 19:38:14 +00005746 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00005747
5748 if (tst->syscallno != -1)
5749 VG_(printf)("tid %d has syscall %d\n", tst->tid, tst->syscallno);
5750
nethercote1c2a3f52004-11-12 20:38:34 +00005751 vg_assert(tst->syscallno == -1); // should be no current syscall
5752 vg_assert(tst->status == VgTs_Runnable); // should be runnable */
jsgf855d93d2003-10-13 22:26:55 +00005753
5754 /* the syscall no is in %eax. For syscalls with <= 6 args,
5755 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
5756 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00005757 containing the args.
5758
5759 The result is returned in %eax. If this value >= 0, the call
5760 succeeded, and this is the return value. If < 0, it failed, and
5761 the negation of this value is errno. To be more specific,
5762 if res is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
5763 (kernel 2.4.9 sources, include/asm-i386/errno.h)
5764 then it indicates an error. Otherwise it doesn't.
5765
5766 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
5767 (inclusive?) indicate error returns. Not sure where the -4095
5768 comes from.
5769 */
5770
jsgf855d93d2003-10-13 22:26:55 +00005771 tst->syscallno = syscallno;
fitzhardingef0f911c2003-11-09 09:51:33 +00005772 vg_assert(tst->status == VgTs_Runnable);
sewardjde4a1d02002-03-22 01:27:54 +00005773
nethercote8ff888f2004-11-17 17:11:45 +00005774 if (syscallno < VGA_(syscall_table_size) &&
5775 VGA_(syscall_table)[syscallno].before != NULL)
5776 {
5777 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005778 } else {
5779 sys = &bad_sys;
nethercotec8734892004-11-10 18:57:37 +00005780 }
nethercote85a456f2004-11-16 17:31:56 +00005781 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00005782
nethercote1fe55d62004-11-12 11:02:00 +00005783 {
5784 Bool nbrunInLWP = ( flags & NBRunInLWP ? True : False );
5785 isSpecial = ( flags & Special ? True : False );
5786 mayBlock = ( flags & MayBlock ? True : False );
5787 runInLWP = mayBlock || nbrunInLWP;
5788 // At most one of these should be true
5789 vg_assert( isSpecial + mayBlock + nbrunInLWP <= 1 );
5790 }
nethercotec8734892004-11-10 18:57:37 +00005791
5792 tst->sys_flags = flags;
5793
jsgf855d93d2003-10-13 22:26:55 +00005794 /* Do any pre-syscall actions */
5795 if (VG_(needs).syscall_wrapper) {
5796 VGP_PUSHCC(VgpSkinSysWrap);
nethercotec8734892004-11-10 18:57:37 +00005797 tst->sys_pre_res = SK_(pre_syscall)(tid, syscallno, mayBlock);
jsgf855d93d2003-10-13 22:26:55 +00005798 VGP_POPCC(VgpSkinSysWrap);
5799 }
5800
nethercoteef0c7662004-11-06 15:38:43 +00005801 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
5802 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00005803 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00005804 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00005805
nethercotec8734892004-11-10 18:57:37 +00005806 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00005807 /* "Special" syscalls are implemented by Valgrind internally,
5808 and do not generate real kernel calls. The expectation,
5809 therefore, is that the "before" function not only does the
5810 appropriate tests, but also performs the syscall itself and
5811 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00005812 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00005813
5814 (sys->before)(tst->tid, tst);
5815
nethercotec8734892004-11-10 18:57:37 +00005816 vg_assert(tst->sys_flags == flags);
thughesbaa46e52004-07-29 17:44:23 +00005817
nethercoteef0c7662004-11-06 15:38:43 +00005818 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005819 syscall_done = True;
5820 } else {
5821 (sys->before)(tst->tid, tst);
5822
nethercote44d9aaa2004-11-04 19:38:14 +00005823 if ((Word)res <= 0) {
jsgf855d93d2003-10-13 22:26:55 +00005824 /* "before" decided the syscall wasn't viable, so don't do
5825 anything - just pretend the syscall happened. */
nethercoteef0c7662004-11-06 15:38:43 +00005826 PRINT(" ==> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005827 syscall_done = True;
nethercote1fe55d62004-11-12 11:02:00 +00005828 } else if (runInLWP) {
fitzhardinge33730212003-11-10 21:21:00 +00005829 /* Issue to worker. If we're waiting on the syscall because
5830 it's in the hands of the ProxyLWP, then set the thread
5831 state to WaitSys. */
nethercoteef0c7662004-11-06 15:38:43 +00005832 PRINT(" --> ...\n");
fitzhardinge33730212003-11-10 21:21:00 +00005833 tst->status = VgTs_WaitSys;
jsgf855d93d2003-10-13 22:26:55 +00005834 VG_(sys_issue)(tid);
5835 } else {
5836 /* run the syscall directly */
nethercotea4670f62004-08-23 16:39:42 +00005837 res = VG_(do_syscall)(syscallno, arg1, arg2, arg3, arg4, arg5, arg6);
nethercoteef0c7662004-11-06 15:38:43 +00005838 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005839 syscall_done = True;
5840 }
5841 }
5842
5843 VGP_POPCC(VgpCoreSysWrap);
5844
fitzhardinge33730212003-11-10 21:21:00 +00005845 vg_assert(( syscall_done && tst->status == VgTs_Runnable) ||
5846 (!syscall_done && tst->status == VgTs_WaitSys ));
fitzhardingef0f911c2003-11-09 09:51:33 +00005847
jsgf855d93d2003-10-13 22:26:55 +00005848 return syscall_done;
5849}
5850
nethercote85cdd342004-08-01 22:36:40 +00005851static void restart_syscall(ThreadId tid)
5852{
5853 ThreadState* tst;
5854 tst = VG_(get_ThreadState)(tid);
5855
5856 vg_assert(tst != NULL);
5857 vg_assert(tst->status == VgTs_WaitSys);
5858 vg_assert(tst->syscallno != -1);
5859
nethercote427e9512004-08-23 16:36:09 +00005860 SYSNO = tst->syscallno;
nethercote41c75da2004-10-18 15:34:14 +00005861 VGA_(restart_syscall)(&tst->arch);
nethercote85cdd342004-08-01 22:36:40 +00005862}
jsgf855d93d2003-10-13 22:26:55 +00005863
fitzhardinge31ba9052004-01-16 02:15:23 +00005864void VG_(post_syscall) ( ThreadId tid, Bool restart )
jsgf855d93d2003-10-13 22:26:55 +00005865{
5866 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005867 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005868 const struct SyscallTableEntry *sys;
nethercotec8734892004-11-10 18:57:37 +00005869 Bool isSpecial = False;
fitzhardinge31ba9052004-01-16 02:15:23 +00005870 Bool restarted = False;
jsgf855d93d2003-10-13 22:26:55 +00005871 void *pre_res;
5872
5873 VGP_PUSHCC(VgpCoreSysWrap);
5874
5875 tst = VG_(get_ThreadState)(tid);
nethercoteef0c7662004-11-06 15:38:43 +00005876 vg_assert(tst->tid == tid);
jsgf855d93d2003-10-13 22:26:55 +00005877
nethercote996901a2004-08-03 13:29:09 +00005878 /* Tell the tool about the syscall return value */
nethercote427e9512004-08-23 16:36:09 +00005879 SET_SYSCALL_RETVAL(tst->tid, res);
jsgf855d93d2003-10-13 22:26:55 +00005880
5881 syscallno = tst->syscallno;
5882 pre_res = tst->sys_pre_res;
5883
5884 vg_assert(syscallno != -1); /* must be a current syscall */
jsgf855d93d2003-10-13 22:26:55 +00005885
nethercote8ff888f2004-11-17 17:11:45 +00005886 if (syscallno < VGA_(syscall_table_size) &&
5887 VGA_(syscall_table)[syscallno].before != NULL)
5888 {
5889 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005890 } else {
5891 sys = &bad_sys;
jsgf855d93d2003-10-13 22:26:55 +00005892 }
nethercote85a456f2004-11-16 17:31:56 +00005893 flags = *(sys->flags_ptr);
nethercotec8734892004-11-10 18:57:37 +00005894
5895 isSpecial = flags & Special;
fitzhardingef0f911c2003-11-09 09:51:33 +00005896
nethercote427e9512004-08-23 16:36:09 +00005897 if (res == -VKI_ERESTARTSYS) {
fitzhardinge31ba9052004-01-16 02:15:23 +00005898 /* Applications never expect to see this, so we should either
5899 restart the syscall or fail it with EINTR, depending on what
5900 our caller wants. Generally they'll want to restart, but if
5901 client set the signal state to not restart, then we fail with
5902 EINTR. Either way, ERESTARTSYS means the syscall made no
5903 progress, and so can be failed or restarted without
5904 consequence. */
5905 if (0)
5906 VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
5907 syscallno, restart);
5908
5909 if (restart) {
5910 restarted = True;
nethercote85cdd342004-08-01 22:36:40 +00005911 restart_syscall(tid);
fitzhardinge31ba9052004-01-16 02:15:23 +00005912 } else
nethercotea4670f62004-08-23 16:39:42 +00005913 res = -VKI_EINTR;
fitzhardinge31ba9052004-01-16 02:15:23 +00005914 }
5915
5916 if (!restarted) {
thughesbaa46e52004-07-29 17:44:23 +00005917 if (sys->after != NULL &&
nethercote427e9512004-08-23 16:36:09 +00005918 ((tst->sys_flags & PostOnFail) != 0 || !VG_(is_kerror)(res)))
fitzhardinge31ba9052004-01-16 02:15:23 +00005919 (sys->after)(tst->tid, tst);
5920
5921 /* Do any post-syscall actions
5922
5923 NOTE: this is only called if the syscall completed. If the
5924 syscall was restarted, then it will call the Tool's
5925 pre_syscall again, without calling post_syscall (ie, more
5926 pre's than post's)
5927 */
5928 if (VG_(needs).syscall_wrapper) {
5929 VGP_PUSHCC(VgpSkinSysWrap);
nethercote427e9512004-08-23 16:36:09 +00005930 SK_(post_syscall)(tid, syscallno, pre_res, res, /*isBlocking*/True); // did block
fitzhardinge31ba9052004-01-16 02:15:23 +00005931 VGP_POPCC(VgpSkinSysWrap);
5932 }
fitzhardingee1c06d82003-10-30 07:21:44 +00005933 }
5934
jsgf855d93d2003-10-13 22:26:55 +00005935 tst->status = VgTs_Runnable; /* runnable again */
fitzhardinge31ba9052004-01-16 02:15:23 +00005936 tst->syscallno = -1; /* no current syscall */
sewardj2e93c502002-04-12 11:12:52 +00005937
njn25e49d8e72002-09-23 09:36:25 +00005938 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00005939}
5940
nethercote427e9512004-08-23 16:36:09 +00005941#undef SYSNO
5942#undef res
5943#undef arg1
5944#undef arg2
5945#undef arg3
5946#undef arg4
5947#undef arg5
5948#undef arg6
5949
sewardjde4a1d02002-03-22 01:27:54 +00005950/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00005951/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005952/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00005953