blob: 9d02cccd35c6414167e42a5c50e1d26bc3683639 [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) {
njn26f02512004-11-22 18:33:15 +0000861 TL_(pre_mem_write) ( Vg_CoreSysCall,
fitzhardinge98abfc72003-12-16 02:05:15 +0000862 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) {
njn26f02512004-11-22 18:33:15 +0000874 TL_(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_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00001927{
nethercote5b653bc2004-11-15 14:32:12 +00001928 PRINT("sys_fchdir ( %d )", arg1);
1929 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001930}
1931
nethercote85a456f2004-11-16 17:31:56 +00001932PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00001933{
nethercote2e1c37d2004-11-13 13:57:12 +00001934 PRINT("sys_fchown16 ( %d, %d, %d )", arg1,arg2,arg3);
1935 PRE_REG_READ3(long, "fchown16",
1936 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00001937}
1938
nethercote85a456f2004-11-16 17:31:56 +00001939PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00001940{
1941 PRINT("sys_fchown ( %d, %d, %d )", arg1,arg2,arg3);
1942 PRE_REG_READ3(long, "fchown",
1943 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
1944}
jsgf855d93d2003-10-13 22:26:55 +00001945
nethercote85a456f2004-11-16 17:31:56 +00001946PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00001947{
nethercoteac866b92004-11-15 20:23:15 +00001948 PRINT("sys_fchmod ( %d, %d )", arg1,arg2);
nethercotedc18c0a2004-11-14 20:06:27 +00001949 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00001950}
1951
njncfb8ad52004-11-23 14:57:49 +00001952void common_pre_fcntl(Bool is64, ThreadId tid, ThreadState* tst)
1953{
1954 switch (arg2) {
1955 // These ones ignore arg3.
1956 case VKI_F_GETFD:
1957 case VKI_F_GETFL:
1958 case VKI_F_GETOWN:
1959 case VKI_F_SETOWN:
1960 case VKI_F_GETSIG:
1961 case VKI_F_SETSIG:
1962 case VKI_F_GETLEASE:
1963 if (is64) {
1964 PRINT("sys_fcntl64 ( %d, %d )", arg1,arg2);
1965 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
1966 } else {
1967 PRINT("sys_fcntl ( %d, %d )", arg1,arg2);
1968 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1969 }
1970 break;
1971
1972 // These ones use arg3 as "arg".
1973 case VKI_F_DUPFD:
1974 case VKI_F_SETFD:
1975 case VKI_F_SETFL:
1976 case VKI_F_SETLEASE:
1977 case VKI_F_NOTIFY:
1978 if (is64) {
1979 PRINT("sys_fcntl64[arg3=='arg'] ( %d, %d, %d )", arg1,arg2,arg3);
1980 PRE_REG_READ3(long, "fcntl64",
1981 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1982 } else {
1983 PRINT("sys_fcntl[arg3=='arg'] ( %d, %d, %d )", arg1,arg2,arg3);
1984 PRE_REG_READ3(long, "fcntl",
1985 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1986 }
1987 break;
1988
1989 // These ones use arg3 as "lock".
1990 case VKI_F_GETLK:
1991 case VKI_F_SETLK:
1992 case VKI_F_SETLKW:
1993 case VKI_F_GETLK64:
1994 case VKI_F_SETLK64:
1995 case VKI_F_SETLKW64:
1996 if (is64) {
1997 PRINT("sys_fcntl64[arg3=='lock'] ( %d, %d, %p )", arg1,arg2,arg3);
1998 PRE_REG_READ3(long, "fcntl64",
1999 unsigned int, fd, unsigned int, cmd,
2000 struct flock64 *, lock);
2001 } else {
2002 PRINT("sys_fcntl[arg3=='lock'] ( %d, %d, %p )", arg1,arg2,arg3);
2003 PRE_REG_READ3(long, "fcntl",
2004 unsigned int, fd, unsigned int, cmd,
2005 struct flock64 *, lock);
2006 }
2007 break;
2008 }
2009}
2010
2011PRE(sys_fcntl, 0)
2012{
2013 common_pre_fcntl(/*is64*/False, tid, tst);
2014
2015 if (arg2 == VKI_F_SETLKW)
2016 tst->sys_flags |= MayBlock;
2017}
2018
2019POST(sys_fcntl)
2020{
2021 if (arg2 == VKI_F_DUPFD) {
2022 if (!VG_(fd_allowed)(res, "fcntl(DUPFD)", tid, True)) {
2023 VG_(close)(res);
2024 set_result( -VKI_EMFILE );
2025 } else {
2026 if (VG_(clo_track_fds))
2027 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
2028 }
2029 }
2030}
2031
nethercote06c7bd72004-11-14 19:11:56 +00002032// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00002033PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00002034{
njncfb8ad52004-11-23 14:57:49 +00002035 common_pre_fcntl(/*is64*/True, tid, tst);
2036
thughesd4b51a62004-07-29 21:20:11 +00002037 if (arg2 == VKI_F_SETLKW || arg2 == VKI_F_SETLKW64)
2038 tst->sys_flags |= MayBlock;
rjwalshf5f536f2003-11-17 17:45:00 +00002039}
2040
nethercote85a456f2004-11-16 17:31:56 +00002041POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002042{
nethercote493dd182004-02-24 23:57:47 +00002043 if (arg2 == VKI_F_DUPFD) {
nethercote3d5e9102004-11-17 18:22:38 +00002044 if (!VG_(fd_allowed)(res, "fcntl64(DUPFD)", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00002045 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00002046 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002047 } else {
2048 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00002049 VG_(record_fd_open)(tid, res, VG_(resolve_filename)(res));
nethercote493dd182004-02-24 23:57:47 +00002050 }
2051 }
jsgf855d93d2003-10-13 22:26:55 +00002052}
2053
nethercote85a456f2004-11-16 17:31:56 +00002054PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00002055{
nethercote2e1c37d2004-11-13 13:57:12 +00002056 PRINT("sys_newfstat ( %d, %p )", arg1,arg2);
2057 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
2058 PRE_MEM_WRITE( "fstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002059}
2060
nethercote85a456f2004-11-16 17:31:56 +00002061POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00002062{
nethercoteef0c7662004-11-06 15:38:43 +00002063 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002064}
2065
nethercote73b526f2004-10-31 18:48:21 +00002066static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002067
nethercote75a8c982004-11-11 19:03:34 +00002068// In Linux, the sys_fork() function varies across architectures, but we
2069// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00002070PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00002071{
nethercote73b526f2004-10-31 18:48:21 +00002072 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002073
nethercote75a8c982004-11-11 19:03:34 +00002074 PRINT("sys_fork ( )");
2075 PRE_REG_READ0(long, "fork");
2076
jsgf855d93d2003-10-13 22:26:55 +00002077 vg_assert(VG_(gettid)() == VG_(main_pid));
2078
2079 /* Block all signals during fork, so that we can fix things up in
2080 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002081 VG_(sigfillset)(&mask);
2082 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002083
jsgf855d93d2003-10-13 22:26:55 +00002084 do_atfork_pre(tid);
2085}
2086
nethercote85a456f2004-11-16 17:31:56 +00002087POST(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002088{
2089 if (res == 0) {
2090 do_atfork_child(tid);
2091
2092 /* I am the child. Nuke all other threads which I might
2093 have inherited from my parent. POSIX mandates this. */
2094 VG_(nuke_all_threads_except)( tid );
2095
2096 /* XXX TODO: tid 1 is special, and is presumed to be present.
2097 We should move this TID to 1 in the child. */
2098
2099 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002100 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002101 } else {
nethercoteef0c7662004-11-06 15:38:43 +00002102 PRINT(" fork: process %d created child %d\n", VG_(main_pid), res);
jsgf855d93d2003-10-13 22:26:55 +00002103
2104 do_atfork_parent(tid);
2105
2106 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002107 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002108 }
2109}
2110
nethercote85a456f2004-11-16 17:31:56 +00002111PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002112{
nethercote5a945af2004-11-14 18:37:07 +00002113 PRINT("sys_ftruncate ( %d, %lld )", arg1,(ULong)arg2);
2114 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002115}
2116
nethercote85a456f2004-11-16 17:31:56 +00002117PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002118{
nethercote5a945af2004-11-14 18:37:07 +00002119 PRINT("sys_truncate ( %p(%s), %d )", arg1,arg1,arg2);
2120 PRE_REG_READ2(long, "truncate",
2121 const char *, path, unsigned long, length);
2122 PRE_MEM_RASCIIZ( "truncate(path)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00002123}
2124
nethercote5a945af2004-11-14 18:37:07 +00002125// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002126PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002127{
2128 PRINT("sys_ftruncate64 ( %d, %lld )", arg1, LOHI64(arg2,arg3));
2129 PRE_REG_READ3(long, "ftruncate64",
2130 unsigned int, fd,
2131 vki_u32, length_low32, vki_u32, length_high32);
2132}
2133
2134// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002135PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002136{
2137 PRINT("sys_truncate64 ( %p, %lld )", arg1, LOHI64(arg2, arg3));
2138 PRE_REG_READ3(long, "truncate64",
2139 const char *, path,
2140 vki_u32, length_low32, vki_u32, length_high32);
2141 PRE_MEM_RASCIIZ( "truncate64(path)", arg1 );
2142}
2143
2144
nethercote85a456f2004-11-16 17:31:56 +00002145PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002146{
nethercote06c7bd72004-11-14 19:11:56 +00002147 PRINT("sys_getdents ( %d, %p, %d )", arg1,arg2,arg3);
2148 PRE_REG_READ3(long, "getdents",
2149 unsigned int, fd, struct linux_dirent *, dirp,
2150 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002151 PRE_MEM_WRITE( "getdents(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002152}
2153
nethercote85a456f2004-11-16 17:31:56 +00002154POST(sys_getdents)
jsgf855d93d2003-10-13 22:26:55 +00002155{
2156 if (res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002157 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00002158}
2159
nethercote85a456f2004-11-16 17:31:56 +00002160PRE(sys_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002161{
nethercoteac866b92004-11-15 20:23:15 +00002162 PRINT("sys_getdents64 ( %d, %p, %d )",arg1,arg2,arg3);
nethercote06c7bd72004-11-14 19:11:56 +00002163 PRE_REG_READ3(long, "getdents64",
2164 unsigned int, fd, struct linux_dirent64 *, dirp,
2165 unsigned int, count);
nethercoteef0c7662004-11-06 15:38:43 +00002166 PRE_MEM_WRITE( "getdents64(dirp)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00002167}
2168
nethercote85a456f2004-11-16 17:31:56 +00002169POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002170{
2171 if (res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002172 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00002173}
2174
nethercote85a456f2004-11-16 17:31:56 +00002175PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002176{
nethercote686b5db2004-11-14 13:42:51 +00002177 PRINT("sys_getgroups16 ( %d, %p )", arg1, arg2);
2178 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
2179 if (arg1 > 0)
2180 PRE_MEM_WRITE( "getgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
2181}
2182
nethercote85a456f2004-11-16 17:31:56 +00002183POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002184{
2185 if (arg1 > 0 && res > 0)
2186 POST_MEM_WRITE( arg2, res * sizeof(vki_old_gid_t) );
2187}
2188
nethercote85a456f2004-11-16 17:31:56 +00002189PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002190{
nethercoteac866b92004-11-15 20:23:15 +00002191 PRINT("sys_getgroups ( %d, %p )", arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00002192 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00002193 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002194 PRE_MEM_WRITE( "getgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002195}
2196
nethercote85a456f2004-11-16 17:31:56 +00002197POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002198{
2199 if (arg1 > 0 && res > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002200 POST_MEM_WRITE( arg2, res * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002201}
2202
nethercote85a456f2004-11-16 17:31:56 +00002203PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002204{
nethercoteac866b92004-11-15 20:23:15 +00002205 // Note that the kernel version of getcwd() behaves quite differently to
2206 // the glibc one.
2207 PRINT("sys_getcwd ( %p, %llu )", arg1,(ULong)arg2);
2208 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
nethercoteef0c7662004-11-06 15:38:43 +00002209 PRE_MEM_WRITE( "getcwd(buf)", arg1, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00002210}
2211
nethercote85a456f2004-11-16 17:31:56 +00002212POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002213{
2214 if (res != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00002215 POST_MEM_WRITE( arg1, res );
jsgf855d93d2003-10-13 22:26:55 +00002216}
2217
nethercote85a456f2004-11-16 17:31:56 +00002218PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002219{
nethercote0df495a2004-11-11 16:38:21 +00002220 PRINT("sys_geteuid16 ( )");
2221 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002222}
2223
nethercote85a456f2004-11-16 17:31:56 +00002224PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002225{
nethercote0df495a2004-11-11 16:38:21 +00002226 PRINT("sys_geteuid ( )");
2227 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002228}
2229
nethercote85a456f2004-11-16 17:31:56 +00002230PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002231{
nethercote0df495a2004-11-11 16:38:21 +00002232 PRINT("sys_getegid16 ( )");
2233 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002234}
2235
nethercote85a456f2004-11-16 17:31:56 +00002236PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002237{
nethercote0df495a2004-11-11 16:38:21 +00002238 PRINT("sys_getegid ( )");
2239 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002240}
2241
nethercote85a456f2004-11-16 17:31:56 +00002242PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002243{
nethercote0df495a2004-11-11 16:38:21 +00002244 PRINT("sys_getgid16 ( )");
2245 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002246}
2247
nethercote85a456f2004-11-16 17:31:56 +00002248PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002249{
nethercote0df495a2004-11-11 16:38:21 +00002250 PRINT("sys_getgid ( )");
2251 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002252}
2253
nethercote85a456f2004-11-16 17:31:56 +00002254PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002255{
nethercote4e632c22004-11-09 16:45:33 +00002256 PRINT("sys_getpid ()");
2257 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002258}
2259
nethercote85a456f2004-11-16 17:31:56 +00002260PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002261{
nethercote5b653bc2004-11-15 14:32:12 +00002262 PRINT("sys_getpgid ( %d )", arg1);
2263 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002264}
2265
nethercote85a456f2004-11-16 17:31:56 +00002266PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002267{
nethercote0df495a2004-11-11 16:38:21 +00002268 PRINT("sys_getpgrp ()");
2269 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002270}
2271
nethercote85a456f2004-11-16 17:31:56 +00002272PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002273{
nethercote4e632c22004-11-09 16:45:33 +00002274 PRINT("sys_getppid ()");
2275 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002276}
2277
nethercote620154f2004-11-12 21:21:07 +00002278static void common_post_getrlimit(UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002279{
nethercote620154f2004-11-12 21:21:07 +00002280 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002281
nethercote620154f2004-11-12 21:21:07 +00002282 switch (a1) {
2283 case VKI_RLIMIT_NOFILE:
2284 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2285 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2286 break;
nethercote535f03b2004-02-15 15:32:51 +00002287
nethercote620154f2004-11-12 21:21:07 +00002288 case VKI_RLIMIT_DATA:
2289 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2290 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002291
nethercote620154f2004-11-12 21:21:07 +00002292 case VKI_RLIMIT_STACK:
2293 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2294 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002295 }
jsgf855d93d2003-10-13 22:26:55 +00002296}
2297
nethercote85a456f2004-11-16 17:31:56 +00002298PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002299{
2300 PRINT("sys_old_getrlimit ( %d, %p )", arg1,arg2);
2301 PRE_REG_READ2(long, "old_getrlimit",
2302 unsigned int, resource, struct rlimit *, rlim);
2303 PRE_MEM_WRITE( "old_getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2304}
2305
nethercote85a456f2004-11-16 17:31:56 +00002306POST(sys_old_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002307{
2308 common_post_getrlimit(arg1, arg2);
2309}
2310
nethercote85a456f2004-11-16 17:31:56 +00002311PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002312{
2313 PRINT("sys_getrlimit ( %d, %p )", arg1,arg2);
2314 PRE_REG_READ2(long, "getrlimit",
2315 unsigned int, resource, struct rlimit *, rlim);
2316 PRE_MEM_WRITE( "getrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
2317}
2318
nethercote85a456f2004-11-16 17:31:56 +00002319POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002320{
2321 common_post_getrlimit(arg1, arg2);
2322}
jsgf855d93d2003-10-13 22:26:55 +00002323
nethercote85a456f2004-11-16 17:31:56 +00002324PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00002325{
2326 /* int getrusage (int who, struct rusage *usage); */
nethercotef1049bf2004-11-14 17:03:47 +00002327 PRINT("sys_getrusage ( %d, %p )", arg1,arg2);
2328 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
nethercoteef0c7662004-11-06 15:38:43 +00002329 PRE_MEM_WRITE( "getrusage(usage)", arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002330}
2331
nethercote85a456f2004-11-16 17:31:56 +00002332POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00002333{
2334 if (res == 0)
nethercotef1049bf2004-11-14 17:03:47 +00002335 VG_TRACK( post_mem_write, arg2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00002336}
2337
nethercote85a456f2004-11-16 17:31:56 +00002338PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00002339{
nethercote686b5db2004-11-14 13:42:51 +00002340 PRINT("sys_gettimeofday ( %p, %p )", arg1,arg2);
2341 PRE_REG_READ2(long, "gettimeofday",
2342 struct timeval *, tv, struct timezone *, tz);
nethercoteef0c7662004-11-06 15:38:43 +00002343 PRE_MEM_WRITE( "gettimeofday(tv)", arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002344 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002345 PRE_MEM_WRITE( "gettimeofday(tz)", arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002346}
2347
nethercote85a456f2004-11-16 17:31:56 +00002348POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00002349{
2350 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002351 POST_MEM_WRITE( arg1, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00002352 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002353 POST_MEM_WRITE( arg2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00002354 }
2355}
2356
nethercote85a456f2004-11-16 17:31:56 +00002357PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00002358{
2359 PRINT("sys_settimeofday ( %p, %p )", arg1,arg2);
2360 PRE_REG_READ2(long, "settimeofday",
2361 struct timeval *, tv, struct timezone *, tz);
2362 PRE_MEM_READ( "settimeofday(tv)", arg1, sizeof(struct vki_timeval) );
2363 if (arg2 != 0) {
2364 PRE_MEM_READ( "settimeofday(tz)", arg2, sizeof(struct vki_timezone) );
2365 /* maybe should warn if tz->tz_dsttime is non-zero? */
2366 }
2367}
2368
nethercote85a456f2004-11-16 17:31:56 +00002369PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002370{
nethercote0df495a2004-11-11 16:38:21 +00002371 PRINT("sys_getuid16 ( )");
2372 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00002373}
2374
nethercote85a456f2004-11-16 17:31:56 +00002375PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002376{
nethercote0df495a2004-11-11 16:38:21 +00002377 PRINT("sys_getuid ( )");
2378 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00002379}
2380
nethercote7f7e4d12004-11-15 12:28:58 +00002381// XXX: x86-specific
2382// XXX: should use the constants here (eg. SHMAT), not the numbers directly!
nethercote85a456f2004-11-16 17:31:56 +00002383PRE(sys_ipc, 0)
jsgf855d93d2003-10-13 22:26:55 +00002384{
nethercote7f7e4d12004-11-15 12:28:58 +00002385 PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", arg1,arg2,arg3,arg4,arg5,arg6);
2386 // XXX: this is simplistic -- some args are not used in all circumstances.
2387 PRE_REG_READ6(int, "ipc",
2388 vki_uint, call, int, first, int, second, int, third,
2389 void *, ptr, long, fifth)
2390
jsgf855d93d2003-10-13 22:26:55 +00002391 switch (arg1 /* call */) {
2392 case 1: /* IPCOP_semop */
nethercoteef0c7662004-11-06 15:38:43 +00002393 PRE_MEM_READ( "semop(sops)", arg5, arg3 * sizeof(struct vki_sembuf) );
thughes024f25d2004-07-29 22:40:07 +00002394 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002395 break;
2396 case 2: /* IPCOP_semget */
jsgf855d93d2003-10-13 22:26:55 +00002397 break;
thughes60797102004-08-13 22:21:51 +00002398 case 3: /* IPCOP_semctl */
2399 {
nethercote73b526f2004-10-31 18:48:21 +00002400 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002401 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002402 case VKI_IPC_INFO:
2403 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002404 {
2405 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002406 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002407 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002408 break;
2409 }
nethercote73b526f2004-10-31 18:48:21 +00002410 case VKI_IPC_STAT:
2411 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002412 {
2413 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002414 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002415 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002416 break;
2417 }
nethercote73b526f2004-10-31 18:48:21 +00002418 case VKI_IPC_SET:
thughes60797102004-08-13 22:21:51 +00002419 {
2420 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002421 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002422 sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002423 break;
2424 }
nethercote73b526f2004-10-31 18:48:21 +00002425 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002426 {
2427 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2428 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002429 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002430 sizeof(short) * nsems );
2431 break;
2432 }
nethercote73b526f2004-10-31 18:48:21 +00002433 case VKI_SETALL:
thughes60797102004-08-13 22:21:51 +00002434 {
2435 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2436 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002437 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002438 sizeof(short) * nsems );
2439 break;
2440 }
nethercote73b526f2004-10-31 18:48:21 +00002441 case VKI_SETVAL:
thughes60797102004-08-13 22:21:51 +00002442 {
nethercoteef0c7662004-11-06 15:38:43 +00002443 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002444 (Addr)&arg->val, sizeof(arg->val) );
2445 break;
2446 }
nethercote73b526f2004-10-31 18:48:21 +00002447 case VKI_IPC_INFO|VKI_IPC_64:
2448 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002449 {
2450 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(IPC_INFO, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002451 PRE_MEM_WRITE( "semctl(IPC_INFO, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002452 sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002453 break;
2454 }
nethercote73b526f2004-10-31 18:48:21 +00002455 case VKI_IPC_STAT|VKI_IPC_64:
2456 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002457 {
2458 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_STAT, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002459 PRE_MEM_WRITE( "semctl(IPC_STAT, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002460 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002461 break;
2462 }
nethercote73b526f2004-10-31 18:48:21 +00002463 case VKI_IPC_SET|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002464 {
2465 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(IPC_SET, arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002466 PRE_MEM_READ( "semctl(IPC_SET, arg->buf)", buf,
nethercote73b526f2004-10-31 18:48:21 +00002467 sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002468 break;
2469 }
nethercote73b526f2004-10-31 18:48:21 +00002470 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002471 {
2472 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_GETALL, arg)" );
2473 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002474 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002475 sizeof(short) * nsems );
2476 break;
2477 }
nethercote73b526f2004-10-31 18:48:21 +00002478 case VKI_SETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002479 {
2480 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(IPC_SETALL, arg)" );
2481 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002482 PRE_MEM_READ( "semctl(IPC_SETALL, arg->array)", array,
thughes60797102004-08-13 22:21:51 +00002483 sizeof(short) * nsems );
2484 break;
2485 }
nethercote73b526f2004-10-31 18:48:21 +00002486 case VKI_SETVAL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002487 {
nethercoteef0c7662004-11-06 15:38:43 +00002488 PRE_MEM_READ( "semctl(IPC_SETVAL, arg->array)",
thughes60797102004-08-13 22:21:51 +00002489 (Addr)&arg->val, sizeof(arg->val) );
2490 break;
2491 }
thughes60797102004-08-13 22:21:51 +00002492 default:
2493 break;
2494 }
2495 break;
2496 }
thughes03766282004-06-13 14:23:00 +00002497 case 4: /* IPCOP_semtimedop */
nethercoteef0c7662004-11-06 15:38:43 +00002498 PRE_MEM_READ( "semtimedop(sops)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002499 arg3 * sizeof(struct vki_sembuf) );
nethercote163c5e82004-11-17 18:42:20 +00002500 if (arg6 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00002501 PRE_MEM_READ( "semtimedop(timeout)", arg6,
nethercote73b526f2004-10-31 18:48:21 +00002502 sizeof(struct vki_timespec) );
thughes024f25d2004-07-29 22:40:07 +00002503 tst->sys_flags |= MayBlock;
thughes03766282004-06-13 14:23:00 +00002504 break;
jsgf855d93d2003-10-13 22:26:55 +00002505 case 11: /* IPCOP_msgsnd */
2506 {
nethercote73b526f2004-10-31 18:48:21 +00002507 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg5;
jsgf855d93d2003-10-13 22:26:55 +00002508 Int msgsz = arg3;
2509
nethercoteef0c7662004-11-06 15:38:43 +00002510 PRE_MEM_READ( "msgsnd(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002511 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002512 PRE_MEM_READ( "msgsnd(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002513 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002514
2515 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2516 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002517 break;
2518 }
2519 case 12: /* IPCOP_msgrcv */
2520 {
nethercote73b526f2004-10-31 18:48:21 +00002521 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002522 Int msgsz = arg3;
2523
nethercote73b526f2004-10-31 18:48:21 +00002524 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2525 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002526 "msgrcv(msgp)" );
2527
nethercoteef0c7662004-11-06 15:38:43 +00002528 PRE_MEM_WRITE( "msgrcv(msgp->mtype)",
nethercotea8c1e922004-10-26 10:57:24 +00002529 (Addr)&msgp->mtype, sizeof(msgp->mtype) );
nethercoteef0c7662004-11-06 15:38:43 +00002530 PRE_MEM_WRITE( "msgrcv(msgp->mtext)",
nethercotea8c1e922004-10-26 10:57:24 +00002531 (Addr)msgp->mtext, msgsz );
thughes024f25d2004-07-29 22:40:07 +00002532
2533 if ((arg4 & VKI_IPC_NOWAIT) == 0)
2534 tst->sys_flags |= MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00002535 break;
2536 }
2537 case 13: /* IPCOP_msgget */
2538 break;
2539 case 14: /* IPCOP_msgctl */
2540 {
2541 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002542 case VKI_IPC_INFO:
2543 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002544 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002545 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002546 break;
nethercote73b526f2004-10-31 18:48:21 +00002547 case VKI_IPC_STAT:
2548 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002549 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002550 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002551 break;
nethercote73b526f2004-10-31 18:48:21 +00002552 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002553 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002554 sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002555 break;
nethercote73b526f2004-10-31 18:48:21 +00002556 case VKI_IPC_INFO|VKI_IPC_64:
2557 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002558 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002559 sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002560 break;
nethercote73b526f2004-10-31 18:48:21 +00002561 case VKI_IPC_STAT|VKI_IPC_64:
2562 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002563 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002564 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002565 break;
nethercote73b526f2004-10-31 18:48:21 +00002566 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002567 PRE_MEM_READ( "msgctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002568 sizeof(struct vki_msqid64_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002569 break;
jsgf855d93d2003-10-13 22:26:55 +00002570 default:
2571 break;
2572 }
2573 break;
2574 }
2575 case 21: /* IPCOP_shmat */
2576 {
fitzhardinge98abfc72003-12-16 02:05:15 +00002577 UInt shmid = arg2;
2578 UInt segmentSize = get_shm_size ( shmid );
2579
2580 /* If they didn't ask for a particular address, then place it
2581 like an mmap. */
2582 if (arg5 == 0)
2583 arg5 = VG_(find_map_space)(0, segmentSize, True);
nethercote8ff888f2004-11-17 17:11:45 +00002584 else if (!VG_(valid_client_addr)(arg5, segmentSize, tid, "shmat"))
nethercote35122912004-10-18 17:00:30 +00002585 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002586 break;
2587 }
2588 case 22: /* IPCOP_shmdt */
nethercote8ff888f2004-11-17 17:11:45 +00002589 if (!VG_(valid_client_addr)(arg5, 1, tid, "shmdt"))
nethercote35122912004-10-18 17:00:30 +00002590 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00002591 break;
2592 case 23: /* IPCOP_shmget */
2593 break;
2594 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002595 {
thughes60797102004-08-13 22:21:51 +00002596 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002597 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002598 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002599 sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002600 break;
nethercote73b526f2004-10-31 18:48:21 +00002601 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002602 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002603 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002604 break;
nethercote73b526f2004-10-31 18:48:21 +00002605 case VKI_IPC_STAT:
2606 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002607 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002608 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002609 break;
nethercote73b526f2004-10-31 18:48:21 +00002610 case VKI_IPC_SET:
nethercoteef0c7662004-11-06 15:38:43 +00002611 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002612 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002613 break;
nethercote73b526f2004-10-31 18:48:21 +00002614 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002615 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002616 sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002617 break;
nethercote73b526f2004-10-31 18:48:21 +00002618 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002619 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002620 sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002621 break;
nethercote73b526f2004-10-31 18:48:21 +00002622 case VKI_IPC_STAT|VKI_IPC_64:
2623 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002624 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002625 sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002626 break;
nethercote73b526f2004-10-31 18:48:21 +00002627 case VKI_IPC_SET|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002628 PRE_MEM_READ( "shmctl(IPC_SET, buf)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00002629 sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002630 break;
thughes60797102004-08-13 22:21:51 +00002631 default:
2632 break;
jsgf855d93d2003-10-13 22:26:55 +00002633 }
thughes60797102004-08-13 22:21:51 +00002634 break;
jsgf855d93d2003-10-13 22:26:55 +00002635 }
jsgf855d93d2003-10-13 22:26:55 +00002636 default:
2637 VG_(message)(Vg_DebugMsg,
2638 "FATAL: unhandled syscall(ipc) %d",
2639 arg1 );
2640 VG_(core_panic)("... bye!\n");
2641 break; /*NOTREACHED*/
2642 }
2643}
2644
nethercote85a456f2004-11-16 17:31:56 +00002645POST(sys_ipc)
jsgf855d93d2003-10-13 22:26:55 +00002646{
2647 switch (arg1 /* call */) {
2648 case 1: /* IPCOP_semop */
jsgf855d93d2003-10-13 22:26:55 +00002649 case 2: /* IPCOP_semget */
thughes60797102004-08-13 22:21:51 +00002650 break;
jsgf855d93d2003-10-13 22:26:55 +00002651 case 3: /* IPCOP_semctl */
thughes60797102004-08-13 22:21:51 +00002652 {
nethercote73b526f2004-10-31 18:48:21 +00002653 union vki_semun *arg = (union vki_semun *)arg5;
thughes60797102004-08-13 22:21:51 +00002654 switch (arg4 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002655 case VKI_IPC_INFO:
2656 case VKI_SEM_INFO:
thughes60797102004-08-13 22:21:51 +00002657 {
2658 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002659 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002660 break;
2661 }
nethercote73b526f2004-10-31 18:48:21 +00002662 case VKI_IPC_STAT:
2663 case VKI_SEM_STAT:
thughes60797102004-08-13 22:21:51 +00002664 {
2665 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002666 POST_MEM_WRITE( buf, sizeof(struct vki_semid_ds) );
thughes60797102004-08-13 22:21:51 +00002667 break;
2668 }
nethercote73b526f2004-10-31 18:48:21 +00002669 case VKI_GETALL:
thughes60797102004-08-13 22:21:51 +00002670 {
2671 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2672 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002673 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002674 break;
2675 }
nethercote73b526f2004-10-31 18:48:21 +00002676 case VKI_IPC_INFO|VKI_IPC_64:
2677 case VKI_SEM_INFO|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002678 {
2679 Addr buf = deref_Addr( tid, (Addr)&arg->__buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002680 POST_MEM_WRITE( buf, sizeof(struct vki_seminfo) );
thughes60797102004-08-13 22:21:51 +00002681 break;
2682 }
nethercote73b526f2004-10-31 18:48:21 +00002683 case VKI_IPC_STAT|VKI_IPC_64:
2684 case VKI_SEM_STAT|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002685 {
2686 Addr buf = deref_Addr( tid, (Addr)&arg->buf, "semctl(arg)" );
nethercoteef0c7662004-11-06 15:38:43 +00002687 POST_MEM_WRITE( buf, sizeof(struct vki_semid64_ds) );
thughes60797102004-08-13 22:21:51 +00002688 break;
2689 }
nethercote73b526f2004-10-31 18:48:21 +00002690 case VKI_GETALL|VKI_IPC_64:
thughes60797102004-08-13 22:21:51 +00002691 {
2692 Addr array = deref_Addr( tid, (Addr)&arg->array, "semctl(arg)" );
2693 UInt nsems = get_sem_count( arg2 );
nethercoteef0c7662004-11-06 15:38:43 +00002694 POST_MEM_WRITE( array, sizeof(short) * nsems );
thughes60797102004-08-13 22:21:51 +00002695 break;
2696 }
thughes60797102004-08-13 22:21:51 +00002697 default:
2698 break;
2699 }
2700 break;
2701 }
thughes03766282004-06-13 14:23:00 +00002702 case 4: /* IPCOP_semtimedop */
jsgf855d93d2003-10-13 22:26:55 +00002703 break;
2704 case 11: /* IPCOP_msgsnd */
2705 break;
2706 case 12: /* IPCOP_msgrcv */
2707 {
nethercote73b526f2004-10-31 18:48:21 +00002708 struct vki_msgbuf *msgp;
jsgf855d93d2003-10-13 22:26:55 +00002709
nethercote73b526f2004-10-31 18:48:21 +00002710 msgp = (struct vki_msgbuf *)deref_Addr( tid,
2711 (Addr) (&((struct vki_ipc_kludge *)arg5)->msgp),
jsgf855d93d2003-10-13 22:26:55 +00002712 "msgrcv(msgp)" );
2713 if ( res > 0 ) {
nethercoteef0c7662004-11-06 15:38:43 +00002714 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
2715 POST_MEM_WRITE( (Addr)msgp->mtext, res );
jsgf855d93d2003-10-13 22:26:55 +00002716 }
2717 break;
2718 }
2719 case 13: /* IPCOP_msgget */
2720 break;
2721 case 14: /* IPCOP_msgctl */
2722 {
2723 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002724 case VKI_IPC_INFO:
2725 case VKI_MSG_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002726 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
thughes60797102004-08-13 22:21:51 +00002727 break;
nethercote73b526f2004-10-31 18:48:21 +00002728 case VKI_IPC_STAT:
2729 case VKI_MSG_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002730 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid_ds) );
jsgf855d93d2003-10-13 22:26:55 +00002731 break;
nethercote73b526f2004-10-31 18:48:21 +00002732 case VKI_IPC_SET:
jsgf855d93d2003-10-13 22:26:55 +00002733 break;
nethercote73b526f2004-10-31 18:48:21 +00002734 case VKI_IPC_INFO|VKI_IPC_64:
2735 case VKI_MSG_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002736 POST_MEM_WRITE( arg5, sizeof(struct vki_msginfo) );
jsgf855d93d2003-10-13 22:26:55 +00002737 break;
nethercote73b526f2004-10-31 18:48:21 +00002738 case VKI_IPC_STAT|VKI_IPC_64:
2739 case VKI_MSG_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002740 POST_MEM_WRITE( arg5, sizeof(struct vki_msqid64_ds) );
thughes60797102004-08-13 22:21:51 +00002741 break;
nethercote73b526f2004-10-31 18:48:21 +00002742 case VKI_IPC_SET|VKI_IPC_64:
jsgf855d93d2003-10-13 22:26:55 +00002743 break;
jsgf855d93d2003-10-13 22:26:55 +00002744 default:
2745 break;
2746 }
2747 break;
2748 }
2749 case 21: /* IPCOP_shmat */
2750 {
2751 Int shmid = arg2;
fitzhardinge98abfc72003-12-16 02:05:15 +00002752 Int shmflag = arg3;
jsgf855d93d2003-10-13 22:26:55 +00002753 Addr addr;
2754
jsgf855d93d2003-10-13 22:26:55 +00002755 /* force readability. before the syscall it is
2756 * indeed uninitialized, as can be seen in
2757 * glibc/sysdeps/unix/sysv/linux/shmat.c */
nethercoteef0c7662004-11-06 15:38:43 +00002758 POST_MEM_WRITE( arg4, sizeof( ULong ) );
jsgf855d93d2003-10-13 22:26:55 +00002759
2760 addr = deref_Addr ( tid, arg4, "shmat(addr)" );
2761 if ( addr > 0 ) {
2762 UInt segmentSize = get_shm_size ( shmid );
2763 if ( segmentSize > 0 ) {
nethercote27ea8bc2004-07-10 17:21:14 +00002764 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
jsgf855d93d2003-10-13 22:26:55 +00002765 /* we don't distinguish whether it's read-only or
2766 * read-write -- it doesn't matter really. */
nethercote071c84a2004-07-10 17:30:07 +00002767 VG_TRACK( new_mem_mmap, addr, segmentSize, True, True, False );
fitzhardinge98abfc72003-12-16 02:05:15 +00002768
fitzhardinge98abfc72003-12-16 02:05:15 +00002769 if (!(shmflag & 010000)) /* = SHM_RDONLY */
2770 prot &= ~VKI_PROT_WRITE;
nethercote27ea8bc2004-07-10 17:21:14 +00002771 VG_(map_segment)(addr, segmentSize, prot, SF_SHARED|SF_SHM);
jsgf855d93d2003-10-13 22:26:55 +00002772 }
2773 }
2774 break;
2775 }
2776 case 22: /* IPCOP_shmdt */
fitzhardinge98abfc72003-12-16 02:05:15 +00002777 {
fitzhardinged25e8a22004-02-25 00:07:10 +00002778 Segment *s = VG_(find_segment)(arg5);
fitzhardinge98abfc72003-12-16 02:05:15 +00002779
fitzhardinged25e8a22004-02-25 00:07:10 +00002780 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg5, 1)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00002781 VG_TRACK( die_mem_munmap, s->addr, s->len );
2782 VG_(unmap_range)(s->addr, s->len);
2783 }
jsgf855d93d2003-10-13 22:26:55 +00002784 break;
fitzhardinge98abfc72003-12-16 02:05:15 +00002785 }
jsgf855d93d2003-10-13 22:26:55 +00002786 case 23: /* IPCOP_shmget */
2787 break;
2788 case 24: /* IPCOP_shmctl */
jsgf855d93d2003-10-13 22:26:55 +00002789 {
thughes60797102004-08-13 22:21:51 +00002790 switch (arg3 /* cmd */) {
nethercote73b526f2004-10-31 18:48:21 +00002791 case VKI_IPC_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002792 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo) );
thughes60797102004-08-13 22:21:51 +00002793 break;
nethercote73b526f2004-10-31 18:48:21 +00002794 case VKI_SHM_INFO:
nethercoteef0c7662004-11-06 15:38:43 +00002795 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002796 break;
nethercote73b526f2004-10-31 18:48:21 +00002797 case VKI_IPC_STAT:
2798 case VKI_SHM_STAT:
nethercoteef0c7662004-11-06 15:38:43 +00002799 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid_ds) );
thughes60797102004-08-13 22:21:51 +00002800 break;
nethercote73b526f2004-10-31 18:48:21 +00002801 case VKI_IPC_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002802 POST_MEM_WRITE( arg5, sizeof(struct vki_shminfo64) );
thughes60797102004-08-13 22:21:51 +00002803 break;
nethercote73b526f2004-10-31 18:48:21 +00002804 case VKI_SHM_INFO|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002805 POST_MEM_WRITE( arg5, sizeof(struct vki_shm_info) );
thughes60797102004-08-13 22:21:51 +00002806 break;
nethercote73b526f2004-10-31 18:48:21 +00002807 case VKI_IPC_STAT|VKI_IPC_64:
2808 case VKI_SHM_STAT|VKI_IPC_64:
nethercoteef0c7662004-11-06 15:38:43 +00002809 POST_MEM_WRITE( arg5, sizeof(struct vki_shmid64_ds) );
thughes60797102004-08-13 22:21:51 +00002810 break;
thughes60797102004-08-13 22:21:51 +00002811 default:
2812 break;
jsgf855d93d2003-10-13 22:26:55 +00002813 }
thughes60797102004-08-13 22:21:51 +00002814 break;
jsgf855d93d2003-10-13 22:26:55 +00002815 }
jsgf855d93d2003-10-13 22:26:55 +00002816 default:
2817 VG_(message)(Vg_DebugMsg,
2818 "FATAL: unhandled syscall(ipc) %d",
2819 arg1 );
2820 VG_(core_panic)("... bye!\n");
2821 break; /*NOTREACHED*/
2822 }
2823}
2824
nethercote2e1c37d2004-11-13 13:57:12 +00002825// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00002826PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002827{
nethercote9c311eb2004-11-12 18:20:12 +00002828 PRINT("sys_ioctl ( %d, 0x%x, %p )",arg1,arg2,arg3);
2829 PRE_REG_READ3(long, "ioctl",
2830 unsigned int, fd, unsigned int, request, unsigned long, arg);
2831
jsgf855d93d2003-10-13 22:26:55 +00002832 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00002833 case VKI_TCSETS:
2834 case VKI_TCSETSW:
2835 case VKI_TCSETSF:
nethercote11e07d32004-11-06 16:17:52 +00002836 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002837 break;
nethercote73b526f2004-10-31 18:48:21 +00002838 case VKI_TCGETS:
nethercote11e07d32004-11-06 16:17:52 +00002839 PRE_MEM_WRITE( "ioctl(TCGETS)", arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00002840 break;
nethercote73b526f2004-10-31 18:48:21 +00002841 case VKI_TCSETA:
2842 case VKI_TCSETAW:
2843 case VKI_TCSETAF:
nethercote11e07d32004-11-06 16:17:52 +00002844 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002845 break;
nethercote73b526f2004-10-31 18:48:21 +00002846 case VKI_TCGETA:
nethercote11e07d32004-11-06 16:17:52 +00002847 PRE_MEM_WRITE( "ioctl(TCGETA)", arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00002848 break;
nethercote73b526f2004-10-31 18:48:21 +00002849 case VKI_TCSBRK:
2850 case VKI_TCXONC:
2851 case VKI_TCSBRKP:
2852 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00002853 /* These just take an int by value */
2854 break;
nethercote73b526f2004-10-31 18:48:21 +00002855 case VKI_TIOCGWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002856 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002857 break;
nethercote73b526f2004-10-31 18:48:21 +00002858 case VKI_TIOCSWINSZ:
nethercote11e07d32004-11-06 16:17:52 +00002859 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00002860 break;
nethercote73b526f2004-10-31 18:48:21 +00002861 case VKI_TIOCMBIS:
nethercote11e07d32004-11-06 16:17:52 +00002862 PRE_MEM_READ( "ioctl(TIOCMBIS)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002863 break;
nethercote73b526f2004-10-31 18:48:21 +00002864 case VKI_TIOCMBIC:
nethercote11e07d32004-11-06 16:17:52 +00002865 PRE_MEM_READ( "ioctl(TIOCMBIC)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002866 break;
nethercote73b526f2004-10-31 18:48:21 +00002867 case VKI_TIOCMSET:
nethercote11e07d32004-11-06 16:17:52 +00002868 PRE_MEM_READ( "ioctl(TIOCMSET)", arg3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00002869 break;
nethercote73b526f2004-10-31 18:48:21 +00002870 case VKI_TIOCLINUX:
nethercote11e07d32004-11-06 16:17:52 +00002871 PRE_MEM_READ( "ioctl(TIOCLINUX)", arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002872 if (*(char *)arg3 == 11) {
nethercote11e07d32004-11-06 16:17:52 +00002873 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", arg3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00002874 }
2875 break;
nethercote73b526f2004-10-31 18:48:21 +00002876 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002877 /* Get process group ID for foreground processing group. */
nethercote11e07d32004-11-06 16:17:52 +00002878 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002879 break;
nethercote73b526f2004-10-31 18:48:21 +00002880 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00002881 /* Set a process group ID? */
nethercote11e07d32004-11-06 16:17:52 +00002882 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002883 break;
nethercote73b526f2004-10-31 18:48:21 +00002884 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercote11e07d32004-11-06 16:17:52 +00002885 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002886 break;
nethercote73b526f2004-10-31 18:48:21 +00002887 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00002888 /* Just takes an int value. */
2889 break;
nethercote73b526f2004-10-31 18:48:21 +00002890 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
nethercote11e07d32004-11-06 16:17:52 +00002891 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002892 break;
nethercote73b526f2004-10-31 18:48:21 +00002893 case VKI_FIONBIO:
nethercote11e07d32004-11-06 16:17:52 +00002894 PRE_MEM_READ( "ioctl(FIONBIO)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002895 break;
nethercote73b526f2004-10-31 18:48:21 +00002896 case VKI_FIOASYNC:
nethercote11e07d32004-11-06 16:17:52 +00002897 PRE_MEM_READ( "ioctl(FIOASYNC)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002898 break;
nethercote73b526f2004-10-31 18:48:21 +00002899 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercote11e07d32004-11-06 16:17:52 +00002900 PRE_MEM_WRITE( "ioctl(FIONREAD)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002901 break;
2902
nethercote73b526f2004-10-31 18:48:21 +00002903 case VKI_SG_SET_COMMAND_Q:
nethercote11e07d32004-11-06 16:17:52 +00002904 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002905 break;
nethercote73b526f2004-10-31 18:48:21 +00002906 case VKI_SG_IO:
nethercote11e07d32004-11-06 16:17:52 +00002907 PRE_MEM_WRITE( "ioctl(SG_IO)", arg3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00002908 break;
nethercote73b526f2004-10-31 18:48:21 +00002909 case VKI_SG_GET_SCSI_ID:
nethercote11e07d32004-11-06 16:17:52 +00002910 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", arg3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00002911 break;
nethercote73b526f2004-10-31 18:48:21 +00002912 case VKI_SG_SET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002913 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002914 break;
nethercote73b526f2004-10-31 18:48:21 +00002915 case VKI_SG_SET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002916 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002917 break;
nethercote73b526f2004-10-31 18:48:21 +00002918 case VKI_SG_GET_RESERVED_SIZE:
nethercote11e07d32004-11-06 16:17:52 +00002919 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002920 break;
nethercote73b526f2004-10-31 18:48:21 +00002921 case VKI_SG_GET_TIMEOUT:
nethercote11e07d32004-11-06 16:17:52 +00002922 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002923 break;
nethercote73b526f2004-10-31 18:48:21 +00002924 case VKI_SG_GET_VERSION_NUM:
nethercote11e07d32004-11-06 16:17:52 +00002925 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00002926 break;
nethercote73b526f2004-10-31 18:48:21 +00002927 case VKI_SG_EMULATED_HOST: /* 0x2203 */
nethercote11e07d32004-11-06 16:17:52 +00002928 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002929 break;
nethercote73b526f2004-10-31 18:48:21 +00002930 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
nethercote11e07d32004-11-06 16:17:52 +00002931 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", arg3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00002932 break;
jsgf855d93d2003-10-13 22:26:55 +00002933
muellera4b153a2003-11-19 22:07:14 +00002934 case VKI_IIOCGETCPS:
nethercoteef0c7662004-11-06 15:38:43 +00002935 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", arg3,
nethercote95a97862004-11-06 16:31:43 +00002936 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00002937 break;
muellera4b153a2003-11-19 22:07:14 +00002938 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00002939 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
nethercote73b526f2004-10-31 18:48:21 +00002940 (Addr)&((vki_isdn_net_ioctl_phone *)arg3)->name,
2941 sizeof(((vki_isdn_net_ioctl_phone *)arg3)->name) );
nethercoteef0c7662004-11-06 15:38:43 +00002942 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00002943 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00002944 break;
2945
2946 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00002947 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00002948 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
nethercote73b526f2004-10-31 18:48:21 +00002949 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002950 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00002951 break;
nethercote73b526f2004-10-31 18:48:21 +00002952 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00002953 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00002954 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002955 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002956 break;
nethercote73b526f2004-10-31 18:48:21 +00002957 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00002958 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002959 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002960 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002961 break;
nethercote73b526f2004-10-31 18:48:21 +00002962 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00002963 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00002964 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002965 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002966 break;
nethercote73b526f2004-10-31 18:48:21 +00002967 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002968 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002969 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002970 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002971 break;
nethercote73b526f2004-10-31 18:48:21 +00002972 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00002973 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
nethercote73b526f2004-10-31 18:48:21 +00002974 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002975 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002976 break;
nethercote73b526f2004-10-31 18:48:21 +00002977 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00002978 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00002979 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002980 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002981 break;
nethercote73b526f2004-10-31 18:48:21 +00002982 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00002983 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00002984 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002985 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002986 break;
nethercote73b526f2004-10-31 18:48:21 +00002987 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00002988 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00002989 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002990 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002991 break;
nethercote73b526f2004-10-31 18:48:21 +00002992 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002993 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002994 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00002995 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00002996 break;
nethercote73b526f2004-10-31 18:48:21 +00002997 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00002998 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
nethercote73b526f2004-10-31 18:48:21 +00002999 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00003000 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003001 break;
nethercote73b526f2004-10-31 18:48:21 +00003002 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003003 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
nethercote73b526f2004-10-31 18:48:21 +00003004 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
3005 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
nethercote11e07d32004-11-06 16:17:52 +00003006 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003007 break;
nethercote73b526f2004-10-31 18:48:21 +00003008 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003009 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
nethercote73b526f2004-10-31 18:48:21 +00003010 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercote11e07d32004-11-06 16:17:52 +00003011 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", arg3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003012 break;
nethercote73b526f2004-10-31 18:48:21 +00003013 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003014 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
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(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003017 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3018 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003019 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003020 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
3021 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003022 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003023 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003024 break;
nethercote73b526f2004-10-31 18:48:21 +00003025 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003026 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00003027 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003028 KERNEL_DO_SYSCALL(tid,res);
3029 if (!VG_(is_kerror)(res) && res == 0)
3030 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
3031 */
nethercoteef0c7662004-11-06 15:38:43 +00003032 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", arg3, sizeof(struct vki_ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003033 if ( arg3 ) {
3034 // TODO len must be readable and writable
3035 // buf pointer only needs to be readable
nethercote73b526f2004-10-31 18:48:21 +00003036 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003037 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003038 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003039 }
3040 break;
nethercote73b526f2004-10-31 18:48:21 +00003041 case VKI_SIOCGSTAMP:
nethercote11e07d32004-11-06 16:17:52 +00003042 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", arg3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003043 break;
3044 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3045 the number of bytes currently in that socket's send buffer.
3046 It writes this value as an int to the memory location
3047 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003048 case VKI_SIOCOUTQ:
nethercote11e07d32004-11-06 16:17:52 +00003049 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003050 break;
nethercote73b526f2004-10-31 18:48:21 +00003051 case VKI_SIOCGRARP: /* get RARP table entry */
3052 case VKI_SIOCGARP: /* get ARP table entry */
nethercote11e07d32004-11-06 16:17:52 +00003053 PRE_MEM_WRITE( "ioctl(SIOCGARP)", arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003054 break;
3055
nethercote73b526f2004-10-31 18:48:21 +00003056 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003057 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00003058 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003059 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
nethercote73b526f2004-10-31 18:48:21 +00003060 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
3061 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003062 break;
nethercote73b526f2004-10-31 18:48:21 +00003063 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003064 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00003065 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003066 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
nethercote73b526f2004-10-31 18:48:21 +00003067 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
3068 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003069 break;
nethercote73b526f2004-10-31 18:48:21 +00003070 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003071 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003072 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003073 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
nethercote73b526f2004-10-31 18:48:21 +00003074 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3075 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003076 break;
nethercote73b526f2004-10-31 18:48:21 +00003077 case VKI_SIOCSIFADDR: /* set PA address */
3078 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3079 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3080 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003081 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003082 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003083 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003084 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3085 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003086 break;
nethercote73b526f2004-10-31 18:48:21 +00003087 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003088 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003089 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003090 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
nethercote73b526f2004-10-31 18:48:21 +00003091 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3092 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003093 break;
nethercote73b526f2004-10-31 18:48:21 +00003094 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003095 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003096 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003097 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
nethercote73b526f2004-10-31 18:48:21 +00003098 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3099 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003100 break;
nethercote73b526f2004-10-31 18:48:21 +00003101 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003102 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003103 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003104 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
nethercote73b526f2004-10-31 18:48:21 +00003105 (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3106 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003107 break;
nethercote73b526f2004-10-31 18:48:21 +00003108 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003109 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003110 (Addr)((struct vki_ifreq *)arg3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003111 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003112 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3113 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003114 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003115 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num,
3116 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003117 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
nethercote73b526f2004-10-31 18:48:21 +00003118 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in,
3119 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003120 break;
jsgf855d93d2003-10-13 22:26:55 +00003121 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003122 case VKI_SIOCADDRT: /* add routing table entry */
3123 case VKI_SIOCDELRT: /* delete routing table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003124 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", arg3,
3125 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003126 break;
3127
3128 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003129 case VKI_SIOCDRARP: /* delete RARP table entry */
3130 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003131 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003132 case VKI_SIOCSARP: /* set ARP table entry */
3133 case VKI_SIOCDARP: /* delete ARP table entry */
nethercoteef0c7662004-11-06 15:38:43 +00003134 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", arg3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003135 break;
3136
nethercote73b526f2004-10-31 18:48:21 +00003137 case VKI_SIOCGPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003138 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003139 break;
nethercote73b526f2004-10-31 18:48:21 +00003140 case VKI_SIOCSPGRP:
nethercoteef0c7662004-11-06 15:38:43 +00003141 PRE_MEM_READ( "ioctl(SIOCSPGRP)", arg3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003142 tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003143 break;
3144
3145 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003146 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3147 case VKI_SNDCTL_SEQ_GETINCOUNT:
3148 case VKI_SNDCTL_SEQ_PERCMODE:
3149 case VKI_SNDCTL_SEQ_TESTMIDI:
3150 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3151 case VKI_SNDCTL_SEQ_NRSYNTHS:
3152 case VKI_SNDCTL_SEQ_NRMIDIS:
3153 case VKI_SNDCTL_SEQ_GETTIME:
3154 case VKI_SNDCTL_DSP_GETFMTS:
3155 case VKI_SNDCTL_DSP_GETTRIGGER:
3156 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003157 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003158 case VKI_SNDCTL_DSP_GETCAPS:
3159 case VKI_SOUND_PCM_READ_RATE:
3160 case VKI_SOUND_PCM_READ_CHANNELS:
3161 case VKI_SOUND_PCM_READ_BITS:
3162 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3163 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003164 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
3165 arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003166 break;
nethercote73b526f2004-10-31 18:48:21 +00003167 case VKI_SNDCTL_SEQ_CTRLRATE:
3168 case VKI_SNDCTL_DSP_SPEED:
3169 case VKI_SNDCTL_DSP_STEREO:
3170 case VKI_SNDCTL_DSP_GETBLKSIZE:
3171 case VKI_SNDCTL_DSP_CHANNELS:
3172 case VKI_SOUND_PCM_WRITE_FILTER:
3173 case VKI_SNDCTL_DSP_SUBDIVIDE:
3174 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003175 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003176 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003177 case VKI_SNDCTL_TMR_TIMEBASE:
3178 case VKI_SNDCTL_TMR_TEMPO:
3179 case VKI_SNDCTL_TMR_SOURCE:
3180 case VKI_SNDCTL_MIDI_PRETIME:
3181 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003182 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003183 arg3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003184 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
jsgf855d93d2003-10-13 22:26:55 +00003185 arg3, sizeof(int));
3186 break;
nethercote73b526f2004-10-31 18:48:21 +00003187 case VKI_SNDCTL_DSP_GETOSPACE:
3188 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003189 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
3190 arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003191 break;
nethercote73b526f2004-10-31 18:48:21 +00003192 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003193 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
jsgf855d93d2003-10-13 22:26:55 +00003194 arg3, sizeof(int));
3195 break;
3196
nethercote73b526f2004-10-31 18:48:21 +00003197 case VKI_SNDCTL_DSP_POST:
3198 case VKI_SNDCTL_DSP_RESET:
3199 case VKI_SNDCTL_DSP_SYNC:
3200 case VKI_SNDCTL_DSP_SETSYNCRO:
3201 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003202 break;
3203
3204 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003205 case VKI_RTC_UIE_ON:
3206 case VKI_RTC_UIE_OFF:
3207 case VKI_RTC_AIE_ON:
3208 case VKI_RTC_AIE_OFF:
3209 case VKI_RTC_PIE_ON:
3210 case VKI_RTC_PIE_OFF:
3211 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003212 break;
nethercote73b526f2004-10-31 18:48:21 +00003213 case VKI_RTC_RD_TIME:
3214 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003215 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
nethercote73b526f2004-10-31 18:48:21 +00003216 arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003217 break;
nethercote73b526f2004-10-31 18:48:21 +00003218 case VKI_RTC_ALM_SET:
nethercote11e07d32004-11-06 16:17:52 +00003219 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003220 break;
nethercote73b526f2004-10-31 18:48:21 +00003221 case VKI_RTC_IRQP_READ:
nethercote11e07d32004-11-06 16:17:52 +00003222 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003223 break;
jsgf855d93d2003-10-13 22:26:55 +00003224
nethercote95a97862004-11-06 16:31:43 +00003225 case VKI_BLKGETSIZE:
nethercote11e07d32004-11-06 16:17:52 +00003226 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003227 break;
jsgf855d93d2003-10-13 22:26:55 +00003228
thughesacbbc322004-06-19 12:12:01 +00003229 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003230 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
nethercoteef0c7662004-11-06 15:38:43 +00003231 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003232 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003233 break;
3234
jsgf855d93d2003-10-13 22:26:55 +00003235 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003236 case VKI_CDROM_GET_MCN:
nethercoteef0c7662004-11-06 15:38:43 +00003237 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003238 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003239 break;
nethercote73b526f2004-10-31 18:48:21 +00003240 case VKI_CDROM_SEND_PACKET:
nethercoteef0c7662004-11-06 15:38:43 +00003241 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003242 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003243 break;
nethercote73b526f2004-10-31 18:48:21 +00003244 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003245 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
3246 (Addr) &(((struct vki_cdrom_subchnl*) arg3)->cdsc_format),
3247 sizeof(((struct vki_cdrom_subchnl*) arg3)->cdsc_format));
3248 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003249 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003250 break;
nethercote73b526f2004-10-31 18:48:21 +00003251 case VKI_CDROMREADMODE2:
nethercote11e07d32004-11-06 16:17:52 +00003252 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", arg3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003253 break;
nethercote73b526f2004-10-31 18:48:21 +00003254 case VKI_CDROMREADTOCHDR:
nethercote11e07d32004-11-06 16:17:52 +00003255 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003256 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003257 break;
nethercote73b526f2004-10-31 18:48:21 +00003258 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003259 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
3260 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_format),
3261 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_format));
3262 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
3263 (Addr) &(((struct vki_cdrom_tocentry*) arg3)->cdte_track),
3264 sizeof(((struct vki_cdrom_tocentry*) arg3)->cdte_track));
3265 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003266 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003267 break;
nethercote73b526f2004-10-31 18:48:21 +00003268 case VKI_CDROMMULTISESSION: /* 0x5310 */
nethercoteef0c7662004-11-06 15:38:43 +00003269 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003270 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003271 break;
nethercote73b526f2004-10-31 18:48:21 +00003272 case VKI_CDROMVOLREAD: /* 0x5313 */
nethercoteef0c7662004-11-06 15:38:43 +00003273 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003274 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003275 break;
nethercote73b526f2004-10-31 18:48:21 +00003276 case VKI_CDROMREADAUDIO: /* 0x530e */
nethercoteef0c7662004-11-06 15:38:43 +00003277 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003278 sizeof (struct vki_cdrom_read_audio));
thughes5b788fb2004-09-11 15:07:14 +00003279 if ( arg3 ) {
3280 /* ToDo: don't do any of the following if the structure is invalid */
nethercote73b526f2004-10-31 18:48:21 +00003281 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003282 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3283 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003284 }
3285 break;
nethercote73b526f2004-10-31 18:48:21 +00003286 case VKI_CDROMPLAYMSF:
nethercote11e07d32004-11-06 16:17:52 +00003287 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", arg3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003288 break;
3289 /* The following two are probably bogus (should check args
3290 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003291 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3292 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003293 break;
thughes66d80092004-06-19 12:41:05 +00003294
nethercote73b526f2004-10-31 18:48:21 +00003295 case VKI_FIGETBSZ:
nethercote11e07d32004-11-06 16:17:52 +00003296 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003297 break;
nethercote73b526f2004-10-31 18:48:21 +00003298 case VKI_FIBMAP:
nethercote11e07d32004-11-06 16:17:52 +00003299 PRE_MEM_READ( "ioctl(FIBMAP)", arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003300 break;
3301
nethercote73b526f2004-10-31 18:48:21 +00003302 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
nethercoteef0c7662004-11-06 15:38:43 +00003303 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003304 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003305 break;
nethercote73b526f2004-10-31 18:48:21 +00003306 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
nethercoteef0c7662004-11-06 15:38:43 +00003307 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", arg3,
nethercote73b526f2004-10-31 18:48:21 +00003308 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003309 break;
jsgf855d93d2003-10-13 22:26:55 +00003310
nethercote73b526f2004-10-31 18:48:21 +00003311 case VKI_PPCLAIM:
3312 case VKI_PPEXCL:
3313 case VKI_PPYIELD:
3314 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003315 break;
nethercote73b526f2004-10-31 18:48:21 +00003316 case VKI_PPSETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003317 PRE_MEM_READ( "ioctl(PPSETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003318 break;
nethercote73b526f2004-10-31 18:48:21 +00003319 case VKI_PPGETMODE:
nethercote11e07d32004-11-06 16:17:52 +00003320 PRE_MEM_WRITE( "ioctl(PPGETMODE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003321 break;
nethercote73b526f2004-10-31 18:48:21 +00003322 case VKI_PPSETPHASE:
nethercote11e07d32004-11-06 16:17:52 +00003323 PRE_MEM_READ( "ioctl(PPSETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003324 break;
nethercote73b526f2004-10-31 18:48:21 +00003325 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003326 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003327 break;
nethercote73b526f2004-10-31 18:48:21 +00003328 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003329 PRE_MEM_WRITE( "ioctl(PPGETMODES)", arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003330 break;
nethercote73b526f2004-10-31 18:48:21 +00003331 case VKI_PPSETFLAGS:
nethercote11e07d32004-11-06 16:17:52 +00003332 PRE_MEM_READ( "ioctl(PPSETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003333 break;
nethercote73b526f2004-10-31 18:48:21 +00003334 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003335 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003336 break;
nethercote73b526f2004-10-31 18:48:21 +00003337 case VKI_PPRSTATUS:
nethercote11e07d32004-11-06 16:17:52 +00003338 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003339 break;
nethercote73b526f2004-10-31 18:48:21 +00003340 case VKI_PPRDATA:
nethercote11e07d32004-11-06 16:17:52 +00003341 PRE_MEM_WRITE( "ioctl(PPRDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003342 break;
nethercote73b526f2004-10-31 18:48:21 +00003343 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003344 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003345 break;
nethercote73b526f2004-10-31 18:48:21 +00003346 case VKI_PPWDATA:
nethercote11e07d32004-11-06 16:17:52 +00003347 PRE_MEM_READ( "ioctl(PPWDATA)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003348 break;
nethercote73b526f2004-10-31 18:48:21 +00003349 case VKI_PPWCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003350 PRE_MEM_READ( "ioctl(PPWCONTROL)", arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003351 break;
nethercote73b526f2004-10-31 18:48:21 +00003352 case VKI_PPFCONTROL:
nethercote11e07d32004-11-06 16:17:52 +00003353 PRE_MEM_READ( "ioctl(PPFCONTROL)", arg3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003354 break;
nethercote73b526f2004-10-31 18:48:21 +00003355 case VKI_PPDATADIR:
nethercote11e07d32004-11-06 16:17:52 +00003356 PRE_MEM_READ( "ioctl(PPDATADIR)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003357 break;
nethercote73b526f2004-10-31 18:48:21 +00003358 case VKI_PPNEGOT:
nethercote11e07d32004-11-06 16:17:52 +00003359 PRE_MEM_READ( "ioctl(PPNEGOT)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003360 break;
nethercote73b526f2004-10-31 18:48:21 +00003361 case VKI_PPWCTLONIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003362 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003363 break;
nethercote73b526f2004-10-31 18:48:21 +00003364 case VKI_PPCLRIRQ:
nethercote11e07d32004-11-06 16:17:52 +00003365 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003366 break;
nethercote73b526f2004-10-31 18:48:21 +00003367 case VKI_PPSETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003368 PRE_MEM_READ( "ioctl(PPSETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003369 break;
nethercote73b526f2004-10-31 18:48:21 +00003370 case VKI_PPGETTIME:
nethercote11e07d32004-11-06 16:17:52 +00003371 PRE_MEM_WRITE( "ioctl(PPGETTIME)", arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003372 break;
3373
thughesb3d3bcf2004-11-13 00:36:15 +00003374 case VKI_GIO_FONT:
3375 PRE_MEM_WRITE( "ioctl(GIO_FONT)", arg3, 32 * 256 );
3376 break;
3377 case VKI_PIO_FONT:
3378 PRE_MEM_READ( "ioctl(PIO_FONT)", arg3, 32 * 256 );
3379 break;
3380
3381 case VKI_GIO_FONTX:
3382 PRE_MEM_READ( "ioctl(GIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3383 if ( arg3 ) {
3384 /* ToDo: don't do any of the following if the structure is invalid */
3385 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3386 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3387 32 * cfd->charcount );
3388 }
3389 break;
3390 case VKI_PIO_FONTX:
3391 PRE_MEM_READ( "ioctl(PIO_FONTX)", arg3, sizeof(struct vki_consolefontdesc) );
3392 if ( arg3 ) {
3393 /* ToDo: don't do any of the following if the structure is invalid */
3394 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)arg3;
3395 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3396 32 * cfd->charcount );
3397 }
3398 break;
3399
3400 case VKI_PIO_FONTRESET:
3401 break;
3402
3403 case VKI_GIO_CMAP:
3404 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", arg3, 16 * 3 );
3405 break;
3406 case VKI_PIO_CMAP:
3407 PRE_MEM_READ( "ioctl(PIO_CMAP)", arg3, 16 * 3 );
3408 break;
3409
3410 case VKI_KIOCSOUND:
3411 case VKI_KDMKTONE:
3412 break;
3413
3414 case VKI_KDGETLED:
3415 PRE_MEM_WRITE( "ioctl(KDGETLED)", arg3, sizeof(char) );
3416 break;
3417 case VKI_KDSETLED:
3418 break;
3419
3420 case VKI_KDGKBTYPE:
3421 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", arg3, sizeof(char) );
3422 break;
3423
3424 case VKI_KDADDIO:
3425 case VKI_KDDELIO:
3426 case VKI_KDENABIO:
3427 case VKI_KDDISABIO:
3428 break;
3429
3430 case VKI_KDSETMODE:
3431 break;
3432 case VKI_KDGETMODE:
3433 PRE_MEM_WRITE( "ioctl(KDGETMODE)", arg3, sizeof(int) );
3434 break;
3435
3436 case VKI_KDMAPDISP:
3437 case VKI_KDUNMAPDISP:
3438 break;
3439
3440 case VKI_GIO_SCRNMAP:
3441 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3442 break;
3443 case VKI_PIO_SCRNMAP:
3444 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", arg3, VKI_E_TABSZ );
3445 break;
3446 case VKI_GIO_UNISCRNMAP:
3447 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", arg3,
3448 VKI_E_TABSZ * sizeof(unsigned short) );
3449 break;
3450 case VKI_PIO_UNISCRNMAP:
3451 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", arg3,
3452 VKI_E_TABSZ * sizeof(unsigned short) );
3453 break;
3454
3455 case VKI_KDGKBMODE:
3456 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", arg3, sizeof(int) );
3457 break;
3458 case VKI_KDSKBMODE:
3459 break;
3460
3461 case VKI_KDGKBMETA:
3462 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", arg3, sizeof(int) );
3463 break;
3464 case VKI_KDSKBMETA:
3465 break;
3466
3467 case VKI_KDGKBLED:
3468 PRE_MEM_WRITE( "ioctl(KDGKBLED)", arg3, sizeof(char) );
3469 break;
3470 case VKI_KDSKBLED:
3471 break;
3472
3473 case VKI_KDGKBENT:
3474 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
3475 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3476 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3477 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
3478 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3479 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3480 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
3481 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3482 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3483 break;
3484 case VKI_KDSKBENT:
3485 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
3486 (Addr)&((struct vki_kbentry *)arg3)->kb_table,
3487 sizeof(((struct vki_kbentry *)arg3)->kb_table) );
3488 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
3489 (Addr)&((struct vki_kbentry *)arg3)->kb_index,
3490 sizeof(((struct vki_kbentry *)arg3)->kb_index) );
3491 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
3492 (Addr)&((struct vki_kbentry *)arg3)->kb_value,
3493 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
3494 break;
3495
3496 case VKI_KDGKBSENT:
3497 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
3498 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3499 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3500 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
3501 (Addr)((struct vki_kbsentry *)arg3)->kb_string,
3502 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
3503 break;
3504 case VKI_KDSKBSENT:
3505 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
3506 (Addr)&((struct vki_kbsentry *)arg3)->kb_func,
3507 sizeof(((struct vki_kbsentry *)arg3)->kb_func) );
3508 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
3509 (Addr)((struct vki_kbsentry *)arg3)->kb_string );
3510 break;
3511
3512 case VKI_KDGKBDIACR:
3513 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3514 break;
3515 case VKI_KDSKBDIACR:
3516 PRE_MEM_READ( "ioctl(KDSKBDIACR)", arg3, sizeof(struct vki_kbdiacrs) );
3517 break;
3518
3519 case VKI_KDGETKEYCODE:
3520 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
3521 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3522 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3523 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
3524 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3525 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3526 break;
3527 case VKI_KDSETKEYCODE:
3528 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
3529 (Addr)&((struct vki_kbkeycode *)arg3)->scancode,
3530 sizeof(((struct vki_kbkeycode *)arg3)->scancode) );
3531 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
3532 (Addr)((struct vki_kbkeycode *)arg3)->keycode,
3533 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
3534 break;
3535
3536 case VKI_KDSIGACCEPT:
3537 break;
3538
3539 case VKI_KDKBDREP:
3540 PRE_MEM_READ( "ioctl(KBKBDREP)", arg3, sizeof(struct vki_kbd_repeat) );
3541 break;
3542
jsgf855d93d2003-10-13 22:26:55 +00003543 /* We don't have any specific information on it, so
3544 try to do something reasonable based on direction and
3545 size bits. The encoding scheme is described in
3546 /usr/include/asm/ioctl.h.
3547
3548 According to Simon Hausmann, _IOC_READ means the kernel
3549 writes a value to the ioctl value passed from the user
3550 space and the other way around with _IOC_WRITE. */
3551 default: {
nethercote73b526f2004-10-31 18:48:21 +00003552 UInt dir = _VKI_IOC_DIR(arg2);
3553 UInt size = _VKI_IOC_SIZE(arg2);
jsgf855d93d2003-10-13 22:26:55 +00003554 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3555 /*
3556 * Be very lax about ioctl handling; the only
3557 * assumption is that the size is correct. Doesn't
3558 * require the full buffer to be initialized when
3559 * writing. Without this, using some device
3560 * drivers with a large number of strange ioctl
3561 * commands becomes very tiresome.
3562 */
nethercote73b526f2004-10-31 18:48:21 +00003563 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003564 static Int moans = 3;
3565 if (moans > 0) {
3566 moans--;
3567 VG_(message)(Vg_UserMsg,
3568 "Warning: noted but unhandled ioctl 0x%x"
3569 " with no size/direction hints",
3570 arg2);
3571 VG_(message)(Vg_UserMsg,
3572 " This could cause spurious value errors"
3573 " to appear.");
3574 VG_(message)(Vg_UserMsg,
3575 " See README_MISSING_SYSCALL_OR_IOCTL for "
3576 "guidance on writing a proper wrapper." );
3577 }
3578 } else {
nethercote73b526f2004-10-31 18:48:21 +00003579 if ((dir & _VKI_IOC_WRITE) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003580 PRE_MEM_READ( "ioctl(generic)", arg3, size);
nethercote73b526f2004-10-31 18:48:21 +00003581 if ((dir & _VKI_IOC_READ) && size > 0)
nethercoteef0c7662004-11-06 15:38:43 +00003582 PRE_MEM_WRITE( "ioctl(generic)", arg3, size);
jsgf855d93d2003-10-13 22:26:55 +00003583 }
3584 break;
3585 }
3586 }
3587}
3588
nethercote85a456f2004-11-16 17:31:56 +00003589POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003590{
jsgf855d93d2003-10-13 22:26:55 +00003591 switch (arg2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003592 case VKI_TCSETS:
3593 case VKI_TCSETSW:
3594 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003595 break;
nethercote73b526f2004-10-31 18:48:21 +00003596 case VKI_TCGETS:
nethercoteef0c7662004-11-06 15:38:43 +00003597 POST_MEM_WRITE( arg3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003598 break;
nethercote73b526f2004-10-31 18:48:21 +00003599 case VKI_TCSETA:
3600 case VKI_TCSETAW:
3601 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003602 break;
nethercote73b526f2004-10-31 18:48:21 +00003603 case VKI_TCGETA:
nethercoteef0c7662004-11-06 15:38:43 +00003604 POST_MEM_WRITE( arg3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003605 break;
nethercote73b526f2004-10-31 18:48:21 +00003606 case VKI_TCSBRK:
3607 case VKI_TCXONC:
3608 case VKI_TCSBRKP:
3609 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003610 break;
nethercote73b526f2004-10-31 18:48:21 +00003611 case VKI_TIOCGWINSZ:
nethercoteef0c7662004-11-06 15:38:43 +00003612 POST_MEM_WRITE( arg3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003613 break;
nethercote73b526f2004-10-31 18:48:21 +00003614 case VKI_TIOCSWINSZ:
3615 case VKI_TIOCMBIS:
3616 case VKI_TIOCMBIC:
3617 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003618 break;
nethercote73b526f2004-10-31 18:48:21 +00003619 case VKI_TIOCLINUX:
nethercoteef0c7662004-11-06 15:38:43 +00003620 POST_MEM_WRITE( arg3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003621 break;
nethercote73b526f2004-10-31 18:48:21 +00003622 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003623 /* Get process group ID for foreground processing group. */
nethercoteef0c7662004-11-06 15:38:43 +00003624 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003625 break;
nethercote73b526f2004-10-31 18:48:21 +00003626 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003627 /* Set a process group ID? */
nethercoteef0c7662004-11-06 15:38:43 +00003628 POST_MEM_WRITE( arg3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003629 break;
nethercote73b526f2004-10-31 18:48:21 +00003630 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
nethercoteef0c7662004-11-06 15:38:43 +00003631 POST_MEM_WRITE( arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003632 break;
nethercote73b526f2004-10-31 18:48:21 +00003633 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003634 break;
nethercote73b526f2004-10-31 18:48:21 +00003635 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003636 break;
nethercote73b526f2004-10-31 18:48:21 +00003637 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003638 break;
nethercote73b526f2004-10-31 18:48:21 +00003639 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003640 break;
nethercote73b526f2004-10-31 18:48:21 +00003641 case VKI_FIONREAD: /* identical to SIOCINQ */
nethercoteef0c7662004-11-06 15:38:43 +00003642 POST_MEM_WRITE( arg3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003643 break;
3644
nethercote73b526f2004-10-31 18:48:21 +00003645 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003646 break;
nethercote73b526f2004-10-31 18:48:21 +00003647 case VKI_SG_IO:
3648 VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003649 break;
nethercote73b526f2004-10-31 18:48:21 +00003650 case VKI_SG_GET_SCSI_ID:
3651 VG_TRACK( post_mem_write,arg3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003652 break;
nethercote73b526f2004-10-31 18:48:21 +00003653 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003654 break;
nethercote73b526f2004-10-31 18:48:21 +00003655 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003656 break;
nethercote73b526f2004-10-31 18:48:21 +00003657 case VKI_SG_GET_RESERVED_SIZE:
thughes64326692004-09-11 15:14:59 +00003658 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003659 break;
nethercote73b526f2004-10-31 18:48:21 +00003660 case VKI_SG_GET_TIMEOUT:
thughes64326692004-09-11 15:14:59 +00003661 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003662 break;
nethercote73b526f2004-10-31 18:48:21 +00003663 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003664 break;
nethercote73b526f2004-10-31 18:48:21 +00003665 case VKI_SG_EMULATED_HOST:
thughes5b788fb2004-09-11 15:07:14 +00003666 VG_TRACK( post_mem_write,arg3, sizeof(int));
3667 break;
nethercote73b526f2004-10-31 18:48:21 +00003668 case VKI_SG_GET_SG_TABLESIZE:
thughes5b788fb2004-09-11 15:07:14 +00003669 VG_TRACK( post_mem_write,arg3, sizeof(int));
3670 break;
jsgf855d93d2003-10-13 22:26:55 +00003671
muellera4b153a2003-11-19 22:07:14 +00003672 case VKI_IIOCGETCPS:
nethercote95a97862004-11-06 16:31:43 +00003673 POST_MEM_WRITE( arg3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003674 break;
muellera4b153a2003-11-19 22:07:14 +00003675 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003676 POST_MEM_WRITE( arg3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003677 break;
3678
3679 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003680 case VKI_SIOCGIFINDEX: /* get iface index */
thughes64326692004-09-11 15:14:59 +00003681 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003682 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_ifindex,
3683 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003684 break;
nethercote73b526f2004-10-31 18:48:21 +00003685 case VKI_SIOCGIFFLAGS: /* get flags */
thughes64326692004-09-11 15:14:59 +00003686 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003687 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_flags,
3688 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003689 break;
nethercote73b526f2004-10-31 18:48:21 +00003690 case VKI_SIOCGIFHWADDR: /* Get hardware address */
thughes64326692004-09-11 15:14:59 +00003691 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003692 (Addr)&((struct vki_ifreq *)arg3)->ifr_hwaddr,
3693 sizeof(((struct vki_ifreq *)arg3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003694 break;
nethercote73b526f2004-10-31 18:48:21 +00003695 case VKI_SIOCGIFMTU: /* get MTU size */
thughes64326692004-09-11 15:14:59 +00003696 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003697 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_mtu,
3698 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003699 break;
nethercote73b526f2004-10-31 18:48:21 +00003700 case VKI_SIOCGIFADDR: /* get PA address */
3701 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3702 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3703 case VKI_SIOCGIFNETMASK: /* get network PA mask */
thughes64326692004-09-11 15:14:59 +00003704 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003705 (Addr)&((struct vki_ifreq *)arg3)->ifr_addr,
3706 sizeof(((struct vki_ifreq *)arg3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003707 break;
nethercote73b526f2004-10-31 18:48:21 +00003708 case VKI_SIOCGIFMETRIC: /* get metric */
thughes64326692004-09-11 15:14:59 +00003709 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003710 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_metric,
3711 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003712 break;
nethercote73b526f2004-10-31 18:48:21 +00003713 case VKI_SIOCGIFMAP: /* Get device parameters */
thughes64326692004-09-11 15:14:59 +00003714 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003715 (Addr)&((struct vki_ifreq *)arg3)->ifr_map,
3716 sizeof(((struct vki_ifreq *)arg3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003717 break;
3718 break;
nethercote73b526f2004-10-31 18:48:21 +00003719 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
thughes64326692004-09-11 15:14:59 +00003720 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003721 (Addr)&((struct vki_ifreq *)arg3)->ifr_qlen,
3722 sizeof(((struct vki_ifreq *)arg3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003723 break;
nethercote73b526f2004-10-31 18:48:21 +00003724 case VKI_SIOCGIFNAME: /* get iface name */
thughes64326692004-09-11 15:14:59 +00003725 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003726 (Addr)&((struct vki_ifreq *)arg3)->vki_ifr_name,
3727 sizeof(((struct vki_ifreq *)arg3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003728 break;
nethercote73b526f2004-10-31 18:48:21 +00003729 case VKI_SIOCGMIIPHY: /* get hardware entry */
thughes64326692004-09-11 15:14:59 +00003730 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003731 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id,
3732 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003733 break;
nethercote73b526f2004-10-31 18:48:21 +00003734 case VKI_SIOCGMIIREG: /* get hardware entry registers */
thughes64326692004-09-11 15:14:59 +00003735 VG_TRACK( post_mem_write,
nethercote73b526f2004-10-31 18:48:21 +00003736 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out,
3737 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)arg3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003738 break;
nethercote73b526f2004-10-31 18:48:21 +00003739 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003740 /* WAS:
nethercoteef0c7662004-11-06 15:38:43 +00003741 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", arg3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003742 KERNEL_DO_SYSCALL(tid,res);
3743 if (!VG_(is_kerror)(res) && res == 0)
3744 VG_TRACK( post_mem_write,arg3, sizeof(struct ifconf));
3745 */
3746 if (res == 0 && arg3 ) {
nethercote73b526f2004-10-31 18:48:21 +00003747 struct vki_ifconf *ifc = (struct vki_ifconf *) arg3;
3748 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003749 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003750 }
3751 break;
nethercote73b526f2004-10-31 18:48:21 +00003752 case VKI_SIOCGSTAMP:
3753 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003754 break;
3755 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3756 the number of bytes currently in that socket's send buffer.
3757 It writes this value as an int to the memory location
3758 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003759 case VKI_SIOCOUTQ:
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_SIOCGRARP: /* get RARP table entry */
3763 case VKI_SIOCGARP: /* get ARP table entry */
3764 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003765 break;
3766
nethercote73b526f2004-10-31 18:48:21 +00003767 case VKI_SIOCSIFFLAGS: /* set flags */
3768 case VKI_SIOCSIFMAP: /* Set device parameters */
3769 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
3770 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3771 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3772 case VKI_SIOCSIFNETMASK: /* set network PA mask */
3773 case VKI_SIOCSIFMETRIC: /* set metric */
3774 case VKI_SIOCSIFADDR: /* set PA address */
3775 case VKI_SIOCSIFMTU: /* set MTU size */
3776 case VKI_SIOCSIFHWADDR: /* set hardware address */
3777 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00003778 break;
3779 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003780 case VKI_SIOCADDRT: /* add routing table entry */
3781 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00003782 break;
3783
3784 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003785 case VKI_SIOCDRARP: /* delete RARP table entry */
3786 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003787 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003788 case VKI_SIOCSARP: /* set ARP table entry */
3789 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003790 break;
3791
nethercote73b526f2004-10-31 18:48:21 +00003792 case VKI_SIOCGPGRP:
thughes1174fed2004-09-11 15:33:17 +00003793 VG_TRACK( post_mem_write,arg3, sizeof(int));
3794 break;
nethercote73b526f2004-10-31 18:48:21 +00003795 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003796 break;
3797
3798 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003799 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3800 case VKI_SNDCTL_SEQ_GETINCOUNT:
3801 case VKI_SNDCTL_SEQ_PERCMODE:
3802 case VKI_SNDCTL_SEQ_TESTMIDI:
3803 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3804 case VKI_SNDCTL_SEQ_NRSYNTHS:
3805 case VKI_SNDCTL_SEQ_NRMIDIS:
3806 case VKI_SNDCTL_SEQ_GETTIME:
3807 case VKI_SNDCTL_DSP_GETFMTS:
3808 case VKI_SNDCTL_DSP_GETTRIGGER:
3809 case VKI_SNDCTL_DSP_GETODELAY:
3810 case VKI_SNDCTL_DSP_GETSPDIF:
3811 case VKI_SNDCTL_DSP_GETCAPS:
3812 case VKI_SOUND_PCM_READ_RATE:
3813 case VKI_SOUND_PCM_READ_CHANNELS:
3814 case VKI_SOUND_PCM_READ_BITS:
3815 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3816 case VKI_SOUND_PCM_READ_FILTER:
thughes64326692004-09-11 15:14:59 +00003817 VG_TRACK( post_mem_write,arg3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003818 break;
nethercote73b526f2004-10-31 18:48:21 +00003819 case VKI_SNDCTL_SEQ_CTRLRATE:
3820 case VKI_SNDCTL_DSP_SPEED:
3821 case VKI_SNDCTL_DSP_STEREO:
3822 case VKI_SNDCTL_DSP_GETBLKSIZE:
3823 case VKI_SNDCTL_DSP_CHANNELS:
3824 case VKI_SOUND_PCM_WRITE_FILTER:
3825 case VKI_SNDCTL_DSP_SUBDIVIDE:
3826 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003827 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003828 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003829 case VKI_SNDCTL_TMR_TIMEBASE:
3830 case VKI_SNDCTL_TMR_TEMPO:
3831 case VKI_SNDCTL_TMR_SOURCE:
3832 case VKI_SNDCTL_MIDI_PRETIME:
3833 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00003834 break;
nethercote73b526f2004-10-31 18:48:21 +00003835 case VKI_SNDCTL_DSP_GETOSPACE:
3836 case VKI_SNDCTL_DSP_GETISPACE:
3837 VG_TRACK( post_mem_write,arg3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003838 break;
nethercote73b526f2004-10-31 18:48:21 +00003839 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00003840 break;
3841
nethercote73b526f2004-10-31 18:48:21 +00003842 case VKI_SNDCTL_DSP_POST:
3843 case VKI_SNDCTL_DSP_RESET:
3844 case VKI_SNDCTL_DSP_SYNC:
3845 case VKI_SNDCTL_DSP_SETSYNCRO:
3846 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003847 break;
3848
3849 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003850 case VKI_RTC_UIE_ON:
3851 case VKI_RTC_UIE_OFF:
3852 case VKI_RTC_AIE_ON:
3853 case VKI_RTC_AIE_OFF:
3854 case VKI_RTC_PIE_ON:
3855 case VKI_RTC_PIE_OFF:
3856 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003857 break;
nethercote73b526f2004-10-31 18:48:21 +00003858 case VKI_RTC_RD_TIME:
3859 case VKI_RTC_ALM_READ:
3860 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003861 break;
nethercote73b526f2004-10-31 18:48:21 +00003862 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00003863 break;
nethercote73b526f2004-10-31 18:48:21 +00003864 case VKI_RTC_IRQP_READ:
thughes64326692004-09-11 15:14:59 +00003865 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003866 break;
jsgf855d93d2003-10-13 22:26:55 +00003867
nethercote95a97862004-11-06 16:31:43 +00003868 case VKI_BLKGETSIZE:
thughes64326692004-09-11 15:14:59 +00003869 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003870 break;
jsgf855d93d2003-10-13 22:26:55 +00003871
thughesacbbc322004-06-19 12:12:01 +00003872 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003873 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
3874 VG_TRACK( post_mem_write,arg3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003875 break;
3876
jsgf855d93d2003-10-13 22:26:55 +00003877 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003878 case VKI_CDROMSUBCHNL:
3879 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003880 break;
nethercote73b526f2004-10-31 18:48:21 +00003881 case VKI_CDROMREADTOCHDR:
3882 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003883 break;
nethercote73b526f2004-10-31 18:48:21 +00003884 case VKI_CDROMREADTOCENTRY:
3885 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003886 break;
nethercote73b526f2004-10-31 18:48:21 +00003887 case VKI_CDROMMULTISESSION:
3888 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003889 break;
nethercote73b526f2004-10-31 18:48:21 +00003890 case VKI_CDROMVOLREAD:
3891 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003892 break;
nethercote73b526f2004-10-31 18:48:21 +00003893 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00003894 {
nethercote73b526f2004-10-31 18:48:21 +00003895 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) arg3;
nethercoteef0c7662004-11-06 15:38:43 +00003896 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003897 break;
3898 }
3899
nethercote73b526f2004-10-31 18:48:21 +00003900 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00003901 break;
3902 /* The following two are probably bogus (should check args
3903 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003904 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3905 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003906 break;
3907
nethercote73b526f2004-10-31 18:48:21 +00003908 case VKI_FIGETBSZ:
thughes64326692004-09-11 15:14:59 +00003909 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003910 break;
nethercote73b526f2004-10-31 18:48:21 +00003911 case VKI_FIBMAP:
thughes64326692004-09-11 15:14:59 +00003912 VG_TRACK( post_mem_write,arg3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003913 break;
3914
nethercote73b526f2004-10-31 18:48:21 +00003915 case VKI_FBIOGET_VSCREENINFO: //0x4600
3916 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003917 break;
nethercote73b526f2004-10-31 18:48:21 +00003918 case VKI_FBIOGET_FSCREENINFO: //0x4602
3919 VG_TRACK( post_mem_write,arg3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003920 break;
3921
nethercote73b526f2004-10-31 18:48:21 +00003922 case VKI_PPCLAIM:
3923 case VKI_PPEXCL:
3924 case VKI_PPYIELD:
3925 case VKI_PPRELEASE:
3926 case VKI_PPSETMODE:
3927 case VKI_PPSETPHASE:
3928 case VKI_PPSETFLAGS:
3929 case VKI_PPWDATA:
3930 case VKI_PPWCONTROL:
3931 case VKI_PPFCONTROL:
3932 case VKI_PPDATADIR:
3933 case VKI_PPNEGOT:
3934 case VKI_PPWCTLONIRQ:
3935 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00003936 break;
nethercote73b526f2004-10-31 18:48:21 +00003937 case VKI_PPGETMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003938 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003939 break;
nethercote73b526f2004-10-31 18:48:21 +00003940 case VKI_PPGETPHASE:
nethercoteef0c7662004-11-06 15:38:43 +00003941 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003942 break;
nethercote73b526f2004-10-31 18:48:21 +00003943 case VKI_PPGETMODES:
nethercoteef0c7662004-11-06 15:38:43 +00003944 POST_MEM_WRITE( arg3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003945 break;
nethercote73b526f2004-10-31 18:48:21 +00003946 case VKI_PPGETFLAGS:
nethercoteef0c7662004-11-06 15:38:43 +00003947 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003948 break;
nethercote73b526f2004-10-31 18:48:21 +00003949 case VKI_PPRSTATUS:
nethercoteef0c7662004-11-06 15:38:43 +00003950 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003951 break;
nethercote73b526f2004-10-31 18:48:21 +00003952 case VKI_PPRDATA:
nethercoteef0c7662004-11-06 15:38:43 +00003953 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003954 break;
nethercote73b526f2004-10-31 18:48:21 +00003955 case VKI_PPRCONTROL:
nethercoteef0c7662004-11-06 15:38:43 +00003956 POST_MEM_WRITE( arg3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003957 break;
nethercote73b526f2004-10-31 18:48:21 +00003958 case VKI_PPCLRIRQ:
nethercoteef0c7662004-11-06 15:38:43 +00003959 POST_MEM_WRITE( arg3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003960 break;
nethercote73b526f2004-10-31 18:48:21 +00003961 case VKI_PPGETTIME:
nethercoteef0c7662004-11-06 15:38:43 +00003962 POST_MEM_WRITE( arg3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003963 break;
3964
thughesc3b842d2004-11-13 10:38:04 +00003965 case VKI_GIO_FONT:
3966 POST_MEM_WRITE( arg3, 32 * 256 );
3967 break;
3968 case VKI_PIO_FONT:
3969 break;
3970
3971 case VKI_GIO_FONTX:
3972 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)arg3)->chardata,
3973 32 * ((struct vki_consolefontdesc *)arg3)->charcount );
3974 break;
3975 case VKI_PIO_FONTX:
3976 break;
3977
3978 case VKI_PIO_FONTRESET:
3979 break;
3980
3981 case VKI_GIO_CMAP:
3982 POST_MEM_WRITE( arg3, 16 * 3 );
3983 break;
3984 case VKI_PIO_CMAP:
3985 break;
3986
3987 case VKI_KIOCSOUND:
3988 case VKI_KDMKTONE:
3989 break;
3990
3991 case VKI_KDGETLED:
3992 POST_MEM_WRITE( arg3, sizeof(char) );
3993 break;
3994 case VKI_KDSETLED:
3995 break;
3996
3997 case VKI_KDGKBTYPE:
3998 POST_MEM_WRITE( arg3, sizeof(char) );
3999 break;
4000
4001 case VKI_KDADDIO:
4002 case VKI_KDDELIO:
4003 case VKI_KDENABIO:
4004 case VKI_KDDISABIO:
4005 break;
4006
4007 case VKI_KDSETMODE:
4008 break;
4009 case VKI_KDGETMODE:
4010 POST_MEM_WRITE( arg3, sizeof(int) );
4011 break;
4012
4013 case VKI_KDMAPDISP:
4014 case VKI_KDUNMAPDISP:
4015 break;
4016
4017 case VKI_GIO_SCRNMAP:
4018 POST_MEM_WRITE( arg3, VKI_E_TABSZ );
4019 break;
4020 case VKI_PIO_SCRNMAP:
4021 break;
4022 case VKI_GIO_UNISCRNMAP:
4023 POST_MEM_WRITE( arg3, VKI_E_TABSZ * sizeof(unsigned short) );
4024 break;
4025 case VKI_PIO_UNISCRNMAP:
4026 break;
4027
4028 case VKI_KDGKBMODE:
4029 POST_MEM_WRITE( arg3, sizeof(int) );
4030 break;
4031 case VKI_KDSKBMODE:
4032 break;
4033
4034 case VKI_KDGKBMETA:
4035 POST_MEM_WRITE( arg3, sizeof(int) );
4036 break;
4037 case VKI_KDSKBMETA:
4038 break;
4039
4040 case VKI_KDGKBLED:
4041 POST_MEM_WRITE( arg3, sizeof(char) );
4042 break;
4043 case VKI_KDSKBLED:
4044 break;
4045
4046 case VKI_KDGKBENT:
4047 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)arg3)->kb_value,
4048 sizeof(((struct vki_kbentry *)arg3)->kb_value) );
4049 break;
4050 case VKI_KDSKBENT:
4051 break;
4052
4053 case VKI_KDGKBSENT:
4054 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)arg3)->kb_string,
4055 sizeof(((struct vki_kbsentry *)arg3)->kb_string) );
4056 break;
4057 case VKI_KDSKBSENT:
4058 break;
4059
4060 case VKI_KDGKBDIACR:
4061 POST_MEM_WRITE( arg3, sizeof(struct vki_kbdiacrs) );
4062 break;
4063 case VKI_KDSKBDIACR:
4064 break;
4065
4066 case VKI_KDGETKEYCODE:
4067 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)arg3)->keycode,
4068 sizeof(((struct vki_kbkeycode *)arg3)->keycode) );
4069 break;
4070 case VKI_KDSETKEYCODE:
4071 break;
4072
4073 case VKI_KDSIGACCEPT:
4074 break;
4075
4076 case VKI_KDKBDREP:
4077 break;
4078
jsgf855d93d2003-10-13 22:26:55 +00004079 /* We don't have any specific information on it, so
4080 try to do something reasonable based on direction and
4081 size bits. The encoding scheme is described in
4082 /usr/include/asm/ioctl.h.
4083
4084 According to Simon Hausmann, _IOC_READ means the kernel
4085 writes a value to the ioctl value passed from the user
4086 space and the other way around with _IOC_WRITE. */
4087 default: {
nethercote73b526f2004-10-31 18:48:21 +00004088 UInt dir = _VKI_IOC_DIR(arg2);
4089 UInt size = _VKI_IOC_SIZE(arg2);
4090 if (size > 0 && (dir & _VKI_IOC_READ)
jsgf855d93d2003-10-13 22:26:55 +00004091 && res == 0
4092 && arg3 != (Addr)NULL)
4093 VG_TRACK( post_mem_write,arg3, size);
4094 break;
4095 }
4096 }
4097}
4098
nethercote85a456f2004-11-16 17:31:56 +00004099PRE(sys_kill, 0)
jsgf855d93d2003-10-13 22:26:55 +00004100{
4101 /* int kill(pid_t pid, int sig); */
nethercote9a3beb92004-11-12 17:07:26 +00004102 PRINT("sys_kill ( %d, %d )", arg1,arg2);
4103 PRE_REG_READ2(long, "kill", int, pid, int, sig);
jsgf855d93d2003-10-13 22:26:55 +00004104 if (arg2 == VKI_SIGVGINT || arg2 == VKI_SIGVGKILL)
nethercote35122912004-10-18 17:00:30 +00004105 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004106}
4107
nethercote85a456f2004-11-16 17:31:56 +00004108POST(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004109{
4110 /* If this was a self-kill then wait for a signal to be
4111 delivered to any thread before claiming the kill is done. */
nethercote9a3beb92004-11-12 17:07:26 +00004112 if (res >= 0 && // if it was successful and
4113 arg2 != 0 && // if a real signal and
4114 !VG_(is_sig_ign)(arg2) && // that isn't ignored and
4115 !VG_(sigismember)(&tst->eff_sig_mask, arg2) && // we're not blocking it
4116 (arg1 == VG_(getpid)() || // directed at us or
4117 arg1 == -1 || // directed at everyone or
4118 arg1 == 0 || // directed at whole group or
4119 -arg1 == VG_(getpgrp)())) { // directed at our group...
jsgf855d93d2003-10-13 22:26:55 +00004120 /* ...then wait for that signal to be delivered to someone
nethercote9a3beb92004-11-12 17:07:26 +00004121 (might be us, might be someone else who doesn't have it blocked) */
jsgf855d93d2003-10-13 22:26:55 +00004122 VG_(proxy_waitsig)();
4123 }
4124}
4125
nethercote85a456f2004-11-16 17:31:56 +00004126PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004127{
nethercotec6851dd2004-11-11 18:00:47 +00004128 PRINT("sys_link ( %p, %p)", arg1, arg2);
4129 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004130 PRE_MEM_RASCIIZ( "link(oldpath)", arg1);
4131 PRE_MEM_RASCIIZ( "link(newpath)", arg2);
jsgf855d93d2003-10-13 22:26:55 +00004132}
4133
nethercote85a456f2004-11-16 17:31:56 +00004134PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00004135{
nethercotec6851dd2004-11-11 18:00:47 +00004136 PRINT("sys_lseek ( %d, %d, %d )", arg1,arg2,arg3);
4137 PRE_REG_READ3(vki_off_t, "lseek",
4138 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004139}
4140
nethercote85a456f2004-11-16 17:31:56 +00004141PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004142{
nethercote2e1c37d2004-11-13 13:57:12 +00004143 PRINT("sys_newlstat ( %p(%s), %p )", arg1,arg1,arg2);
4144 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004145 PRE_MEM_RASCIIZ( "lstat(file_name)", arg1 );
4146 PRE_MEM_WRITE( "lstat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004147}
4148
nethercote85a456f2004-11-16 17:31:56 +00004149POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00004150{
4151 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004152 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004153 }
4154}
4155
nethercote85a456f2004-11-16 17:31:56 +00004156PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004157{
nethercoteac866b92004-11-15 20:23:15 +00004158 PRINT("sys_lstat64 ( %p(%s), %p )",arg1,arg1,arg2);
nethercote2e1c37d2004-11-13 13:57:12 +00004159 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00004160 PRE_MEM_RASCIIZ( "lstat64(file_name)", arg1 );
4161 PRE_MEM_WRITE( "lstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004162}
4163
nethercote85a456f2004-11-16 17:31:56 +00004164POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004165{
4166 if (res == 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004167 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004168 }
4169}
4170
nethercote85a456f2004-11-16 17:31:56 +00004171PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004172{
nethercote9a3beb92004-11-12 17:07:26 +00004173 PRINT("sys_mkdir ( %p, %d )", arg1,arg2);
4174 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004175 PRE_MEM_RASCIIZ( "mkdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004176}
4177
nethercote85a456f2004-11-16 17:31:56 +00004178PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004179{
nethercote151effa2004-11-15 12:57:39 +00004180 /* struct mmap_arg_struct {
4181 unsigned long addr;
4182 unsigned long len;
4183 unsigned long prot;
4184 unsigned long flags;
4185 unsigned long fd;
4186 unsigned long offset;
4187 }; */
jsgf855d93d2003-10-13 22:26:55 +00004188 UInt a1, a2, a3, a4, a5, a6;
4189
nethercote151effa2004-11-15 12:57:39 +00004190 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
nethercote6456ab12004-10-18 14:47:48 +00004191 PLATFORM_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004192
nethercote151effa2004-11-15 12:57:39 +00004193 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4194 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004195
fitzhardinge98abfc72003-12-16 02:05:15 +00004196 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004197 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004198 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
4199 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004200 }
4201 } else {
nethercote6456ab12004-10-18 14:47:48 +00004202 a1 = VG_(find_map_space)(a1, a2, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00004203 if (a1 == 0)
nethercote151effa2004-11-15 12:57:39 +00004204 set_result( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004205 else
nethercote151effa2004-11-15 12:57:39 +00004206 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004207 }
jsgf855d93d2003-10-13 22:26:55 +00004208
fitzhardinge98abfc72003-12-16 02:05:15 +00004209 if (res != -VKI_ENOMEM) {
nethercote6456ab12004-10-18 14:47:48 +00004210 PLATFORM_DO_MMAP(res, a1, a2, a3, a4, a5, a6);
fitzhardingec2d65072004-01-07 08:44:43 +00004211
4212 if (!VG_(is_kerror)(res)) {
nethercote8ff888f2004-11-17 17:11:45 +00004213 vg_assert(VG_(valid_client_addr)(res, a2, tid, "old_mmap"));
nethercoteb4250ae2004-07-10 16:50:09 +00004214 mmap_segment( (Addr)res, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004215 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004216 }
jsgf855d93d2003-10-13 22:26:55 +00004217}
4218
nethercote3d5e9102004-11-17 18:22:38 +00004219PRE(sys_mmap2, 0)
4220{
4221 // Exactly like old_mmap() except:
4222 // - all 6 args are passed in regs, rather than in a memory-block.
4223 // - the file offset is specified in pagesize units rather than bytes,
4224 // so that it can be used for files bigger than 2^32 bytes.
4225 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
4226 arg1, (ULong)arg2, arg3, arg4, arg5, arg6 );
4227 PRE_REG_READ6(long, "mmap2",
4228 unsigned long, start, unsigned long, length,
4229 unsigned long, prot, unsigned long, flags,
4230 unsigned long, fd, unsigned long, offset);
4231
4232 if (arg4 & VKI_MAP_FIXED) {
4233 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mmap2"))
4234 set_result( -VKI_ENOMEM );
4235 } else {
4236 arg1 = VG_(find_map_space)(arg1, arg2, True);
4237 if (arg1 == 0)
4238 set_result( -VKI_ENOMEM );
4239 else
4240 arg4 |= VKI_MAP_FIXED;
4241 }
4242}
4243
4244POST(sys_mmap2)
4245{
4246 vg_assert(VG_(valid_client_addr)(res, arg2, tid, "mmap2"));
4247 mmap_segment( (Addr)res, arg2, arg3, arg4, arg5,
4248 arg6 * (ULong)VKI_PAGE_SIZE );
4249}
4250
nethercote85a456f2004-11-16 17:31:56 +00004251PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004252{
nethercote06c7bd72004-11-14 19:11:56 +00004253 PRINT("sys_mprotect ( %p, %llu, %d )", arg1,(ULong)arg2,arg3);
4254 PRE_REG_READ3(long, "mprotect",
4255 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004256
nethercote8ff888f2004-11-17 17:11:45 +00004257 if (!VG_(valid_client_addr)(arg1, arg2, tid, "mprotect"))
nethercote35122912004-10-18 17:00:30 +00004258 set_result( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004259}
4260
nethercote85a456f2004-11-16 17:31:56 +00004261POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004262{
nethercote27ea8bc2004-07-10 17:21:14 +00004263 Addr a = arg1;
nethercote928a5f72004-11-03 18:10:37 +00004264 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004265 Int prot = arg3;
4266 Bool rr = prot & VKI_PROT_READ;
4267 Bool ww = prot & VKI_PROT_WRITE;
4268 Bool xx = prot & VKI_PROT_EXEC;
4269
nethercote27ea8bc2004-07-10 17:21:14 +00004270 mash_addr_and_len(&a, &len);
4271 VG_(mprotect_range)(a, len, prot);
4272 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004273}
4274
nethercote85a456f2004-11-16 17:31:56 +00004275PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004276{
nethercote06c7bd72004-11-14 19:11:56 +00004277 PRINT("sys_munmap ( %p, %llu )", arg1,(ULong)arg2);
4278 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004279
nethercote8ff888f2004-11-17 17:11:45 +00004280 if (!VG_(valid_client_addr)(arg1, arg2, tid, "munmap"))
nethercote35122912004-10-18 17:00:30 +00004281 set_result( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004282}
4283
nethercote85a456f2004-11-16 17:31:56 +00004284POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004285{
nethercote928a5f72004-11-03 18:10:37 +00004286 Addr a = arg1;
4287 SizeT len = arg2;
nethercote27ea8bc2004-07-10 17:21:14 +00004288
4289 mash_addr_and_len(&a, &len);
4290 VG_(unmap_range)(a, len);
4291 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004292}
4293
nethercote85a456f2004-11-16 17:31:56 +00004294PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004295{
nethercoteac866b92004-11-15 20:23:15 +00004296 PRINT("sys_mincore ( %p, %llu, %p )", arg1,(ULong)arg2,arg3);
4297 PRE_REG_READ3(long, "mincore",
4298 unsigned long, start, vki_size_t, length,
4299 unsigned char *, vec);
nethercoteef0c7662004-11-06 15:38:43 +00004300 PRE_MEM_WRITE( "mincore(vec)", arg3, (arg2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004301}
4302
nethercote85a456f2004-11-16 17:31:56 +00004303POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004304{
nethercoteef0c7662004-11-06 15:38:43 +00004305 POST_MEM_WRITE( arg3, (arg2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004306}
4307
nethercote85a456f2004-11-16 17:31:56 +00004308PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004309{
nethercoteac866b92004-11-15 20:23:15 +00004310 PRINT("sys_nanosleep ( %p, %p )", arg1,arg2);
nethercote5b653bc2004-11-15 14:32:12 +00004311 PRE_REG_READ2(long, "nanosleep",
4312 struct timespec *, req, struct timespec *, rem);
nethercoteef0c7662004-11-06 15:38:43 +00004313 PRE_MEM_READ( "nanosleep(req)", arg1, sizeof(struct vki_timespec) );
nethercote163c5e82004-11-17 18:42:20 +00004314 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00004315 PRE_MEM_WRITE( "nanosleep(rem)", arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004316}
4317
nethercote85a456f2004-11-16 17:31:56 +00004318POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004319{
nethercote163c5e82004-11-17 18:42:20 +00004320 if (arg2 != 0 && res == -VKI_EINTR)
nethercoteef0c7662004-11-06 15:38:43 +00004321 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004322}
4323
nethercote85a456f2004-11-16 17:31:56 +00004324PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004325{
nethercotee70bd7d2004-08-18 14:37:17 +00004326 if (arg2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004327 // 3-arg version
4328 PRINT("sys_open ( %p(%s), %d, %d )",arg1,arg1,arg2,arg3);
4329 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004330 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004331 } else {
nethercotee824cc42004-11-09 16:20:46 +00004332 // 2-arg version
4333 PRINT("sys_open ( %p(%s), %d )",arg1,arg1,arg2);
4334 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004335 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004336 }
nethercotee824cc42004-11-09 16:20:46 +00004337 PRE_MEM_RASCIIZ( "open(filename)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004338}
4339
nethercote85a456f2004-11-16 17:31:56 +00004340POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004341{
nethercote3d5e9102004-11-17 18:22:38 +00004342 if (!VG_(fd_allowed)(res, "open", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004343 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004344 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004345 } else {
nethercote493dd182004-02-24 23:57:47 +00004346 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004347 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004348 }
jsgf855d93d2003-10-13 22:26:55 +00004349}
4350
nethercote85a456f2004-11-16 17:31:56 +00004351PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004352{
nethercote8b76fe52004-11-08 19:20:09 +00004353 PRINT("sys_read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4354 PRE_REG_READ3(ssize_t, "read",
nethercote0df495a2004-11-11 16:38:21 +00004355 unsigned int, fd, char *, buf, size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004356
nethercote3d5e9102004-11-17 18:22:38 +00004357 if (!VG_(fd_allowed)(arg1, "read", tid, False))
nethercote35122912004-10-18 17:00:30 +00004358 set_result( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004359 else
nethercoteef0c7662004-11-06 15:38:43 +00004360 PRE_MEM_WRITE( "read(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004361}
4362
nethercote85a456f2004-11-16 17:31:56 +00004363POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004364{
nethercoteef0c7662004-11-06 15:38:43 +00004365 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004366}
4367
nethercote85a456f2004-11-16 17:31:56 +00004368PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004369{
nethercote8b76fe52004-11-08 19:20:09 +00004370 PRINT("sys_write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
4371 PRE_REG_READ3(ssize_t, "write",
nethercote0df495a2004-11-11 16:38:21 +00004372 unsigned int, fd, const char *, buf, size_t, count);
nethercote3d5e9102004-11-17 18:22:38 +00004373 if (!VG_(fd_allowed)(arg1, "write", tid, False))
nethercote35122912004-10-18 17:00:30 +00004374 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004375 else
nethercoteef0c7662004-11-06 15:38:43 +00004376 PRE_MEM_READ( "write(buf)", arg2, arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004377}
4378
nethercote85a456f2004-11-16 17:31:56 +00004379PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004380{
nethercotec6851dd2004-11-11 18:00:47 +00004381 PRINT("sys_creat ( %p(%s), %d )", arg1,arg1,arg2);
4382 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
nethercoteef0c7662004-11-06 15:38:43 +00004383 PRE_MEM_RASCIIZ( "creat(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004384}
4385
nethercote85a456f2004-11-16 17:31:56 +00004386POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004387{
nethercote3d5e9102004-11-17 18:22:38 +00004388 if (!VG_(fd_allowed)(res, "creat", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004389 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004390 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004391 } else {
nethercote493dd182004-02-24 23:57:47 +00004392 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004393 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
jsgf855d93d2003-10-13 22:26:55 +00004394 }
jsgf855d93d2003-10-13 22:26:55 +00004395}
4396
nethercote9a3beb92004-11-12 17:07:26 +00004397// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004398PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004399{
nethercote9a3beb92004-11-12 17:07:26 +00004400 PRINT("sys_pipe ( %p )", arg1);
4401 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
4402 PRE_MEM_WRITE( "pipe(filedes)", arg1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004403}
4404
nethercote85a456f2004-11-16 17:31:56 +00004405POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004406{
nethercote9a3beb92004-11-12 17:07:26 +00004407 // XXX: use of Int here -- 32-bit-specific?
jsgf855d93d2003-10-13 22:26:55 +00004408 Int *p = (Int *)arg1;
4409
nethercote3d5e9102004-11-17 18:22:38 +00004410 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4411 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004412 VG_(close)(p[0]);
4413 VG_(close)(p[1]);
nethercote35122912004-10-18 17:00:30 +00004414 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004415 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004416 POST_MEM_WRITE( arg1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004417 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004418 VG_(record_fd_open)(tid, p[0], NULL);
4419 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004420 }
4421 }
jsgf855d93d2003-10-13 22:26:55 +00004422}
4423
nethercotef90953e2004-11-15 14:50:02 +00004424// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004425PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004426{
4427 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004428 int fd; -- file descriptor
4429 short events; -- requested events
4430 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004431 };
nethercoteeb0592d2004-11-05 12:02:27 +00004432 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004433 */
nethercoteeb0592d2004-11-05 12:02:27 +00004434 UInt i;
4435 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
nethercotef90953e2004-11-15 14:50:02 +00004436 PRINT("sys_poll ( %p, %d, %d )\n", arg1,arg2,arg3);
4437 PRE_REG_READ3(long, "poll",
4438 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004439
nethercoteeb0592d2004-11-05 12:02:27 +00004440 for (i = 0; i < arg2; i++) {
4441 // 'fd' and 'events' field are inputs; 'revents' is output.
4442 // XXX: this is x86 specific -- the pollfd struct varies across
4443 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004444 PRE_MEM_READ( "poll(ufds)",
4445 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4446 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4447 }
jsgf855d93d2003-10-13 22:26:55 +00004448}
4449
nethercote85a456f2004-11-16 17:31:56 +00004450POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004451{
4452 if (res > 0) {
4453 UInt i;
nethercoteeb0592d2004-11-05 12:02:27 +00004454 struct vki_pollfd* ufds = (struct vki_pollfd *)arg1;
4455 // XXX: again, this is x86-specific
jsgf855d93d2003-10-13 22:26:55 +00004456 for (i = 0; i < arg2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004457 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004458 }
4459}
4460
rjwalsh17d85302004-11-18 22:56:09 +00004461PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004462{
rjwalsh093047d2004-11-19 02:11:56 +00004463 int saved = SYSNO;
nethercote5a945af2004-11-14 18:37:07 +00004464 PRINT("sys_readlink ( %p, %p, %llu )", arg1,arg2,(ULong)arg3);
4465 PRE_REG_READ3(long, "readlink",
4466 const char *, path, char *, buf, int, bufsiz);
nethercoteef0c7662004-11-06 15:38:43 +00004467 PRE_MEM_RASCIIZ( "readlink(path)", arg1 );
4468 PRE_MEM_WRITE( "readlink(buf)", arg2,arg3 );
jsgf855d93d2003-10-13 22:26:55 +00004469
rjwalsh17d85302004-11-18 22:56:09 +00004470 /*
rjwalsh093047d2004-11-19 02:11:56 +00004471 * Handle the case where readlink is looking at /proc/self/exe or
4472 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004473 */
4474
rjwalsh093047d2004-11-19 02:11:56 +00004475 set_result( VG_(do_syscall)(saved, arg1, arg2, arg3));
4476 if ((Int)res == -2) {
4477 char name[25];
4478
4479 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004480
rjwalsh093047d2004-11-19 02:11:56 +00004481 if (VG_(strcmp)((Char *)arg1, name) == 0 ||
4482 VG_(strcmp)((Char *)arg1, "/proc/self/exe") == 0) {
4483 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
4484 set_result( VG_(do_syscall)(saved, name, arg2, arg3));
4485 }
rjwalsh17d85302004-11-18 22:56:09 +00004486 }
4487
rjwalsh093047d2004-11-19 02:11:56 +00004488 if ((Int)res > 0)
rjwalsh17d85302004-11-18 22:56:09 +00004489 POST_MEM_WRITE( arg2, res );
jsgf855d93d2003-10-13 22:26:55 +00004490}
4491
nethercote85a456f2004-11-16 17:31:56 +00004492PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004493{
jsgf855d93d2003-10-13 22:26:55 +00004494 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004495 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00004496 PRINT("sys_readv ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
4497 PRE_REG_READ3(ssize_t, "readv",
4498 unsigned long, fd, const struct iovec *, vector,
4499 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00004500 if (!VG_(fd_allowed)(arg1, "readv", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00004501 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004502 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004503 PRE_MEM_READ( "readv(vector)", arg2, arg3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004504
nethercote163c5e82004-11-17 18:42:20 +00004505 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004506 /* ToDo: don't do any of the following if the vector is invalid */
4507 vec = (struct vki_iovec *)arg2;
4508 for (i = 0; i < (Int)arg3; i++)
4509 PRE_MEM_WRITE( "readv(vector[...])",
4510 (Addr)vec[i].iov_base, vec[i].iov_len );
4511 }
jsgf855d93d2003-10-13 22:26:55 +00004512 }
4513}
4514
nethercote85a456f2004-11-16 17:31:56 +00004515POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004516{
4517 if (res > 0) {
4518 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004519 struct vki_iovec * vec = (struct vki_iovec *)arg2;
jsgf855d93d2003-10-13 22:26:55 +00004520 Int remains = res;
4521
4522 /* res holds the number of bytes read. */
4523 for (i = 0; i < (Int)arg3; i++) {
4524 Int nReadThisBuf = vec[i].iov_len;
4525 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004526 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004527 remains -= nReadThisBuf;
4528 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4529 }
4530 }
4531}
4532
nethercote85a456f2004-11-16 17:31:56 +00004533PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004534{
nethercote9a3beb92004-11-12 17:07:26 +00004535 PRINT("sys_rename ( %p, %p )", arg1, arg2 );
4536 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00004537 PRE_MEM_RASCIIZ( "rename(oldpath)", arg1 );
4538 PRE_MEM_RASCIIZ( "rename(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00004539}
4540
nethercote85a456f2004-11-16 17:31:56 +00004541PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004542{
nethercote9a3beb92004-11-12 17:07:26 +00004543 PRINT("sys_rmdir ( %p )", arg1);
4544 PRE_REG_READ1(long, "rmdir", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00004545 PRE_MEM_RASCIIZ( "rmdir(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00004546}
4547
nethercote85a456f2004-11-16 17:31:56 +00004548PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004549{
nethercoteef0c7662004-11-06 15:38:43 +00004550 PRINT("sched_setparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004551 PRE_REG_READ2(long, "sched_setparam",
4552 vki_pid_t, pid, struct sched_param *, p);
4553 PRE_MEM_READ( "sched_setparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004554}
4555
nethercote85a456f2004-11-16 17:31:56 +00004556POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004557{
nethercoteef0c7662004-11-06 15:38:43 +00004558 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004559}
4560
nethercote85a456f2004-11-16 17:31:56 +00004561PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004562{
nethercoteef0c7662004-11-06 15:38:43 +00004563 PRINT("sched_getparam ( %d, %p )", arg1, arg2 );
nethercote5b653bc2004-11-15 14:32:12 +00004564 PRE_REG_READ2(long, "sched_getparam",
4565 vki_pid_t, pid, struct sched_param *, p);
4566 PRE_MEM_WRITE( "sched_getparam(p)", arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004567}
4568
nethercote85a456f2004-11-16 17:31:56 +00004569POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004570{
nethercoteef0c7662004-11-06 15:38:43 +00004571 POST_MEM_WRITE( arg2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004572}
4573
nethercote85a456f2004-11-16 17:31:56 +00004574PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004575{
4576 PRINT("sys_select ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
4577 PRE_REG_READ5(long, "select",
4578 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4579 vki_fd_set *, exceptfds, struct timeval *, timeout);
4580 // XXX: this possibly understates how much memory is read.
4581 if (arg2 != 0)
4582 PRE_MEM_READ( "select(readfds)",
4583 arg2, arg1/8 /* __FD_SETSIZE/8 */ );
4584 if (arg3 != 0)
4585 PRE_MEM_READ( "select(writefds)",
4586 arg3, arg1/8 /* __FD_SETSIZE/8 */ );
4587 if (arg4 != 0)
4588 PRE_MEM_READ( "select(exceptfds)",
4589 arg4, arg1/8 /* __FD_SETSIZE/8 */ );
4590 if (arg5 != 0)
4591 PRE_MEM_READ( "select(timeout)", arg5, sizeof(struct vki_timeval) );
4592}
4593
nethercote85a456f2004-11-16 17:31:56 +00004594PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004595{
nethercote9c311eb2004-11-12 18:20:12 +00004596 PRINT("sys_setgid16 ( %d )", arg1);
4597 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4598}
4599
nethercote85a456f2004-11-16 17:31:56 +00004600PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004601{
4602 PRINT("sys_setgid ( %d )", arg1);
4603 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004604}
4605
nethercote85a456f2004-11-16 17:31:56 +00004606PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004607{
nethercote0df495a2004-11-11 16:38:21 +00004608 PRINT("sys_setsid ( )");
4609 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004610}
4611
nethercote85a456f2004-11-16 17:31:56 +00004612PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004613{
nethercote686b5db2004-11-14 13:42:51 +00004614 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)arg1, arg2);
4615 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
4616 if (arg1 > 0)
4617 PRE_MEM_READ( "setgroups16(list)", arg2, arg1 * sizeof(vki_old_gid_t) );
4618}
4619
nethercote85a456f2004-11-16 17:31:56 +00004620PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004621{
nethercoteef0c7662004-11-06 15:38:43 +00004622 PRINT("setgroups ( %llu, %p )", (ULong)arg1, arg2);
nethercote686b5db2004-11-14 13:42:51 +00004623 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
jsgf855d93d2003-10-13 22:26:55 +00004624 if (arg1 > 0)
nethercoteef0c7662004-11-06 15:38:43 +00004625 PRE_MEM_READ( "setgroups(list)", arg2, arg1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004626}
4627
nethercote85a456f2004-11-16 17:31:56 +00004628PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004629{
nethercoteef0c7662004-11-06 15:38:43 +00004630 PRINT("setpgid ( %d, %d )", arg1, arg2);
nethercote9c311eb2004-11-12 18:20:12 +00004631 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004632}
4633
nethercote85a456f2004-11-16 17:31:56 +00004634POST(sys_setpgid)
jsgf855d93d2003-10-13 22:26:55 +00004635{
4636 VG_(main_pgrp) = VG_(getpgrp)();
4637}
4638
nethercote85a456f2004-11-16 17:31:56 +00004639PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004640{
nethercote17258dc2004-11-12 19:55:08 +00004641 PRINT("sys_setregid ( %d, %d )", arg1, arg2);
4642 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004643}
4644
nethercote85a456f2004-11-16 17:31:56 +00004645PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004646{
nethercote17258dc2004-11-12 19:55:08 +00004647 PRINT("setreuid16 ( 0x%x, 0x%x )", arg1, arg2);
4648 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4649}
4650
nethercote85a456f2004-11-16 17:31:56 +00004651PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004652{
4653 PRINT("sys_setreuid ( 0x%x, 0x%x )", arg1, arg2);
4654 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004655}
4656
nethercote85a456f2004-11-16 17:31:56 +00004657PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004658{
nethercote17258dc2004-11-12 19:55:08 +00004659 PRINT("sys_setrlimit ( %d, %p )", arg1,arg2);
4660 PRE_REG_READ2(long, "setrlimit",
4661 unsigned int, resource, struct rlimit *, rlim);
nethercoteef0c7662004-11-06 15:38:43 +00004662 PRE_MEM_READ( "setrlimit(rlim)", arg2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004663
thughesad1c9562004-06-26 11:27:52 +00004664 if (arg1 == VKI_RLIMIT_NOFILE) {
nethercote73b526f2004-10-31 18:48:21 +00004665 if (((struct vki_rlimit *)arg2)->rlim_cur > VG_(fd_hard_limit) ||
4666 ((struct vki_rlimit *)arg2)->rlim_max != VG_(fd_hard_limit)) {
nethercote35122912004-10-18 17:00:30 +00004667 set_result( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004668 }
4669 else {
nethercote73b526f2004-10-31 18:48:21 +00004670 VG_(fd_soft_limit) = ((struct vki_rlimit *)arg2)->rlim_cur;
nethercote35122912004-10-18 17:00:30 +00004671 set_result( 0 );
thughesad1c9562004-06-26 11:27:52 +00004672 }
4673 }
4674 else if (arg1 == VKI_RLIMIT_DATA) {
nethercote73b526f2004-10-31 18:48:21 +00004675 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4676 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004677 set_result( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004678 }
4679 else {
nethercote73b526f2004-10-31 18:48:21 +00004680 VG_(client_rlimit_data) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004681 set_result( 0 );
thughesaa4fb112004-09-11 14:19:25 +00004682 }
fitzhardingeb50068f2004-02-24 23:42:55 +00004683 }
thughesc37184f2004-09-11 14:16:57 +00004684 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
nethercote73b526f2004-10-31 18:48:21 +00004685 if (((struct vki_rlimit *)arg2)->rlim_cur > ((struct vki_rlimit *)arg2)->rlim_max ||
4686 ((struct vki_rlimit *)arg2)->rlim_max > ((struct vki_rlimit *)arg2)->rlim_max) {
nethercote35122912004-10-18 17:00:30 +00004687 set_result( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00004688 }
4689 else {
nethercote73b526f2004-10-31 18:48:21 +00004690 VG_(threads)[tid].stack_size = ((struct vki_rlimit *)arg2)->rlim_cur;
4691 VG_(client_rlimit_stack) = *(struct vki_rlimit *)arg2;
nethercote35122912004-10-18 17:00:30 +00004692 set_result( 0 );
thughesc37184f2004-09-11 14:16:57 +00004693 }
4694 }
jsgf855d93d2003-10-13 22:26:55 +00004695}
4696
nethercote85a456f2004-11-16 17:31:56 +00004697PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004698{
nethercotec6851dd2004-11-11 18:00:47 +00004699 PRINT("sys_setuid16 ( %d )", arg1);
4700 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00004701}
4702
nethercote85a456f2004-11-16 17:31:56 +00004703PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00004704{
4705 PRINT("sys_setuid ( %d )", arg1);
4706 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4707}
jsgf855d93d2003-10-13 22:26:55 +00004708
nethercote85a456f2004-11-16 17:31:56 +00004709PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004710{
nethercotedc18c0a2004-11-14 20:06:27 +00004711 PRINT("sys_socketcall ( %d, %p )",arg1,arg2);
4712 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
4713
jsgf855d93d2003-10-13 22:26:55 +00004714 switch (arg1 /* request */) {
4715
nethercote73b526f2004-10-31 18:48:21 +00004716 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00004717 /* int socketpair(int d, int type, int protocol, int sv[2]); */
nethercoteef0c7662004-11-06 15:38:43 +00004718 PRE_MEM_READ( "socketcall.socketpair(args)", arg2, 4*sizeof(Addr) );
4719 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
nethercotef1d810d2004-11-04 19:57:03 +00004720 ((UWord*)arg2)[3], 2*sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004721 break;
4722
nethercote73b526f2004-10-31 18:48:21 +00004723 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00004724 /* int socket(int domain, int type, int protocol); */
nethercoteef0c7662004-11-06 15:38:43 +00004725 PRE_MEM_READ( "socketcall.socket(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004726 break;
4727
nethercote73b526f2004-10-31 18:48:21 +00004728 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004729 /* int bind(int sockfd, struct sockaddr *my_addr,
4730 int addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004731 PRE_MEM_READ( "socketcall.bind(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004732 pre_mem_read_sockaddr( tid, "socketcall.bind(my_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004733 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004734 break;
4735
nethercote73b526f2004-10-31 18:48:21 +00004736 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004737 /* int listen(int s, int backlog); */
nethercoteef0c7662004-11-06 15:38:43 +00004738 PRE_MEM_READ( "socketcall.listen(args)", arg2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004739 break;
4740
nethercote73b526f2004-10-31 18:48:21 +00004741 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004742 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004743 PRE_MEM_READ( "socketcall.accept(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004744 {
nethercotef1d810d2004-11-04 19:57:03 +00004745 Addr addr_p = ((UWord*)arg2)[1];
4746 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004747 if (addr_p != (Addr)NULL)
4748 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
4749 "socketcall.accept(addr)",
4750 "socketcall.accept(addrlen_in)" );
4751 }
4752 break;
4753 }
4754
nethercote73b526f2004-10-31 18:48:21 +00004755 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004756 /* int sendto(int s, const void *msg, int len,
4757 unsigned int flags,
4758 const struct sockaddr *to, int tolen); */
nethercoteef0c7662004-11-06 15:38:43 +00004759 PRE_MEM_READ( "socketcall.sendto(args)", arg2, 6*sizeof(Addr) );
4760 PRE_MEM_READ( "socketcall.sendto(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004761 ((UWord*)arg2)[1], /* msg */
4762 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004763 pre_mem_read_sockaddr( tid, "socketcall.sendto(to.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004764 (struct vki_sockaddr *) (((UWord*)arg2)[4]), ((UWord*)arg2)[5]);
jsgf855d93d2003-10-13 22:26:55 +00004765 break;
4766
nethercote73b526f2004-10-31 18:48:21 +00004767 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004768 /* int send(int s, const void *msg, size_t len, int flags); */
nethercoteef0c7662004-11-06 15:38:43 +00004769 PRE_MEM_READ( "socketcall.send(args)", arg2, 4*sizeof(Addr) );
4770 PRE_MEM_READ( "socketcall.send(msg)",
nethercotef1d810d2004-11-04 19:57:03 +00004771 ((UWord*)arg2)[1], /* msg */
4772 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004773 break;
4774
nethercote73b526f2004-10-31 18:48:21 +00004775 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004776 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
4777 struct sockaddr *from, int *fromlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004778 PRE_MEM_READ( "socketcall.recvfrom(args)", arg2, 6*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004779 {
nethercotef1d810d2004-11-04 19:57:03 +00004780 Addr buf_p = ((UWord*)arg2)[1];
4781 Int len = ((UWord*)arg2)[2];
4782 Addr from_p = ((UWord*)arg2)[4];
4783 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004784
nethercoteef0c7662004-11-06 15:38:43 +00004785 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004786 if (from_p != (Addr)NULL)
4787 buf_and_len_pre_check ( tid, from_p, fromlen_p,
4788 "socketcall.recvfrom(from)",
4789 "socketcall.recvfrom(fromlen_in)" );
4790 }
4791 break;
4792
nethercote73b526f2004-10-31 18:48:21 +00004793 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00004794 /* int recv(int s, void *buf, int len, unsigned int flags); */
4795 /* man 2 recv says:
4796 The recv call is normally used only on a connected socket
4797 (see connect(2)) and is identical to recvfrom with a NULL
4798 from parameter.
4799 */
nethercoteef0c7662004-11-06 15:38:43 +00004800 PRE_MEM_READ( "socketcall.recv(args)", arg2, 4*sizeof(Addr) );
4801 PRE_MEM_WRITE( "socketcall.recv(buf)",
nethercotef1d810d2004-11-04 19:57:03 +00004802 ((UWord*)arg2)[1], /* buf */
4803 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004804 break;
4805
nethercote73b526f2004-10-31 18:48:21 +00004806 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004807 /* int connect(int sockfd,
4808 struct sockaddr *serv_addr, int addrlen ); */
nethercoteef0c7662004-11-06 15:38:43 +00004809 PRE_MEM_READ( "socketcall.connect(args)", arg2, 3*sizeof(Addr) );
4810 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
nethercotef1d810d2004-11-04 19:57:03 +00004811 ((UWord*)arg2)[1], /* serv_addr */
nethercote73b526f2004-10-31 18:48:21 +00004812 sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +00004813 pre_mem_read_sockaddr( tid,
4814 "socketcall.connect(serv_addr.%s)",
nethercotef1d810d2004-11-04 19:57:03 +00004815 (struct vki_sockaddr *) (((UWord*)arg2)[1]), ((UWord*)arg2)[2]);
jsgf855d93d2003-10-13 22:26:55 +00004816 break;
4817
nethercote73b526f2004-10-31 18:48:21 +00004818 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004819 /* int setsockopt(int s, int level, int optname,
4820 const void *optval, int optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004821 PRE_MEM_READ( "socketcall.setsockopt(args)", arg2, 5*sizeof(Addr) );
4822 PRE_MEM_READ( "socketcall.setsockopt(optval)",
nethercotef1d810d2004-11-04 19:57:03 +00004823 ((UWord*)arg2)[3], /* optval */
4824 ((UWord*)arg2)[4] /* optlen */ );
jsgf855d93d2003-10-13 22:26:55 +00004825 break;
4826
nethercote73b526f2004-10-31 18:48:21 +00004827 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00004828 /* int setsockopt(int s, int level, int optname,
4829 void *optval, socklen_t *optlen); */
nethercoteef0c7662004-11-06 15:38:43 +00004830 PRE_MEM_READ( "socketcall.getsockopt(args)", arg2, 5*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004831 {
nethercotef1d810d2004-11-04 19:57:03 +00004832 Addr optval_p = ((UWord*)arg2)[3];
4833 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00004834 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
4835 if (optval_p != (Addr)NULL)
4836 buf_and_len_pre_check ( tid, optval_p, optlen_p,
4837 "socketcall.getsockopt(optval)",
4838 "socketcall.getsockopt(optlen)" );
4839 }
4840 break;
4841
nethercote73b526f2004-10-31 18:48:21 +00004842 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00004843 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004844 PRE_MEM_READ( "socketcall.getsockname(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004845 {
nethercotef1d810d2004-11-04 19:57:03 +00004846 Addr name_p = ((UWord*)arg2)[1];
4847 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004848
4849 /* Nb: name_p cannot be NULL */
4850 buf_and_len_pre_check ( tid, name_p, namelen_p,
4851 "socketcall.getsockname(name)",
4852 "socketcall.getsockname(namelen_in)" );
4853 }
4854 break;
4855
nethercote73b526f2004-10-31 18:48:21 +00004856 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00004857 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
nethercoteef0c7662004-11-06 15:38:43 +00004858 PRE_MEM_READ( "socketcall.getpeername(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004859 {
nethercotef1d810d2004-11-04 19:57:03 +00004860 Addr name_p = ((UWord*)arg2)[1];
4861 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004862
4863 /* Nb: name_p cannot be NULL */
4864 buf_and_len_pre_check ( tid, name_p, namelen_p,
4865 "socketcall.getpeername(name)",
4866 "socketcall.getpeername(namelen_in)" );
4867 }
4868 break;
4869
nethercote73b526f2004-10-31 18:48:21 +00004870 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00004871 /* int shutdown(int s, int how); */
nethercoteef0c7662004-11-06 15:38:43 +00004872 PRE_MEM_READ( "socketcall.shutdown(args)", arg2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004873 break;
4874
nethercote73b526f2004-10-31 18:48:21 +00004875 case VKI_SYS_SENDMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004876 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
4877
4878 /* this causes warnings, and I don't get why. glibc bug?
4879 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004880 PRE_MEM_READ( "socketcall.sendmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004881 */
4882
nethercote22208362004-11-04 20:00:44 +00004883 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004884 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
4885
4886 break;
4887 }
4888
nethercote73b526f2004-10-31 18:48:21 +00004889 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00004890 /* int recvmsg(int s, struct msghdr *msg, int flags); */
4891
4892 /* this causes warnings, and I don't get why. glibc bug?
4893 * (after all it's glibc providing the arguments array)
nethercoteef0c7662004-11-06 15:38:43 +00004894 PRE_MEM_READ("socketcall.recvmsg(args)", arg2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00004895 */
4896
nethercote22208362004-11-04 20:00:44 +00004897 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00004898 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
4899
4900 break;
4901 }
4902
4903 default:
jsgf17059e02003-10-19 16:46:06 +00004904 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",arg1);
nethercote35122912004-10-18 17:00:30 +00004905 set_result( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00004906 break;
jsgf855d93d2003-10-13 22:26:55 +00004907 }
4908}
4909
nethercote85a456f2004-11-16 17:31:56 +00004910POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00004911{
jsgf855d93d2003-10-13 22:26:55 +00004912 switch (arg1 /* request */) {
4913
nethercote73b526f2004-10-31 18:48:21 +00004914 case VKI_SYS_SOCKETPAIR: {
nethercotef1d810d2004-11-04 19:57:03 +00004915 Int fd1 = ((Int*)((UWord*)arg2)[3])[0];
4916 Int fd2 = ((Int*)((UWord*)arg2)[3])[1];
nethercoteef0c7662004-11-06 15:38:43 +00004917 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote3d5e9102004-11-17 18:22:38 +00004918 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
4919 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
nethercote493dd182004-02-24 23:57:47 +00004920 VG_(close)(fd1);
4921 VG_(close)(fd2);
nethercote35122912004-10-18 17:00:30 +00004922 set_result( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00004923 } else {
nethercoteef0c7662004-11-06 15:38:43 +00004924 POST_MEM_WRITE( ((UWord*)arg2)[3], 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004925 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004926 VG_(record_fd_open)(tid, fd1, NULL);
4927 VG_(record_fd_open)(tid, fd2, NULL);
nethercote493dd182004-02-24 23:57:47 +00004928 }
rjwalshf5f536f2003-11-17 17:45:00 +00004929 }
jsgf855d93d2003-10-13 22:26:55 +00004930 break;
nethercote493dd182004-02-24 23:57:47 +00004931 }
jsgf855d93d2003-10-13 22:26:55 +00004932
nethercote73b526f2004-10-31 18:48:21 +00004933 case VKI_SYS_SOCKET:
nethercote3d5e9102004-11-17 18:22:38 +00004934 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004935 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004936 set_result( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004937 } else {
nethercote493dd182004-02-24 23:57:47 +00004938 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004939 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004940 }
4941 break;
4942
nethercote73b526f2004-10-31 18:48:21 +00004943 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00004944 /* int bind(int sockfd, struct sockaddr *my_addr,
4945 int addrlen); */
4946 break;
4947
nethercote73b526f2004-10-31 18:48:21 +00004948 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00004949 /* int listen(int s, int backlog); */
4950 break;
4951
nethercote73b526f2004-10-31 18:48:21 +00004952 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00004953 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
nethercote3d5e9102004-11-17 18:22:38 +00004954 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004955 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00004956 set_result( -VKI_EMFILE );
jsgf855d93d2003-10-13 22:26:55 +00004957 } else {
nethercotef1d810d2004-11-04 19:57:03 +00004958 Addr addr_p = ((UWord*)arg2)[1];
4959 Addr addrlen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00004960
4961 if (addr_p != (Addr)NULL)
4962 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
4963 "socketcall.accept(addrlen_out)" );
nethercote493dd182004-02-24 23:57:47 +00004964 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00004965 VG_(record_fd_open)(tid, res, NULL);
jsgf855d93d2003-10-13 22:26:55 +00004966 }
4967 break;
4968 }
4969
nethercote73b526f2004-10-31 18:48:21 +00004970 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00004971 break;
4972
nethercote73b526f2004-10-31 18:48:21 +00004973 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00004974 break;
4975
nethercote73b526f2004-10-31 18:48:21 +00004976 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00004977 {
nethercotef1d810d2004-11-04 19:57:03 +00004978 Addr buf_p = ((UWord*)arg2)[1];
4979 Int len = ((UWord*)arg2)[2];
4980 Addr from_p = ((UWord*)arg2)[4];
4981 Addr fromlen_p = ((UWord*)arg2)[5];
jsgf855d93d2003-10-13 22:26:55 +00004982
4983 if (from_p != (Addr)NULL)
4984 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
4985 "socketcall.recvfrom(fromlen_out)" );
nethercoteef0c7662004-11-06 15:38:43 +00004986 POST_MEM_WRITE( buf_p, len );
jsgf855d93d2003-10-13 22:26:55 +00004987 }
4988 break;
4989
nethercote73b526f2004-10-31 18:48:21 +00004990 case VKI_SYS_RECV:
nethercote163c5e82004-11-17 18:42:20 +00004991 if (res >= 0 && ((UWord*)arg2)[1] != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00004992 POST_MEM_WRITE( ((UWord*)arg2)[1], /* buf */
4993 ((UWord*)arg2)[2] /* len */ );
jsgf855d93d2003-10-13 22:26:55 +00004994 }
4995 break;
4996
nethercote73b526f2004-10-31 18:48:21 +00004997 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00004998 break;
4999
nethercote73b526f2004-10-31 18:48:21 +00005000 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005001 break;
5002
nethercote73b526f2004-10-31 18:48:21 +00005003 case VKI_SYS_GETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005004 {
nethercotef1d810d2004-11-04 19:57:03 +00005005 Addr optval_p = ((UWord*)arg2)[3];
5006 Addr optlen_p = ((UWord*)arg2)[4];
jsgf855d93d2003-10-13 22:26:55 +00005007
5008 if (optval_p != (Addr)NULL)
5009 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
5010 "socketcall.getsockopt(optlen_out)" );
5011 }
5012 break;
5013
nethercote73b526f2004-10-31 18:48:21 +00005014 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00005015 {
nethercotef1d810d2004-11-04 19:57:03 +00005016 Addr name_p = ((UWord*)arg2)[1];
5017 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00005018
5019 buf_and_len_post_check ( tid, res, name_p, namelen_p,
5020 "socketcall.getsockname(namelen_out)" );
5021 }
5022 break;
5023
nethercote73b526f2004-10-31 18:48:21 +00005024 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00005025 {
nethercotef1d810d2004-11-04 19:57:03 +00005026 Addr name_p = ((UWord*)arg2)[1];
5027 Addr namelen_p = ((UWord*)arg2)[2];
jsgf855d93d2003-10-13 22:26:55 +00005028
5029 buf_and_len_post_check ( tid, res, name_p, namelen_p,
5030 "socketcall.getpeername(namelen_out)" );
5031 }
5032 break;
5033
nethercote73b526f2004-10-31 18:48:21 +00005034 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00005035 break;
5036
nethercote73b526f2004-10-31 18:48:21 +00005037 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00005038 break;
5039
nethercote73b526f2004-10-31 18:48:21 +00005040 case VKI_SYS_RECVMSG:
jsgf855d93d2003-10-13 22:26:55 +00005041 {
nethercote22208362004-11-04 20:00:44 +00005042 struct vki_msghdr *msg = (struct vki_msghdr *)((UWord*)arg2)[ 1 ];
jsgf855d93d2003-10-13 22:26:55 +00005043
5044 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
rjwalshf5f536f2003-11-17 17:45:00 +00005045 check_cmsg_for_fds( tid, msg );
jsgf855d93d2003-10-13 22:26:55 +00005046
5047 break;
5048 }
5049
5050 default:
5051 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",arg1);
5052 VG_(core_panic)("... bye!\n");
5053 break; /*NOTREACHED*/
5054 }
5055}
5056
nethercote85a456f2004-11-16 17:31:56 +00005057PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00005058{
nethercote2e1c37d2004-11-13 13:57:12 +00005059 PRINT("sys_newstat ( %p(%s), %p )", arg1,arg1,arg2);
5060 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005061 PRE_MEM_RASCIIZ( "stat(file_name)", arg1 );
5062 PRE_MEM_WRITE( "stat(buf)", arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005063}
5064
nethercote85a456f2004-11-16 17:31:56 +00005065POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00005066{
nethercoteef0c7662004-11-06 15:38:43 +00005067 POST_MEM_WRITE( arg2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005068}
5069
nethercote85a456f2004-11-16 17:31:56 +00005070PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00005071{
nethercotedc18c0a2004-11-14 20:06:27 +00005072 PRINT("sys_statfs ( %p, %p )",arg1,arg2);
5073 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005074 PRE_MEM_RASCIIZ( "statfs(path)", arg1 );
5075 PRE_MEM_WRITE( "statfs(buf)", arg2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00005076}
5077
nethercote85a456f2004-11-16 17:31:56 +00005078POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00005079{
nethercoteef0c7662004-11-06 15:38:43 +00005080 POST_MEM_WRITE( arg2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00005081}
5082
nethercote85a456f2004-11-16 17:31:56 +00005083PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00005084{
nethercotedc18c0a2004-11-14 20:06:27 +00005085 PRINT("sys_statfs64 ( %p, %llu, %p )",arg1,(ULong)arg2,arg3);
5086 PRE_REG_READ3(long, "statfs64",
5087 const char *, path, vki_size_t, size, struct statfs64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005088 PRE_MEM_RASCIIZ( "statfs64(path)", arg1 );
5089 PRE_MEM_WRITE( "statfs64(buf)", arg3, arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005090}
5091
nethercote85a456f2004-11-16 17:31:56 +00005092POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00005093{
nethercoteef0c7662004-11-06 15:38:43 +00005094 POST_MEM_WRITE( arg3, arg2 );
muellerd3502b62003-11-19 00:43:57 +00005095}
5096
nethercote85a456f2004-11-16 17:31:56 +00005097PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005098{
nethercote5a945af2004-11-14 18:37:07 +00005099 PRINT("sys_symlink ( %p, %p )",arg1,arg2);
5100 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
nethercoteef0c7662004-11-06 15:38:43 +00005101 PRE_MEM_RASCIIZ( "symlink(oldpath)", arg1 );
5102 PRE_MEM_RASCIIZ( "symlink(newpath)", arg2 );
jsgf855d93d2003-10-13 22:26:55 +00005103}
5104
nethercote85a456f2004-11-16 17:31:56 +00005105PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005106{
nethercote2e1c37d2004-11-13 13:57:12 +00005107 PRINT("sys_stat64 ( %p, %p )",arg1,arg2);
5108 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005109 PRE_MEM_RASCIIZ( "stat64(file_name)", arg1 );
5110 PRE_MEM_WRITE( "stat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005111}
5112
nethercote85a456f2004-11-16 17:31:56 +00005113POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00005114{
nethercoteef0c7662004-11-06 15:38:43 +00005115 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005116}
5117
nethercote85a456f2004-11-16 17:31:56 +00005118PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005119{
nethercote2e1c37d2004-11-13 13:57:12 +00005120 PRINT("sys_fstat64 ( %d, %p )",arg1,arg2);
5121 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005122 PRE_MEM_WRITE( "fstat64(buf)", arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005123}
5124
nethercote85a456f2004-11-16 17:31:56 +00005125POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00005126{
nethercoteef0c7662004-11-06 15:38:43 +00005127 POST_MEM_WRITE( arg2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005128}
5129
nethercote85a456f2004-11-16 17:31:56 +00005130PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00005131{
5132 /* time_t time(time_t *t); */
nethercotec6851dd2004-11-11 18:00:47 +00005133 PRINT("sys_time ( %p )",arg1);
5134 PRE_REG_READ1(long, "time", int *, t);
nethercote163c5e82004-11-17 18:42:20 +00005135 if (arg1 != 0) {
nethercotec6851dd2004-11-11 18:00:47 +00005136 PRE_MEM_WRITE( "time(t)", arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005137 }
5138}
5139
nethercote85a456f2004-11-16 17:31:56 +00005140POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005141{
nethercote163c5e82004-11-17 18:42:20 +00005142 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005143 POST_MEM_WRITE( arg1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005144 }
5145}
5146
nethercote85a456f2004-11-16 17:31:56 +00005147PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00005148{
nethercote9c311eb2004-11-12 18:20:12 +00005149 PRINT("sys_times ( %p )", arg1);
5150 PRE_REG_READ1(long, "times", struct tms *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005151 PRE_MEM_WRITE( "times(buf)", arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005152}
5153
nethercote85a456f2004-11-16 17:31:56 +00005154POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00005155{
nethercote163c5e82004-11-17 18:42:20 +00005156 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005157 POST_MEM_WRITE( arg1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005158 }
5159}
5160
nethercote85a456f2004-11-16 17:31:56 +00005161PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00005162{
nethercote9c311eb2004-11-12 18:20:12 +00005163 PRINT("sys_umask ( %d )", arg1);
5164 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00005165}
5166
nethercote85a456f2004-11-16 17:31:56 +00005167PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005168{
nethercotec6851dd2004-11-11 18:00:47 +00005169 PRINT("sys_unlink ( %p(%s) )", arg1,arg1);
5170 PRE_REG_READ1(long, "unlink", const char *, pathname);
nethercoteef0c7662004-11-06 15:38:43 +00005171 PRE_MEM_RASCIIZ( "unlink(pathname)", arg1 );
jsgf855d93d2003-10-13 22:26:55 +00005172}
5173
nethercote85a456f2004-11-16 17:31:56 +00005174PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00005175{
nethercote1a1b9b72004-11-12 11:19:36 +00005176 PRINT("sys_newuname ( %p )", arg1);
5177 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005178 PRE_MEM_WRITE( "uname(buf)", arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005179}
5180
nethercote85a456f2004-11-16 17:31:56 +00005181POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005182{
nethercote163c5e82004-11-17 18:42:20 +00005183 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005184 POST_MEM_WRITE( arg1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005185 }
5186}
5187
nethercote85a456f2004-11-16 17:31:56 +00005188PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005189{
nethercote9a3beb92004-11-12 17:07:26 +00005190 PRINT("sys_utime ( %p, %p )", arg1,arg2);
5191 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
nethercoteef0c7662004-11-06 15:38:43 +00005192 PRE_MEM_RASCIIZ( "utime(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005193 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005194 PRE_MEM_READ( "utime(buf)", arg2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00005195}
5196
nethercote85a456f2004-11-16 17:31:56 +00005197PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005198{
nethercotec6851dd2004-11-11 18:00:47 +00005199 PRINT("sys_waitpid ( %d, %p, %d )", arg1,arg2,arg3);
5200 PRE_REG_READ3(long, "waitpid",
5201 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005202
jsgf855d93d2003-10-13 22:26:55 +00005203 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005204 PRE_MEM_WRITE( "waitpid(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005205}
5206
nethercote85a456f2004-11-16 17:31:56 +00005207POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005208{
5209 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005210 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005211}
5212
nethercote85a456f2004-11-16 17:31:56 +00005213PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005214{
nethercote7f7e4d12004-11-15 12:28:58 +00005215 PRINT("sys_wait4 ( %d, %p, %d, %p )", arg1,arg2,arg3,arg4);
nethercote73b526f2004-10-31 18:48:21 +00005216 arg3 &= ~(__VKI_WCLONE | __VKI_WALL);
jsgf855d93d2003-10-13 22:26:55 +00005217
nethercote7f7e4d12004-11-15 12:28:58 +00005218 PRE_REG_READ4(long, "wait4",
5219 vki_pid_t, pid, unsigned int *, status, int, options,
5220 struct rusage *, rusage);
jsgf855d93d2003-10-13 22:26:55 +00005221 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005222 PRE_MEM_WRITE( "wait4(status)", arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005223 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005224 PRE_MEM_WRITE( "wait4(rusage)", arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005225}
5226
nethercote85a456f2004-11-16 17:31:56 +00005227POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005228{
5229 if (arg2 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005230 POST_MEM_WRITE( arg2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005231 if (arg4 != (Addr)NULL)
nethercoteef0c7662004-11-06 15:38:43 +00005232 POST_MEM_WRITE( arg4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005233}
5234
nethercote85a456f2004-11-16 17:31:56 +00005235PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005236{
jsgf855d93d2003-10-13 22:26:55 +00005237 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005238 struct vki_iovec * vec;
nethercoted6b5a212004-11-15 17:04:14 +00005239 PRINT("sys_writev ( %d, %p, %llu )",arg1,arg2,(ULong)arg3);
5240 PRE_REG_READ3(ssize_t, "writev",
5241 unsigned long, fd, const struct iovec *, vector,
5242 unsigned long, count);
nethercote3d5e9102004-11-17 18:22:38 +00005243 if (!VG_(fd_allowed)(arg1, "writev", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005244 set_result( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005245 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005246 PRE_MEM_READ( "writev(vector)",
nethercote73b526f2004-10-31 18:48:21 +00005247 arg2, arg3 * sizeof(struct vki_iovec) );
nethercote163c5e82004-11-17 18:42:20 +00005248 if (arg2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005249 /* ToDo: don't do any of the following if the vector is invalid */
5250 vec = (struct vki_iovec *)arg2;
5251 for (i = 0; i < (Int)arg3; i++)
5252 PRE_MEM_READ( "writev(vector[...])",
5253 (Addr)vec[i].iov_base, vec[i].iov_len );
5254 }
jsgf855d93d2003-10-13 22:26:55 +00005255 }
5256}
5257
nethercote85a456f2004-11-16 17:31:56 +00005258PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005259{
nethercoteac866b92004-11-15 20:23:15 +00005260 PRINT("sys_utimes ( %p, %p )", arg1,arg2);
nethercoteac866b92004-11-15 20:23:15 +00005261 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
nethercote38e0a9e2004-11-15 20:42:06 +00005262 PRE_MEM_RASCIIZ( "utimes(filename)", arg1 );
nethercote163c5e82004-11-17 18:42:20 +00005263 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005264 PRE_MEM_READ( "utimes(tvp)", arg2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005265}
5266
nethercote85a456f2004-11-16 17:31:56 +00005267PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005268{
nethercoteef0c7662004-11-06 15:38:43 +00005269 PRINT("sched_setaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005270 PRE_REG_READ3(long, "sched_setaffinity",
5271 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005272 PRE_MEM_READ( "sched_setaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005273}
5274
nethercote85a456f2004-11-16 17:31:56 +00005275PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005276{
nethercoteef0c7662004-11-06 15:38:43 +00005277 PRINT("sched_getaffinity ( %d, %d, %p )", arg1, arg2, arg3);
nethercote5b653bc2004-11-15 14:32:12 +00005278 PRE_REG_READ3(long, "sched_getaffinity",
5279 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
nethercoteef0c7662004-11-06 15:38:43 +00005280 PRE_MEM_WRITE( "sched_getaffinity(mask)", arg3, arg2);
thughes2f8d5f82004-09-11 14:29:19 +00005281}
5282
nethercote85a456f2004-11-16 17:31:56 +00005283POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005284{
5285 VG_TRACK(post_mem_write, arg3, arg2);
5286}
5287
nethercote85a456f2004-11-16 17:31:56 +00005288PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005289{
nethercote2b0cae62004-11-12 14:57:34 +00005290 PRINT("sys_acct ( %p )", arg1);
5291 PRE_REG_READ1(long, "acct", const char *, filename);
nethercoteef0c7662004-11-06 15:38:43 +00005292 PRE_MEM_RASCIIZ( "acct(filename)", arg1 );
nethercote2bc5a212004-04-10 00:26:10 +00005293}
5294
nethercote85a456f2004-11-16 17:31:56 +00005295PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005296{
nethercote0df495a2004-11-11 16:38:21 +00005297 PRINT("sys_pause ( )");
5298 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005299}
5300
nethercotea3a2c142004-11-14 14:13:05 +00005301// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005302PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005303{
thughesc3e85df2004-11-15 09:27:24 +00005304 /* The C library interface to sigsuspend just takes a pointer to
5305 a signal mask but this system call has three arguments - the first
5306 two don't appear to be used by the kernel and are always passed as
5307 zero by glibc and the third is the first word of the signal mask
5308 so only 32 signals are supported.
5309
5310 In fact glibc normally uses rt_sigsuspend if it is available as
5311 that takes a pointer to the signal mask so supports more signals.
5312 */
thughesd8e00412004-11-14 19:44:25 +00005313 PRINT("sys_sigsuspend ( %d, %d, %d )", arg1,arg2,arg3 );
5314 PRE_REG_READ3(int, "sigsuspend",
5315 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005316 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005317}
5318
nethercotea3a2c142004-11-14 14:13:05 +00005319// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005320PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005321{
thughesc3e85df2004-11-15 09:27:24 +00005322 /* The C library interface to sigsuspend just takes a pointer to
5323 a signal mask but this system call has two arguments - a pointer
5324 to the mask and the number of bytes used by it. The kernel insists
5325 on the size being equal to sizeof(sigset_t) however and will just
5326 return EINVAL if it isn't.
5327 */
nethercotea3a2c142004-11-14 14:13:05 +00005328 PRINT("sys_rt_sigsuspend ( %p, %d )", arg1,arg2 );
5329 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
5330 if (arg1 != (Addr)NULL) {
5331 PRE_MEM_READ( "rt_sigsuspend(mask)", arg1, sizeof(vki_sigset_t) );
5332 }
5333}
jsgf855d93d2003-10-13 22:26:55 +00005334
nethercote85a456f2004-11-16 17:31:56 +00005335PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005336{
nethercoteac866b92004-11-15 20:23:15 +00005337 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
5338 arg1,arg2,arg3,(ULong)arg4);
5339 PRE_REG_READ4(long, "rt_sigtimedwait",
5340 const vki_sigset_t *, set, vki_siginfo_t *, info,
5341 const struct timespec *, timeout, vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005342 if (arg1 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005343 PRE_MEM_READ( "rt_sigtimedwait(set)", arg1, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005344 if (arg2 != 0)
nethercoteac866b92004-11-15 20:23:15 +00005345 PRE_MEM_WRITE( "rt_sigtimedwait(info)", arg2, sizeof(vki_siginfo_t) );
5346 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
5347 arg4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005348}
5349
nethercote85a456f2004-11-16 17:31:56 +00005350POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005351{
nethercote163c5e82004-11-17 18:42:20 +00005352 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005353 POST_MEM_WRITE( arg2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005354}
5355
nethercote85a456f2004-11-16 17:31:56 +00005356PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005357{
nethercote92b2fd52004-11-16 16:15:41 +00005358 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", arg1, arg2, arg3);
5359 PRE_REG_READ3(long, "rt_sigqueueinfo",
5360 int, pid, int, sig, vki_siginfo_t *, uinfo);
nethercote163c5e82004-11-17 18:42:20 +00005361 if (arg2 != 0)
nethercote92b2fd52004-11-16 16:15:41 +00005362 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", arg3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005363}
5364
nethercote85a456f2004-11-16 17:31:56 +00005365POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005366{
5367 if (res >= 0 &&
5368 arg2 != 0 &&
5369 !VG_(is_sig_ign)(arg2) &&
nethercote73b526f2004-10-31 18:48:21 +00005370 !VG_(sigismember)(&tst->eff_sig_mask, arg2) &&
jsgf855d93d2003-10-13 22:26:55 +00005371 arg1 == VG_(getpid)()) {
5372 VG_(proxy_waitsig)();
5373 }
5374}
5375
nethercotec8734892004-11-10 18:57:37 +00005376#define SIGNAL_SIMULATION 1
5377
5378#if SIGNAL_SIMULATION
5379#define SIG_SIM Special
5380#else
5381#define SIG_SIM 0
5382#endif
5383
nethercoteb77dee62004-11-16 17:13:24 +00005384// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005385PRE(sys_sigaltstack, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005386{
5387 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
nethercoteef0c7662004-11-06 15:38:43 +00005388 PRINT("sigaltstack ( %p, %p )",arg1,arg2);
nethercoteb77dee62004-11-16 17:13:24 +00005389 PRE_REG_READ2(int, "sigaltstack",
5390 const vki_stack_t *, ss, vki_stack_t *, oss);
nethercote163c5e82004-11-17 18:42:20 +00005391 if (arg1 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005392 PRE_MEM_READ( "sigaltstack(ss)", arg1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005393 }
nethercote163c5e82004-11-17 18:42:20 +00005394 if (arg2 != 0) {
nethercoteef0c7662004-11-06 15:38:43 +00005395 PRE_MEM_WRITE( "sigaltstack(oss)", arg2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005396 }
5397
5398 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005399 VG_(do_sys_sigaltstack) (tid);
jsgf855d93d2003-10-13 22:26:55 +00005400}
5401
nethercote85a456f2004-11-16 17:31:56 +00005402POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005403{
nethercote163c5e82004-11-17 18:42:20 +00005404 if (res == 0 && arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005405 POST_MEM_WRITE( arg2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005406}
5407
nethercote71f05f32004-11-12 18:49:27 +00005408// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005409PRE(sys_sigaction, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005410{
nethercote71f05f32004-11-12 18:49:27 +00005411 PRINT("sys_sigaction ( %d, %p, %p )", arg1,arg2,arg3);
5412 PRE_REG_READ3(int, "sigaction",
5413 int, signum, const struct old_sigaction *, act,
5414 struct old_sigaction *, oldact)
nethercote163c5e82004-11-17 18:42:20 +00005415 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005416 PRE_MEM_READ( "sigaction(act)", arg2, sizeof(struct vki_old_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005417 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005418 PRE_MEM_WRITE( "sigaction(oldact)", arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005419
5420 if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005421 VG_(do_sys_sigaction)(tid);
jsgf855d93d2003-10-13 22:26:55 +00005422}
5423
nethercote85a456f2004-11-16 17:31:56 +00005424POST(sys_sigaction)
jsgf855d93d2003-10-13 22:26:55 +00005425{
nethercote163c5e82004-11-17 18:42:20 +00005426 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005427 POST_MEM_WRITE( arg3, sizeof(struct vki_old_sigaction));
jsgf855d93d2003-10-13 22:26:55 +00005428}
5429
nethercote686b5db2004-11-14 13:42:51 +00005430// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005431PRE(sys_rt_sigaction, SIG_SIM)
nethercote686b5db2004-11-14 13:42:51 +00005432{
5433 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", arg1,arg2,arg3,arg4);
5434 PRE_REG_READ4(long, "rt_sigaction",
5435 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005436 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005437
nethercote163c5e82004-11-17 18:42:20 +00005438 if (arg2 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005439 PRE_MEM_READ( "rt_sigaction(act)", arg2, sizeof(struct vki_sigaction));
nethercote163c5e82004-11-17 18:42:20 +00005440 if (arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005441 PRE_MEM_WRITE( "rt_sigaction(oldact)", arg3, sizeof(struct vki_sigaction));
5442
5443 // XXX: hmm... doesn't seem quite right...
5444 if (SIGNAL_SIMULATION)
5445 VG_(do_sys_sigaction)(tid);
5446}
5447
nethercote85a456f2004-11-16 17:31:56 +00005448POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005449{
nethercote163c5e82004-11-17 18:42:20 +00005450 if (res == 0 && arg3 != 0)
nethercote686b5db2004-11-14 13:42:51 +00005451 POST_MEM_WRITE( arg3, sizeof(struct vki_sigaction));
5452}
jsgf855d93d2003-10-13 22:26:55 +00005453
nethercote85a456f2004-11-16 17:31:56 +00005454PRE(sys_sigprocmask, SIG_SIM)
jsgf855d93d2003-10-13 22:26:55 +00005455{
nethercote7fbe08a2004-11-15 19:03:27 +00005456 PRINT("sys_sigprocmask ( %d, %p, %p )",arg1,arg2,arg3);
5457 PRE_REG_READ3(long, "sigprocmask",
5458 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
nethercote163c5e82004-11-17 18:42:20 +00005459 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005460 PRE_MEM_READ( "sigprocmask(set)", arg2, sizeof(vki_old_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005461 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005462 PRE_MEM_WRITE( "sigprocmask(oldset)", arg3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005463
nethercote7fbe08a2004-11-15 19:03:27 +00005464 if (SIGNAL_SIMULATION) {
5465 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5466 // vki_sigset_t params.
5467 vki_old_sigset_t* set = (vki_old_sigset_t*)arg2;
5468 vki_old_sigset_t* oldset = (vki_old_sigset_t*)arg3;
5469 vki_sigset_t bigger_set;
5470 vki_sigset_t bigger_oldset;
5471
5472 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5473 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
5474
5475 VG_(do_sys_sigprocmask) ( tid,
5476 arg1 /*how*/,
5477 &bigger_set,
5478 &bigger_oldset );
5479
thughes1112cab2004-11-16 12:08:45 +00005480 if (oldset)
nethercote330abb52004-11-16 12:58:04 +00005481 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005482 }
5483}
5484
nethercote85a456f2004-11-16 17:31:56 +00005485POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005486{
nethercote163c5e82004-11-17 18:42:20 +00005487 if (res == 0 && arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005488 POST_MEM_WRITE( arg3, sizeof(vki_old_sigset_t));
5489}
5490
nethercote85a456f2004-11-16 17:31:56 +00005491PRE(sys_rt_sigprocmask, SIG_SIM)
nethercote7fbe08a2004-11-15 19:03:27 +00005492{
5493 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",arg1,arg2,arg3,(ULong)arg4);
5494 PRE_REG_READ4(long, "rt_sigprocmask",
5495 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5496 vki_size_t, sigsetsize);
nethercote163c5e82004-11-17 18:42:20 +00005497 if (arg2 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005498 PRE_MEM_READ( "rt_sigprocmask(set)", arg2, sizeof(vki_sigset_t));
nethercote163c5e82004-11-17 18:42:20 +00005499 if (arg3 != 0)
nethercote7fbe08a2004-11-15 19:03:27 +00005500 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", arg3, sizeof(vki_sigset_t));
5501
5502 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
5503 if (sizeof(vki_sigset_t) != arg4)
5504 set_result( -VKI_EMFILE );
5505 else if (SIGNAL_SIMULATION)
nethercote93d9aa12004-11-10 19:08:31 +00005506 VG_(do_sys_sigprocmask) ( tid,
jsgf855d93d2003-10-13 22:26:55 +00005507 arg1 /*how*/,
nethercote73b526f2004-10-31 18:48:21 +00005508 (vki_sigset_t*) arg2,
5509 (vki_sigset_t*) arg3 );
jsgf855d93d2003-10-13 22:26:55 +00005510}
5511
nethercote85a456f2004-11-16 17:31:56 +00005512POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005513{
nethercote163c5e82004-11-17 18:42:20 +00005514 if (res == 0 && arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005515 POST_MEM_WRITE( arg3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005516}
5517
nethercote85a456f2004-11-16 17:31:56 +00005518PRE(sys_sigpending, NBRunInLWP)
jsgf855d93d2003-10-13 22:26:55 +00005519{
nethercote17258dc2004-11-12 19:55:08 +00005520 PRINT( "sys_sigpending ( %p )", arg1 );
5521 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
5522 PRE_MEM_WRITE( "sigpending(set)", arg1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005523}
5524
nethercote85a456f2004-11-16 17:31:56 +00005525POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005526{
nethercotea6395d12004-11-15 19:23:46 +00005527 POST_MEM_WRITE( arg1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005528}
5529
nethercote85a456f2004-11-16 17:31:56 +00005530PRE(sys_rt_sigpending, NBRunInLWP)
nethercotea6395d12004-11-15 19:23:46 +00005531{
nethercote38e0a9e2004-11-15 20:42:06 +00005532 PRINT( "sys_rt_sigpending ( %p )", arg1 );
nethercotea6395d12004-11-15 19:23:46 +00005533 PRE_REG_READ2(long, "rt_sigpending",
5534 vki_sigset_t *, set, vki_size_t, sigsetsize);
nethercote38e0a9e2004-11-15 20:42:06 +00005535 PRE_MEM_WRITE( "rt_sigpending(set)", arg1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005536}
5537
nethercote85a456f2004-11-16 17:31:56 +00005538POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005539{
5540 POST_MEM_WRITE( arg1, sizeof(vki_sigset_t) ) ;
5541}
jsgf855d93d2003-10-13 22:26:55 +00005542
nethercote85a456f2004-11-16 17:31:56 +00005543PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005544{
nethercote330abb52004-11-16 12:58:04 +00005545 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
5546 arg1,arg1,arg2,(ULong)arg3,arg4);
5547 PRE_REG_READ4(long, "mq_open",
5548 const char *, name, int, oflag, vki_mode_t, mode,
5549 struct mq_attr *, attr);
nethercoteef0c7662004-11-06 15:38:43 +00005550 PRE_MEM_RASCIIZ( "mq_open(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005551 if ((arg2 & VKI_O_CREAT) != 0 && arg4 != 0) {
5552 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg4;
nethercoteef0c7662004-11-06 15:38:43 +00005553 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005554 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005555 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005556 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5557 }
5558}
5559
nethercote85a456f2004-11-16 17:31:56 +00005560POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005561{
nethercote3d5e9102004-11-17 18:22:38 +00005562 if (!VG_(fd_allowed)(res, "mq_open", tid, True)) {
thughes8579b102004-08-14 18:52:27 +00005563 VG_(close)(res);
nethercote35122912004-10-18 17:00:30 +00005564 set_result( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005565 } else {
5566 if (VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +00005567 VG_(record_fd_open)(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
thughes8579b102004-08-14 18:52:27 +00005568 }
thughes8579b102004-08-14 18:52:27 +00005569}
5570
nethercote85a456f2004-11-16 17:31:56 +00005571PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005572{
nethercote330abb52004-11-16 12:58:04 +00005573 PRINT("sys_mq_unlink ( %p(%s) )", arg1,arg1);
5574 PRE_REG_READ1(long, "mq_unlink", const char *, name);
nethercoteef0c7662004-11-06 15:38:43 +00005575 PRE_MEM_RASCIIZ( "mq_unlink(name)", arg1 );
thughes8579b102004-08-14 18:52:27 +00005576}
5577
nethercote85a456f2004-11-16 17:31:56 +00005578PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005579{
nethercote330abb52004-11-16 12:58:04 +00005580 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
5581 arg1,arg2,(ULong)arg3,arg4,arg5);
5582 PRE_REG_READ5(long, "mq_timedsend",
5583 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5584 unsigned int, msg_prio, const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005585 if (!VG_(fd_allowed)(arg1, "mq_timedsend", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005586 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005587 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005588 PRE_MEM_READ( "mq_timedsend(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005589 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005590 PRE_MEM_READ( "mq_timedsend(abs_timeout)", arg5,
nethercote73b526f2004-10-31 18:48:21 +00005591 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005592 }
5593}
5594
nethercote85a456f2004-11-16 17:31:56 +00005595PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005596{
nethercote330abb52004-11-16 12:58:04 +00005597 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
5598 arg1,arg2,(ULong)arg3,arg4,arg5);
5599 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5600 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5601 unsigned int *, msg_prio,
5602 const struct timespec *, abs_timeout);
nethercote3d5e9102004-11-17 18:22:38 +00005603 if (!VG_(fd_allowed)(arg1, "mq_timedreceive", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005604 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005605 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005606 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005607 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005608 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
thughes8579b102004-08-14 18:52:27 +00005609 arg4, sizeof(unsigned int) );
5610 if (arg5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005611 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
nethercote73b526f2004-10-31 18:48:21 +00005612 arg5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005613 }
5614}
5615
nethercote85a456f2004-11-16 17:31:56 +00005616POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005617{
nethercoteef0c7662004-11-06 15:38:43 +00005618 POST_MEM_WRITE( arg2, arg3 );
thughes8579b102004-08-14 18:52:27 +00005619 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005620 POST_MEM_WRITE( arg4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005621}
5622
nethercote85a456f2004-11-16 17:31:56 +00005623PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005624{
nethercote330abb52004-11-16 12:58:04 +00005625 PRINT("sys_mq_notify( %d, %p )", arg1,arg2 );
5626 PRE_REG_READ2(long, "mq_notify",
5627 vki_mqd_t, mqdes, const struct sigevent *, notification);
nethercote3d5e9102004-11-17 18:22:38 +00005628 if (!VG_(fd_allowed)(arg1, "mq_notify", tid, False))
nethercote35122912004-10-18 17:00:30 +00005629 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005630 else if (arg2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005631 PRE_MEM_READ( "mq_notify(notification)",
5632 arg2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005633}
5634
nethercote85a456f2004-11-16 17:31:56 +00005635PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005636{
nethercote330abb52004-11-16 12:58:04 +00005637 PRINT("sys_mq_getsetattr( %d, %p, %p )", arg1,arg2,arg3 );
5638 PRE_REG_READ3(long, "mq_getsetattr",
5639 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5640 struct mq_attr *, omqstat);
nethercote3d5e9102004-11-17 18:22:38 +00005641 if (!VG_(fd_allowed)(arg1, "mq_getsetattr", tid, False)) {
nethercote35122912004-10-18 17:00:30 +00005642 set_result( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005643 } else {
5644 if (arg2 != 0) {
5645 const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg2;
nethercoteef0c7662004-11-06 15:38:43 +00005646 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005647 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5648 }
5649 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005650 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", arg3,
thughes8579b102004-08-14 18:52:27 +00005651 sizeof(struct vki_mq_attr) );
5652 }
5653}
5654
nethercote85a456f2004-11-16 17:31:56 +00005655POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005656{
5657 if (arg3 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005658 POST_MEM_WRITE( arg3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005659}
5660
nethercote85a456f2004-11-16 17:31:56 +00005661PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005662{
nethercote92b2fd52004-11-16 16:15:41 +00005663 PRINT("sys_timer_create( %d, %p, %p )", arg1,arg2,arg3);
5664 PRE_REG_READ3(long, "timer_create",
5665 vki_clockid_t, clockid, struct sigevent *, evp,
5666 vki_timer_t *, timerid);
thughese1a925d2004-08-30 19:50:02 +00005667 if (arg2 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005668 PRE_MEM_READ( "timer_create(evp)", arg2, sizeof(struct vki_sigevent) );
5669 PRE_MEM_WRITE( "timer_create(timerid)", arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005670}
5671
nethercote85a456f2004-11-16 17:31:56 +00005672POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005673{
nethercoteef0c7662004-11-06 15:38:43 +00005674 POST_MEM_WRITE( arg3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005675}
5676
nethercote85a456f2004-11-16 17:31:56 +00005677PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005678{
nethercote92b2fd52004-11-16 16:15:41 +00005679 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)arg1,arg2,arg3,arg4);
5680 PRE_REG_READ4(long, "timer_settime",
5681 vki_timer_t, timerid, int, flags,
5682 const struct itimerspec *, value,
5683 struct itimerspec *, ovalue);
nethercoteef0c7662004-11-06 15:38:43 +00005684 PRE_MEM_READ( "timer_settime(value)", arg3,
thughese1a925d2004-08-30 19:50:02 +00005685 sizeof(struct vki_itimerspec) );
5686 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005687 PRE_MEM_WRITE( "timer_settime(ovalue)", arg4,
thughese1a925d2004-08-30 19:50:02 +00005688 sizeof(struct vki_itimerspec) );
5689}
5690
nethercote85a456f2004-11-16 17:31:56 +00005691POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005692{
5693 if (arg4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005694 POST_MEM_WRITE( arg4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005695}
5696
nethercote85a456f2004-11-16 17:31:56 +00005697PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005698{
nethercote92b2fd52004-11-16 16:15:41 +00005699 PRINT("sys_timer_gettime( %lld, %p )", (ULong)arg1,arg2);
5700 PRE_REG_READ2(long, "timer_gettime",
5701 vki_timer_t, timerid, struct itimerspec *, value);
nethercoteef0c7662004-11-06 15:38:43 +00005702 PRE_MEM_WRITE( "timer_gettime(value)", arg2,
thughese1a925d2004-08-30 19:50:02 +00005703 sizeof(struct vki_itimerspec));
5704}
5705
nethercote85a456f2004-11-16 17:31:56 +00005706POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005707{
nethercoteef0c7662004-11-06 15:38:43 +00005708 POST_MEM_WRITE( arg2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005709}
5710
nethercote85a456f2004-11-16 17:31:56 +00005711PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005712{
nethercote92b2fd52004-11-16 16:15:41 +00005713 PRINT("sys_timer_getoverrun( %p )", arg1);
5714 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005715}
5716
nethercote85a456f2004-11-16 17:31:56 +00005717PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005718{
nethercote92b2fd52004-11-16 16:15:41 +00005719 PRINT("sys_timer_delete( %p )", arg1);
5720 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005721}
5722
nethercote85a456f2004-11-16 17:31:56 +00005723PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005724{
nethercote92b2fd52004-11-16 16:15:41 +00005725 PRINT("sys_clock_settime( %d, %p )", arg1,arg2);
5726 PRE_REG_READ2(long, "clock_settime",
5727 vki_clockid_t, clk_id, const struct timespec *, tp);
5728 PRE_MEM_READ( "clock_settime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005729}
5730
nethercote85a456f2004-11-16 17:31:56 +00005731PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005732{
nethercote92b2fd52004-11-16 16:15:41 +00005733 PRINT("sys_clock_gettime( %d, %p )" , arg1,arg2);
5734 PRE_REG_READ2(long, "clock_gettime",
5735 vki_clockid_t, clk_id, struct timespec *, tp);
5736 PRE_MEM_WRITE( "clock_gettime(tp)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005737}
5738
nethercote85a456f2004-11-16 17:31:56 +00005739POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005740{
nethercote92b2fd52004-11-16 16:15:41 +00005741 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005742}
5743
nethercote85a456f2004-11-16 17:31:56 +00005744PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005745{
nethercote92b2fd52004-11-16 16:15:41 +00005746 PRINT("sys_clock_getres( %d, %p )" , arg1,arg2);
5747 // Nb: we can't use "res" as the param name because that's a macro
5748 // defined above!
5749 PRE_REG_READ2(long, "clock_getres",
5750 vki_clockid_t, clk_id, struct timespec *, cres);
5751 PRE_MEM_WRITE( "clock_getres(cres)", arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005752}
5753
nethercote85a456f2004-11-16 17:31:56 +00005754POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005755{
nethercote92b2fd52004-11-16 16:15:41 +00005756 POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005757}
5758
nethercote4fa681f2004-11-08 17:51:39 +00005759
5760/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005761 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005762 ------------------------------------------------------------------ */
5763
nethercote85a456f2004-11-16 17:31:56 +00005764static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005765static void bad_before(ThreadId tid, ThreadState *tst)
5766{
5767 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005768 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005769 if (VG_(clo_verbosity) > 1) {
5770 ExeContext *ec = VG_(get_ExeContext)(tid);
5771 VG_(pp_ExeContext)(ec);
5772 }
jsgf855d93d2003-10-13 22:26:55 +00005773 VG_(message)
5774 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5775 VG_(message)
5776 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5777
nethercote35122912004-10-18 17:00:30 +00005778 set_result( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005779}
5780
nethercote8ff888f2004-11-17 17:11:45 +00005781static const struct SyscallTableEntry bad_sys =
5782 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005783
nethercote4fa681f2004-11-08 17:51:39 +00005784
jsgf855d93d2003-10-13 22:26:55 +00005785Bool VG_(pre_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00005786{
sewardj018f7622002-05-15 21:13:39 +00005787 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005788 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005789 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00005790 Bool isSpecial = False;
5791 Bool mayBlock = False;
5792 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00005793 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00005794
njn25e49d8e72002-09-23 09:36:25 +00005795 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00005796
jsgf855d93d2003-10-13 22:26:55 +00005797 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00005798
jsgf855d93d2003-10-13 22:26:55 +00005799 /* Convert vfork to fork, since we can't handle it otherwise. */
nethercote427e9512004-08-23 16:36:09 +00005800 if (SYSNO == __NR_vfork)
5801 SYSNO = __NR_fork;
sewardjde4a1d02002-03-22 01:27:54 +00005802
nethercote44d9aaa2004-11-04 19:38:14 +00005803 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00005804
5805 if (tst->syscallno != -1)
5806 VG_(printf)("tid %d has syscall %d\n", tst->tid, tst->syscallno);
5807
nethercote1c2a3f52004-11-12 20:38:34 +00005808 vg_assert(tst->syscallno == -1); // should be no current syscall
5809 vg_assert(tst->status == VgTs_Runnable); // should be runnable */
jsgf855d93d2003-10-13 22:26:55 +00005810
5811 /* the syscall no is in %eax. For syscalls with <= 6 args,
5812 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
5813 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00005814 containing the args.
5815
5816 The result is returned in %eax. If this value >= 0, the call
5817 succeeded, and this is the return value. If < 0, it failed, and
5818 the negation of this value is errno. To be more specific,
5819 if res is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
5820 (kernel 2.4.9 sources, include/asm-i386/errno.h)
5821 then it indicates an error. Otherwise it doesn't.
5822
5823 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
5824 (inclusive?) indicate error returns. Not sure where the -4095
5825 comes from.
5826 */
5827
jsgf855d93d2003-10-13 22:26:55 +00005828 tst->syscallno = syscallno;
fitzhardingef0f911c2003-11-09 09:51:33 +00005829 vg_assert(tst->status == VgTs_Runnable);
sewardjde4a1d02002-03-22 01:27:54 +00005830
nethercote8ff888f2004-11-17 17:11:45 +00005831 if (syscallno < VGA_(syscall_table_size) &&
5832 VGA_(syscall_table)[syscallno].before != NULL)
5833 {
5834 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005835 } else {
5836 sys = &bad_sys;
nethercotec8734892004-11-10 18:57:37 +00005837 }
nethercote85a456f2004-11-16 17:31:56 +00005838 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00005839
nethercote1fe55d62004-11-12 11:02:00 +00005840 {
5841 Bool nbrunInLWP = ( flags & NBRunInLWP ? True : False );
5842 isSpecial = ( flags & Special ? True : False );
5843 mayBlock = ( flags & MayBlock ? True : False );
5844 runInLWP = mayBlock || nbrunInLWP;
5845 // At most one of these should be true
5846 vg_assert( isSpecial + mayBlock + nbrunInLWP <= 1 );
5847 }
nethercotec8734892004-11-10 18:57:37 +00005848
5849 tst->sys_flags = flags;
5850
jsgf855d93d2003-10-13 22:26:55 +00005851 /* Do any pre-syscall actions */
5852 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00005853 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00005854 TL_(pre_syscall)(tid, syscallno);
njn4be0a692004-11-22 18:10:36 +00005855 VGP_POPCC(VgpToolSysWrap);
jsgf855d93d2003-10-13 22:26:55 +00005856 }
5857
nethercoteef0c7662004-11-06 15:38:43 +00005858 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
5859 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00005860 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00005861 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00005862
nethercotec8734892004-11-10 18:57:37 +00005863 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00005864 /* "Special" syscalls are implemented by Valgrind internally,
5865 and do not generate real kernel calls. The expectation,
5866 therefore, is that the "before" function not only does the
5867 appropriate tests, but also performs the syscall itself and
5868 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00005869 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00005870
5871 (sys->before)(tst->tid, tst);
5872
nethercotec8734892004-11-10 18:57:37 +00005873 vg_assert(tst->sys_flags == flags);
thughesbaa46e52004-07-29 17:44:23 +00005874
nethercoteef0c7662004-11-06 15:38:43 +00005875 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005876 syscall_done = True;
5877 } else {
5878 (sys->before)(tst->tid, tst);
5879
nethercote44d9aaa2004-11-04 19:38:14 +00005880 if ((Word)res <= 0) {
jsgf855d93d2003-10-13 22:26:55 +00005881 /* "before" decided the syscall wasn't viable, so don't do
5882 anything - just pretend the syscall happened. */
nethercoteef0c7662004-11-06 15:38:43 +00005883 PRINT(" ==> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005884 syscall_done = True;
nethercote1fe55d62004-11-12 11:02:00 +00005885 } else if (runInLWP) {
fitzhardinge33730212003-11-10 21:21:00 +00005886 /* Issue to worker. If we're waiting on the syscall because
5887 it's in the hands of the ProxyLWP, then set the thread
5888 state to WaitSys. */
nethercoteef0c7662004-11-06 15:38:43 +00005889 PRINT(" --> ...\n");
fitzhardinge33730212003-11-10 21:21:00 +00005890 tst->status = VgTs_WaitSys;
jsgf855d93d2003-10-13 22:26:55 +00005891 VG_(sys_issue)(tid);
5892 } else {
5893 /* run the syscall directly */
nethercotea4670f62004-08-23 16:39:42 +00005894 res = VG_(do_syscall)(syscallno, arg1, arg2, arg3, arg4, arg5, arg6);
nethercoteef0c7662004-11-06 15:38:43 +00005895 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)res, (ULong)res);
jsgf855d93d2003-10-13 22:26:55 +00005896 syscall_done = True;
5897 }
5898 }
5899
5900 VGP_POPCC(VgpCoreSysWrap);
5901
fitzhardinge33730212003-11-10 21:21:00 +00005902 vg_assert(( syscall_done && tst->status == VgTs_Runnable) ||
5903 (!syscall_done && tst->status == VgTs_WaitSys ));
fitzhardingef0f911c2003-11-09 09:51:33 +00005904
jsgf855d93d2003-10-13 22:26:55 +00005905 return syscall_done;
5906}
5907
nethercote85cdd342004-08-01 22:36:40 +00005908static void restart_syscall(ThreadId tid)
5909{
5910 ThreadState* tst;
5911 tst = VG_(get_ThreadState)(tid);
5912
5913 vg_assert(tst != NULL);
5914 vg_assert(tst->status == VgTs_WaitSys);
5915 vg_assert(tst->syscallno != -1);
5916
nethercote427e9512004-08-23 16:36:09 +00005917 SYSNO = tst->syscallno;
nethercote41c75da2004-10-18 15:34:14 +00005918 VGA_(restart_syscall)(&tst->arch);
nethercote85cdd342004-08-01 22:36:40 +00005919}
jsgf855d93d2003-10-13 22:26:55 +00005920
fitzhardinge31ba9052004-01-16 02:15:23 +00005921void VG_(post_syscall) ( ThreadId tid, Bool restart )
jsgf855d93d2003-10-13 22:26:55 +00005922{
5923 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00005924 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00005925 const struct SyscallTableEntry *sys;
nethercotec8734892004-11-10 18:57:37 +00005926 Bool isSpecial = False;
fitzhardinge31ba9052004-01-16 02:15:23 +00005927 Bool restarted = False;
jsgf855d93d2003-10-13 22:26:55 +00005928
5929 VGP_PUSHCC(VgpCoreSysWrap);
5930
5931 tst = VG_(get_ThreadState)(tid);
nethercoteef0c7662004-11-06 15:38:43 +00005932 vg_assert(tst->tid == tid);
jsgf855d93d2003-10-13 22:26:55 +00005933
nethercote996901a2004-08-03 13:29:09 +00005934 /* Tell the tool about the syscall return value */
nethercote427e9512004-08-23 16:36:09 +00005935 SET_SYSCALL_RETVAL(tst->tid, res);
jsgf855d93d2003-10-13 22:26:55 +00005936
5937 syscallno = tst->syscallno;
jsgf855d93d2003-10-13 22:26:55 +00005938
5939 vg_assert(syscallno != -1); /* must be a current syscall */
jsgf855d93d2003-10-13 22:26:55 +00005940
nethercote8ff888f2004-11-17 17:11:45 +00005941 if (syscallno < VGA_(syscall_table_size) &&
5942 VGA_(syscall_table)[syscallno].before != NULL)
5943 {
5944 sys = &VGA_(syscall_table)[syscallno];
jsgf855d93d2003-10-13 22:26:55 +00005945 } else {
5946 sys = &bad_sys;
jsgf855d93d2003-10-13 22:26:55 +00005947 }
nethercote85a456f2004-11-16 17:31:56 +00005948 flags = *(sys->flags_ptr);
nethercotec8734892004-11-10 18:57:37 +00005949
5950 isSpecial = flags & Special;
fitzhardingef0f911c2003-11-09 09:51:33 +00005951
nethercote427e9512004-08-23 16:36:09 +00005952 if (res == -VKI_ERESTARTSYS) {
fitzhardinge31ba9052004-01-16 02:15:23 +00005953 /* Applications never expect to see this, so we should either
5954 restart the syscall or fail it with EINTR, depending on what
5955 our caller wants. Generally they'll want to restart, but if
5956 client set the signal state to not restart, then we fail with
5957 EINTR. Either way, ERESTARTSYS means the syscall made no
5958 progress, and so can be failed or restarted without
5959 consequence. */
5960 if (0)
5961 VG_(printf)("syscall %d returned ERESTARTSYS; restart=%d\n",
5962 syscallno, restart);
5963
5964 if (restart) {
5965 restarted = True;
nethercote85cdd342004-08-01 22:36:40 +00005966 restart_syscall(tid);
fitzhardinge31ba9052004-01-16 02:15:23 +00005967 } else
nethercotea4670f62004-08-23 16:39:42 +00005968 res = -VKI_EINTR;
fitzhardinge31ba9052004-01-16 02:15:23 +00005969 }
5970
5971 if (!restarted) {
thughesbaa46e52004-07-29 17:44:23 +00005972 if (sys->after != NULL &&
nethercote427e9512004-08-23 16:36:09 +00005973 ((tst->sys_flags & PostOnFail) != 0 || !VG_(is_kerror)(res)))
fitzhardinge31ba9052004-01-16 02:15:23 +00005974 (sys->after)(tst->tid, tst);
5975
5976 /* Do any post-syscall actions
5977
5978 NOTE: this is only called if the syscall completed. If the
5979 syscall was restarted, then it will call the Tool's
5980 pre_syscall again, without calling post_syscall (ie, more
5981 pre's than post's)
5982 */
5983 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00005984 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00005985 TL_(post_syscall)(tid, syscallno, res);
njn4be0a692004-11-22 18:10:36 +00005986 VGP_POPCC(VgpToolSysWrap);
fitzhardinge31ba9052004-01-16 02:15:23 +00005987 }
fitzhardingee1c06d82003-10-30 07:21:44 +00005988 }
5989
jsgf855d93d2003-10-13 22:26:55 +00005990 tst->status = VgTs_Runnable; /* runnable again */
fitzhardinge31ba9052004-01-16 02:15:23 +00005991 tst->syscallno = -1; /* no current syscall */
sewardj2e93c502002-04-12 11:12:52 +00005992
njn25e49d8e72002-09-23 09:36:25 +00005993 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00005994}
5995
nethercote427e9512004-08-23 16:36:09 +00005996#undef SYSNO
5997#undef res
5998#undef arg1
5999#undef arg2
6000#undef arg3
6001#undef arg4
6002#undef arg5
6003#undef arg6
6004
sewardjde4a1d02002-03-22 01:27:54 +00006005/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00006006/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00006007/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00006008