blob: 8894254d9b064df6578ff72714584370fbf2ef1b [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njn87ef6a62003-08-14 15:23:55 +00003/*--- Handle system calls. vg_syscalls.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
njn53612422005-03-12 16:22:54 +000010 Copyright (C) 2000-2005 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
nethercotef1e5e152004-09-01 23:58:16 +000031#include "core.h"
njnd01fef72005-03-25 23:35:48 +000032#include "pub_core_stacktrace.h"
sewardj55f9d1a2005-04-25 11:11:44 +000033#include "pub_core_aspacemgr.h"
34
sewardjde4a1d02002-03-22 01:27:54 +000035
njn25e49d8e72002-09-23 09:36:25 +000036/* All system calls are channelled through here, doing two things:
sewardjde4a1d02002-03-22 01:27:54 +000037
nethercote4fa681f2004-11-08 17:51:39 +000038 * notify the tool of the events (mem/reg reads, writes) happening
sewardjde4a1d02002-03-22 01:27:54 +000039
40 * perform the syscall, usually by passing it along to the kernel
jsgf855d93d2003-10-13 22:26:55 +000041 unmodified.
sewardjde4a1d02002-03-22 01:27:54 +000042
jsgf855d93d2003-10-13 22:26:55 +000043 A magical piece of assembly code, VG_(do_syscall)(), in vg_syscall.S
sewardjde4a1d02002-03-22 01:27:54 +000044 does the tricky bit of passing a syscall to the kernel, whilst
45 having the simulator retain control.
46*/
47
jsgf855d93d2003-10-13 22:26:55 +000048/* ---------------------------------------------------------------------
49 A simple atfork() facility for Valgrind's internal use
50 ------------------------------------------------------------------ */
51
52struct atfork {
53 vg_atfork_t pre;
54 vg_atfork_t parent;
55 vg_atfork_t child;
56};
57
58#define VG_MAX_ATFORK 10
59
60static struct atfork atforks[VG_MAX_ATFORK];
61static Int n_atfork;
62
63void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
64{
65 Int i;
66
67 for(i = 0; i < n_atfork; i++) {
68 if (atforks[i].pre == pre &&
69 atforks[i].parent == parent &&
70 atforks[i].child == child)
71 return;
72 }
73
74 if (n_atfork >= VG_MAX_ATFORK)
75 VG_(core_panic)("Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
76
77 atforks[n_atfork].pre = pre;
78 atforks[n_atfork].parent = parent;
79 atforks[n_atfork].child = child;
80
81 n_atfork++;
82}
83
sewardjb5f6f512005-03-10 23:59:00 +000084void VG_(do_atfork_pre)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000085{
86 Int i;
87
88 for(i = 0; i < n_atfork; i++)
89 if (atforks[i].pre != NULL)
90 (*atforks[i].pre)(tid);
91}
92
sewardjb5f6f512005-03-10 23:59:00 +000093void VG_(do_atfork_parent)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +000094{
95 Int i;
96
97 for(i = 0; i < n_atfork; i++)
98 if (atforks[i].parent != NULL)
99 (*atforks[i].parent)(tid);
100}
101
sewardjb5f6f512005-03-10 23:59:00 +0000102void VG_(do_atfork_child)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +0000103{
104 Int i;
105
106 for(i = 0; i < n_atfork; i++)
107 if (atforks[i].child != NULL)
108 (*atforks[i].child)(tid);
109}
110
fitzhardinge1a303042003-12-22 08:48:50 +0000111/* return true if address range entirely contained within client
112 address space */
nethercote8ff888f2004-11-17 17:11:45 +0000113Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
114 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +0000115{
116 Addr end = start+size;
117 Addr cl_base = VG_(client_base);
118 Bool ret;
119
120 if (size == 0)
121 return True;
122
sewardj16063e62005-03-15 23:29:13 +0000123 if (0 && cl_base < 0x10000)
fitzhardinge1a303042003-12-22 08:48:50 +0000124 cl_base = 0x10000;
125
126 ret =
127 (end >= start) &&
128 start >= cl_base && start < VG_(client_end) &&
129 (end <= VG_(client_end));
130
131 if (0)
132 VG_(printf)("%s: test=%p-%p client=%p-%p ret=%d\n",
nethercote1543adf2004-10-25 15:43:21 +0000133 syscallname, start, end, cl_base, VG_(client_end), ret);
fitzhardinge1a303042003-12-22 08:48:50 +0000134
nethercote1543adf2004-10-25 15:43:21 +0000135 if (!ret && syscallname != NULL) {
fitzhardinge1a303042003-12-22 08:48:50 +0000136 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried to modify addresses %p-%p",
nethercote1543adf2004-10-25 15:43:21 +0000137 syscallname, start, end);
fitzhardinge1a303042003-12-22 08:48:50 +0000138
139 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000140 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge1a303042003-12-22 08:48:50 +0000141 }
142 }
143
144 return ret;
145}
146
njn25e49d8e72002-09-23 09:36:25 +0000147/* ---------------------------------------------------------------------
nethercote27ea8bc2004-07-10 17:21:14 +0000148 Doing mmap, mremap
njn25e49d8e72002-09-23 09:36:25 +0000149 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000150
njn25e49d8e72002-09-23 09:36:25 +0000151// Nb: this isn't done as precisely as possible, but it seems that programs
152// are usually sufficiently well-behaved that the more obscure corner cases
153// aren't important. Various comments in the few functions below give more
154// details... njn 2002-Sep-17
155
156/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
157 munmap, mprotect (and mremap??) work at the page level. So addresses
158 and lengths must be adjusted for this. */
159
160/* Mash around start and length so that the area exactly covers
161 an integral number of pages. If we don't do that, memcheck's
162 idea of addressible memory diverges from that of the
163 kernel's, which causes the leak detector to crash. */
164static
nethercote928a5f72004-11-03 18:10:37 +0000165void mash_addr_and_len( Addr* a, SizeT* len)
sewardjde4a1d02002-03-22 01:27:54 +0000166{
fitzhardinge98abfc72003-12-16 02:05:15 +0000167 Addr ra;
168
169 ra = PGROUNDDN(*a);
170 *len = PGROUNDUP(*a + *len) - ra;
171 *a = ra;
sewardjde4a1d02002-03-22 01:27:54 +0000172}
173
174static
nethercote928a5f72004-11-03 18:10:37 +0000175void mmap_segment ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, ULong offset )
sewardjde4a1d02002-03-22 01:27:54 +0000176{
sewardj40f8ebe2002-10-23 21:46:13 +0000177 Bool rr, ww, xx;
fitzhardinge98abfc72003-12-16 02:05:15 +0000178 UInt flags;
njn25e49d8e72002-09-23 09:36:25 +0000179
fitzhardinge98abfc72003-12-16 02:05:15 +0000180 flags = SF_MMAP;
181
182 if (mm_flags & VKI_MAP_FIXED)
183 flags |= SF_FIXED;
184 if (!(mm_flags & VKI_MAP_PRIVATE))
185 flags |= SF_SHARED;
186
187 if (fd != -1)
188 flags |= SF_FILE;
189
190 VG_(map_fd_segment)(a, len, prot, flags, fd, offset, NULL);
njn25e49d8e72002-09-23 09:36:25 +0000191
fitzhardinge1a303042003-12-22 08:48:50 +0000192 rr = prot & VKI_PROT_READ;
193 ww = prot & VKI_PROT_WRITE;
194 xx = prot & VKI_PROT_EXEC;
njn25e49d8e72002-09-23 09:36:25 +0000195
sewardj40f8ebe2002-10-23 21:46:13 +0000196 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
sewardjde4a1d02002-03-22 01:27:54 +0000197}
198
njn25e49d8e72002-09-23 09:36:25 +0000199static
nethercote928a5f72004-11-03 18:10:37 +0000200Addr mremap_segment ( Addr old_addr, SizeT old_size,
201 Addr new_addr, SizeT new_size,
fitzhardinge1a303042003-12-22 08:48:50 +0000202 UInt flags, ThreadId tid)
njn25e49d8e72002-09-23 09:36:25 +0000203{
fitzhardinge1a303042003-12-22 08:48:50 +0000204 Addr ret;
205 Segment *seg, *next;
njn25e49d8e72002-09-23 09:36:25 +0000206
fitzhardinge1a303042003-12-22 08:48:50 +0000207 old_size = PGROUNDUP(old_size);
208 new_size = PGROUNDUP(new_size);
njn25e49d8e72002-09-23 09:36:25 +0000209
fitzhardinge1a303042003-12-22 08:48:50 +0000210 if (PGROUNDDN(old_addr) != old_addr)
211 return -VKI_EINVAL;
212
nethercote8ff888f2004-11-17 17:11:45 +0000213 if (!VG_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
fitzhardinge1a303042003-12-22 08:48:50 +0000214 return -VKI_EFAULT;
215
216 /* fixed at the current address means we don't move it */
217 if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
218 flags &= ~(VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE);
219
220 if (flags & VKI_MREMAP_FIXED) {
221 if (PGROUNDDN(new_addr) != new_addr)
222 return -VKI_EINVAL;
223
nethercote8ff888f2004-11-17 17:11:45 +0000224 if (!VG_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
fitzhardinge1a303042003-12-22 08:48:50 +0000225 return -VKI_ENOMEM;
226
227 /* check for overlaps */
228 if ((old_addr < (new_addr+new_size) &&
229 (old_addr+old_size) > new_addr) ||
230 (new_addr < (old_addr+new_size) &&
231 (new_addr+new_size) > old_addr))
232 return -VKI_EINVAL;
njn25e49d8e72002-09-23 09:36:25 +0000233 }
fitzhardinge1a303042003-12-22 08:48:50 +0000234
235 /* Do nothing */
236 if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
237 return old_addr;
238
239 seg = VG_(find_segment)(old_addr);
240
241 /* range must be contained within segment */
242 if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
243 return -VKI_EINVAL;
244
sewardj1024cf72005-02-28 14:39:21 +0000245 next = VG_(find_segment_above_mapped)(old_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000246
247 if (0)
248 VG_(printf)("mremap: old_addr+new_size=%p next->addr=%p flags=%d\n",
249 old_addr+new_size, next->addr, flags);
250
251 if ((flags & VKI_MREMAP_FIXED) ||
252 (next != NULL && (old_addr+new_size) > next->addr)) {
253 /* we're moving the block */
254 Addr a;
255
256 if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
257 return -VKI_ENOMEM; /* not allowed to move */
258
259 if ((flags & VKI_MREMAP_FIXED) == 0)
260 new_addr = 0;
261
262 a = VG_(find_map_space)(new_addr, new_size, True);
263
264 if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
265 return -VKI_ENOMEM; /* didn't find the place we wanted */
266
267 new_addr = a;
268 ret = a;
269
270 /* we've nailed down the location */
271 flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
272
njnca6fef02004-11-29 16:49:18 +0000273 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
274 flags, new_addr);
fitzhardinge1a303042003-12-22 08:48:50 +0000275
276 if (ret != new_addr) {
277 vg_assert(VG_(is_kerror)(ret));
278 return ret;
279 }
280
281 VG_TRACK(copy_mem_remap, old_addr, new_addr,
282 (old_size < new_size) ? old_size : new_size);
283
284 if (new_size > old_size)
285 VG_TRACK(new_mem_mmap, new_addr+old_size, new_size-old_size,
286 seg->prot & VKI_PROT_READ,
287 seg->prot & VKI_PROT_WRITE,
288 seg->prot & VKI_PROT_EXEC);
289 VG_TRACK(die_mem_munmap, old_addr, old_size);
290
291 VG_(map_file_segment)(new_addr, new_size,
292 seg->prot,
293 seg->flags,
294 seg->dev, seg->ino,
295 seg->offset, seg->filename);
296
297 VG_(munmap)((void *)old_addr, old_size);
298 } else {
299 /* staying in place */
300 ret = old_addr;
301
302 if (new_size < old_size) {
303 VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
304 VG_(munmap)((void *)(old_addr+new_size), old_size-new_size);
305 } else {
306 /* we've nailed down the location */
307 flags &= ~VKI_MREMAP_MAYMOVE;
308
309 if (0)
310 VG_(printf)("mremap: old_addr=%p old_size=%d new_size=%d flags=%d\n",
311 old_addr, old_size, new_size, flags);
312
njnca6fef02004-11-29 16:49:18 +0000313 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size,
314 flags, 0);
fitzhardinge1a303042003-12-22 08:48:50 +0000315
316 if (ret != old_addr)
317 return ret;
318
319 VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
320 seg->prot & VKI_PROT_READ,
321 seg->prot & VKI_PROT_WRITE,
322 seg->prot & VKI_PROT_EXEC);
323
324 VG_(map_file_segment)(old_addr+old_size, new_size-old_size,
325 seg->prot,
326 seg->flags,
327 seg->dev, seg->ino,
328 seg->offset, seg->filename);
329 }
330 }
331
332 return ret;
sewardjde4a1d02002-03-22 01:27:54 +0000333}
334
335
336/* Is this a Linux kernel error return value? */
337/* From:
338 http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
339 linux/i386/sysdep.h?
340 rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
341
njn25e49d8e72002-09-23 09:36:25 +0000342 \begin{quote}:
sewardjde4a1d02002-03-22 01:27:54 +0000343
344 Linux uses a negative return value to indicate syscall errors,
345 unlike most Unices, which use the condition codes' carry flag.
346
347 Since version 2.1 the return value of a system call might be
348 negative even if the call succeeded. E.g., the `lseek' system call
349 might return a large offset. Therefore we must not anymore test
350 for < 0, but test for a real error by making sure the value in %eax
351 is a real error number. Linus said he will make sure the no syscall
daywalker7e73e5f2003-07-04 16:18:15 +0000352 returns a value in -1 .. -4095 as a valid result so we can safely
sewardjde4a1d02002-03-22 01:27:54 +0000353 test with -4095.
354
355 END QUOTE
356*/
nethercoteada0d2b2004-11-04 19:10:43 +0000357Bool VG_(is_kerror) ( Word res )
sewardjde4a1d02002-03-22 01:27:54 +0000358{
359 if (res >= -4095 && res <= -1)
360 return True;
361 else
362 return False;
363}
364
rjwalshf5f536f2003-11-17 17:45:00 +0000365/* One of these is allocated for each open file descriptor. */
366
367typedef struct OpenFd
368{
369 Int fd; /* The file descriptor */
370 Char *pathname; /* NULL if not a regular file or unknown */
371 ExeContext *where; /* NULL if inherited from parent */
372 struct OpenFd *next, *prev;
373} OpenFd;
374
375/* List of allocated file descriptors. */
376
377static OpenFd *allocated_fds;
378
379/* Count of open file descriptors. */
380
381static int fd_count = 0;
382
rjwalshf5f536f2003-11-17 17:45:00 +0000383
sewardj79048ce2005-02-18 08:28:32 +0000384
385/* Given a file descriptor, attempt to deduce its filename. To do
386 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
387 or if it doesn't exist, we just return NULL. The caller is
388 responsible for copying the contents of buf out immediately. */
389
390static HChar resolve_filename_buf[VKI_PATH_MAX];
391
392HChar* VG_(resolve_filename_nodup) ( Int fd )
rjwalshf5f536f2003-11-17 17:45:00 +0000393{
sewardj79048ce2005-02-18 08:28:32 +0000394 HChar tmp[64];
rjwalshf5f536f2003-11-17 17:45:00 +0000395
396 VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
sewardj79048ce2005-02-18 08:28:32 +0000397 VG_(memset)(resolve_filename_buf, 0, VKI_PATH_MAX);
rjwalshf5f536f2003-11-17 17:45:00 +0000398
sewardj79048ce2005-02-18 08:28:32 +0000399 if (VG_(readlink)(tmp, resolve_filename_buf, VKI_PATH_MAX) == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000400 return NULL;
401
sewardj79048ce2005-02-18 08:28:32 +0000402 return (resolve_filename_buf[0] == '/')
403 ? resolve_filename_buf
404 : NULL;
405}
406
407/* Same as resolve_filename_nodup, except that the result is copied
408 into new memory which the caller is responsible for freeing. */
409
410HChar* VG_(resolve_filename) ( Int fd )
411{
412 HChar* transient = VG_(resolve_filename_nodup)(fd);
413 return transient
414 ? VG_(arena_strdup)(VG_AR_CORE, transient)
415 : NULL;
rjwalshf5f536f2003-11-17 17:45:00 +0000416}
417
418
419/* Note the fact that a file descriptor was just closed. */
420
421static
njnc6168192004-11-29 13:54:10 +0000422void record_fd_close(ThreadId tid, Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000423{
424 OpenFd *i = allocated_fds;
425
thughesad1c9562004-06-26 11:27:52 +0000426 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000427 return; /* Valgrind internal */
428
rjwalshf5f536f2003-11-17 17:45:00 +0000429 while(i) {
430 if(i->fd == fd) {
431 if(i->prev)
432 i->prev->next = i->next;
433 else
434 allocated_fds = i->next;
435 if(i->next)
436 i->next->prev = i->prev;
437 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000438 VG_(arena_free) (VG_AR_CORE, i->pathname);
439 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000440 fd_count--;
441 break;
442 }
443 i = i->next;
444 }
445}
446
447/* Note the fact that a file descriptor was just opened. If the
448 tid is -1, this indicates an inherited fd. If the pathname is NULL,
449 this either indicates a non-standard file (i.e. a pipe or socket or
450 some such thing) or that we don't know the filename. If the fd is
451 already open, then we're probably doing a dup2() to an existing fd,
452 so just overwrite the existing one. */
453
njnc6168192004-11-29 13:54:10 +0000454void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000455{
456 OpenFd *i;
457
thughesad1c9562004-06-26 11:27:52 +0000458 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000459 return; /* Valgrind internal */
460
rjwalshf5f536f2003-11-17 17:45:00 +0000461 /* Check to see if this fd is already open. */
462 i = allocated_fds;
463 while (i) {
464 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000465 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000466 break;
467 }
468 i = i->next;
469 }
470
471 /* Not already one: allocate an OpenFd */
472 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000473 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000474
475 i->prev = NULL;
476 i->next = allocated_fds;
477 if(allocated_fds) allocated_fds->prev = i;
478 allocated_fds = i;
479 fd_count++;
480 }
481
482 i->fd = fd;
483 i->pathname = pathname;
njnd01fef72005-03-25 23:35:48 +0000484 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
rjwalshf5f536f2003-11-17 17:45:00 +0000485}
486
487static
nethercote73b526f2004-10-31 18:48:21 +0000488Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000489{
nethercote73b526f2004-10-31 18:48:21 +0000490 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000491 VG_(sprintf)(name, "<unknown>");
492 } else {
493 VG_(sprintf)(name, "%s", sa->sun_path);
494 }
495
496 return name;
497}
498
499static
nethercote73b526f2004-10-31 18:48:21 +0000500Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000501{
nethercote73b526f2004-10-31 18:48:21 +0000502 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000503 VG_(sprintf)(name, "<unknown>");
504 } else {
505 UInt addr = sa->sin_addr.s_addr;
506
507 if (addr == 0) {
508 VG_(sprintf)(name, "<unbound>");
509 } else {
510 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
511 addr & 0xFF, (addr>>8) & 0xFF,
512 (addr>>16) & 0xFF, (addr>>24) & 0xFF,
nethercote73b526f2004-10-31 18:48:21 +0000513 vki_ntohs(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000514 }
515 }
516
517 return name;
518}
519
520
521/*
522 * Try get some details about a socket.
523 */
524
525static void
526getsockdetails(int fd)
527{
528 union u {
nethercote73b526f2004-10-31 18:48:21 +0000529 struct vki_sockaddr a;
530 struct vki_sockaddr_in in;
531 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000532 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000533 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000534
535 llen = sizeof(laddr);
536 VG_(memset)(&laddr, 0, llen);
537
538 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
539 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000540 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000541 static char lname[32];
542 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000543 struct vki_sockaddr_in paddr;
544 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000545
546 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
547 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
548 inet2name(&(laddr.in), llen, lname),
549 inet2name(&paddr, plen, pname));
550 } else {
551 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
552 fd, inet2name(&(laddr.in), llen, lname));
553 }
554 return;
555 }
nethercote73b526f2004-10-31 18:48:21 +0000556 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000557 static char lname[256];
558 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
559 unix2name(&(laddr.un), llen, lname));
560 return;
561 }
562 default:
563 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
564 laddr.a.sa_family, fd);
565 return;
566 }
567 }
568
569 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
570}
571
572
nethercote3a42fb82004-08-03 18:08:50 +0000573/* Dump out a summary, and a more detailed list, of open file descriptors. */
574void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000575{
576 OpenFd *i = allocated_fds;
577
nethercote3a42fb82004-08-03 18:08:50 +0000578 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000579
580 while(i) {
581 if(i->pathname) {
582 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
583 i->pathname);
584 } else {
585 int val;
nethercote73b526f2004-10-31 18:48:21 +0000586 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000587
nethercote73b526f2004-10-31 18:48:21 +0000588 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000589 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
590 } else {
591 getsockdetails(i->fd);
592 }
593 }
594
595 if(i->where) {
596 VG_(pp_ExeContext)(i->where);
597 VG_(message)(Vg_UserMsg, "");
598 } else {
599 VG_(message)(Vg_UserMsg, " <inherited from parent>");
600 VG_(message)(Vg_UserMsg, "");
601 }
602
603 i = i->next;
604 }
605
606 VG_(message)(Vg_UserMsg, "");
607}
608
609/* If /proc/self/fd doesn't exist for some weird reason (like you've
610 got a kernel that doesn't have /proc support compiled in), then we
611 need to find out what file descriptors we inherited from our parent
612 process the hard way - by checking each fd in turn. */
613
614static
615void do_hacky_preopened()
616{
617 struct vki_rlimit lim;
618 unsigned int count;
619 int i;
620
nethercote620154f2004-11-12 21:21:07 +0000621 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000622 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
623 an arbitrarily high number. 1024 happens to be the limit in
624 the 2.4 kernels. */
625 count = 1024;
626 } else {
627 count = lim.rlim_cur;
628 }
629
630 for (i = 0; i < count; i++)
631 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
nethercote3d5e9102004-11-17 18:22:38 +0000632 VG_(record_fd_open)(-1, i, NULL);
rjwalshf5f536f2003-11-17 17:45:00 +0000633}
634
635/* Initialize the list of open file descriptors with the file descriptors
636 we inherited from out parent process. */
637
638void VG_(init_preopened_fds)()
639{
640 int f, ret;
641 struct vki_dirent d;
642
643 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
644 if(f == -1) {
645 do_hacky_preopened();
646 return;
647 }
648
649 while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
650 if(ret == -1)
651 goto out;
652
653 if(VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
654 int fno = VG_(atoll)(d.d_name);
655
656 if(fno != f)
657 if(VG_(clo_track_fds))
nethercote3d5e9102004-11-17 18:22:38 +0000658 VG_(record_fd_open)(-1, fno, VG_(resolve_filename)(fno));
rjwalshf5f536f2003-11-17 17:45:00 +0000659 }
660
661 VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
662 }
663
664out:
665 VG_(close)(f);
666}
667
sewardjde4a1d02002-03-22 01:27:54 +0000668static
sewardj8c824512002-04-14 04:16:48 +0000669Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000670{
671 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000672 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000673 VG_(strcpy) ( result, s1 );
674 VG_(strcat) ( result, s2 );
675 return result;
676}
677
678static
jsgf855d93d2003-10-13 22:26:55 +0000679void pre_mem_read_sendmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000680 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000681{
njn9f46df62005-03-13 18:11:44 +0000682 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000683 PRE_MEM_READ( outmsg, base, size );
njn25e49d8e72002-09-23 09:36:25 +0000684
njn9f46df62005-03-13 18:11:44 +0000685 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000686}
687
688static
jsgf855d93d2003-10-13 22:26:55 +0000689void pre_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000690 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000691{
njn9f46df62005-03-13 18:11:44 +0000692 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000693 PRE_MEM_WRITE( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000694 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000695}
696
697static
njn72718642003-07-24 08:45:32 +0000698void post_mem_write_recvmsg ( ThreadId tid,
nethercote928a5f72004-11-03 18:10:37 +0000699 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000700{
nethercoteef0c7662004-11-06 15:38:43 +0000701 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000702}
703
704static
sewardj8c824512002-04-14 04:16:48 +0000705void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000706 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000707 struct vki_msghdr *msg,
nethercote928a5f72004-11-03 18:10:37 +0000708 void (*foreach_func)( ThreadId, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000709 )
sewardjde4a1d02002-03-22 01:27:54 +0000710{
711 if ( !msg )
712 return;
713
nethercote73b526f2004-10-31 18:48:21 +0000714 foreach_func ( tid, "(msg)", (Addr)msg, sizeof( struct vki_msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000715
716 if ( msg->msg_name )
njn72718642003-07-24 08:45:32 +0000717 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000718 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000719 (Addr)msg->msg_name, msg->msg_namelen );
720
721 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000722 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000723 UInt i;
724
njn72718642003-07-24 08:45:32 +0000725 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000726 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000727 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000728
729 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
njn72718642003-07-24 08:45:32 +0000730 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000731 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000732 (Addr)iov->iov_base, iov->iov_len );
733 }
734
735 if ( msg->msg_control )
njn72718642003-07-24 08:45:32 +0000736 foreach_func ( tid,
sewardj8c824512002-04-14 04:16:48 +0000737 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000738 (Addr)msg->msg_control, msg->msg_controllen );
739}
740
sewardjb5f6f512005-03-10 23:59:00 +0000741static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000742{
nethercote73b526f2004-10-31 18:48:21 +0000743 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000744
745 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000746 if (cm->cmsg_level == VKI_SOL_SOCKET &&
747 cm->cmsg_type == VKI_SCM_RIGHTS ) {
748 int *fds = (int *) VKI_CMSG_DATA(cm);
749 int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000750 / sizeof(int);
751 int i;
752
753 for (i = 0; i < fdc; i++)
754 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000755 // XXX: must we check the range on these fds with
nethercote3d5e9102004-11-17 18:22:38 +0000756 // VG_(fd_allowed)()?
757 VG_(record_fd_open) (tid, fds[i], VG_(resolve_filename)(fds[i]));
rjwalshf5f536f2003-11-17 17:45:00 +0000758 }
759
nethercote73b526f2004-10-31 18:48:21 +0000760 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000761 }
762}
763
sewardjc483e8f2002-05-03 21:01:35 +0000764static
jsgf855d93d2003-10-13 22:26:55 +0000765void pre_mem_read_sockaddr ( ThreadId tid,
766 Char *description,
nethercote73b526f2004-10-31 18:48:21 +0000767 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000768{
sewardjff7c1ab2003-02-24 21:55:34 +0000769 Char *outmsg;
770
771 /* NULL/zero-length sockaddrs are legal */
772 if ( sa == NULL || salen == 0 ) return;
773
njn9f46df62005-03-13 18:11:44 +0000774 outmsg = VG_(arena_malloc) ( VG_AR_CORE,
nethercote73b526f2004-10-31 18:48:21 +0000775 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000776
777 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000778 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000779
sewardjc483e8f2002-05-03 21:01:35 +0000780 switch (sa->sa_family) {
781
nethercote73b526f2004-10-31 18:48:21 +0000782 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000783 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000784 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000785 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000786 break;
787
nethercote73b526f2004-10-31 18:48:21 +0000788 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000789 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000790 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000791 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
792 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000793 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000794 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000795 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
796 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000797 break;
798
nethercote73b526f2004-10-31 18:48:21 +0000799 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000800 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000801 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000802 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
803 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000804 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000805 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000806 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
807 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000808 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
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_addr,
811 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000812 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
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_scope_id,
815 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000816 break;
817
818 default:
819 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000820 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000821 break;
822 }
823
njn9f46df62005-03-13 18:11:44 +0000824 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000825}
826
njn25e49d8e72002-09-23 09:36:25 +0000827/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000828static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000829{
830 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000831 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000832 if (a_p == NULL)
833 return 0;
834 else
835 return *a_p;
836}
837
njn25e49d8e72002-09-23 09:36:25 +0000838static
njn72718642003-07-24 08:45:32 +0000839void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000840 Char* buf_s, Char* buflen_s )
841{
fitzhardinge98abfc72003-12-16 02:05:15 +0000842 if (VG_(defined_pre_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000843 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000844 if (buflen_in > 0) {
njncf45fd42004-11-24 16:30:22 +0000845 TL_(pre_mem_write) ( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000846 }
847 }
848}
849
850static
njn72718642003-07-24 08:45:32 +0000851void buf_and_len_post_check( ThreadId tid, Int res,
njn25e49d8e72002-09-23 09:36:25 +0000852 Addr buf_p, Addr buflen_p, Char* s )
853{
fitzhardinge98abfc72003-12-16 02:05:15 +0000854 if (!VG_(is_kerror)(res) && VG_(defined_post_mem_write)()) {
njn72718642003-07-24 08:45:32 +0000855 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000856 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njncf45fd42004-11-24 16:30:22 +0000857 TL_(post_mem_write) ( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000858 }
859 }
860}
861
862/* ---------------------------------------------------------------------
863 Data seg end, for brk()
864 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000865
fitzhardinge98abfc72003-12-16 02:05:15 +0000866static Addr do_brk(Addr newbrk)
njn25e49d8e72002-09-23 09:36:25 +0000867{
fitzhardinge98abfc72003-12-16 02:05:15 +0000868 Addr ret = VG_(brk_limit);
sewardje517b802005-02-16 01:58:51 +0000869 static const Bool debug = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000870 Segment *seg;
nethercotece471262004-08-25 13:43:44 +0000871 Addr current, newaddr;
872
fitzhardinge98abfc72003-12-16 02:05:15 +0000873
874 if (debug)
sewardj548be6d2005-02-16 01:31:37 +0000875 VG_(printf)("\ndo_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
fitzhardinge98abfc72003-12-16 02:05:15 +0000876 VG_(brk_base), VG_(brk_limit), newbrk);
877
sewardj79048ce2005-02-18 08:28:32 +0000878# if 0
sewardje517b802005-02-16 01:58:51 +0000879 if (0) show_segments("in_brk");
sewardj79048ce2005-02-18 08:28:32 +0000880# endif
sewardj548be6d2005-02-16 01:31:37 +0000881
fitzhardinge98abfc72003-12-16 02:05:15 +0000882 if (newbrk < VG_(brk_base) || newbrk >= VG_(client_end))
883 return VG_(brk_limit);
884
885 /* brk isn't allowed to grow over anything else */
sewardj548be6d2005-02-16 01:31:37 +0000886 seg = VG_(find_segment)(VG_(brk_limit) -1);
fitzhardinge98abfc72003-12-16 02:05:15 +0000887
888 vg_assert(seg != NULL);
889
njn25e49d8e72002-09-23 09:36:25 +0000890 if (0)
fitzhardinge98abfc72003-12-16 02:05:15 +0000891 VG_(printf)("brk_limit=%p seg->addr=%p seg->end=%p\n",
892 VG_(brk_limit), seg->addr, seg->addr+seg->len);
sewardj79048ce2005-02-18 08:28:32 +0000893 vg_assert(VG_(brk_limit) >= seg->addr && VG_(brk_limit)
894 <= (seg->addr + seg->len));
fitzhardinge98abfc72003-12-16 02:05:15 +0000895
sewardj79048ce2005-02-18 08:28:32 +0000896 seg = VG_(find_segment_above_mapped)(VG_(brk_limit)-1);
897 if (0 && seg)
898 VG_(printf)("NEXT addr = %p\n", seg->addr);
fitzhardinge98abfc72003-12-16 02:05:15 +0000899 if (seg != NULL && newbrk > seg->addr)
900 return VG_(brk_limit);
901
nethercotece471262004-08-25 13:43:44 +0000902 current = PGROUNDUP(VG_(brk_limit));
903 newaddr = PGROUNDUP(newbrk);
904 if (newaddr != current) {
fitzhardinge98abfc72003-12-16 02:05:15 +0000905
906 /* new brk in a new page - fix the mappings */
907 if (newbrk > VG_(brk_limit)) {
908
909 if (debug)
910 VG_(printf)(" extending brk: current=%p newaddr=%p delta=%d\n",
911 current, newaddr, newaddr-current);
912
913 if (newaddr == current) {
914 ret = newbrk;
nethercoteb4250ae2004-07-10 16:50:09 +0000915 } else if ((void*)-1 != VG_(mmap)((void*)current, newaddr-current,
916 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
917 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MAP_CLIENT,
918 SF_FIXED|SF_BRK, -1, 0))
919 {
fitzhardinge98abfc72003-12-16 02:05:15 +0000920 ret = newbrk;
921 }
922 } else {
923 vg_assert(newbrk < VG_(brk_limit));
924
925 if (debug)
926 VG_(printf)(" shrinking brk: current=%p newaddr=%p delta=%d\n",
927 current, newaddr, current-newaddr);
928
929 if (newaddr != current) {
nethercotee567e702004-07-10 17:49:17 +0000930 int res = VG_(munmap)((void *)newaddr, current - newaddr);
931 vg_assert(0 == res);
fitzhardinge98abfc72003-12-16 02:05:15 +0000932 }
933 ret = newbrk;
934 }
935 } else
936 ret = newbrk;
937
938 VG_(brk_limit) = ret;
939
940 return ret;
941}
942
943
njn25e49d8e72002-09-23 09:36:25 +0000944/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +0000945 Vet file descriptors for sanity
946 ------------------------------------------------------------------ */
947
948/* Return true if we're allowed to use or create this fd */
nethercote3d5e9102004-11-17 18:22:38 +0000949Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft)
jsgf855d93d2003-10-13 22:26:55 +0000950{
thughesad1c9562004-06-26 11:27:52 +0000951 if (fd < 0 || fd >= VG_(fd_hard_limit) || fd == VG_(clo_log_fd)) {
jsewardd9320a42003-12-12 06:40:05 +0000952 VG_(message)(Vg_UserMsg,
953 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +0000954 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +0000955 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +0000956 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +0000957 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +0000958 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +0000959 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
jsgf855d93d2003-10-13 22:26:55 +0000960 }
961 return False;
962 }
thughesad1c9562004-06-26 11:27:52 +0000963 else if (soft && fd >= VG_(fd_soft_limit)) {
964 return False;
965 }
jsgf855d93d2003-10-13 22:26:55 +0000966 return True;
967}
968
969
970/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +0000971 Deal with a bunch of socket-related syscalls
972 ------------------------------------------------------------------ */
973
974/* ------ */
975
sewardj987a8eb2005-03-01 19:00:30 +0000976void
977VG_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +0000978 UWord arg0, UWord arg1,
979 UWord arg2, UWord arg3 )
980{
981 /* int socketpair(int d, int type, int protocol, int sv[2]); */
982 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
983 arg3, 2*sizeof(int) );
984}
985
sewardj987a8eb2005-03-01 19:00:30 +0000986UWord
987VG_(generic_POST_sys_socketpair) ( ThreadId tid,
988 UWord res,
989 UWord arg0, UWord arg1,
990 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +0000991{
992 UWord r = res;
993 Int fd1 = ((Int*)arg3)[0];
994 Int fd2 = ((Int*)arg3)[1];
995 POST_MEM_WRITE( arg3, 2*sizeof(int) );
996 if (!VG_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
997 !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
998 VG_(close)(fd1);
999 VG_(close)(fd2);
1000 r = -VKI_EMFILE;
1001 } else {
1002 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1003 if (VG_(clo_track_fds)) {
1004 VG_(record_fd_open)(tid, fd1, NULL);
1005 VG_(record_fd_open)(tid, fd2, NULL);
1006 }
1007 }
1008 return r;
1009}
1010
1011/* ------ */
1012
sewardj987a8eb2005-03-01 19:00:30 +00001013UWord
1014VG_(generic_POST_sys_socket) ( ThreadId tid, UWord res )
sewardj9efbbef2005-03-01 16:45:23 +00001015{
1016 UWord r = res;
1017 if (!VG_(fd_allowed)(res, "socket", tid, True)) {
1018 VG_(close)(res);
1019 r = -VKI_EMFILE;
1020 } else {
1021 if (VG_(clo_track_fds))
1022 VG_(record_fd_open)(tid, res, NULL);
1023 }
1024 return r;
1025}
1026
1027/* ------ */
1028
sewardj987a8eb2005-03-01 19:00:30 +00001029void
1030VG_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001031 UWord arg0, UWord arg1, UWord arg2 )
1032{
1033 /* int bind(int sockfd, struct sockaddr *my_addr,
1034 int addrlen); */
1035 pre_mem_read_sockaddr(
1036 tid, "socketcall.bind(my_addr.%s)",
1037 (struct vki_sockaddr *) arg1, arg2
1038 );
1039}
1040
1041/* ------ */
1042
sewardj987a8eb2005-03-01 19:00:30 +00001043void
1044VG_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001045 UWord arg0, UWord arg1, UWord arg2 )
1046{
1047 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1048 Addr addr_p = arg1;
1049 Addr addrlen_p = arg2;
1050 if (addr_p != (Addr)NULL)
1051 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
1052 "socketcall.accept(addr)",
1053 "socketcall.accept(addrlen_in)" );
1054}
1055
sewardj987a8eb2005-03-01 19:00:30 +00001056UWord
1057VG_(generic_POST_sys_accept) ( ThreadId tid,
1058 UWord res,
1059 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +00001060{
1061 UWord r = res;
1062 if (!VG_(fd_allowed)(res, "accept", tid, True)) {
1063 VG_(close)(res);
1064 r = -VKI_EMFILE;
1065 } else {
1066 Addr addr_p = arg1;
1067 Addr addrlen_p = arg2;
1068 if (addr_p != (Addr)NULL)
1069 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
1070 "socketcall.accept(addrlen_out)" );
1071 if (VG_(clo_track_fds))
1072 VG_(record_fd_open)(tid, res, NULL);
1073 }
1074 return r;
1075}
1076
1077/* ------ */
1078
sewardj987a8eb2005-03-01 19:00:30 +00001079void
1080VG_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001081 UWord arg0, UWord arg1, UWord arg2,
1082 UWord arg3, UWord arg4, UWord arg5 )
1083{
1084 /* int sendto(int s, const void *msg, int len,
1085 unsigned int flags,
1086 const struct sockaddr *to, int tolen); */
1087 PRE_MEM_READ( "socketcall.sendto(msg)",
1088 arg1, /* msg */
1089 arg2 /* len */ );
1090 pre_mem_read_sockaddr(
1091 tid, "socketcall.sendto(to.%s)",
1092 (struct vki_sockaddr *) arg4, arg5
1093 );
1094}
1095
1096/* ------ */
1097
sewardj987a8eb2005-03-01 19:00:30 +00001098void
1099VG_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001100 UWord arg0, UWord arg1, UWord arg2 )
1101{
1102 /* int send(int s, const void *msg, size_t len, int flags); */
1103 PRE_MEM_READ( "socketcall.send(msg)",
1104 arg1, /* msg */
1105 arg2 /* len */ );
1106
1107}
1108
1109/* ------ */
1110
sewardj987a8eb2005-03-01 19:00:30 +00001111void
1112VG_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001113 UWord arg0, UWord arg1, UWord arg2,
1114 UWord arg3, UWord arg4, UWord arg5 )
1115{
1116 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1117 struct sockaddr *from, int *fromlen); */
1118 Addr buf_p = arg1;
1119 Int len = arg2;
1120 Addr from_p = arg4;
1121 Addr fromlen_p = arg5;
1122 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1123 if (from_p != (Addr)NULL)
1124 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1125 "socketcall.recvfrom(from)",
1126 "socketcall.recvfrom(fromlen_in)" );
1127}
1128
sewardj987a8eb2005-03-01 19:00:30 +00001129void
1130VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001131 UWord res,
1132 UWord arg0, UWord arg1, UWord arg2,
1133 UWord arg3, UWord arg4, UWord arg5 )
1134{
1135 Addr buf_p = arg1;
1136 Int len = arg2;
1137 Addr from_p = arg4;
1138 Addr fromlen_p = arg5;
1139
1140 if (from_p != (Addr)NULL)
1141 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1142 "socketcall.recvfrom(fromlen_out)" );
1143 POST_MEM_WRITE( buf_p, len );
1144}
1145
1146/* ------ */
1147
sewardj987a8eb2005-03-01 19:00:30 +00001148void
1149VG_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001150 UWord arg0, UWord arg1, UWord arg2 )
1151{
1152 /* int recv(int s, void *buf, int len, unsigned int flags); */
1153 /* man 2 recv says:
1154 The recv call is normally used only on a connected socket
1155 (see connect(2)) and is identical to recvfrom with a NULL
1156 from parameter.
1157 */
1158 PRE_MEM_WRITE( "socketcall.recv(buf)",
1159 arg1, /* buf */
1160 arg2 /* len */ );
1161}
1162
sewardj987a8eb2005-03-01 19:00:30 +00001163void
1164VG_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001165 UWord res,
1166 UWord arg0, UWord arg1, UWord arg2 )
1167{
1168 if (res >= 0 && arg1 != 0) {
1169 POST_MEM_WRITE( arg1, /* buf */
1170 arg2 /* len */ );
1171 }
1172}
1173
1174/* ------ */
1175
sewardj987a8eb2005-03-01 19:00:30 +00001176void
1177VG_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001178 UWord arg0, UWord arg1, UWord arg2 )
1179{
1180 /* int connect(int sockfd,
1181 struct sockaddr *serv_addr, int addrlen ); */
1182 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1183 arg1, /* serv_addr */
1184 sizeof(vki_sa_family_t));
1185 pre_mem_read_sockaddr( tid,
1186 "socketcall.connect(serv_addr.%s)",
1187 (struct vki_sockaddr *) arg1, arg2);
1188}
1189
1190/* ------ */
1191
sewardj987a8eb2005-03-01 19:00:30 +00001192void
1193VG_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001194 UWord arg0, UWord arg1, UWord arg2,
1195 UWord arg3, UWord arg4 )
1196{
1197 /* int setsockopt(int s, int level, int optname,
1198 const void *optval, int optlen); */
1199 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1200 arg3, /* optval */
1201 arg4 /* optlen */ );
1202}
1203
1204/* ------ */
1205
sewardj987a8eb2005-03-01 19:00:30 +00001206void
1207VG_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001208 UWord arg0, UWord arg1, UWord arg2,
1209 UWord arg3, UWord arg4 )
1210{
1211 /* int getsockopt(int s, int level, int optname,
1212 void *optval, socklen_t *optlen); */
1213 Addr optval_p = arg3;
1214 Addr optlen_p = arg4;
1215 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
1216 if (optval_p != (Addr)NULL)
1217 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1218 "socketcall.getsockopt(optval)",
1219 "socketcall.getsockopt(optlen)" );
1220}
1221
sewardj987a8eb2005-03-01 19:00:30 +00001222void
1223VG_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001224 UWord res,
1225 UWord arg0, UWord arg1, UWord arg2,
1226 UWord arg3, UWord arg4 )
1227{
1228 Addr optval_p = arg3;
1229 Addr optlen_p = arg4;
1230 if (optval_p != (Addr)NULL)
1231 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1232 "socketcall.getsockopt(optlen_out)" );
1233}
1234
1235/* ------ */
1236
sewardj987a8eb2005-03-01 19:00:30 +00001237void
1238VG_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001239 UWord arg0, UWord arg1, UWord arg2 )
1240{
1241 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1242 Addr name_p = arg1;
1243 Addr namelen_p = arg2;
1244 /* Nb: name_p cannot be NULL */
1245 buf_and_len_pre_check ( tid, name_p, namelen_p,
1246 "socketcall.getsockname(name)",
1247 "socketcall.getsockname(namelen_in)" );
1248}
1249
sewardj987a8eb2005-03-01 19:00:30 +00001250void
1251VG_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001252 UWord res,
1253 UWord arg0, UWord arg1, UWord arg2 )
1254{
1255 Addr name_p = arg1;
1256 Addr namelen_p = arg2;
1257 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1258 "socketcall.getsockname(namelen_out)" );
1259}
1260
1261/* ------ */
1262
sewardj987a8eb2005-03-01 19:00:30 +00001263void
1264VG_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001265 UWord arg0, UWord arg1, UWord arg2 )
1266{
1267 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1268 Addr name_p = arg1;
1269 Addr namelen_p = arg2;
1270 /* Nb: name_p cannot be NULL */
1271 buf_and_len_pre_check ( tid, name_p, namelen_p,
1272 "socketcall.getpeername(name)",
1273 "socketcall.getpeername(namelen_in)" );
1274}
1275
sewardj987a8eb2005-03-01 19:00:30 +00001276void
1277VG_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001278 UWord res,
1279 UWord arg0, UWord arg1, UWord arg2 )
1280{
1281 Addr name_p = arg1;
1282 Addr namelen_p = arg2;
1283 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1284 "socketcall.getpeername(namelen_out)" );
1285}
1286
1287/* ------ */
1288
sewardj987a8eb2005-03-01 19:00:30 +00001289void
1290VG_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001291 UWord arg0, UWord arg1 )
1292{
1293 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1294 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1295 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1296}
1297
1298/* ------ */
1299
sewardj987a8eb2005-03-01 19:00:30 +00001300void
1301VG_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001302 UWord arg0, UWord arg1 )
1303{
1304 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1305 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1306 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1307}
1308
sewardj987a8eb2005-03-01 19:00:30 +00001309void
1310VG_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001311 UWord res,
1312 UWord arg0, UWord arg1 )
1313{
1314 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1315 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1316 check_cmsg_for_fds( tid, msg );
1317}
1318
1319
1320/* ---------------------------------------------------------------------
sewardjb369c5e2005-03-24 17:52:02 +00001321 Deal with a bunch of IPC related syscalls
1322 ------------------------------------------------------------------ */
1323
1324/* ------ */
1325
1326void
1327VG_(generic_PRE_sys_semop) ( ThreadId tid,
1328 UWord arg0, UWord arg1, UWord arg2 )
1329{
1330 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1331 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1332}
1333
1334/* ------ */
1335
1336void
1337VG_(generic_PRE_sys_semtimedop) ( ThreadId tid,
1338 UWord arg0, UWord arg1,
1339 UWord arg2, UWord arg3 )
1340{
1341 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1342 struct timespec *timeout); */
1343 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1344 if (arg3 != 0)
1345 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1346}
1347
1348/* ------ */
1349
1350static
1351UInt get_sem_count( Int semid )
1352{
1353 struct vki_semid_ds buf;
1354 union vki_semun arg;
1355 long res;
1356
1357 arg.buf = &buf;
1358
1359#ifdef __NR_semctl
1360 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1361#else
1362 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
1363 VKI_IPC_STAT, (UWord)&arg);
1364#endif
1365 if ( VG_(is_kerror)(res) )
1366 return 0;
1367
1368 return buf.sem_nsems;
1369}
1370
1371void
1372VG_(generic_PRE_sys_semctl) ( ThreadId tid,
1373 UWord arg0, UWord arg1,
1374 UWord arg2, UWord arg3 )
1375{
1376 /* int semctl(int semid, int semnum, int cmd, ...); */
1377 union vki_semun arg = *(union vki_semun *)&arg3;
1378 UInt nsems;
1379 switch (arg2 /* cmd */) {
1380 case VKI_IPC_INFO:
1381 case VKI_SEM_INFO:
1382 case VKI_IPC_INFO|VKI_IPC_64:
1383 case VKI_SEM_INFO|VKI_IPC_64:
1384 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
1385 (Addr)arg.buf, sizeof(struct vki_seminfo) );
1386 break;
1387 case VKI_IPC_STAT:
1388 case VKI_SEM_STAT:
1389 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1390 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1391 break;
1392 case VKI_IPC_STAT|VKI_IPC_64:
1393 case VKI_SEM_STAT|VKI_IPC_64:
1394 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1395 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1396 break;
1397 case VKI_IPC_SET:
1398 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1399 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1400 break;
1401 case VKI_IPC_SET|VKI_IPC_64:
1402 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1403 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1404 break;
1405 case VKI_GETALL:
1406 case VKI_GETALL|VKI_IPC_64:
1407 nsems = get_sem_count( arg0 );
1408 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
1409 (Addr)arg.array, sizeof(unsigned short) * nsems );
1410 break;
1411 case VKI_SETALL:
1412 case VKI_SETALL|VKI_IPC_64:
1413 nsems = get_sem_count( arg0 );
1414 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
1415 (Addr)arg.array, sizeof(unsigned short) * nsems );
1416 break;
1417 }
1418}
1419
1420void
1421VG_(generic_POST_sys_semctl) ( ThreadId tid,
1422 UWord res,
1423 UWord arg0, UWord arg1,
1424 UWord arg2, UWord arg3 )
1425{
1426 union vki_semun arg = *(union vki_semun *)&arg3;
1427 UInt nsems;
1428 switch (arg2 /* cmd */) {
1429 case VKI_IPC_INFO:
1430 case VKI_SEM_INFO:
1431 case VKI_IPC_INFO|VKI_IPC_64:
1432 case VKI_SEM_INFO|VKI_IPC_64:
1433 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
1434 break;
1435 case VKI_IPC_STAT:
1436 case VKI_SEM_STAT:
1437 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1438 break;
1439 case VKI_IPC_STAT|VKI_IPC_64:
1440 case VKI_SEM_STAT|VKI_IPC_64:
1441 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1442 break;
1443 case VKI_GETALL:
1444 case VKI_GETALL|VKI_IPC_64:
1445 nsems = get_sem_count( arg0 );
1446 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
1447 break;
1448 }
1449}
1450
1451/* ------ */
1452
1453void
1454VG_(generic_PRE_sys_msgsnd) ( ThreadId tid,
1455 UWord arg0, UWord arg1,
1456 UWord arg2, UWord arg3 )
1457{
1458 /* int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); */
1459 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1460 PRE_MEM_READ( "msgsnd(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1461 PRE_MEM_READ( "msgsnd(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1462}
1463
1464/* ------ */
1465
1466void
1467VG_(generic_PRE_sys_msgrcv) ( ThreadId tid,
1468 UWord arg0, UWord arg1, UWord arg2,
1469 UWord arg3, UWord arg4 )
1470{
1471 /* ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,
1472 long msgtyp, int msgflg); */
1473 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1474 PRE_MEM_WRITE( "msgrcv(msgp->mtype)", (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1475 PRE_MEM_WRITE( "msgrcv(msgp->mtext)", (Addr)&msgp->mtext, arg2 );
1476}
1477
1478void
1479VG_(generic_POST_sys_msgrcv) ( ThreadId tid,
1480 UWord res,
1481 UWord arg0, UWord arg1, UWord arg2,
1482 UWord arg3, UWord arg4 )
1483{
1484 struct vki_msgbuf *msgp = (struct vki_msgbuf *)arg1;
1485 POST_MEM_WRITE( (Addr)&msgp->mtype, sizeof(msgp->mtype) );
1486 POST_MEM_WRITE( (Addr)&msgp->mtext, res );
1487}
1488
1489/* ------ */
1490
1491void
1492VG_(generic_PRE_sys_msgctl) ( ThreadId tid,
1493 UWord arg0, UWord arg1, UWord arg2 )
1494{
1495 /* int msgctl(int msqid, int cmd, struct msqid_ds *buf); */
1496 switch (arg1 /* cmd */) {
1497 case VKI_IPC_INFO:
1498 case VKI_MSG_INFO:
1499 case VKI_IPC_INFO|VKI_IPC_64:
1500 case VKI_MSG_INFO|VKI_IPC_64:
1501 PRE_MEM_WRITE( "msgctl(IPC_INFO, buf)",
1502 arg2, sizeof(struct vki_msginfo) );
1503 break;
1504 case VKI_IPC_STAT:
1505 case VKI_MSG_STAT:
1506 PRE_MEM_WRITE( "msgctl(IPC_STAT, buf)",
1507 arg2, sizeof(struct vki_msqid_ds) );
1508 break;
1509 case VKI_IPC_STAT|VKI_IPC_64:
1510 case VKI_MSG_STAT|VKI_IPC_64:
1511 PRE_MEM_WRITE( "msgctl(IPC_STAT, arg.buf)",
1512 arg2, sizeof(struct vki_msqid64_ds) );
1513 break;
1514 case VKI_IPC_SET:
1515 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1516 arg2, sizeof(struct vki_msqid_ds) );
1517 break;
1518 case VKI_IPC_SET|VKI_IPC_64:
1519 PRE_MEM_READ( "msgctl(IPC_SET, arg.buf)",
1520 arg2, sizeof(struct vki_msqid64_ds) );
1521 break;
1522 }
1523}
1524
1525void
1526VG_(generic_POST_sys_msgctl) ( ThreadId tid,
1527 UWord res,
1528 UWord arg0, UWord arg1, UWord arg2 )
1529{
1530 switch (arg1 /* cmd */) {
1531 case VKI_IPC_INFO:
1532 case VKI_MSG_INFO:
1533 case VKI_IPC_INFO|VKI_IPC_64:
1534 case VKI_MSG_INFO|VKI_IPC_64:
1535 POST_MEM_WRITE( arg2, sizeof(struct vki_msginfo) );
1536 break;
1537 case VKI_IPC_STAT:
1538 case VKI_MSG_STAT:
1539 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid_ds) );
1540 break;
1541 case VKI_IPC_STAT|VKI_IPC_64:
1542 case VKI_MSG_STAT|VKI_IPC_64:
1543 POST_MEM_WRITE( arg2, sizeof(struct vki_msqid64_ds) );
1544 break;
1545 }
1546}
1547
1548/* ------ */
1549
1550static
1551UInt get_shm_size ( Int shmid )
1552{
1553#ifdef __NR_shmctl
1554 struct vki_shmid64_ds buf;
1555 long __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
1556#else
1557 struct vki_shmid_ds buf;
1558 long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
1559 VKI_IPC_STAT, 0, (UWord)&buf);
1560#endif
1561 if ( VG_(is_kerror) ( __res ) )
1562 return 0;
1563
1564 return buf.shm_segsz;
1565}
1566
1567UWord
1568VG_(generic_PRE_sys_shmat) ( ThreadId tid,
1569 UWord arg0, UWord arg1, UWord arg2 )
1570{
1571 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
1572 UInt segmentSize = get_shm_size ( arg0 );
1573 if (arg1 == 0)
1574 arg1 = VG_(find_map_space)(0, segmentSize, True);
1575 else if (!VG_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
1576 arg1 = 0;
1577 return arg1;
1578}
1579
1580void
1581VG_(generic_POST_sys_shmat) ( ThreadId tid,
1582 UWord res,
1583 UWord arg0, UWord arg1, UWord arg2 )
1584{
1585 UInt segmentSize = get_shm_size ( arg0 );
1586 if ( segmentSize > 0 ) {
1587 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
1588 /* we don't distinguish whether it's read-only or
1589 * read-write -- it doesn't matter really. */
1590 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
1591
1592 if (!(arg2 & 010000)) /* = SHM_RDONLY */
1593 prot &= ~VKI_PROT_WRITE;
1594 VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
1595 }
1596}
1597
1598/* ------ */
1599
1600Bool
1601VG_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
1602{
1603 /* int shmdt(const void *shmaddr); */
1604 return VG_(valid_client_addr)(arg0, 1, tid, "shmdt");
1605}
1606
1607void
1608VG_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
1609{
1610 Segment *s = VG_(find_segment)(arg0);
1611
1612 if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, 1)) {
1613 VG_TRACK( die_mem_munmap, s->addr, s->len );
1614 VG_(unmap_range)(s->addr, s->len);
1615 }
1616}
1617/* ------ */
1618
1619void
1620VG_(generic_PRE_sys_shmctl) ( ThreadId tid,
1621 UWord arg0, UWord arg1, UWord arg2 )
1622{
1623 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
1624 switch (arg1 /* cmd */) {
1625 case VKI_IPC_INFO:
1626 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1627 arg2, sizeof(struct vki_shminfo) );
1628 break;
1629 case VKI_IPC_INFO|VKI_IPC_64:
1630 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1631 arg2, sizeof(struct vki_shminfo64) );
1632 break;
1633 case VKI_SHM_INFO:
1634 case VKI_SHM_INFO|VKI_IPC_64:
1635 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
1636 arg2, sizeof(struct vki_shm_info) );
1637 break;
1638 case VKI_IPC_STAT:
1639 case VKI_SHM_STAT:
1640 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
1641 arg2, sizeof(struct vki_shmid_ds) );
1642 break;
1643 case VKI_IPC_STAT|VKI_IPC_64:
1644 case VKI_SHM_STAT|VKI_IPC_64:
1645 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
1646 arg2, sizeof(struct vki_shmid64_ds) );
1647 break;
1648 case VKI_IPC_SET:
1649 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1650 arg2, sizeof(struct vki_shmid_ds) );
1651 break;
1652 case VKI_IPC_SET|VKI_IPC_64:
1653 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1654 arg2, sizeof(struct vki_shmid64_ds) );
1655 break;
1656 }
1657}
1658
1659void
1660VG_(generic_POST_sys_shmctl) ( ThreadId tid,
1661 UWord res,
1662 UWord arg0, UWord arg1, UWord arg2 )
1663{
1664 switch (arg1 /* cmd */) {
1665 case VKI_IPC_INFO:
1666 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
1667 break;
1668 case VKI_IPC_INFO|VKI_IPC_64:
1669 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
1670 break;
1671 case VKI_SHM_INFO:
1672 case VKI_SHM_INFO|VKI_IPC_64:
1673 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
1674 break;
1675 case VKI_IPC_STAT:
1676 case VKI_SHM_STAT:
1677 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
1678 break;
1679 case VKI_IPC_STAT|VKI_IPC_64:
1680 case VKI_SHM_STAT|VKI_IPC_64:
1681 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
1682 break;
1683 }
1684}
1685
1686
1687/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001688 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001689 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001690
nethercote4fa681f2004-11-08 17:51:39 +00001691/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001692 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001693 names like sys_write(); a few have names like old_mmap(). See the
nethercote8ff888f2004-11-17 17:11:45 +00001694 comment for VGA_(syscall_table)[] for important info about the __NR_foo
1695 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001696
nethercote92b2fd52004-11-16 16:15:41 +00001697 Some notes about names used for syscalls and args:
1698 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1699 ambiguity.
1700
1701 - For error messages, we generally use a somewhat generic name
1702 for the syscall (eg. "write" rather than "sys_write"). This should be
1703 good enough for the average user to understand what is happening,
1704 without confusing them with names like "sys_write".
1705
1706 - Also, for error messages the arg names are mostly taken from the man
1707 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001708 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001709 for the same reason -- a user presented with a "bogus foo(bar)" arg
1710 will most likely look at the "foo" man page to see which is the "bar"
1711 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001712
nethercote9c311eb2004-11-12 18:20:12 +00001713 Note that we use our own vki_* types. The one exception is in
1714 PRE_REG_READn calls, where pointer types haven't been changed, because
1715 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1716 be visible.
1717
nethercote4fa681f2004-11-08 17:51:39 +00001718 XXX: some of these are arch-specific, and should be factored out.
1719*/
1720
njn61fa0af2004-11-27 15:22:24 +00001721#define PRE(name, f) PRE_TEMPLATE( , vgArch_gen, name, f)
1722#define POST(name) POST_TEMPLATE( , vgArch_gen, name)
jsgf855d93d2003-10-13 22:26:55 +00001723
nethercoteef0c7662004-11-06 15:38:43 +00001724// Combine two 32-bit values into a 64-bit value
1725#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1726
sewardjb5f6f512005-03-10 23:59:00 +00001727//PRE(sys_exit_group, Special)
1728//{
1729// VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1730//}
jsgf855d93d2003-10-13 22:26:55 +00001731
nethercote85a456f2004-11-16 17:31:56 +00001732PRE(sys_exit, Special)
jsgf855d93d2003-10-13 22:26:55 +00001733{
sewardja922b612005-03-11 02:47:32 +00001734 /* simple; just make this thread exit */
1735 PRINT("exit( %d )", ARG1);
1736 PRE_REG_READ1(void, "exit", int, exitcode);
1737 tst->exitreason = VgSrc_ExitSyscall;
1738 tst->os_state.exitcode = ARG1;
1739 /* exit doesn't return anything (it doesn't return.)
1740 Nevertheless, if we don't do this, the result-not-assigned-
1741 yet-you-said-you-were-Special assertion in the main syscall
1742 handling logic will fire. Hence ..
1743 */
1744 SET_RESULT(0);
jsgf855d93d2003-10-13 22:26:55 +00001745}
1746
sewardjb5f6f512005-03-10 23:59:00 +00001747PRE(sys_sched_yield, MayBlock)
nethercote5b653bc2004-11-15 14:32:12 +00001748{
sewardjb5f6f512005-03-10 23:59:00 +00001749 PRINT("sched_yield()");
1750 PRE_REG_READ0(long, "sys_sched_yield");
nethercote5b653bc2004-11-15 14:32:12 +00001751}
1752
nethercote85a456f2004-11-16 17:31:56 +00001753PRE(sys_ni_syscall, Special)
nethercoteeb1c7b72004-11-11 19:43:50 +00001754{
1755 PRINT("non-existent syscall! (ni_syscall)");
1756 PRE_REG_READ0(long, "ni_syscall");
njn22cfccb2004-11-27 16:10:23 +00001757 SET_RESULT( -VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001758}
1759
sewardjb5f6f512005-03-10 23:59:00 +00001760PRE(sys_set_tid_address, 0)
rjwalshcdf1cb52004-04-29 08:40:50 +00001761{
njn22cfccb2004-11-27 16:10:23 +00001762 PRINT("sys_set_tid_address ( %p )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00001763 PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
rjwalshcdf1cb52004-04-29 08:40:50 +00001764}
1765
nethercote85a456f2004-11-16 17:31:56 +00001766PRE(sys_iopl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001767{
njn22cfccb2004-11-27 16:10:23 +00001768 PRINT("sys_iopl ( %d )", ARG1);
nethercote7f7e4d12004-11-15 12:28:58 +00001769 PRE_REG_READ1(long, "iopl", unsigned long, level);
jsgf855d93d2003-10-13 22:26:55 +00001770}
1771
nethercote85a456f2004-11-16 17:31:56 +00001772PRE(sys_setxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001773{
nethercote2e1c37d2004-11-13 13:57:12 +00001774 PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001775 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001776 PRE_REG_READ5(long, "setxattr",
1777 char *, path, char *, name,
1778 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001779 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1780 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1781 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001782}
1783
nethercote85a456f2004-11-16 17:31:56 +00001784PRE(sys_lsetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001785{
nethercote2e1c37d2004-11-13 13:57:12 +00001786 PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001787 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001788 PRE_REG_READ5(long, "lsetxattr",
1789 char *, path, char *, name,
1790 void *, value, vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001791 PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
1792 PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
1793 PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001794}
1795
nethercote85a456f2004-11-16 17:31:56 +00001796PRE(sys_fsetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001797{
1798 PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
njn22cfccb2004-11-27 16:10:23 +00001799 ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
nethercote2e1c37d2004-11-13 13:57:12 +00001800 PRE_REG_READ5(long, "fsetxattr",
1801 int, fd, char *, name, void *, value,
1802 vki_size_t, size, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001803 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1804 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001805}
1806
nethercote85a456f2004-11-16 17:31:56 +00001807PRE(sys_getxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001808{
njn22cfccb2004-11-27 16:10:23 +00001809 PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001810 PRE_REG_READ4(ssize_t, "getxattr",
1811 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001812 PRE_MEM_RASCIIZ( "getxattr(path)", ARG1 );
1813 PRE_MEM_RASCIIZ( "getxattr(name)", ARG2 );
1814 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001815}
1816
nethercote85a456f2004-11-16 17:31:56 +00001817POST(sys_getxattr)
jsgf855d93d2003-10-13 22:26:55 +00001818{
njn22cfccb2004-11-27 16:10:23 +00001819 if (RES > 0 && ARG3 != (Addr)NULL) {
1820 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001821 }
1822}
1823
nethercote85a456f2004-11-16 17:31:56 +00001824PRE(sys_lgetxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001825{
njn22cfccb2004-11-27 16:10:23 +00001826 PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001827 PRE_REG_READ4(ssize_t, "lgetxattr",
1828 char *, path, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001829 PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
1830 PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
1831 PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
nethercote2e1c37d2004-11-13 13:57:12 +00001832}
1833
nethercote85a456f2004-11-16 17:31:56 +00001834POST(sys_lgetxattr)
nethercote2e1c37d2004-11-13 13:57:12 +00001835{
njn22cfccb2004-11-27 16:10:23 +00001836 if (RES > 0 && ARG3 != (Addr)NULL) {
1837 POST_MEM_WRITE( ARG3, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001838 }
1839}
1840
nethercote85a456f2004-11-16 17:31:56 +00001841PRE(sys_fgetxattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001842{
njn22cfccb2004-11-27 16:10:23 +00001843 PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
nethercote2e1c37d2004-11-13 13:57:12 +00001844 PRE_REG_READ4(ssize_t, "fgetxattr",
1845 int, fd, char *, name, void *, value, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001846 PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
1847 PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
jsgf855d93d2003-10-13 22:26:55 +00001848}
1849
nethercote85a456f2004-11-16 17:31:56 +00001850POST(sys_fgetxattr)
jsgf855d93d2003-10-13 22:26:55 +00001851{
njn22cfccb2004-11-27 16:10:23 +00001852 if (RES > 0 && ARG3 != (Addr)NULL)
1853 POST_MEM_WRITE( ARG3, RES );
jsgf855d93d2003-10-13 22:26:55 +00001854}
1855
nethercote85a456f2004-11-16 17:31:56 +00001856PRE(sys_listxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001857{
njn22cfccb2004-11-27 16:10:23 +00001858 PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001859 PRE_REG_READ3(ssize_t, "listxattr",
1860 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001861 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1862 PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001863}
1864
nethercote85a456f2004-11-16 17:31:56 +00001865POST(sys_listxattr)
jsgf855d93d2003-10-13 22:26:55 +00001866{
njn22cfccb2004-11-27 16:10:23 +00001867 if (RES > 0 && ARG2 != (Addr)NULL)
1868 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001869}
1870
nethercote85a456f2004-11-16 17:31:56 +00001871PRE(sys_llistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001872{
njn22cfccb2004-11-27 16:10:23 +00001873 PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001874 PRE_REG_READ3(ssize_t, "llistxattr",
1875 char *, path, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001876 PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
1877 PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001878}
1879
nethercote85a456f2004-11-16 17:31:56 +00001880POST(sys_llistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001881{
njn22cfccb2004-11-27 16:10:23 +00001882 if (RES > 0 && ARG2 != (Addr)NULL)
1883 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00001884}
1885
nethercote85a456f2004-11-16 17:31:56 +00001886PRE(sys_flistxattr, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001887{
njn22cfccb2004-11-27 16:10:23 +00001888 PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00001889 PRE_REG_READ3(ssize_t, "flistxattr",
1890 int, fd, char *, list, vki_size_t, size);
njn22cfccb2004-11-27 16:10:23 +00001891 PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00001892}
1893
nethercote85a456f2004-11-16 17:31:56 +00001894POST(sys_flistxattr)
jsgf855d93d2003-10-13 22:26:55 +00001895{
njn22cfccb2004-11-27 16:10:23 +00001896 if (RES > 0 && ARG2 != (Addr)NULL)
1897 POST_MEM_WRITE( ARG2, RES );
nethercote2e1c37d2004-11-13 13:57:12 +00001898}
1899
nethercote85a456f2004-11-16 17:31:56 +00001900PRE(sys_removexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001901{
njn22cfccb2004-11-27 16:10:23 +00001902 PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001903 PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001904 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1905 PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001906}
1907
nethercote85a456f2004-11-16 17:31:56 +00001908PRE(sys_lremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001909{
njn22cfccb2004-11-27 16:10:23 +00001910 PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001911 PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001912 PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
1913 PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
nethercote2e1c37d2004-11-13 13:57:12 +00001914}
1915
nethercote85a456f2004-11-16 17:31:56 +00001916PRE(sys_fremovexattr, MayBlock)
nethercote2e1c37d2004-11-13 13:57:12 +00001917{
njn22cfccb2004-11-27 16:10:23 +00001918 PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00001919 PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
njn22cfccb2004-11-27 16:10:23 +00001920 PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001921}
1922
nethercote85a456f2004-11-16 17:31:56 +00001923PRE(sys_quotactl, 0)
jsgf855d93d2003-10-13 22:26:55 +00001924{
njn22cfccb2004-11-27 16:10:23 +00001925 PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
nethercote5b653bc2004-11-15 14:32:12 +00001926 PRE_REG_READ4(long, "quotactl",
1927 unsigned int, cmd, const char *, special, vki_qid_t, id,
1928 void *, addr);
njn22cfccb2004-11-27 16:10:23 +00001929 PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001930}
1931
nethercote5a945af2004-11-14 18:37:07 +00001932// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00001933PRE(sys_lookup_dcookie, 0)
jsgf855d93d2003-10-13 22:26:55 +00001934{
njn22cfccb2004-11-27 16:10:23 +00001935 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
nethercote660e4ee2004-11-12 13:29:24 +00001936 PRE_REG_READ4(long, "lookup_dcookie",
1937 vki_u32, cookie_low32, vki_u32, cookie_high32,
1938 char *, buf, vki_size_t, len);
njn22cfccb2004-11-27 16:10:23 +00001939 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
jsgf855d93d2003-10-13 22:26:55 +00001940}
1941
nethercote85a456f2004-11-16 17:31:56 +00001942POST(sys_lookup_dcookie)
jsgf855d93d2003-10-13 22:26:55 +00001943{
njn22cfccb2004-11-27 16:10:23 +00001944 if (ARG3 != (Addr)NULL)
1945 POST_MEM_WRITE( ARG3, RES);
jsgf855d93d2003-10-13 22:26:55 +00001946}
1947
nethercote85a456f2004-11-16 17:31:56 +00001948PRE(sys_fsync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001949{
njn22cfccb2004-11-27 16:10:23 +00001950 PRINT("sys_fsync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001951 PRE_REG_READ1(long, "fsync", unsigned int, fd);
1952}
1953
nethercote85a456f2004-11-16 17:31:56 +00001954PRE(sys_fdatasync, MayBlock)
nethercotedc18c0a2004-11-14 20:06:27 +00001955{
njn22cfccb2004-11-27 16:10:23 +00001956 PRINT("sys_fdatasync ( %d )", ARG1);
nethercotedc18c0a2004-11-14 20:06:27 +00001957 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00001958}
1959
nethercote85a456f2004-11-16 17:31:56 +00001960PRE(sys_msync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001961{
njn22cfccb2004-11-27 16:10:23 +00001962 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00001963 PRE_REG_READ3(long, "msync",
1964 unsigned long, start, vki_size_t, length, int, flags);
njn22cfccb2004-11-27 16:10:23 +00001965 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00001966}
1967
nethercoteef0c7662004-11-06 15:38:43 +00001968// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
1969// versions of LiS (Linux Streams). They are not part of the kernel.
1970// Therefore, we have to provide this type ourself, rather than getting it
1971// from the kernel sources.
nethercoteb77dee62004-11-16 17:13:24 +00001972struct vki_pmsg_strbuf {
jsgf855d93d2003-10-13 22:26:55 +00001973 int maxlen; /* no. of bytes in buffer */
1974 int len; /* no. of bytes returned */
nethercote73b526f2004-10-31 18:48:21 +00001975 vki_caddr_t buf; /* pointer to data */
jsgf855d93d2003-10-13 22:26:55 +00001976};
1977
nethercote85a456f2004-11-16 17:31:56 +00001978PRE(sys_getpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00001979{
1980 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00001981 struct vki_pmsg_strbuf *ctrl;
1982 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00001983 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00001984 PRE_REG_READ5(int, "getpmsg",
1985 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
1986 int *, bandp, int *, flagsp);
njn22cfccb2004-11-27 16:10:23 +00001987 ctrl = (struct vki_pmsg_strbuf *)ARG2;
1988 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00001989 if (ctrl && ctrl->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001990 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
jsgf855d93d2003-10-13 22:26:55 +00001991 if (data && data->maxlen > 0)
nethercoteef0c7662004-11-06 15:38:43 +00001992 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
njn22cfccb2004-11-27 16:10:23 +00001993 if (ARG4)
1994 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
1995 if (ARG5)
1996 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00001997}
1998
nethercote85a456f2004-11-16 17:31:56 +00001999POST(sys_getpmsg)
jsgf855d93d2003-10-13 22:26:55 +00002000{
nethercoteb77dee62004-11-16 17:13:24 +00002001 struct vki_pmsg_strbuf *ctrl;
2002 struct vki_pmsg_strbuf *data;
jsgf855d93d2003-10-13 22:26:55 +00002003
njn22cfccb2004-11-27 16:10:23 +00002004 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2005 data = (struct vki_pmsg_strbuf *)ARG3;
2006 if (RES == 0 && ctrl && ctrl->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002007 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00002008 }
njn22cfccb2004-11-27 16:10:23 +00002009 if (RES == 0 && data && data->len > 0) {
nethercoteef0c7662004-11-06 15:38:43 +00002010 POST_MEM_WRITE( (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00002011 }
2012}
2013
nethercote85a456f2004-11-16 17:31:56 +00002014PRE(sys_putpmsg, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002015{
2016 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
nethercoteb77dee62004-11-16 17:13:24 +00002017 struct vki_pmsg_strbuf *ctrl;
2018 struct vki_pmsg_strbuf *data;
njn22cfccb2004-11-27 16:10:23 +00002019 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercoteb77dee62004-11-16 17:13:24 +00002020 PRE_REG_READ5(int, "putpmsg",
2021 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2022 int, band, int, flags);
njn22cfccb2004-11-27 16:10:23 +00002023 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2024 data = (struct vki_pmsg_strbuf *)ARG3;
jsgf855d93d2003-10-13 22:26:55 +00002025 if (ctrl && ctrl->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002026 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
jsgf855d93d2003-10-13 22:26:55 +00002027 if (data && data->len > 0)
nethercoteef0c7662004-11-06 15:38:43 +00002028 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
jsgf855d93d2003-10-13 22:26:55 +00002029}
2030
sewardjb5f6f512005-03-10 23:59:00 +00002031PRE(sys_getitimer, 0)
jsgf855d93d2003-10-13 22:26:55 +00002032{
njn22cfccb2004-11-27 16:10:23 +00002033 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00002034 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
njn22cfccb2004-11-27 16:10:23 +00002035 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
jsgf855d93d2003-10-13 22:26:55 +00002036}
2037
nethercote85a456f2004-11-16 17:31:56 +00002038POST(sys_getitimer)
jsgf855d93d2003-10-13 22:26:55 +00002039{
njn22cfccb2004-11-27 16:10:23 +00002040 if (ARG2 != (Addr)NULL) {
2041 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
jsgf855d93d2003-10-13 22:26:55 +00002042 }
2043}
2044
sewardjb5f6f512005-03-10 23:59:00 +00002045PRE(sys_setitimer, 0)
nethercote5b653bc2004-11-15 14:32:12 +00002046{
njn22cfccb2004-11-27 16:10:23 +00002047 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00002048 PRE_REG_READ3(long, "setitimer",
2049 int, which,
2050 struct itimerval *, value, struct itimerval *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00002051 if (ARG2 != (Addr)NULL)
2052 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
2053 if (ARG3 != (Addr)NULL)
2054 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00002055}
2056
nethercote85a456f2004-11-16 17:31:56 +00002057POST(sys_setitimer)
nethercote5b653bc2004-11-15 14:32:12 +00002058{
njn22cfccb2004-11-27 16:10:23 +00002059 if (ARG3 != (Addr)NULL) {
2060 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
nethercote5b653bc2004-11-15 14:32:12 +00002061 }
2062}
2063
nethercote85a456f2004-11-16 17:31:56 +00002064PRE(sys_chroot, 0)
jsgf855d93d2003-10-13 22:26:55 +00002065{
njn22cfccb2004-11-27 16:10:23 +00002066 PRINT("sys_chroot ( %p )", ARG1);
nethercote71f05f32004-11-12 18:49:27 +00002067 PRE_REG_READ1(long, "chroot", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002068 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002069}
2070
nethercote85a456f2004-11-16 17:31:56 +00002071PRE(sys_madvise, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002072{
njn22cfccb2004-11-27 16:10:23 +00002073 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00002074 PRE_REG_READ3(long, "madvise",
2075 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00002076}
2077
nethercote85a456f2004-11-16 17:31:56 +00002078PRE(sys_mremap, Special)
jsgf855d93d2003-10-13 22:26:55 +00002079{
nethercote27ea8bc2004-07-10 17:21:14 +00002080 // Nb: this is different to the glibc version described in the man pages,
2081 // which lacks the fifth 'new_address' argument.
nethercote06c7bd72004-11-14 19:11:56 +00002082 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
njn22cfccb2004-11-27 16:10:23 +00002083 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
nethercote06c7bd72004-11-14 19:11:56 +00002084 PRE_REG_READ5(unsigned long, "mremap",
2085 unsigned long, old_addr, unsigned long, old_size,
2086 unsigned long, new_size, unsigned long, flags,
2087 unsigned long, new_addr);
njn22cfccb2004-11-27 16:10:23 +00002088 SET_RESULT( mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) );
jsgf855d93d2003-10-13 22:26:55 +00002089}
2090
nethercote85a456f2004-11-16 17:31:56 +00002091PRE(sys_nice, 0)
jsgf855d93d2003-10-13 22:26:55 +00002092{
njn22cfccb2004-11-27 16:10:23 +00002093 PRINT("sys_nice ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002094 PRE_REG_READ1(long, "nice", int, inc);
jsgf855d93d2003-10-13 22:26:55 +00002095}
2096
nethercote85a456f2004-11-16 17:31:56 +00002097PRE(sys_sched_getscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00002098{
njn22cfccb2004-11-27 16:10:23 +00002099 PRINT("sys_sched_getscheduler ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002100 PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002101}
2102
nethercote85a456f2004-11-16 17:31:56 +00002103PRE(sys_sched_setscheduler, 0)
jsgf855d93d2003-10-13 22:26:55 +00002104{
njn22cfccb2004-11-27 16:10:23 +00002105 PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00002106 PRE_REG_READ3(long, "sched_setscheduler",
2107 vki_pid_t, pid, int, policy, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00002108 if (ARG3 != 0)
nethercote5b653bc2004-11-15 14:32:12 +00002109 PRE_MEM_READ( "sched_setscheduler(p)",
njn22cfccb2004-11-27 16:10:23 +00002110 ARG3, sizeof(struct vki_sched_param));
jsgf855d93d2003-10-13 22:26:55 +00002111}
2112
nethercote85a456f2004-11-16 17:31:56 +00002113PRE(sys_mlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002114{
njn22cfccb2004-11-27 16:10:23 +00002115 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00002116 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00002117}
2118
nethercote85a456f2004-11-16 17:31:56 +00002119PRE(sys_munlock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002120{
njn22cfccb2004-11-27 16:10:23 +00002121 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00002122 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
jsgf855d93d2003-10-13 22:26:55 +00002123}
2124
nethercote85a456f2004-11-16 17:31:56 +00002125PRE(sys_mlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002126{
njn22cfccb2004-11-27 16:10:23 +00002127 PRINT("sys_mlockall ( %x )", ARG1);
nethercote06c7bd72004-11-14 19:11:56 +00002128 PRE_REG_READ1(long, "mlockall", int, flags);
jsgf855d93d2003-10-13 22:26:55 +00002129}
2130
nethercote85a456f2004-11-16 17:31:56 +00002131PRE(sys_munlockall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002132{
nethercote0df495a2004-11-11 16:38:21 +00002133 PRINT("sys_munlockall ( )");
2134 PRE_REG_READ0(long, "munlockall");
jsgf855d93d2003-10-13 22:26:55 +00002135}
2136
nethercote85a456f2004-11-16 17:31:56 +00002137PRE(sys_sched_get_priority_max, 0)
jsgf855d93d2003-10-13 22:26:55 +00002138{
njn22cfccb2004-11-27 16:10:23 +00002139 PRINT("sched_get_priority_max ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002140 PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00002141}
2142
nethercote85a456f2004-11-16 17:31:56 +00002143PRE(sys_sched_get_priority_min, 0)
jsgf855d93d2003-10-13 22:26:55 +00002144{
njn22cfccb2004-11-27 16:10:23 +00002145 PRINT("sched_get_priority_min ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002146 PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
jsgf855d93d2003-10-13 22:26:55 +00002147}
2148
nethercote85a456f2004-11-16 17:31:56 +00002149PRE(sys_setpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00002150{
njn22cfccb2004-11-27 16:10:23 +00002151 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00002152 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
jsgf855d93d2003-10-13 22:26:55 +00002153}
2154
nethercote85a456f2004-11-16 17:31:56 +00002155PRE(sys_getpriority, 0)
jsgf855d93d2003-10-13 22:26:55 +00002156{
njn22cfccb2004-11-27 16:10:23 +00002157 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002158 PRE_REG_READ2(long, "getpriority", int, which, int, who);
jsgf855d93d2003-10-13 22:26:55 +00002159}
2160
nethercote85a456f2004-11-16 17:31:56 +00002161PRE(sys_setregid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002162{
njn22cfccb2004-11-27 16:10:23 +00002163 PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00002164 PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00002165}
2166
nethercoteac866b92004-11-15 20:23:15 +00002167// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00002168PRE(sys_pwrite64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002169{
nethercoteac866b92004-11-15 20:23:15 +00002170 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00002171 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00002172 PRE_REG_READ5(ssize_t, "pwrite64",
2173 unsigned int, fd, const char *, buf, vki_size_t, count,
2174 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00002175 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002176}
2177
nethercote85a456f2004-11-16 17:31:56 +00002178PRE(sys_sync, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002179{
nethercote0df495a2004-11-11 16:38:21 +00002180 PRINT("sys_sync ( )");
2181 PRE_REG_READ0(long, "sync");
jsgf855d93d2003-10-13 22:26:55 +00002182}
2183
nethercote85a456f2004-11-16 17:31:56 +00002184PRE(sys_fstatfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00002185{
njn22cfccb2004-11-27 16:10:23 +00002186 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002187 PRE_REG_READ2(long, "fstatfs",
2188 unsigned int, fd, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00002189 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00002190}
2191
nethercote85a456f2004-11-16 17:31:56 +00002192POST(sys_fstatfs)
jsgf855d93d2003-10-13 22:26:55 +00002193{
njn22cfccb2004-11-27 16:10:23 +00002194 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
jsgf855d93d2003-10-13 22:26:55 +00002195}
2196
nethercote85a456f2004-11-16 17:31:56 +00002197PRE(sys_fstatfs64, 0)
thughesa996d3b2004-09-24 22:57:17 +00002198{
njn22cfccb2004-11-27 16:10:23 +00002199 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00002200 PRE_REG_READ3(long, "fstatfs64",
2201 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00002202 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00002203}
2204
nethercote85a456f2004-11-16 17:31:56 +00002205POST(sys_fstatfs64)
thughesa996d3b2004-09-24 22:57:17 +00002206{
njn22cfccb2004-11-27 16:10:23 +00002207 POST_MEM_WRITE( ARG3, ARG2 );
thughesa996d3b2004-09-24 22:57:17 +00002208}
2209
nethercote85a456f2004-11-16 17:31:56 +00002210PRE(sys_getsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002211{
njn22cfccb2004-11-27 16:10:23 +00002212 PRINT("sys_getsid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002213 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002214}
2215
nethercoteac866b92004-11-15 20:23:15 +00002216// XXX: only for 32-bit archs
nethercote85a456f2004-11-16 17:31:56 +00002217PRE(sys_pread64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002218{
nethercoteac866b92004-11-15 20:23:15 +00002219 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
njn22cfccb2004-11-27 16:10:23 +00002220 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
nethercoteac866b92004-11-15 20:23:15 +00002221 PRE_REG_READ5(ssize_t, "pread64",
2222 unsigned int, fd, char *, buf, vki_size_t, count,
2223 vki_u32, offset_low32, vki_u32, offset_high32);
njn22cfccb2004-11-27 16:10:23 +00002224 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002225}
2226
nethercote85a456f2004-11-16 17:31:56 +00002227POST(sys_pread64)
jsgf855d93d2003-10-13 22:26:55 +00002228{
njn22cfccb2004-11-27 16:10:23 +00002229 if (RES > 0) {
2230 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002231 }
2232}
2233
nethercote85a456f2004-11-16 17:31:56 +00002234PRE(sys_mknod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002235{
njn22cfccb2004-11-27 16:10:23 +00002236 PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00002237 PRE_REG_READ3(long, "mknod",
2238 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00002239 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002240}
2241
nethercote85a456f2004-11-16 17:31:56 +00002242PRE(sys_flock, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002243{
njn22cfccb2004-11-27 16:10:23 +00002244 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
nethercote06c7bd72004-11-14 19:11:56 +00002245 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
jsgf855d93d2003-10-13 22:26:55 +00002246}
2247
nethercote85a456f2004-11-16 17:31:56 +00002248PRE(sys_init_module, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002249{
njn22cfccb2004-11-27 16:10:23 +00002250 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
nethercote0eafe552004-11-15 16:40:40 +00002251 PRE_REG_READ3(long, "init_module",
2252 void *, umod, unsigned long, len, const char *, uargs);
njn22cfccb2004-11-27 16:10:23 +00002253 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
2254 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002255}
2256
nethercote85a456f2004-11-16 17:31:56 +00002257PRE(sys_capget, 0)
jsgf855d93d2003-10-13 22:26:55 +00002258{
njn22cfccb2004-11-27 16:10:23 +00002259 PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00002260 PRE_REG_READ2(long, "capget",
2261 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
njn22cfccb2004-11-27 16:10:23 +00002262 PRE_MEM_READ( "capget(header)", ARG1,
nethercote73b526f2004-10-31 18:48:21 +00002263 sizeof(struct __vki_user_cap_header_struct) );
njn22cfccb2004-11-27 16:10:23 +00002264 PRE_MEM_WRITE( "capget(data)", ARG2,
nethercote73b526f2004-10-31 18:48:21 +00002265 sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002266}
2267
nethercote85a456f2004-11-16 17:31:56 +00002268POST(sys_capget)
jsgf855d93d2003-10-13 22:26:55 +00002269{
njn22cfccb2004-11-27 16:10:23 +00002270 if (ARG2 != (Addr)NULL)
2271 POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002272}
2273
nethercote85a456f2004-11-16 17:31:56 +00002274PRE(sys_capset, 0)
jsgf855d93d2003-10-13 22:26:55 +00002275{
njn22cfccb2004-11-27 16:10:23 +00002276 PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00002277 PRE_REG_READ2(long, "capset",
2278 vki_cap_user_header_t, header,
2279 const vki_cap_user_data_t, data);
nethercoteef0c7662004-11-06 15:38:43 +00002280 PRE_MEM_READ( "capset(header)",
njn22cfccb2004-11-27 16:10:23 +00002281 ARG1, sizeof(struct __vki_user_cap_header_struct) );
nethercoteef0c7662004-11-06 15:38:43 +00002282 PRE_MEM_READ( "capset(data)",
njn22cfccb2004-11-27 16:10:23 +00002283 ARG2, sizeof(struct __vki_user_cap_data_struct) );
jsgf855d93d2003-10-13 22:26:55 +00002284}
2285
nethercotea81e9162004-02-12 14:34:14 +00002286// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00002287static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00002288{
2289 while (True) {
njnb249fd72004-11-29 14:24:57 +00002290 Addr a_deref;
2291 Addr* a_p = (Addr*)a;
2292 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2293 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00002294 if (0 == a_deref)
2295 break;
nethercoteef0c7662004-11-06 15:38:43 +00002296 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00002297 a += sizeof(char*);
2298 }
2299}
2300
nethercote7310afb2004-11-12 15:41:06 +00002301// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
2302// but it seems to work nonetheless...
nethercote85a456f2004-11-16 17:31:56 +00002303PRE(sys_execve, Special)
jsgf855d93d2003-10-13 22:26:55 +00002304{
sewardjb5f6f512005-03-10 23:59:00 +00002305 Char *path; /* path to executable */
2306
njn22cfccb2004-11-27 16:10:23 +00002307 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00002308 PRE_REG_READ3(vki_off_t, "execve",
2309 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00002310 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
2311 if (ARG2 != 0)
2312 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
2313 if (ARG3 != 0)
2314 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00002315
sewardjb5f6f512005-03-10 23:59:00 +00002316 path = (Char *)ARG1;
2317
fitzhardingee1c06d82003-10-30 07:21:44 +00002318 /* Erk. If the exec fails, then the following will have made a
2319 mess of things which makes it hard for us to continue. The
2320 right thing to do is piece everything together again in
2321 POST(execve), but that's hard work. Instead, we make an effort
2322 to check that the execve will work before actually calling
2323 exec. */
2324 {
2325 struct vki_stat st;
njn22cfccb2004-11-27 16:10:23 +00002326 Int ret = VG_(stat)((Char *)ARG1, &st);
fitzhardingee1c06d82003-10-30 07:21:44 +00002327
2328 if (ret < 0) {
njn22cfccb2004-11-27 16:10:23 +00002329 SET_RESULT( ret );
fitzhardingee1c06d82003-10-30 07:21:44 +00002330 return;
2331 }
thughes90efa302004-09-25 16:13:55 +00002332 /* just look for regular file with any X bit set
fitzhardingee1c06d82003-10-30 07:21:44 +00002333 XXX do proper permissions check?
2334 */
thughes90efa302004-09-25 16:13:55 +00002335 if ((st.st_mode & 0100111) == 0100000) {
njn22cfccb2004-11-27 16:10:23 +00002336 SET_RESULT( -VKI_EACCES );
fitzhardingee1c06d82003-10-30 07:21:44 +00002337 return;
2338 }
2339 }
2340
2341 /* Resistance is futile. Nuke all other threads. POSIX mandates
2342 this. (Really, nuke them all, since the new process will make
2343 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00002344 VG_(master_tid) = tid; /* become the master */
2345 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
2346 VGA_(reap_threads)(tid);
2347
2348 if (0) {
2349 /* Shut down cleanly and report final state
2350 XXX Is this reasonable? */
2351 tst->exitreason = VgSrc_ExitSyscall;
2352 VG_(shutdown_actions)(tid);
2353 }
fitzhardingee1c06d82003-10-30 07:21:44 +00002354
fitzhardinge5408c062004-01-04 23:52:59 +00002355 {
nethercote60a96c52004-08-03 13:08:31 +00002356 // Remove the valgrind-specific stuff from the environment so the
sewardjb5f6f512005-03-10 23:59:00 +00002357 // child doesn't get vg_inject.so, vgpreload.so, etc. This is
nethercote60a96c52004-08-03 13:08:31 +00002358 // done unconditionally, since if we are tracing the child,
2359 // stage1/2 will set up the appropriate client environment.
njn22cfccb2004-11-27 16:10:23 +00002360 Char** envp = (Char**)ARG3;
fitzhardinge98abfc72003-12-16 02:05:15 +00002361
2362 if (envp != NULL) {
sewardjb5f6f512005-03-10 23:59:00 +00002363 VG_(env_remove_valgrind_env_stuff)( envp );
jsgf855d93d2003-10-13 22:26:55 +00002364 }
fitzhardinge5408c062004-01-04 23:52:59 +00002365 }
2366
2367 if (VG_(clo_trace_children)) {
njn22cfccb2004-11-27 16:10:23 +00002368 Char* optvar = VG_(build_child_VALGRINDCLO)( (Char*)ARG1 );
fitzhardinge98abfc72003-12-16 02:05:15 +00002369
njn22cfccb2004-11-27 16:10:23 +00002370 // Set VALGRINDCLO and VALGRINDLIB in ARG3 (the environment)
2371 VG_(env_setenv)( (Char***)&ARG3, VALGRINDCLO, optvar);
2372 VG_(env_setenv)( (Char***)&ARG3, VALGRINDLIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002373
njn22cfccb2004-11-27 16:10:23 +00002374 // Create executable name: "/proc/self/fd/<vgexecfd>", update ARG1
sewardj8e332792005-03-11 12:56:56 +00002375 path = VG_(build_child_exename)();
fitzhardinge98abfc72003-12-16 02:05:15 +00002376 }
2377
2378 if (0) {
2379 Char **cpp;
2380
njn22cfccb2004-11-27 16:10:23 +00002381 VG_(printf)("exec: %s\n", (Char *)ARG1);
2382 for(cpp = (Char **)ARG2; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002383 VG_(printf)("argv: %s\n", *cpp);
njn22cfccb2004-11-27 16:10:23 +00002384 for(cpp = (Char **)ARG3; cpp && *cpp; cpp++)
nethercotef6a1d502004-08-09 12:21:57 +00002385 VG_(printf)("env: %s\n", *cpp);
jsgf855d93d2003-10-13 22:26:55 +00002386 }
jsgf855d93d2003-10-13 22:26:55 +00002387
sewardjb5f6f512005-03-10 23:59:00 +00002388 /* restore the DATA rlimit for the child */
2389 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2390
2391 /*
2392 Set the signal state up for exec.
2393
2394 We need to set the real signal state to make sure the exec'd
2395 process gets SIG_IGN properly.
2396
2397 Also set our real sigmask to match the client's sigmask so that
2398 the exec'd child will get the right mask. First we need to
2399 clear out any pending signals so they they don't get delivered,
2400 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002401
2402 XXX This is a bug - the signals should remain pending, and be
2403 delivered to the new process after exec. There's also a
2404 race-condition, since if someone delivers us a signal between
2405 the sigprocmask and the execve, we'll still get the signal. Oh
2406 well.
2407 */
2408 {
nethercote73b526f2004-10-31 18:48:21 +00002409 vki_sigset_t allsigs;
2410 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002411 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002412 Int i;
2413
2414 for(i = 1; i < VG_(max_signal); i++) {
2415 struct vki_sigaction sa;
2416 VG_(do_sys_sigaction)(i, NULL, &sa);
2417 if (sa.ksa_handler == VKI_SIG_IGN)
2418 VG_(sigaction)(i, &sa, NULL);
2419 else {
2420 sa.ksa_handler = VKI_SIG_DFL;
2421 VG_(sigaction)(i, &sa, NULL);
2422 }
2423 }
2424
nethercote73b526f2004-10-31 18:48:21 +00002425 VG_(sigfillset)(&allsigs);
2426 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002427 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002428
nethercote73b526f2004-10-31 18:48:21 +00002429 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002430 }
2431
sewardjb5f6f512005-03-10 23:59:00 +00002432 SET_RESULT( VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) );
fitzhardingeb50068f2004-02-24 23:42:55 +00002433
sewardjb5f6f512005-03-10 23:59:00 +00002434 /* If we got here, then the execve failed. We've already made too
2435 much of a mess of ourselves to continue, so we have to abort. */
nethercotee70bd7d2004-08-18 14:37:17 +00002436 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
sewardjb5f6f512005-03-10 23:59:00 +00002437 ARG1, ARG1, ARG2, ARG3, -RES);
2438 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2439 "execve() failing, so I'm dying.");
2440 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(execve), "
2441 "or work out how to recover.");
2442 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002443}
2444
nethercote85a456f2004-11-16 17:31:56 +00002445PRE(sys_access, 0)
jsgf855d93d2003-10-13 22:26:55 +00002446{
njn22cfccb2004-11-27 16:10:23 +00002447 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002448 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002449 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002450}
2451
sewardjb5f6f512005-03-10 23:59:00 +00002452PRE(sys_alarm, 0)
jsgf855d93d2003-10-13 22:26:55 +00002453{
njn22cfccb2004-11-27 16:10:23 +00002454 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002455 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002456}
2457
nethercote85a456f2004-11-16 17:31:56 +00002458PRE(sys_brk, Special)
jsgf855d93d2003-10-13 22:26:55 +00002459{
fitzhardinge98abfc72003-12-16 02:05:15 +00002460 Addr brk_limit = VG_(brk_limit);
2461
jsgf855d93d2003-10-13 22:26:55 +00002462 /* libc says: int brk(void *end_data_segment);
2463 kernel says: void* brk(void* end_data_segment); (more or less)
2464
2465 libc returns 0 on success, and -1 (and sets errno) on failure.
2466 Nb: if you ask to shrink the dataseg end below what it
2467 currently is, that always succeeds, even if the dataseg end
2468 doesn't actually change (eg. brk(0)). Unless it seg faults.
2469
2470 Kernel returns the new dataseg end. If the brk() failed, this
2471 will be unchanged from the old one. That's why calling (kernel)
2472 brk(0) gives the current dataseg end (libc brk() just returns
2473 zero in that case).
2474
2475 Both will seg fault if you shrink it back into a text segment.
2476 */
njn22cfccb2004-11-27 16:10:23 +00002477 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002478 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002479
njn22cfccb2004-11-27 16:10:23 +00002480 SET_RESULT( do_brk(ARG1) );
fitzhardinge98abfc72003-12-16 02:05:15 +00002481
njn22cfccb2004-11-27 16:10:23 +00002482 if (RES == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002483 /* brk() succeeded */
njn22cfccb2004-11-27 16:10:23 +00002484 if (RES < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002485 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002486 VG_TRACK( die_mem_brk, (Addr)ARG1,
2487 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002488 } else
njn22cfccb2004-11-27 16:10:23 +00002489 if (RES > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002490 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002491 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002492 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002493 }
jsgf855d93d2003-10-13 22:26:55 +00002494 } else {
2495 /* brk() failed */
njn22cfccb2004-11-27 16:10:23 +00002496 vg_assert(brk_limit == RES);
jsgf855d93d2003-10-13 22:26:55 +00002497 }
2498}
2499
nethercote85a456f2004-11-16 17:31:56 +00002500PRE(sys_chdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002501{
njn22cfccb2004-11-27 16:10:23 +00002502 PRINT("sys_chdir ( %p )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002503 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002504 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002505}
2506
nethercote85a456f2004-11-16 17:31:56 +00002507PRE(sys_chmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002508{
njn22cfccb2004-11-27 16:10:23 +00002509 PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002510 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002511 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002512}
2513
nethercote85a456f2004-11-16 17:31:56 +00002514PRE(sys_chown16, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002515{
njn22cfccb2004-11-27 16:10:23 +00002516 PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002517 PRE_REG_READ3(long, "chown16",
2518 const char *, path,
2519 vki_old_uid_t, owner, vki_old_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002520 PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002521}
2522
nethercote85a456f2004-11-16 17:31:56 +00002523PRE(sys_chown, 0)
jsgf855d93d2003-10-13 22:26:55 +00002524{
2525 /* int chown(const char *path, uid_t owner, gid_t group); */
njn22cfccb2004-11-27 16:10:23 +00002526 PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002527 PRE_REG_READ3(long, "chown",
2528 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002529 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002530}
2531
nethercote85a456f2004-11-16 17:31:56 +00002532PRE(sys_lchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002533{
njn22cfccb2004-11-27 16:10:23 +00002534 PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002535 PRE_REG_READ3(long, "lchown",
2536 const char *, path, vki_uid_t, owner, vki_gid_t, group);
njn22cfccb2004-11-27 16:10:23 +00002537 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
nethercote2e1c37d2004-11-13 13:57:12 +00002538}
jsgf855d93d2003-10-13 22:26:55 +00002539
nethercote85a456f2004-11-16 17:31:56 +00002540PRE(sys_close, 0)
jsgf855d93d2003-10-13 22:26:55 +00002541{
njn22cfccb2004-11-27 16:10:23 +00002542 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002543 PRE_REG_READ1(long, "close", unsigned int, fd);
2544
nethercotef8548672004-06-21 12:42:35 +00002545 /* Detect and negate attempts by the client to close Valgrind's log fd */
njn22cfccb2004-11-27 16:10:23 +00002546 if (!VG_(fd_allowed)(ARG1, "close", tid, False))
2547 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002548}
2549
nethercote85a456f2004-11-16 17:31:56 +00002550POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002551{
njn22cfccb2004-11-27 16:10:23 +00002552 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002553}
jsgf855d93d2003-10-13 22:26:55 +00002554
nethercote85a456f2004-11-16 17:31:56 +00002555PRE(sys_dup, 0)
jsgf855d93d2003-10-13 22:26:55 +00002556{
njn22cfccb2004-11-27 16:10:23 +00002557 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002558 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002559}
2560
nethercote85a456f2004-11-16 17:31:56 +00002561POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002562{
njn22cfccb2004-11-27 16:10:23 +00002563 if (!VG_(fd_allowed)(RES, "dup", tid, True)) {
2564 VG_(close)(RES);
2565 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002566 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002567 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002568 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002569 }
2570}
2571
nethercote85a456f2004-11-16 17:31:56 +00002572PRE(sys_dup2, 0)
jsgf855d93d2003-10-13 22:26:55 +00002573{
njn22cfccb2004-11-27 16:10:23 +00002574 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002575 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
njn22cfccb2004-11-27 16:10:23 +00002576 if (!VG_(fd_allowed)(ARG2, "dup2", tid, True))
2577 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002578}
2579
nethercote85a456f2004-11-16 17:31:56 +00002580POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002581{
nethercote71f05f32004-11-12 18:49:27 +00002582 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002583 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
jsgf855d93d2003-10-13 22:26:55 +00002584}
2585
nethercote85a456f2004-11-16 17:31:56 +00002586PRE(sys_fchdir, 0)
jsgf855d93d2003-10-13 22:26:55 +00002587{
njn22cfccb2004-11-27 16:10:23 +00002588 PRINT("sys_fchdir ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002589 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
jsgf855d93d2003-10-13 22:26:55 +00002590}
2591
nethercote85a456f2004-11-16 17:31:56 +00002592PRE(sys_fchown16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002593{
njn22cfccb2004-11-27 16:10:23 +00002594 PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002595 PRE_REG_READ3(long, "fchown16",
2596 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
jsgf855d93d2003-10-13 22:26:55 +00002597}
2598
nethercote85a456f2004-11-16 17:31:56 +00002599PRE(sys_fchown, 0)
nethercote2e1c37d2004-11-13 13:57:12 +00002600{
njn22cfccb2004-11-27 16:10:23 +00002601 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercote2e1c37d2004-11-13 13:57:12 +00002602 PRE_REG_READ3(long, "fchown",
2603 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2604}
jsgf855d93d2003-10-13 22:26:55 +00002605
nethercote85a456f2004-11-16 17:31:56 +00002606PRE(sys_fchmod, 0)
jsgf855d93d2003-10-13 22:26:55 +00002607{
njn22cfccb2004-11-27 16:10:23 +00002608 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00002609 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
jsgf855d93d2003-10-13 22:26:55 +00002610}
2611
njnc6168192004-11-29 13:54:10 +00002612PRE(sys_fcntl, 0)
njncfb8ad52004-11-23 14:57:49 +00002613{
njn22cfccb2004-11-27 16:10:23 +00002614 switch (ARG2) {
2615 // These ones ignore ARG3.
njncfb8ad52004-11-23 14:57:49 +00002616 case VKI_F_GETFD:
2617 case VKI_F_GETFL:
2618 case VKI_F_GETOWN:
2619 case VKI_F_SETOWN:
2620 case VKI_F_GETSIG:
2621 case VKI_F_SETSIG:
2622 case VKI_F_GETLEASE:
njnc6168192004-11-29 13:54:10 +00002623 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2624 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
njncfb8ad52004-11-23 14:57:49 +00002625 break;
2626
njn22cfccb2004-11-27 16:10:23 +00002627 // These ones use ARG3 as "arg".
njncfb8ad52004-11-23 14:57:49 +00002628 case VKI_F_DUPFD:
2629 case VKI_F_SETFD:
2630 case VKI_F_SETFL:
2631 case VKI_F_SETLEASE:
2632 case VKI_F_NOTIFY:
njnc6168192004-11-29 13:54:10 +00002633 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2634 PRE_REG_READ3(long, "fcntl",
2635 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
njncfb8ad52004-11-23 14:57:49 +00002636 break;
2637
njn22cfccb2004-11-27 16:10:23 +00002638 // These ones use ARG3 as "lock".
njncfb8ad52004-11-23 14:57:49 +00002639 case VKI_F_GETLK:
2640 case VKI_F_SETLK:
2641 case VKI_F_SETLKW:
njnc6168192004-11-29 13:54:10 +00002642#ifndef __amd64__
njncfb8ad52004-11-23 14:57:49 +00002643 case VKI_F_GETLK64:
2644 case VKI_F_SETLK64:
2645 case VKI_F_SETLKW64:
njnc6168192004-11-29 13:54:10 +00002646#else
2647#endif
2648 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2649 PRE_REG_READ3(long, "fcntl",
2650 unsigned int, fd, unsigned int, cmd,
2651 struct flock64 *, lock);
njncfb8ad52004-11-23 14:57:49 +00002652 break;
2653 }
njncfb8ad52004-11-23 14:57:49 +00002654
sewardjb5f6f512005-03-10 23:59:00 +00002655 //if (ARG2 == VKI_F_SETLKW)
2656 // tst->sys_flags |= MayBlock;
njncfb8ad52004-11-23 14:57:49 +00002657}
2658
2659POST(sys_fcntl)
2660{
njn22cfccb2004-11-27 16:10:23 +00002661 if (ARG2 == VKI_F_DUPFD) {
2662 if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
2663 VG_(close)(RES);
2664 SET_RESULT( -VKI_EMFILE );
njncfb8ad52004-11-23 14:57:49 +00002665 } else {
2666 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002667 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
njncfb8ad52004-11-23 14:57:49 +00002668 }
2669 }
2670}
2671
nethercote06c7bd72004-11-14 19:11:56 +00002672// XXX: wrapper only suitable for 32-bit systems
nethercote85a456f2004-11-16 17:31:56 +00002673PRE(sys_fcntl64, 0)
jsgf855d93d2003-10-13 22:26:55 +00002674{
njnc6168192004-11-29 13:54:10 +00002675 switch (ARG2) {
2676 // These ones ignore ARG3.
2677 case VKI_F_GETFD:
2678 case VKI_F_GETFL:
2679 case VKI_F_GETOWN:
2680 case VKI_F_SETOWN:
2681 case VKI_F_GETSIG:
2682 case VKI_F_SETSIG:
2683 case VKI_F_GETLEASE:
2684 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2685 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2686 break;
2687
2688 // These ones use ARG3 as "arg".
2689 case VKI_F_DUPFD:
2690 case VKI_F_SETFD:
2691 case VKI_F_SETFL:
2692 case VKI_F_SETLEASE:
2693 case VKI_F_NOTIFY:
2694 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2695 PRE_REG_READ3(long, "fcntl64",
2696 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2697 break;
2698
2699 // These ones use ARG3 as "lock".
2700 case VKI_F_GETLK:
2701 case VKI_F_SETLK:
2702 case VKI_F_SETLKW:
2703#ifndef __amd64__
2704 case VKI_F_GETLK64:
2705 case VKI_F_SETLK64:
2706 case VKI_F_SETLKW64:
2707#endif
2708 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2709 PRE_REG_READ3(long, "fcntl64",
2710 unsigned int, fd, unsigned int, cmd,
2711 struct flock64 *, lock);
2712 break;
2713 }
njncfb8ad52004-11-23 14:57:49 +00002714
njnc6168192004-11-29 13:54:10 +00002715#ifndef __amd64__
sewardjb5f6f512005-03-10 23:59:00 +00002716 //if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2717 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002718#else
sewardjb5f6f512005-03-10 23:59:00 +00002719 //if (ARG2 == VKI_F_SETLKW)
2720 // tst->sys_flags |= MayBlock;
njnc6168192004-11-29 13:54:10 +00002721#endif
rjwalshf5f536f2003-11-17 17:45:00 +00002722}
2723
nethercote85a456f2004-11-16 17:31:56 +00002724POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002725{
njn22cfccb2004-11-27 16:10:23 +00002726 if (ARG2 == VKI_F_DUPFD) {
2727 if (!VG_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
2728 VG_(close)(RES);
2729 SET_RESULT( -VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002730 } else {
2731 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00002732 VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
nethercote493dd182004-02-24 23:57:47 +00002733 }
2734 }
jsgf855d93d2003-10-13 22:26:55 +00002735}
2736
nethercote85a456f2004-11-16 17:31:56 +00002737PRE(sys_newfstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00002738{
njn22cfccb2004-11-27 16:10:23 +00002739 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00002740 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00002741 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002742}
2743
nethercote85a456f2004-11-16 17:31:56 +00002744POST(sys_newfstat)
jsgf855d93d2003-10-13 22:26:55 +00002745{
njn22cfccb2004-11-27 16:10:23 +00002746 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00002747}
2748
nethercote73b526f2004-10-31 18:48:21 +00002749static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002750
nethercote75a8c982004-11-11 19:03:34 +00002751// In Linux, the sys_fork() function varies across architectures, but we
2752// ignore the various args it gets, and so it looks arch-neutral. Hmm.
nethercote85a456f2004-11-16 17:31:56 +00002753PRE(sys_fork, 0)
jsgf855d93d2003-10-13 22:26:55 +00002754{
nethercote73b526f2004-10-31 18:48:21 +00002755 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002756
nethercote75a8c982004-11-11 19:03:34 +00002757 PRINT("sys_fork ( )");
2758 PRE_REG_READ0(long, "fork");
2759
jsgf855d93d2003-10-13 22:26:55 +00002760 /* Block all signals during fork, so that we can fix things up in
2761 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002762 VG_(sigfillset)(&mask);
2763 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002764
sewardjb5f6f512005-03-10 23:59:00 +00002765 VG_(do_atfork_pre)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002766
sewardjb5f6f512005-03-10 23:59:00 +00002767 SET_RESULT(VG_(do_syscall0)(__NR_fork));
2768
njn22cfccb2004-11-27 16:10:23 +00002769 if (RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002770 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002771
2772 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002773 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardjb5f6f512005-03-10 23:59:00 +00002774 } else if (RES > 0) {
2775 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002776
sewardjb5f6f512005-03-10 23:59:00 +00002777 VG_(do_atfork_parent)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002778
2779 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002780 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002781 }
2782}
2783
nethercote85a456f2004-11-16 17:31:56 +00002784PRE(sys_ftruncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002785{
njn22cfccb2004-11-27 16:10:23 +00002786 PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002787 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
jsgf855d93d2003-10-13 22:26:55 +00002788}
2789
nethercote85a456f2004-11-16 17:31:56 +00002790PRE(sys_truncate, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002791{
njn22cfccb2004-11-27 16:10:23 +00002792 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00002793 PRE_REG_READ2(long, "truncate",
2794 const char *, path, unsigned long, length);
njn22cfccb2004-11-27 16:10:23 +00002795 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002796}
2797
nethercote5a945af2004-11-14 18:37:07 +00002798// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002799PRE(sys_ftruncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002800{
njn22cfccb2004-11-27 16:10:23 +00002801 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002802 PRE_REG_READ3(long, "ftruncate64",
2803 unsigned int, fd,
2804 vki_u32, length_low32, vki_u32, length_high32);
2805}
2806
2807// XXX: this wrapper is only suitable for 32-bit platforms
nethercote85a456f2004-11-16 17:31:56 +00002808PRE(sys_truncate64, MayBlock)
nethercote5a945af2004-11-14 18:37:07 +00002809{
njn22cfccb2004-11-27 16:10:23 +00002810 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
nethercote5a945af2004-11-14 18:37:07 +00002811 PRE_REG_READ3(long, "truncate64",
2812 const char *, path,
2813 vki_u32, length_low32, vki_u32, length_high32);
njn22cfccb2004-11-27 16:10:23 +00002814 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
nethercote5a945af2004-11-14 18:37:07 +00002815}
2816
2817
nethercote85a456f2004-11-16 17:31:56 +00002818PRE(sys_getdents, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002819{
njn22cfccb2004-11-27 16:10:23 +00002820 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002821 PRE_REG_READ3(long, "getdents",
2822 unsigned int, fd, struct linux_dirent *, dirp,
2823 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002824 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002825}
2826
nethercote85a456f2004-11-16 17:31:56 +00002827POST(sys_getdents)
jsgf855d93d2003-10-13 22:26:55 +00002828{
njn22cfccb2004-11-27 16:10:23 +00002829 if (RES > 0)
2830 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002831}
2832
nethercote85a456f2004-11-16 17:31:56 +00002833PRE(sys_getdents64, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00002834{
njn22cfccb2004-11-27 16:10:23 +00002835 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002836 PRE_REG_READ3(long, "getdents64",
2837 unsigned int, fd, struct linux_dirent64 *, dirp,
2838 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002839 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002840}
2841
nethercote85a456f2004-11-16 17:31:56 +00002842POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002843{
njn22cfccb2004-11-27 16:10:23 +00002844 if (RES > 0)
2845 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002846}
2847
nethercote85a456f2004-11-16 17:31:56 +00002848PRE(sys_getgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002849{
njn22cfccb2004-11-27 16:10:23 +00002850 PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002851 PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002852 if (ARG1 > 0)
2853 PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002854}
2855
nethercote85a456f2004-11-16 17:31:56 +00002856POST(sys_getgroups16)
nethercote686b5db2004-11-14 13:42:51 +00002857{
njn22cfccb2004-11-27 16:10:23 +00002858 if (ARG1 > 0 && RES > 0)
2859 POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00002860}
2861
nethercote85a456f2004-11-16 17:31:56 +00002862PRE(sys_getgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00002863{
njn22cfccb2004-11-27 16:10:23 +00002864 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00002865 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00002866 if (ARG1 > 0)
2867 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002868}
2869
nethercote85a456f2004-11-16 17:31:56 +00002870POST(sys_getgroups)
jsgf855d93d2003-10-13 22:26:55 +00002871{
njn22cfccb2004-11-27 16:10:23 +00002872 if (ARG1 > 0 && RES > 0)
2873 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00002874}
2875
nethercote85a456f2004-11-16 17:31:56 +00002876PRE(sys_getcwd, 0)
jsgf855d93d2003-10-13 22:26:55 +00002877{
nethercoteac866b92004-11-15 20:23:15 +00002878 // Note that the kernel version of getcwd() behaves quite differently to
2879 // the glibc one.
njn22cfccb2004-11-27 16:10:23 +00002880 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002881 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002882 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002883}
2884
nethercote85a456f2004-11-16 17:31:56 +00002885POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002886{
njn22cfccb2004-11-27 16:10:23 +00002887 if (RES != (Addr)NULL)
2888 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002889}
2890
nethercote85a456f2004-11-16 17:31:56 +00002891PRE(sys_geteuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002892{
nethercote0df495a2004-11-11 16:38:21 +00002893 PRINT("sys_geteuid16 ( )");
2894 PRE_REG_READ0(long, "geteuid16");
jsgf855d93d2003-10-13 22:26:55 +00002895}
2896
nethercote85a456f2004-11-16 17:31:56 +00002897PRE(sys_geteuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002898{
nethercote0df495a2004-11-11 16:38:21 +00002899 PRINT("sys_geteuid ( )");
2900 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002901}
2902
nethercote85a456f2004-11-16 17:31:56 +00002903PRE(sys_getegid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002904{
nethercote0df495a2004-11-11 16:38:21 +00002905 PRINT("sys_getegid16 ( )");
2906 PRE_REG_READ0(long, "getegid16");
jsgf855d93d2003-10-13 22:26:55 +00002907}
2908
nethercote85a456f2004-11-16 17:31:56 +00002909PRE(sys_getegid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002910{
nethercote0df495a2004-11-11 16:38:21 +00002911 PRINT("sys_getegid ( )");
2912 PRE_REG_READ0(long, "getegid");
jsgf855d93d2003-10-13 22:26:55 +00002913}
2914
nethercote85a456f2004-11-16 17:31:56 +00002915PRE(sys_getgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00002916{
nethercote0df495a2004-11-11 16:38:21 +00002917 PRINT("sys_getgid16 ( )");
2918 PRE_REG_READ0(long, "getgid16");
jsgf855d93d2003-10-13 22:26:55 +00002919}
2920
nethercote85a456f2004-11-16 17:31:56 +00002921PRE(sys_getgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002922{
nethercote0df495a2004-11-11 16:38:21 +00002923 PRINT("sys_getgid ( )");
2924 PRE_REG_READ0(long, "getgid");
jsgf855d93d2003-10-13 22:26:55 +00002925}
2926
nethercote85a456f2004-11-16 17:31:56 +00002927PRE(sys_getpid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002928{
nethercote4e632c22004-11-09 16:45:33 +00002929 PRINT("sys_getpid ()");
2930 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00002931}
2932
nethercote85a456f2004-11-16 17:31:56 +00002933PRE(sys_getpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002934{
njn22cfccb2004-11-27 16:10:23 +00002935 PRINT("sys_getpgid ( %d )", ARG1);
nethercote5b653bc2004-11-15 14:32:12 +00002936 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
jsgf855d93d2003-10-13 22:26:55 +00002937}
2938
nethercote85a456f2004-11-16 17:31:56 +00002939PRE(sys_getpgrp, 0)
jsgf855d93d2003-10-13 22:26:55 +00002940{
nethercote0df495a2004-11-11 16:38:21 +00002941 PRINT("sys_getpgrp ()");
2942 PRE_REG_READ0(long, "getpgrp");
jsgf855d93d2003-10-13 22:26:55 +00002943}
2944
nethercote85a456f2004-11-16 17:31:56 +00002945PRE(sys_getppid, 0)
jsgf855d93d2003-10-13 22:26:55 +00002946{
nethercote4e632c22004-11-09 16:45:33 +00002947 PRINT("sys_getppid ()");
2948 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00002949}
2950
njn03f1e582005-03-26 20:08:06 +00002951POST(sys_getppid)
2952{
2953 /* If the master thread has already exited, and it is this thread's
2954 parent, then force getppid to return 1 (init) rather than the
2955 real ppid, so that it thinks its parent has exited. */
2956 if (VG_(threads)[VG_(master_tid)].os_state.lwpid == RES &&
2957 VG_(is_exiting)(VG_(master_tid)))
2958 RES = 1;
2959}
2960
njncf45fd42004-11-24 16:30:22 +00002961static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00002962{
nethercote620154f2004-11-12 21:21:07 +00002963 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00002964
nethercote620154f2004-11-12 21:21:07 +00002965 switch (a1) {
2966 case VKI_RLIMIT_NOFILE:
2967 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
2968 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
2969 break;
nethercote535f03b2004-02-15 15:32:51 +00002970
nethercote620154f2004-11-12 21:21:07 +00002971 case VKI_RLIMIT_DATA:
2972 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
2973 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002974
nethercote620154f2004-11-12 21:21:07 +00002975 case VKI_RLIMIT_STACK:
2976 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
2977 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00002978 }
jsgf855d93d2003-10-13 22:26:55 +00002979}
2980
nethercote85a456f2004-11-16 17:31:56 +00002981PRE(sys_old_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002982{
njn22cfccb2004-11-27 16:10:23 +00002983 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002984 PRE_REG_READ2(long, "old_getrlimit",
2985 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002986 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00002987}
2988
nethercote85a456f2004-11-16 17:31:56 +00002989POST(sys_old_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00002990{
njn22cfccb2004-11-27 16:10:23 +00002991 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00002992}
2993
nethercote85a456f2004-11-16 17:31:56 +00002994PRE(sys_getrlimit, 0)
nethercote620154f2004-11-12 21:21:07 +00002995{
njn22cfccb2004-11-27 16:10:23 +00002996 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00002997 PRE_REG_READ2(long, "getrlimit",
2998 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00002999 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00003000}
3001
nethercote85a456f2004-11-16 17:31:56 +00003002POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00003003{
njn22cfccb2004-11-27 16:10:23 +00003004 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00003005}
jsgf855d93d2003-10-13 22:26:55 +00003006
nethercote85a456f2004-11-16 17:31:56 +00003007PRE(sys_getrusage, 0)
jsgf855d93d2003-10-13 22:26:55 +00003008{
3009 /* int getrusage (int who, struct rusage *usage); */
njn22cfccb2004-11-27 16:10:23 +00003010 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
nethercotef1049bf2004-11-14 17:03:47 +00003011 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
njn22cfccb2004-11-27 16:10:23 +00003012 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00003013}
3014
nethercote85a456f2004-11-16 17:31:56 +00003015POST(sys_getrusage)
jsgf855d93d2003-10-13 22:26:55 +00003016{
njn22cfccb2004-11-27 16:10:23 +00003017 if (RES == 0)
3018 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00003019}
3020
nethercote85a456f2004-11-16 17:31:56 +00003021PRE(sys_gettimeofday, 0)
jsgf855d93d2003-10-13 22:26:55 +00003022{
njn22cfccb2004-11-27 16:10:23 +00003023 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003024 PRE_REG_READ2(long, "gettimeofday",
3025 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003026 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3027 if (ARG2 != 0)
3028 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003029}
3030
nethercote85a456f2004-11-16 17:31:56 +00003031POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003032{
njn22cfccb2004-11-27 16:10:23 +00003033 if (RES == 0) {
3034 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
3035 if (ARG2 != 0)
3036 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003037 }
3038}
3039
nethercote85a456f2004-11-16 17:31:56 +00003040PRE(sys_settimeofday, 0)
nethercote686b5db2004-11-14 13:42:51 +00003041{
njn22cfccb2004-11-27 16:10:23 +00003042 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003043 PRE_REG_READ2(long, "settimeofday",
3044 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003045 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3046 if (ARG2 != 0) {
3047 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
nethercote686b5db2004-11-14 13:42:51 +00003048 /* maybe should warn if tz->tz_dsttime is non-zero? */
3049 }
3050}
3051
nethercote85a456f2004-11-16 17:31:56 +00003052PRE(sys_getuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00003053{
nethercote0df495a2004-11-11 16:38:21 +00003054 PRINT("sys_getuid16 ( )");
3055 PRE_REG_READ0(long, "getuid16");
jsgf855d93d2003-10-13 22:26:55 +00003056}
3057
nethercote85a456f2004-11-16 17:31:56 +00003058PRE(sys_getuid, 0)
jsgf855d93d2003-10-13 22:26:55 +00003059{
nethercote0df495a2004-11-11 16:38:21 +00003060 PRINT("sys_getuid ( )");
3061 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00003062}
3063
nethercote2e1c37d2004-11-13 13:57:12 +00003064// XXX: I reckon some of these cases must be x86-specific
nethercote85a456f2004-11-16 17:31:56 +00003065PRE(sys_ioctl, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00003066{
njn22cfccb2004-11-27 16:10:23 +00003067 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00003068 PRE_REG_READ3(long, "ioctl",
3069 unsigned int, fd, unsigned int, request, unsigned long, arg);
3070
njn22cfccb2004-11-27 16:10:23 +00003071 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003072 case VKI_TCSETS:
3073 case VKI_TCSETSW:
3074 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00003075 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003076 break;
nethercote73b526f2004-10-31 18:48:21 +00003077 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003078 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003079 break;
nethercote73b526f2004-10-31 18:48:21 +00003080 case VKI_TCSETA:
3081 case VKI_TCSETAW:
3082 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00003083 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003084 break;
nethercote73b526f2004-10-31 18:48:21 +00003085 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003086 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003087 break;
nethercote73b526f2004-10-31 18:48:21 +00003088 case VKI_TCSBRK:
3089 case VKI_TCXONC:
3090 case VKI_TCSBRKP:
3091 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003092 /* These just take an int by value */
3093 break;
nethercote73b526f2004-10-31 18:48:21 +00003094 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003095 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003096 break;
nethercote73b526f2004-10-31 18:48:21 +00003097 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003098 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003099 break;
nethercote73b526f2004-10-31 18:48:21 +00003100 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00003101 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003102 break;
nethercote73b526f2004-10-31 18:48:21 +00003103 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00003104 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003105 break;
nethercote73b526f2004-10-31 18:48:21 +00003106 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00003107 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003108 break;
nethercote73b526f2004-10-31 18:48:21 +00003109 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003110 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
3111 if (*(char *)ARG3 == 11) {
3112 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003113 }
3114 break;
nethercote73b526f2004-10-31 18:48:21 +00003115 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003116 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003117 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003118 break;
nethercote73b526f2004-10-31 18:48:21 +00003119 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003120 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003121 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003122 break;
nethercote73b526f2004-10-31 18:48:21 +00003123 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003124 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003125 break;
nethercote73b526f2004-10-31 18:48:21 +00003126 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003127 /* Just takes an int value. */
3128 break;
nethercote73b526f2004-10-31 18:48:21 +00003129 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00003130 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003131 break;
nethercote73b526f2004-10-31 18:48:21 +00003132 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00003133 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003134 break;
nethercote73b526f2004-10-31 18:48:21 +00003135 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00003136 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003137 break;
nethercote73b526f2004-10-31 18:48:21 +00003138 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003139 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003140 break;
3141
nethercote73b526f2004-10-31 18:48:21 +00003142 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00003143 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003144 break;
nethercote73b526f2004-10-31 18:48:21 +00003145 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003146 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00003147 break;
nethercote73b526f2004-10-31 18:48:21 +00003148 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003149 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00003150 break;
nethercote73b526f2004-10-31 18:48:21 +00003151 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003152 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003153 break;
nethercote73b526f2004-10-31 18:48:21 +00003154 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003155 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003156 break;
nethercote73b526f2004-10-31 18:48:21 +00003157 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003158 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003159 break;
nethercote73b526f2004-10-31 18:48:21 +00003160 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003161 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003162 break;
nethercote73b526f2004-10-31 18:48:21 +00003163 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00003164 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003165 break;
nethercote73b526f2004-10-31 18:48:21 +00003166 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00003167 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003168 break;
nethercote73b526f2004-10-31 18:48:21 +00003169 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00003170 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003171 break;
jsgf855d93d2003-10-13 22:26:55 +00003172
muellera4b153a2003-11-19 22:07:14 +00003173 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003174 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00003175 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003176 break;
muellera4b153a2003-11-19 22:07:14 +00003177 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003178 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00003179 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
3180 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
3181 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003182 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003183 break;
3184
3185 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003186 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00003187 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00003188 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3189 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003190 break;
nethercote73b526f2004-10-31 18:48:21 +00003191 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00003192 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003193 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3194 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003195 break;
nethercote73b526f2004-10-31 18:48:21 +00003196 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003197 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003198 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3199 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003200 break;
nethercote73b526f2004-10-31 18:48:21 +00003201 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003202 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003203 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3204 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003205 break;
nethercote73b526f2004-10-31 18:48:21 +00003206 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003207 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00003208 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3209 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003210 break;
nethercote73b526f2004-10-31 18:48:21 +00003211 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003212 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00003213 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3214 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003215 break;
nethercote73b526f2004-10-31 18:48:21 +00003216 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00003217 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003218 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3219 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003220 break;
nethercote73b526f2004-10-31 18:48:21 +00003221 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003222 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003223 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3224 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003225 break;
nethercote73b526f2004-10-31 18:48:21 +00003226 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003227 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003228 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3229 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003230 break;
nethercote73b526f2004-10-31 18:48:21 +00003231 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003232 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00003233 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3234 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003235 break;
nethercote73b526f2004-10-31 18:48:21 +00003236 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003237 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00003238 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3239 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003240 break;
nethercote73b526f2004-10-31 18:48:21 +00003241 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003242 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
njn22cfccb2004-11-27 16:10:23 +00003243 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3244 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
3245 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003246 break;
nethercote73b526f2004-10-31 18:48:21 +00003247 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003248 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00003249 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3250 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003251 break;
nethercote73b526f2004-10-31 18:48:21 +00003252 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003253 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003254 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003255 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003256 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3257 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003258 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003259 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3260 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
3261 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003262 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003263 break;
nethercote73b526f2004-10-31 18:48:21 +00003264 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003265 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003266 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3267 KERNEL_DO_SYSCALL(tid,RES);
3268 if (!VG_(is_kerror)(RES) && RES == 0)
3269 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003270 */
njn22cfccb2004-11-27 16:10:23 +00003271 PRE_MEM_READ( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct vki_ifconf));
3272 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00003273 // TODO len must be readable and writable
3274 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00003275 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003276 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003277 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003278 }
3279 break;
nethercote73b526f2004-10-31 18:48:21 +00003280 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003281 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003282 break;
3283 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3284 the number of bytes currently in that socket's send buffer.
3285 It writes this value as an int to the memory location
3286 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003287 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003288 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003289 break;
nethercote73b526f2004-10-31 18:48:21 +00003290 case VKI_SIOCGRARP: /* get RARP table entry */
3291 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003292 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003293 break;
3294
nethercote73b526f2004-10-31 18:48:21 +00003295 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003296 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003297 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003298 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003299 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3300 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003301 break;
nethercote73b526f2004-10-31 18:48:21 +00003302 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003303 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003304 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003305 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003306 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3307 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003308 break;
nethercote73b526f2004-10-31 18:48:21 +00003309 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003310 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003311 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003312 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003313 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3314 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003315 break;
nethercote73b526f2004-10-31 18:48:21 +00003316 case VKI_SIOCSIFADDR: /* set PA address */
3317 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3318 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3319 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003320 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003321 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003322 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003323 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3324 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003325 break;
nethercote73b526f2004-10-31 18:48:21 +00003326 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003327 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003328 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003329 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003330 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3331 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003332 break;
nethercote73b526f2004-10-31 18:48:21 +00003333 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003334 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003335 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003336 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003337 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3338 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003339 break;
nethercote73b526f2004-10-31 18:48:21 +00003340 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003341 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003342 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003343 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003344 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3345 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003346 break;
nethercote73b526f2004-10-31 18:48:21 +00003347 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003348 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003349 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003350 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003351 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3352 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003353 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003354 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3355 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003356 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003357 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
3358 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003359 break;
jsgf855d93d2003-10-13 22:26:55 +00003360 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003361 case VKI_SIOCADDRT: /* add routing table entry */
3362 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00003363 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00003364 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003365 break;
3366
3367 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003368 case VKI_SIOCDRARP: /* delete RARP table entry */
3369 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003370 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003371 case VKI_SIOCSARP: /* set ARP table entry */
3372 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003373 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003374 break;
3375
nethercote73b526f2004-10-31 18:48:21 +00003376 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003377 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003378 break;
nethercote73b526f2004-10-31 18:48:21 +00003379 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003380 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardjb5f6f512005-03-10 23:59:00 +00003381 //tst->sys_flags &= ~MayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003382 break;
3383
3384 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003385 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3386 case VKI_SNDCTL_SEQ_GETINCOUNT:
3387 case VKI_SNDCTL_SEQ_PERCMODE:
3388 case VKI_SNDCTL_SEQ_TESTMIDI:
3389 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3390 case VKI_SNDCTL_SEQ_NRSYNTHS:
3391 case VKI_SNDCTL_SEQ_NRMIDIS:
3392 case VKI_SNDCTL_SEQ_GETTIME:
3393 case VKI_SNDCTL_DSP_GETFMTS:
3394 case VKI_SNDCTL_DSP_GETTRIGGER:
3395 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003396 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003397 case VKI_SNDCTL_DSP_GETCAPS:
3398 case VKI_SOUND_PCM_READ_RATE:
3399 case VKI_SOUND_PCM_READ_CHANNELS:
3400 case VKI_SOUND_PCM_READ_BITS:
3401 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
3402 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003403 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003404 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003405 break;
nethercote73b526f2004-10-31 18:48:21 +00003406 case VKI_SNDCTL_SEQ_CTRLRATE:
3407 case VKI_SNDCTL_DSP_SPEED:
3408 case VKI_SNDCTL_DSP_STEREO:
3409 case VKI_SNDCTL_DSP_GETBLKSIZE:
3410 case VKI_SNDCTL_DSP_CHANNELS:
3411 case VKI_SOUND_PCM_WRITE_FILTER:
3412 case VKI_SNDCTL_DSP_SUBDIVIDE:
3413 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003414 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003415 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003416 case VKI_SNDCTL_TMR_TIMEBASE:
3417 case VKI_SNDCTL_TMR_TEMPO:
3418 case VKI_SNDCTL_TMR_SOURCE:
3419 case VKI_SNDCTL_MIDI_PRETIME:
3420 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003421 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003422 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003423 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003424 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003425 break;
nethercote73b526f2004-10-31 18:48:21 +00003426 case VKI_SNDCTL_DSP_GETOSPACE:
3427 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003428 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003429 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003430 break;
nethercote73b526f2004-10-31 18:48:21 +00003431 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003432 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003433 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003434 break;
3435
nethercote73b526f2004-10-31 18:48:21 +00003436 case VKI_SNDCTL_DSP_POST:
3437 case VKI_SNDCTL_DSP_RESET:
3438 case VKI_SNDCTL_DSP_SYNC:
3439 case VKI_SNDCTL_DSP_SETSYNCRO:
3440 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003441 break;
3442
3443 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003444 case VKI_RTC_UIE_ON:
3445 case VKI_RTC_UIE_OFF:
3446 case VKI_RTC_AIE_ON:
3447 case VKI_RTC_AIE_OFF:
3448 case VKI_RTC_PIE_ON:
3449 case VKI_RTC_PIE_OFF:
3450 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003451 break;
nethercote73b526f2004-10-31 18:48:21 +00003452 case VKI_RTC_RD_TIME:
3453 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003454 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003455 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003456 break;
nethercote73b526f2004-10-31 18:48:21 +00003457 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003458 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003459 break;
nethercote73b526f2004-10-31 18:48:21 +00003460 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003461 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003462 break;
jsgf855d93d2003-10-13 22:26:55 +00003463
nethercote95a97862004-11-06 16:31:43 +00003464 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003465 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003466 break;
jsgf855d93d2003-10-13 22:26:55 +00003467
thughesacbbc322004-06-19 12:12:01 +00003468 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00003469 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003470 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003471 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003472 break;
3473
jsgf855d93d2003-10-13 22:26:55 +00003474 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003475 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003476 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003477 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003478 break;
nethercote73b526f2004-10-31 18:48:21 +00003479 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003480 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003481 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003482 break;
nethercote73b526f2004-10-31 18:48:21 +00003483 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003484 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003485 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3486 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3487 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003488 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003489 break;
nethercote73b526f2004-10-31 18:48:21 +00003490 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003491 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003492 break;
nethercote73b526f2004-10-31 18:48:21 +00003493 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003494 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003495 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003496 break;
nethercote73b526f2004-10-31 18:48:21 +00003497 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003498 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003499 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3500 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003501 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003502 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3503 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3504 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003505 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003506 break;
nethercote73b526f2004-10-31 18:48:21 +00003507 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003508 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003509 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003510 break;
nethercote73b526f2004-10-31 18:48:21 +00003511 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003512 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003513 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003514 break;
nethercote73b526f2004-10-31 18:48:21 +00003515 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003516 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003517 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003518 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003519 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003520 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003521 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3522 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003523 }
3524 break;
nethercote73b526f2004-10-31 18:48:21 +00003525 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003526 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003527 break;
3528 /* The following two are probably bogus (should check args
3529 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003530 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3531 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003532 break;
thughes66d80092004-06-19 12:41:05 +00003533
nethercote73b526f2004-10-31 18:48:21 +00003534 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003535 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003536 break;
nethercote73b526f2004-10-31 18:48:21 +00003537 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003538 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003539 break;
3540
nethercote73b526f2004-10-31 18:48:21 +00003541 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003542 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003543 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003544 break;
nethercote73b526f2004-10-31 18:48:21 +00003545 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003546 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003547 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003548 break;
jsgf855d93d2003-10-13 22:26:55 +00003549
nethercote73b526f2004-10-31 18:48:21 +00003550 case VKI_PPCLAIM:
3551 case VKI_PPEXCL:
3552 case VKI_PPYIELD:
3553 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003554 break;
nethercote73b526f2004-10-31 18:48:21 +00003555 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003556 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003557 break;
nethercote73b526f2004-10-31 18:48:21 +00003558 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003559 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003560 break;
nethercote73b526f2004-10-31 18:48:21 +00003561 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003562 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003563 break;
nethercote73b526f2004-10-31 18:48:21 +00003564 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003565 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003566 break;
nethercote73b526f2004-10-31 18:48:21 +00003567 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003568 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003569 break;
nethercote73b526f2004-10-31 18:48:21 +00003570 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003571 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003572 break;
nethercote73b526f2004-10-31 18:48:21 +00003573 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003574 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003575 break;
nethercote73b526f2004-10-31 18:48:21 +00003576 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003577 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003578 break;
nethercote73b526f2004-10-31 18:48:21 +00003579 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003580 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003581 break;
nethercote73b526f2004-10-31 18:48:21 +00003582 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003583 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003584 break;
nethercote73b526f2004-10-31 18:48:21 +00003585 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003586 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003587 break;
nethercote73b526f2004-10-31 18:48:21 +00003588 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003589 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003590 break;
nethercote73b526f2004-10-31 18:48:21 +00003591 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003592 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003593 break;
nethercote73b526f2004-10-31 18:48:21 +00003594 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003595 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003596 break;
nethercote73b526f2004-10-31 18:48:21 +00003597 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003598 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003599 break;
nethercote73b526f2004-10-31 18:48:21 +00003600 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003601 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003602 break;
nethercote73b526f2004-10-31 18:48:21 +00003603 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003604 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003605 break;
nethercote73b526f2004-10-31 18:48:21 +00003606 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003607 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003608 break;
nethercote73b526f2004-10-31 18:48:21 +00003609 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003610 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003611 break;
3612
thughesb3d3bcf2004-11-13 00:36:15 +00003613 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003614 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003615 break;
3616 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003617 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003618 break;
3619
3620 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003621 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3622 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003623 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003624 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003625 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3626 32 * cfd->charcount );
3627 }
3628 break;
3629 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003630 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3631 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003632 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003633 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003634 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3635 32 * cfd->charcount );
3636 }
3637 break;
3638
3639 case VKI_PIO_FONTRESET:
3640 break;
3641
3642 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003643 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003644 break;
3645 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003646 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003647 break;
3648
3649 case VKI_KIOCSOUND:
3650 case VKI_KDMKTONE:
3651 break;
3652
3653 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003654 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003655 break;
3656 case VKI_KDSETLED:
3657 break;
3658
3659 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003660 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003661 break;
3662
3663 case VKI_KDADDIO:
3664 case VKI_KDDELIO:
3665 case VKI_KDENABIO:
3666 case VKI_KDDISABIO:
3667 break;
3668
3669 case VKI_KDSETMODE:
3670 break;
3671 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003672 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003673 break;
3674
3675 case VKI_KDMAPDISP:
3676 case VKI_KDUNMAPDISP:
3677 break;
3678
3679 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003680 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003681 break;
3682 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003683 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003684 break;
3685 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003686 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003687 VKI_E_TABSZ * sizeof(unsigned short) );
3688 break;
3689 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003690 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003691 VKI_E_TABSZ * sizeof(unsigned short) );
3692 break;
3693
3694 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003695 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003696 break;
3697 case VKI_KDSKBMODE:
3698 break;
3699
3700 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003701 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003702 break;
3703 case VKI_KDSKBMETA:
3704 break;
3705
3706 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003707 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003708 break;
3709 case VKI_KDSKBLED:
3710 break;
3711
3712 case VKI_KDGKBENT:
3713 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003714 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3715 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003716 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003717 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3718 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003719 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003720 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3721 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003722 break;
3723 case VKI_KDSKBENT:
3724 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003725 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3726 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003727 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003728 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3729 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003730 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003731 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3732 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003733 break;
3734
3735 case VKI_KDGKBSENT:
3736 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003737 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3738 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003739 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003740 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3741 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003742 break;
3743 case VKI_KDSKBSENT:
3744 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003745 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3746 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003747 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003748 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003749 break;
3750
3751 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003752 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003753 break;
3754 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003755 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003756 break;
3757
3758 case VKI_KDGETKEYCODE:
3759 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003760 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3761 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003762 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003763 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3764 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003765 break;
3766 case VKI_KDSETKEYCODE:
3767 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003768 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3769 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003770 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003771 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3772 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003773 break;
3774
3775 case VKI_KDSIGACCEPT:
3776 break;
3777
3778 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003779 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003780 break;
3781
jsgf855d93d2003-10-13 22:26:55 +00003782 /* We don't have any specific information on it, so
3783 try to do something reasonable based on direction and
3784 size bits. The encoding scheme is described in
3785 /usr/include/asm/ioctl.h.
3786
3787 According to Simon Hausmann, _IOC_READ means the kernel
3788 writes a value to the ioctl value passed from the user
3789 space and the other way around with _IOC_WRITE. */
3790 default: {
njn22cfccb2004-11-27 16:10:23 +00003791 UInt dir = _VKI_IOC_DIR(ARG2);
3792 UInt size = _VKI_IOC_SIZE(ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003793 if (VG_(strstr)(VG_(clo_weird_hacks), "lax-ioctls") != NULL) {
3794 /*
3795 * Be very lax about ioctl handling; the only
3796 * assumption is that the size is correct. Doesn't
3797 * require the full buffer to be initialized when
3798 * writing. Without this, using some device
3799 * drivers with a large number of strange ioctl
3800 * commands becomes very tiresome.
3801 */
nethercote73b526f2004-10-31 18:48:21 +00003802 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00003803 static Int moans = 3;
3804 if (moans > 0) {
3805 moans--;
3806 VG_(message)(Vg_UserMsg,
3807 "Warning: noted but unhandled ioctl 0x%x"
3808 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00003809 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00003810 VG_(message)(Vg_UserMsg,
3811 " This could cause spurious value errors"
3812 " to appear.");
3813 VG_(message)(Vg_UserMsg,
3814 " See README_MISSING_SYSCALL_OR_IOCTL for "
3815 "guidance on writing a proper wrapper." );
3816 }
3817 } else {
nethercote73b526f2004-10-31 18:48:21 +00003818 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003819 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00003820 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00003821 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00003822 }
3823 break;
3824 }
3825 }
3826}
3827
nethercote85a456f2004-11-16 17:31:56 +00003828POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003829{
njn22cfccb2004-11-27 16:10:23 +00003830 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003831 case VKI_TCSETS:
3832 case VKI_TCSETSW:
3833 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00003834 break;
nethercote73b526f2004-10-31 18:48:21 +00003835 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003836 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003837 break;
nethercote73b526f2004-10-31 18:48:21 +00003838 case VKI_TCSETA:
3839 case VKI_TCSETAW:
3840 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00003841 break;
nethercote73b526f2004-10-31 18:48:21 +00003842 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003843 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003844 break;
nethercote73b526f2004-10-31 18:48:21 +00003845 case VKI_TCSBRK:
3846 case VKI_TCXONC:
3847 case VKI_TCSBRKP:
3848 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003849 break;
nethercote73b526f2004-10-31 18:48:21 +00003850 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003851 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003852 break;
nethercote73b526f2004-10-31 18:48:21 +00003853 case VKI_TIOCSWINSZ:
3854 case VKI_TIOCMBIS:
3855 case VKI_TIOCMBIC:
3856 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00003857 break;
nethercote73b526f2004-10-31 18:48:21 +00003858 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003859 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003860 break;
nethercote73b526f2004-10-31 18:48:21 +00003861 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003862 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003863 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003864 break;
nethercote73b526f2004-10-31 18:48:21 +00003865 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003866 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003867 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003868 break;
nethercote73b526f2004-10-31 18:48:21 +00003869 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003870 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003871 break;
nethercote73b526f2004-10-31 18:48:21 +00003872 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003873 break;
nethercote73b526f2004-10-31 18:48:21 +00003874 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00003875 break;
nethercote73b526f2004-10-31 18:48:21 +00003876 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00003877 break;
nethercote73b526f2004-10-31 18:48:21 +00003878 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00003879 break;
nethercote73b526f2004-10-31 18:48:21 +00003880 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003881 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003882 break;
3883
nethercote73b526f2004-10-31 18:48:21 +00003884 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00003885 break;
nethercote73b526f2004-10-31 18:48:21 +00003886 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003887 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00003888 break;
nethercote73b526f2004-10-31 18:48:21 +00003889 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003890 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00003891 break;
nethercote73b526f2004-10-31 18:48:21 +00003892 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00003893 break;
nethercote73b526f2004-10-31 18:48:21 +00003894 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00003895 break;
nethercote73b526f2004-10-31 18:48:21 +00003896 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003897 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003898 break;
nethercote73b526f2004-10-31 18:48:21 +00003899 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003900 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003901 break;
nethercote73b526f2004-10-31 18:48:21 +00003902 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00003903 break;
nethercote73b526f2004-10-31 18:48:21 +00003904 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00003905 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003906 break;
nethercote73b526f2004-10-31 18:48:21 +00003907 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00003908 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00003909 break;
jsgf855d93d2003-10-13 22:26:55 +00003910
muellera4b153a2003-11-19 22:07:14 +00003911 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003912 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003913 break;
muellera4b153a2003-11-19 22:07:14 +00003914 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00003915 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003916 break;
3917
3918 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003919 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00003920 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
3921 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00003922 break;
nethercote73b526f2004-10-31 18:48:21 +00003923 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00003924 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3925 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003926 break;
nethercote73b526f2004-10-31 18:48:21 +00003927 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00003928 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3929 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003930 break;
nethercote73b526f2004-10-31 18:48:21 +00003931 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00003932 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3933 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003934 break;
nethercote73b526f2004-10-31 18:48:21 +00003935 case VKI_SIOCGIFADDR: /* get PA address */
3936 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
3937 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
3938 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00003939 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003940 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3941 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00003942 break;
nethercote73b526f2004-10-31 18:48:21 +00003943 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00003944 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003945 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3946 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003947 break;
nethercote73b526f2004-10-31 18:48:21 +00003948 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00003949 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003950 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3951 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003952 break;
3953 break;
nethercote73b526f2004-10-31 18:48:21 +00003954 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00003955 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003956 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3957 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003958 break;
nethercote73b526f2004-10-31 18:48:21 +00003959 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00003960 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003961 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
3962 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00003963 break;
nethercote73b526f2004-10-31 18:48:21 +00003964 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00003965 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003966 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3967 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00003968 break;
nethercote73b526f2004-10-31 18:48:21 +00003969 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00003970 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00003971 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
3972 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00003973 break;
nethercote73b526f2004-10-31 18:48:21 +00003974 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003975 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003976 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3977 KERNEL_DO_SYSCALL(tid,RES);
3978 if (!VG_(is_kerror)(RES) && RES == 0)
3979 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003980 */
njn22cfccb2004-11-27 16:10:23 +00003981 if (RES == 0 && ARG3 ) {
3982 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00003983 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00003984 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003985 }
3986 break;
nethercote73b526f2004-10-31 18:48:21 +00003987 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003988 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00003989 break;
3990 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3991 the number of bytes currently in that socket's send buffer.
3992 It writes this value as an int to the memory location
3993 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003994 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003995 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003996 break;
nethercote73b526f2004-10-31 18:48:21 +00003997 case VKI_SIOCGRARP: /* get RARP table entry */
3998 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003999 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00004000 break;
4001
nethercote73b526f2004-10-31 18:48:21 +00004002 case VKI_SIOCSIFFLAGS: /* set flags */
4003 case VKI_SIOCSIFMAP: /* Set device parameters */
4004 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
4005 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
4006 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
4007 case VKI_SIOCSIFNETMASK: /* set network PA mask */
4008 case VKI_SIOCSIFMETRIC: /* set metric */
4009 case VKI_SIOCSIFADDR: /* set PA address */
4010 case VKI_SIOCSIFMTU: /* set MTU size */
4011 case VKI_SIOCSIFHWADDR: /* set hardware address */
4012 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00004013 break;
4014 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00004015 case VKI_SIOCADDRT: /* add routing table entry */
4016 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00004017 break;
4018
4019 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004020 case VKI_SIOCDRARP: /* delete RARP table entry */
4021 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004022 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004023 case VKI_SIOCSARP: /* set ARP table entry */
4024 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004025 break;
4026
nethercote73b526f2004-10-31 18:48:21 +00004027 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00004028 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00004029 break;
nethercote73b526f2004-10-31 18:48:21 +00004030 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004031 break;
4032
4033 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00004034 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4035 case VKI_SNDCTL_SEQ_GETINCOUNT:
4036 case VKI_SNDCTL_SEQ_PERCMODE:
4037 case VKI_SNDCTL_SEQ_TESTMIDI:
4038 case VKI_SNDCTL_SEQ_RESETSAMPLES:
4039 case VKI_SNDCTL_SEQ_NRSYNTHS:
4040 case VKI_SNDCTL_SEQ_NRMIDIS:
4041 case VKI_SNDCTL_SEQ_GETTIME:
4042 case VKI_SNDCTL_DSP_GETFMTS:
4043 case VKI_SNDCTL_DSP_GETTRIGGER:
4044 case VKI_SNDCTL_DSP_GETODELAY:
4045 case VKI_SNDCTL_DSP_GETSPDIF:
4046 case VKI_SNDCTL_DSP_GETCAPS:
4047 case VKI_SOUND_PCM_READ_RATE:
4048 case VKI_SOUND_PCM_READ_CHANNELS:
4049 case VKI_SOUND_PCM_READ_BITS:
4050 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
4051 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00004052 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004053 break;
nethercote73b526f2004-10-31 18:48:21 +00004054 case VKI_SNDCTL_SEQ_CTRLRATE:
4055 case VKI_SNDCTL_DSP_SPEED:
4056 case VKI_SNDCTL_DSP_STEREO:
4057 case VKI_SNDCTL_DSP_GETBLKSIZE:
4058 case VKI_SNDCTL_DSP_CHANNELS:
4059 case VKI_SOUND_PCM_WRITE_FILTER:
4060 case VKI_SNDCTL_DSP_SUBDIVIDE:
4061 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00004062 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00004063 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00004064 case VKI_SNDCTL_TMR_TIMEBASE:
4065 case VKI_SNDCTL_TMR_TEMPO:
4066 case VKI_SNDCTL_TMR_SOURCE:
4067 case VKI_SNDCTL_MIDI_PRETIME:
4068 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00004069 break;
nethercote73b526f2004-10-31 18:48:21 +00004070 case VKI_SNDCTL_DSP_GETOSPACE:
4071 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00004072 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00004073 break;
nethercote73b526f2004-10-31 18:48:21 +00004074 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00004075 break;
4076
nethercote73b526f2004-10-31 18:48:21 +00004077 case VKI_SNDCTL_DSP_POST:
4078 case VKI_SNDCTL_DSP_RESET:
4079 case VKI_SNDCTL_DSP_SYNC:
4080 case VKI_SNDCTL_DSP_SETSYNCRO:
4081 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00004082 break;
4083
4084 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00004085 case VKI_RTC_UIE_ON:
4086 case VKI_RTC_UIE_OFF:
4087 case VKI_RTC_AIE_ON:
4088 case VKI_RTC_AIE_OFF:
4089 case VKI_RTC_PIE_ON:
4090 case VKI_RTC_PIE_OFF:
4091 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00004092 break;
nethercote73b526f2004-10-31 18:48:21 +00004093 case VKI_RTC_RD_TIME:
4094 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00004095 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00004096 break;
nethercote73b526f2004-10-31 18:48:21 +00004097 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00004098 break;
nethercote73b526f2004-10-31 18:48:21 +00004099 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00004100 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004101 break;
jsgf855d93d2003-10-13 22:26:55 +00004102
nethercote95a97862004-11-06 16:31:43 +00004103 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00004104 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004105 break;
jsgf855d93d2003-10-13 22:26:55 +00004106
thughesacbbc322004-06-19 12:12:01 +00004107 /* Hard disks */
nethercote73b526f2004-10-31 18:48:21 +00004108 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00004109 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00004110 break;
4111
jsgf855d93d2003-10-13 22:26:55 +00004112 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00004113 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00004114 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00004115 break;
nethercote73b526f2004-10-31 18:48:21 +00004116 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00004117 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004118 break;
nethercote73b526f2004-10-31 18:48:21 +00004119 case VKI_CDROMREADTOCENTRY:
njn22cfccb2004-11-27 16:10:23 +00004120 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004121 break;
nethercote73b526f2004-10-31 18:48:21 +00004122 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00004123 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00004124 break;
nethercote73b526f2004-10-31 18:48:21 +00004125 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00004126 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00004127 break;
nethercote73b526f2004-10-31 18:48:21 +00004128 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00004129 {
njn22cfccb2004-11-27 16:10:23 +00004130 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00004131 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00004132 break;
4133 }
4134
nethercote73b526f2004-10-31 18:48:21 +00004135 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00004136 break;
4137 /* The following two are probably bogus (should check args
4138 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00004139 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4140 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00004141 break;
4142
nethercote73b526f2004-10-31 18:48:21 +00004143 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00004144 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004145 break;
nethercote73b526f2004-10-31 18:48:21 +00004146 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00004147 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004148 break;
4149
nethercote73b526f2004-10-31 18:48:21 +00004150 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00004151 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004152 break;
nethercote73b526f2004-10-31 18:48:21 +00004153 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00004154 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004155 break;
4156
nethercote73b526f2004-10-31 18:48:21 +00004157 case VKI_PPCLAIM:
4158 case VKI_PPEXCL:
4159 case VKI_PPYIELD:
4160 case VKI_PPRELEASE:
4161 case VKI_PPSETMODE:
4162 case VKI_PPSETPHASE:
4163 case VKI_PPSETFLAGS:
4164 case VKI_PPWDATA:
4165 case VKI_PPWCONTROL:
4166 case VKI_PPFCONTROL:
4167 case VKI_PPDATADIR:
4168 case VKI_PPNEGOT:
4169 case VKI_PPWCTLONIRQ:
4170 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00004171 break;
nethercote73b526f2004-10-31 18:48:21 +00004172 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004173 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004174 break;
nethercote73b526f2004-10-31 18:48:21 +00004175 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00004176 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004177 break;
nethercote73b526f2004-10-31 18:48:21 +00004178 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00004179 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00004180 break;
nethercote73b526f2004-10-31 18:48:21 +00004181 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00004182 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004183 break;
nethercote73b526f2004-10-31 18:48:21 +00004184 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00004185 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004186 break;
nethercote73b526f2004-10-31 18:48:21 +00004187 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00004188 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004189 break;
nethercote73b526f2004-10-31 18:48:21 +00004190 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00004191 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004192 break;
nethercote73b526f2004-10-31 18:48:21 +00004193 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00004194 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004195 break;
nethercote73b526f2004-10-31 18:48:21 +00004196 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00004197 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00004198 break;
4199
thughesc3b842d2004-11-13 10:38:04 +00004200 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00004201 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00004202 break;
4203 case VKI_PIO_FONT:
4204 break;
4205
4206 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00004207 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
4208 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00004209 break;
4210 case VKI_PIO_FONTX:
4211 break;
4212
4213 case VKI_PIO_FONTRESET:
4214 break;
4215
4216 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00004217 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00004218 break;
4219 case VKI_PIO_CMAP:
4220 break;
4221
4222 case VKI_KIOCSOUND:
4223 case VKI_KDMKTONE:
4224 break;
4225
4226 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00004227 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004228 break;
4229 case VKI_KDSETLED:
4230 break;
4231
4232 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00004233 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004234 break;
4235
4236 case VKI_KDADDIO:
4237 case VKI_KDDELIO:
4238 case VKI_KDENABIO:
4239 case VKI_KDDISABIO:
4240 break;
4241
4242 case VKI_KDSETMODE:
4243 break;
4244 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004245 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004246 break;
4247
4248 case VKI_KDMAPDISP:
4249 case VKI_KDUNMAPDISP:
4250 break;
4251
4252 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004253 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00004254 break;
4255 case VKI_PIO_SCRNMAP:
4256 break;
4257 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004258 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00004259 break;
4260 case VKI_PIO_UNISCRNMAP:
4261 break;
4262
4263 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00004264 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004265 break;
4266 case VKI_KDSKBMODE:
4267 break;
4268
4269 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00004270 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004271 break;
4272 case VKI_KDSKBMETA:
4273 break;
4274
4275 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00004276 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004277 break;
4278 case VKI_KDSKBLED:
4279 break;
4280
4281 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00004282 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
4283 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00004284 break;
4285 case VKI_KDSKBENT:
4286 break;
4287
4288 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00004289 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
4290 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00004291 break;
4292 case VKI_KDSKBSENT:
4293 break;
4294
4295 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00004296 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00004297 break;
4298 case VKI_KDSKBDIACR:
4299 break;
4300
4301 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00004302 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
4303 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00004304 break;
4305 case VKI_KDSETKEYCODE:
4306 break;
4307
4308 case VKI_KDSIGACCEPT:
4309 break;
4310
4311 case VKI_KDKBDREP:
4312 break;
4313
jsgf855d93d2003-10-13 22:26:55 +00004314 /* We don't have any specific information on it, so
4315 try to do something reasonable based on direction and
4316 size bits. The encoding scheme is described in
4317 /usr/include/asm/ioctl.h.
4318
4319 According to Simon Hausmann, _IOC_READ means the kernel
4320 writes a value to the ioctl value passed from the user
4321 space and the other way around with _IOC_WRITE. */
4322 default: {
njn22cfccb2004-11-27 16:10:23 +00004323 UInt dir = _VKI_IOC_DIR(ARG2);
4324 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00004325 if (size > 0 && (dir & _VKI_IOC_READ)
njn22cfccb2004-11-27 16:10:23 +00004326 && RES == 0
4327 && ARG3 != (Addr)NULL)
4328 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004329 break;
4330 }
4331 }
4332}
4333
njn03f1e582005-03-26 20:08:06 +00004334/*
4335 If we're sending a SIGKILL to one of our own threads, then simulate
4336 it rather than really sending the signal, so that the target thread
4337 gets a chance to clean up. Returns True if we did the killing (or
4338 no killing is necessary), and False if the caller should use the
4339 normal kill syscall.
4340
4341 "pid" is any pid argument which can be passed to kill; group kills
4342 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4343 they'll most likely hit all the threads and we won't need to worry
4344 about cleanup. In truth, we can't fully emulate these multicast
4345 kills.
4346
4347 "tgid" is a thread group id. If it is not -1, then the target
4348 thread must be in that thread group.
4349 */
4350Bool VG_(do_sigkill)(Int pid, Int tgid)
4351{
4352 ThreadState *tst;
4353 ThreadId tid;
4354
4355 if (pid <= 0)
4356 return False;
4357
4358 tid = VG_(get_lwp_tid)(pid);
4359 if (tid == VG_INVALID_THREADID)
4360 return False; /* none of our threads */
4361
4362 tst = VG_(get_ThreadState)(tid);
4363 if (tst == NULL || tst->status == VgTs_Empty)
4364 return False; /* hm, shouldn't happen */
4365
4366 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4367 return False; /* not the right thread group */
4368
4369 /* Check to see that the target isn't already exiting. */
4370 if (!VG_(is_exiting)(tid)) {
4371 if (VG_(clo_trace_signals))
4372 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL", tst->tid);
4373
4374 tst->exitreason = VgSrc_FatalSig;
4375 tst->os_state.fatalsig = VKI_SIGKILL;
4376
4377 if (!VG_(is_running_thread)(tid))
4378 VG_(kill_thread)(tid);
4379 }
4380
4381 return True;
4382}
4383
4384PRE(sys_kill, Special)
jsgf855d93d2003-10-13 22:26:55 +00004385{
4386 /* int kill(pid_t pid, int sig); */
njn22cfccb2004-11-27 16:10:23 +00004387 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004388 PRE_REG_READ2(long, "kill", int, pid, int, sig);
njn03f1e582005-03-26 20:08:06 +00004389 if (!VG_(client_signal_OK)(ARG2)) {
njn22cfccb2004-11-27 16:10:23 +00004390 SET_RESULT( -VKI_EINVAL );
njn03f1e582005-03-26 20:08:06 +00004391 return;
4392 }
jsgf855d93d2003-10-13 22:26:55 +00004393
njn03f1e582005-03-26 20:08:06 +00004394 /* If we're sending SIGKILL, check to see if the target is one of
4395 our threads and handle it specially. */
4396 if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
4397 SET_RESULT(0);
4398 else
4399 SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
4400
sewardjb5f6f512005-03-10 23:59:00 +00004401 if (VG_(clo_trace_signals))
4402 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
njn03f1e582005-03-26 20:08:06 +00004403 ARG2, ARG1);
sewardjb5f6f512005-03-10 23:59:00 +00004404 // Check to see if this kill gave us a pending signal
4405 VG_(poll_signals)(tid);
jsgf855d93d2003-10-13 22:26:55 +00004406}
4407
nethercote85a456f2004-11-16 17:31:56 +00004408PRE(sys_link, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004409{
njn22cfccb2004-11-27 16:10:23 +00004410 PRINT("sys_link ( %p, %p)", ARG1, ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004411 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004412 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4413 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004414}
4415
nethercote85a456f2004-11-16 17:31:56 +00004416PRE(sys_lseek, 0)
jsgf855d93d2003-10-13 22:26:55 +00004417{
njn22cfccb2004-11-27 16:10:23 +00004418 PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00004419 PRE_REG_READ3(vki_off_t, "lseek",
4420 unsigned int, fd, vki_off_t, offset, unsigned int, whence);
jsgf855d93d2003-10-13 22:26:55 +00004421}
4422
nethercote85a456f2004-11-16 17:31:56 +00004423PRE(sys_newlstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00004424{
njn22cfccb2004-11-27 16:10:23 +00004425 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004426 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00004427 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4428 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004429}
4430
nethercote85a456f2004-11-16 17:31:56 +00004431POST(sys_newlstat)
jsgf855d93d2003-10-13 22:26:55 +00004432{
njn22cfccb2004-11-27 16:10:23 +00004433 if (RES == 0) {
4434 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00004435 }
4436}
4437
njnc6168192004-11-29 13:54:10 +00004438// XXX: this syscall is generic, but not necessarily applicable to every
4439// architecture -- I think only to 32-bit archs. We're going to need
4440// something like linux/core_os32.h for such things, eventually, I think.
4441// --njn
4442#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00004443PRE(sys_lstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00004444{
njn22cfccb2004-11-27 16:10:23 +00004445 PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00004446 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00004447 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
4448 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004449}
4450
nethercote85a456f2004-11-16 17:31:56 +00004451POST(sys_lstat64)
jsgf855d93d2003-10-13 22:26:55 +00004452{
njn22cfccb2004-11-27 16:10:23 +00004453 if (RES == 0) {
4454 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00004455 }
4456}
njnc6168192004-11-29 13:54:10 +00004457#endif
jsgf855d93d2003-10-13 22:26:55 +00004458
nethercote85a456f2004-11-16 17:31:56 +00004459PRE(sys_mkdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004460{
njn22cfccb2004-11-27 16:10:23 +00004461 PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004462 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004463 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004464}
4465
nethercote85a456f2004-11-16 17:31:56 +00004466PRE(old_mmap, Special)
jsgf855d93d2003-10-13 22:26:55 +00004467{
nethercote151effa2004-11-15 12:57:39 +00004468 /* struct mmap_arg_struct {
4469 unsigned long addr;
4470 unsigned long len;
4471 unsigned long prot;
4472 unsigned long flags;
4473 unsigned long fd;
4474 unsigned long offset;
4475 }; */
jsgf855d93d2003-10-13 22:26:55 +00004476 UInt a1, a2, a3, a4, a5, a6;
4477
nethercote151effa2004-11-15 12:57:39 +00004478 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
njnf6d228b2005-03-26 02:42:31 +00004479 VGP_GET_MMAP_ARGS(tst, a1, a2, a3, a4, a5, a6);
jsgf855d93d2003-10-13 22:26:55 +00004480
nethercote151effa2004-11-15 12:57:39 +00004481 PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
4482 a1, (ULong)a2, a3, a4, a5, a6 );
nethercotedb233322003-12-02 14:56:04 +00004483
sewardjb5f6f512005-03-10 23:59:00 +00004484 if (a2 == 0) {
4485 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4486 shall be established. */
4487 SET_RESULT( -VKI_EINVAL );
4488 return;
4489 }
4490
sewardj565b1ed2005-03-11 14:12:38 +00004491 if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
4492 /* zap any misaligned addresses. */
4493 SET_RESULT( -VKI_EINVAL );
4494 return;
4495 }
4496
fitzhardinge98abfc72003-12-16 02:05:15 +00004497 if (a4 & VKI_MAP_FIXED) {
nethercote8ff888f2004-11-17 17:11:45 +00004498 if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
nethercote151effa2004-11-15 12:57:39 +00004499 PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
njn22cfccb2004-11-27 16:10:23 +00004500 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004501 }
4502 } else {
sewardjd0d97312005-03-23 02:53:13 +00004503 Addr a = VG_(find_map_space)(a1, a2, True);
4504 if (a == 0 && a1 != 0)
4505 a1 = VG_(find_map_space)(0, a2, True);
4506 else
4507 a1 = a;
fitzhardinge98abfc72003-12-16 02:05:15 +00004508 if (a1 == 0)
njn22cfccb2004-11-27 16:10:23 +00004509 SET_RESULT( -VKI_ENOMEM );
fitzhardinge98abfc72003-12-16 02:05:15 +00004510 else
nethercote151effa2004-11-15 12:57:39 +00004511 a4 |= VKI_MAP_FIXED;
fitzhardinge98abfc72003-12-16 02:05:15 +00004512 }
jsgf855d93d2003-10-13 22:26:55 +00004513
njn22cfccb2004-11-27 16:10:23 +00004514 if (RES != -VKI_ENOMEM) {
njn4fbc86c2005-05-08 00:45:11 +00004515 int res;
4516 VGP_DO_MMAP(res, a1, a2, a3, a4, a5, a6);
4517 SET_RESULT(res);
fitzhardingec2d65072004-01-07 08:44:43 +00004518
njn22cfccb2004-11-27 16:10:23 +00004519 if (!VG_(is_kerror)(RES)) {
4520 vg_assert(VG_(valid_client_addr)(RES, a2, tid, "old_mmap"));
4521 mmap_segment( (Addr)RES, a2, a3, a4, a5, a6 );
fitzhardingec2d65072004-01-07 08:44:43 +00004522 }
fitzhardinge98abfc72003-12-16 02:05:15 +00004523 }
jsgf855d93d2003-10-13 22:26:55 +00004524}
4525
nethercote3d5e9102004-11-17 18:22:38 +00004526PRE(sys_mmap2, 0)
4527{
4528 // Exactly like old_mmap() except:
4529 // - all 6 args are passed in regs, rather than in a memory-block.
4530 // - the file offset is specified in pagesize units rather than bytes,
4531 // so that it can be used for files bigger than 2^32 bytes.
4532 PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
njn22cfccb2004-11-27 16:10:23 +00004533 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
nethercote3d5e9102004-11-17 18:22:38 +00004534 PRE_REG_READ6(long, "mmap2",
4535 unsigned long, start, unsigned long, length,
4536 unsigned long, prot, unsigned long, flags,
4537 unsigned long, fd, unsigned long, offset);
4538
sewardjb5f6f512005-03-10 23:59:00 +00004539 if (ARG2 == 0) {
4540 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
4541 shall be established. */
4542 SET_RESULT( -VKI_EINVAL );
4543 return;
4544 }
4545
sewardj565b1ed2005-03-11 14:12:38 +00004546 if (/*(ARG4 & VKI_MAP_FIXED) && */ (0 != (ARG1 & (VKI_PAGE_SIZE-1)))) {
4547 /* zap any misaligned addresses. */
sewardjd0d97312005-03-23 02:53:13 +00004548 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
4549 to fail. Here, we catch them all. */
sewardj565b1ed2005-03-11 14:12:38 +00004550 SET_RESULT( -VKI_EINVAL );
4551 return;
4552 }
4553
njn22cfccb2004-11-27 16:10:23 +00004554 if (ARG4 & VKI_MAP_FIXED) {
4555 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
4556 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004557 } else {
sewardjd0d97312005-03-23 02:53:13 +00004558 Addr a = VG_(find_map_space)(ARG1, ARG2, True);
4559 if (a == 0 && ARG1 != 0)
4560 ARG1 = VG_(find_map_space)(0, ARG2, True);
4561 else
4562 ARG1 = a;
njn22cfccb2004-11-27 16:10:23 +00004563 if (ARG1 == 0)
4564 SET_RESULT( -VKI_ENOMEM );
nethercote3d5e9102004-11-17 18:22:38 +00004565 else
njn22cfccb2004-11-27 16:10:23 +00004566 ARG4 |= VKI_MAP_FIXED;
nethercote3d5e9102004-11-17 18:22:38 +00004567 }
4568}
4569
4570POST(sys_mmap2)
4571{
njn22cfccb2004-11-27 16:10:23 +00004572 vg_assert(VG_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
4573 mmap_segment( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
4574 ARG6 * (ULong)VKI_PAGE_SIZE );
nethercote3d5e9102004-11-17 18:22:38 +00004575}
4576
nethercote85a456f2004-11-16 17:31:56 +00004577PRE(sys_mprotect, 0)
jsgf855d93d2003-10-13 22:26:55 +00004578{
njn22cfccb2004-11-27 16:10:23 +00004579 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004580 PRE_REG_READ3(long, "mprotect",
4581 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004582
njn22cfccb2004-11-27 16:10:23 +00004583 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
4584 SET_RESULT( -VKI_ENOMEM );
jsgf855d93d2003-10-13 22:26:55 +00004585}
4586
nethercote85a456f2004-11-16 17:31:56 +00004587POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004588{
njn22cfccb2004-11-27 16:10:23 +00004589 Addr a = ARG1;
4590 SizeT len = ARG2;
4591 Int prot = ARG3;
nethercote27ea8bc2004-07-10 17:21:14 +00004592 Bool rr = prot & VKI_PROT_READ;
4593 Bool ww = prot & VKI_PROT_WRITE;
4594 Bool xx = prot & VKI_PROT_EXEC;
4595
nethercote27ea8bc2004-07-10 17:21:14 +00004596 mash_addr_and_len(&a, &len);
4597 VG_(mprotect_range)(a, len, prot);
4598 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
jsgf855d93d2003-10-13 22:26:55 +00004599}
4600
nethercote85a456f2004-11-16 17:31:56 +00004601PRE(sys_munmap, 0)
jsgf855d93d2003-10-13 22:26:55 +00004602{
njn22cfccb2004-11-27 16:10:23 +00004603 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004604 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004605
njn22cfccb2004-11-27 16:10:23 +00004606 if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4607 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004608}
4609
nethercote85a456f2004-11-16 17:31:56 +00004610POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004611{
njn22cfccb2004-11-27 16:10:23 +00004612 Addr a = ARG1;
4613 SizeT len = ARG2;
nethercote27ea8bc2004-07-10 17:21:14 +00004614
4615 mash_addr_and_len(&a, &len);
4616 VG_(unmap_range)(a, len);
4617 VG_TRACK( die_mem_munmap, a, len );
jsgf855d93d2003-10-13 22:26:55 +00004618}
4619
nethercote85a456f2004-11-16 17:31:56 +00004620PRE(sys_mincore, 0)
mueller6ceb2312004-01-02 22:52:34 +00004621{
njn22cfccb2004-11-27 16:10:23 +00004622 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00004623 PRE_REG_READ3(long, "mincore",
4624 unsigned long, start, vki_size_t, length,
4625 unsigned char *, vec);
njn22cfccb2004-11-27 16:10:23 +00004626 PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
mueller6ceb2312004-01-02 22:52:34 +00004627}
4628
nethercote85a456f2004-11-16 17:31:56 +00004629POST(sys_mincore)
mueller6ceb2312004-01-02 22:52:34 +00004630{
njn22cfccb2004-11-27 16:10:23 +00004631 POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );
mueller6ceb2312004-01-02 22:52:34 +00004632}
4633
nethercote85a456f2004-11-16 17:31:56 +00004634PRE(sys_nanosleep, MayBlock|PostOnFail)
jsgf855d93d2003-10-13 22:26:55 +00004635{
njn22cfccb2004-11-27 16:10:23 +00004636 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004637 PRE_REG_READ2(long, "nanosleep",
4638 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004639 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4640 if (ARG2 != 0)
4641 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004642}
4643
nethercote85a456f2004-11-16 17:31:56 +00004644POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004645{
njn22cfccb2004-11-27 16:10:23 +00004646 if (ARG2 != 0 && RES == -VKI_EINTR)
4647 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004648}
4649
nethercote85a456f2004-11-16 17:31:56 +00004650PRE(sys_open, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004651{
njn22cfccb2004-11-27 16:10:23 +00004652 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004653 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004654 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004655 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004656 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004657 } else {
nethercotee824cc42004-11-09 16:20:46 +00004658 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004659 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004660 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004661 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004662 }
njn22cfccb2004-11-27 16:10:23 +00004663 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004664}
4665
nethercote85a456f2004-11-16 17:31:56 +00004666POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004667{
njn22cfccb2004-11-27 16:10:23 +00004668 if (!VG_(fd_allowed)(RES, "open", tid, True)) {
4669 VG_(close)(RES);
4670 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004671 } else {
nethercote493dd182004-02-24 23:57:47 +00004672 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004673 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004674 }
jsgf855d93d2003-10-13 22:26:55 +00004675}
4676
nethercote85a456f2004-11-16 17:31:56 +00004677PRE(sys_read, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004678{
njn22cfccb2004-11-27 16:10:23 +00004679 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004680 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00004681 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00004682
njn22cfccb2004-11-27 16:10:23 +00004683 if (!VG_(fd_allowed)(ARG1, "read", tid, False))
4684 SET_RESULT( -VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00004685 else
njn22cfccb2004-11-27 16:10:23 +00004686 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004687}
4688
nethercote85a456f2004-11-16 17:31:56 +00004689POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00004690{
njn22cfccb2004-11-27 16:10:23 +00004691 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004692}
4693
nethercote85a456f2004-11-16 17:31:56 +00004694PRE(sys_write, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004695{
njn22cfccb2004-11-27 16:10:23 +00004696 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00004697 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00004698 unsigned int, fd, const char *, buf, vki_size_t, count);
njn22cfccb2004-11-27 16:10:23 +00004699 if (!VG_(fd_allowed)(ARG1, "write", tid, False))
4700 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004701 else
njn22cfccb2004-11-27 16:10:23 +00004702 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004703}
4704
nethercote85a456f2004-11-16 17:31:56 +00004705PRE(sys_creat, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004706{
njn22cfccb2004-11-27 16:10:23 +00004707 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004708 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004709 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004710}
4711
nethercote85a456f2004-11-16 17:31:56 +00004712POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00004713{
njn22cfccb2004-11-27 16:10:23 +00004714 if (!VG_(fd_allowed)(RES, "creat", tid, True)) {
4715 VG_(close)(RES);
4716 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004717 } else {
nethercote493dd182004-02-24 23:57:47 +00004718 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00004719 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
jsgf855d93d2003-10-13 22:26:55 +00004720 }
jsgf855d93d2003-10-13 22:26:55 +00004721}
4722
nethercote9a3beb92004-11-12 17:07:26 +00004723// XXX: sort of x86-specific
nethercote85a456f2004-11-16 17:31:56 +00004724PRE(sys_pipe, 0)
jsgf855d93d2003-10-13 22:26:55 +00004725{
njn22cfccb2004-11-27 16:10:23 +00004726 PRINT("sys_pipe ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004727 PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
njn22cfccb2004-11-27 16:10:23 +00004728 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(long) );
jsgf855d93d2003-10-13 22:26:55 +00004729}
4730
nethercote85a456f2004-11-16 17:31:56 +00004731POST(sys_pipe)
jsgf855d93d2003-10-13 22:26:55 +00004732{
njn22cfccb2004-11-27 16:10:23 +00004733 Int *p = (Int *)ARG1;
jsgf855d93d2003-10-13 22:26:55 +00004734
nethercote3d5e9102004-11-17 18:22:38 +00004735 if (!VG_(fd_allowed)(p[0], "pipe", tid, True) ||
4736 !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
jsgf855d93d2003-10-13 22:26:55 +00004737 VG_(close)(p[0]);
4738 VG_(close)(p[1]);
njn22cfccb2004-11-27 16:10:23 +00004739 SET_RESULT( -VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004740 } else {
njn22cfccb2004-11-27 16:10:23 +00004741 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
nethercote493dd182004-02-24 23:57:47 +00004742 if (VG_(clo_track_fds)) {
nethercote3d5e9102004-11-17 18:22:38 +00004743 VG_(record_fd_open)(tid, p[0], NULL);
4744 VG_(record_fd_open)(tid, p[1], NULL);
rjwalshf5f536f2003-11-17 17:45:00 +00004745 }
4746 }
jsgf855d93d2003-10-13 22:26:55 +00004747}
4748
nethercotef90953e2004-11-15 14:50:02 +00004749// XXX: x86-specific, due to pollfd struct
nethercote85a456f2004-11-16 17:31:56 +00004750PRE(sys_poll, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004751{
4752 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00004753 int fd; -- file descriptor
4754 short events; -- requested events
4755 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00004756 };
nethercoteeb0592d2004-11-05 12:02:27 +00004757 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00004758 */
nethercoteeb0592d2004-11-05 12:02:27 +00004759 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004760 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
4761 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00004762 PRE_REG_READ3(long, "poll",
4763 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
nethercoteef0c7662004-11-06 15:38:43 +00004764
njn22cfccb2004-11-27 16:10:23 +00004765 for (i = 0; i < ARG2; i++) {
nethercoteeb0592d2004-11-05 12:02:27 +00004766 // 'fd' and 'events' field are inputs; 'revents' is output.
4767 // XXX: this is x86 specific -- the pollfd struct varies across
4768 // different architectures.
nethercoteef0c7662004-11-06 15:38:43 +00004769 PRE_MEM_READ( "poll(ufds)",
4770 (Addr)(&ufds[i]), sizeof(int) + sizeof(short) );
4771 PRE_MEM_WRITE( "poll(ufds)", (Addr)(&ufds[i].revents), sizeof(short) );
4772 }
jsgf855d93d2003-10-13 22:26:55 +00004773}
4774
nethercote85a456f2004-11-16 17:31:56 +00004775POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00004776{
njn22cfccb2004-11-27 16:10:23 +00004777 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004778 UInt i;
njn22cfccb2004-11-27 16:10:23 +00004779 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
nethercoteeb0592d2004-11-05 12:02:27 +00004780 // XXX: again, this is x86-specific
njn22cfccb2004-11-27 16:10:23 +00004781 for (i = 0; i < ARG2; i++)
nethercoteef0c7662004-11-06 15:38:43 +00004782 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(Short) );
jsgf855d93d2003-10-13 22:26:55 +00004783 }
4784}
4785
rjwalsh17d85302004-11-18 22:56:09 +00004786PRE(sys_readlink, Special)
jsgf855d93d2003-10-13 22:26:55 +00004787{
rjwalsh093047d2004-11-19 02:11:56 +00004788 int saved = SYSNO;
njn22cfccb2004-11-27 16:10:23 +00004789 PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00004790 PRE_REG_READ3(long, "readlink",
4791 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00004792 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4793 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00004794
rjwalsh17d85302004-11-18 22:56:09 +00004795 /*
rjwalsh093047d2004-11-19 02:11:56 +00004796 * Handle the case where readlink is looking at /proc/self/exe or
4797 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00004798 */
4799
njnca6fef02004-11-29 16:49:18 +00004800 SET_RESULT( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
njn22cfccb2004-11-27 16:10:23 +00004801 if ((Int)RES == -2) {
rjwalsh093047d2004-11-19 02:11:56 +00004802 char name[25];
4803
4804 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
rjwalsh17d85302004-11-18 22:56:09 +00004805
njn22cfccb2004-11-27 16:10:23 +00004806 if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
4807 VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
rjwalsh093047d2004-11-19 02:11:56 +00004808 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
njnca6fef02004-11-29 16:49:18 +00004809 SET_RESULT( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
rjwalsh093047d2004-11-19 02:11:56 +00004810 }
rjwalsh17d85302004-11-18 22:56:09 +00004811 }
4812
njn22cfccb2004-11-27 16:10:23 +00004813 if ((Int)RES > 0)
4814 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00004815}
4816
nethercote85a456f2004-11-16 17:31:56 +00004817PRE(sys_readv, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004818{
jsgf855d93d2003-10-13 22:26:55 +00004819 Int i;
nethercote73b526f2004-10-31 18:48:21 +00004820 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00004821 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00004822 PRE_REG_READ3(ssize_t, "readv",
4823 unsigned long, fd, const struct iovec *, vector,
4824 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00004825 if (!VG_(fd_allowed)(ARG1, "readv", tid, False)) {
4826 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00004827 } else {
njn22cfccb2004-11-27 16:10:23 +00004828 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00004829
njn22cfccb2004-11-27 16:10:23 +00004830 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00004831 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00004832 vec = (struct vki_iovec *)ARG2;
4833 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00004834 PRE_MEM_WRITE( "readv(vector[...])",
4835 (Addr)vec[i].iov_base, vec[i].iov_len );
4836 }
jsgf855d93d2003-10-13 22:26:55 +00004837 }
4838}
4839
nethercote85a456f2004-11-16 17:31:56 +00004840POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00004841{
njn22cfccb2004-11-27 16:10:23 +00004842 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00004843 Int i;
njn22cfccb2004-11-27 16:10:23 +00004844 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
4845 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00004846
njn22cfccb2004-11-27 16:10:23 +00004847 /* RES holds the number of bytes read. */
4848 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00004849 Int nReadThisBuf = vec[i].iov_len;
4850 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00004851 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00004852 remains -= nReadThisBuf;
4853 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4854 }
4855 }
4856}
4857
nethercote85a456f2004-11-16 17:31:56 +00004858PRE(sys_rename, 0)
jsgf855d93d2003-10-13 22:26:55 +00004859{
njn22cfccb2004-11-27 16:10:23 +00004860 PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
nethercote9a3beb92004-11-12 17:07:26 +00004861 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004862 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4863 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00004864}
4865
nethercote85a456f2004-11-16 17:31:56 +00004866PRE(sys_rmdir, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00004867{
njn22cfccb2004-11-27 16:10:23 +00004868 PRINT("sys_rmdir ( %p )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00004869 PRE_REG_READ1(long, "rmdir", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00004870 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004871}
4872
nethercote85a456f2004-11-16 17:31:56 +00004873PRE(sys_sched_setparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004874{
njn22cfccb2004-11-27 16:10:23 +00004875 PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004876 PRE_REG_READ2(long, "sched_setparam",
4877 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004878 PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004879}
4880
nethercote85a456f2004-11-16 17:31:56 +00004881POST(sys_sched_setparam)
jsgf855d93d2003-10-13 22:26:55 +00004882{
njn22cfccb2004-11-27 16:10:23 +00004883 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004884}
4885
nethercote85a456f2004-11-16 17:31:56 +00004886PRE(sys_sched_getparam, 0)
jsgf855d93d2003-10-13 22:26:55 +00004887{
njn22cfccb2004-11-27 16:10:23 +00004888 PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
nethercote5b653bc2004-11-15 14:32:12 +00004889 PRE_REG_READ2(long, "sched_getparam",
4890 vki_pid_t, pid, struct sched_param *, p);
njn22cfccb2004-11-27 16:10:23 +00004891 PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004892}
4893
nethercote85a456f2004-11-16 17:31:56 +00004894POST(sys_sched_getparam)
jsgf855d93d2003-10-13 22:26:55 +00004895{
njn22cfccb2004-11-27 16:10:23 +00004896 POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
jsgf855d93d2003-10-13 22:26:55 +00004897}
4898
nethercote85a456f2004-11-16 17:31:56 +00004899PRE(sys_select, MayBlock)
nethercotef1049bf2004-11-14 17:03:47 +00004900{
njn22cfccb2004-11-27 16:10:23 +00004901 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00004902 PRE_REG_READ5(long, "select",
4903 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4904 vki_fd_set *, exceptfds, struct timeval *, timeout);
4905 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00004906 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004907 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00004908 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4909 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004910 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00004911 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4912 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00004913 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00004914 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4915 if (ARG5 != 0)
4916 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00004917}
4918
nethercote85a456f2004-11-16 17:31:56 +00004919PRE(sys_setgid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004920{
njn22cfccb2004-11-27 16:10:23 +00004921 PRINT("sys_setgid16 ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004922 PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
4923}
4924
nethercote85a456f2004-11-16 17:31:56 +00004925PRE(sys_setgid, 0)
nethercote9c311eb2004-11-12 18:20:12 +00004926{
njn22cfccb2004-11-27 16:10:23 +00004927 PRINT("sys_setgid ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00004928 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
jsgf855d93d2003-10-13 22:26:55 +00004929}
4930
nethercote85a456f2004-11-16 17:31:56 +00004931PRE(sys_setsid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004932{
nethercote0df495a2004-11-11 16:38:21 +00004933 PRINT("sys_setsid ( )");
4934 PRE_REG_READ0(long, "setsid");
jsgf855d93d2003-10-13 22:26:55 +00004935}
4936
nethercote85a456f2004-11-16 17:31:56 +00004937PRE(sys_setgroups16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004938{
njn22cfccb2004-11-27 16:10:23 +00004939 PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004940 PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004941 if (ARG1 > 0)
4942 PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
nethercote686b5db2004-11-14 13:42:51 +00004943}
4944
nethercote85a456f2004-11-16 17:31:56 +00004945PRE(sys_setgroups, 0)
nethercote686b5db2004-11-14 13:42:51 +00004946{
njn22cfccb2004-11-27 16:10:23 +00004947 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
nethercote686b5db2004-11-14 13:42:51 +00004948 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
njn22cfccb2004-11-27 16:10:23 +00004949 if (ARG1 > 0)
4950 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004951}
4952
nethercote85a456f2004-11-16 17:31:56 +00004953PRE(sys_setpgid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004954{
njn22cfccb2004-11-27 16:10:23 +00004955 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
nethercote9c311eb2004-11-12 18:20:12 +00004956 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
jsgf855d93d2003-10-13 22:26:55 +00004957}
4958
nethercote85a456f2004-11-16 17:31:56 +00004959PRE(sys_setregid, 0)
jsgf855d93d2003-10-13 22:26:55 +00004960{
njn22cfccb2004-11-27 16:10:23 +00004961 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004962 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
jsgf855d93d2003-10-13 22:26:55 +00004963}
4964
nethercote85a456f2004-11-16 17:31:56 +00004965PRE(sys_setreuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00004966{
njn22cfccb2004-11-27 16:10:23 +00004967 PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004968 PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
4969}
4970
nethercote85a456f2004-11-16 17:31:56 +00004971PRE(sys_setreuid, 0)
nethercote17258dc2004-11-12 19:55:08 +00004972{
njn22cfccb2004-11-27 16:10:23 +00004973 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004974 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
jsgf855d93d2003-10-13 22:26:55 +00004975}
4976
nethercote85a456f2004-11-16 17:31:56 +00004977PRE(sys_setrlimit, 0)
jsgf855d93d2003-10-13 22:26:55 +00004978{
njn22cfccb2004-11-27 16:10:23 +00004979 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00004980 PRE_REG_READ2(long, "setrlimit",
4981 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00004982 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00004983
njn22cfccb2004-11-27 16:10:23 +00004984 if (ARG1 == VKI_RLIMIT_NOFILE) {
4985 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4986 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4987 SET_RESULT( -VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00004988 }
4989 else {
njn22cfccb2004-11-27 16:10:23 +00004990 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
4991 SET_RESULT( 0 );
thughesad1c9562004-06-26 11:27:52 +00004992 }
4993 }
njn22cfccb2004-11-27 16:10:23 +00004994 else if (ARG1 == VKI_RLIMIT_DATA) {
4995 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
4996 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
4997 SET_RESULT( -VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00004998 }
4999 else {
njn22cfccb2004-11-27 16:10:23 +00005000 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
5001 SET_RESULT( 0 );
thughesaa4fb112004-09-11 14:19:25 +00005002 }
fitzhardingeb50068f2004-02-24 23:42:55 +00005003 }
njn22cfccb2004-11-27 16:10:23 +00005004 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
5005 if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
5006 ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
5007 SET_RESULT( -VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00005008 }
5009 else {
njn50ba34e2005-04-04 02:41:42 +00005010 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
njn22cfccb2004-11-27 16:10:23 +00005011 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
5012 SET_RESULT( 0 );
thughesc37184f2004-09-11 14:16:57 +00005013 }
5014 }
jsgf855d93d2003-10-13 22:26:55 +00005015}
5016
nethercote85a456f2004-11-16 17:31:56 +00005017PRE(sys_setuid16, 0)
jsgf855d93d2003-10-13 22:26:55 +00005018{
njn22cfccb2004-11-27 16:10:23 +00005019 PRINT("sys_setuid16 ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005020 PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
jsgf855d93d2003-10-13 22:26:55 +00005021}
5022
nethercote85a456f2004-11-16 17:31:56 +00005023PRE(sys_setuid, 0)
nethercotec6851dd2004-11-11 18:00:47 +00005024{
njn22cfccb2004-11-27 16:10:23 +00005025 PRINT("sys_setuid ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005026 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
5027}
jsgf855d93d2003-10-13 22:26:55 +00005028
nethercote85a456f2004-11-16 17:31:56 +00005029PRE(sys_socketcall, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005030{
sewardj9efbbef2005-03-01 16:45:23 +00005031# define ARG2_0 (((UWord*)ARG2)[0])
5032# define ARG2_1 (((UWord*)ARG2)[1])
5033# define ARG2_2 (((UWord*)ARG2)[2])
5034# define ARG2_3 (((UWord*)ARG2)[3])
5035# define ARG2_4 (((UWord*)ARG2)[4])
5036# define ARG2_5 (((UWord*)ARG2)[5])
5037
njn22cfccb2004-11-27 16:10:23 +00005038 PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00005039 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
5040
njn22cfccb2004-11-27 16:10:23 +00005041 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00005042
nethercote73b526f2004-10-31 18:48:21 +00005043 case VKI_SYS_SOCKETPAIR:
jsgf855d93d2003-10-13 22:26:55 +00005044 /* int socketpair(int d, int type, int protocol, int sv[2]); */
njn22cfccb2004-11-27 16:10:23 +00005045 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005046 VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00005047 break;
5048
nethercote73b526f2004-10-31 18:48:21 +00005049 case VKI_SYS_SOCKET:
jsgf855d93d2003-10-13 22:26:55 +00005050 /* int socket(int domain, int type, int protocol); */
njn22cfccb2004-11-27 16:10:23 +00005051 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005052 break;
5053
nethercote73b526f2004-10-31 18:48:21 +00005054 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00005055 /* int bind(int sockfd, struct sockaddr *my_addr,
5056 int addrlen); */
njn22cfccb2004-11-27 16:10:23 +00005057 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005058 VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005059 break;
5060
nethercote73b526f2004-10-31 18:48:21 +00005061 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00005062 /* int listen(int s, int backlog); */
njn22cfccb2004-11-27 16:10:23 +00005063 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005064 break;
5065
nethercote73b526f2004-10-31 18:48:21 +00005066 case VKI_SYS_ACCEPT: {
jsgf855d93d2003-10-13 22:26:55 +00005067 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
njn22cfccb2004-11-27 16:10:23 +00005068 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005069 VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005070 break;
5071 }
5072
nethercote73b526f2004-10-31 18:48:21 +00005073 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00005074 /* int sendto(int s, const void *msg, int len,
sewardj9efbbef2005-03-01 16:45:23 +00005075 unsigned int flags,
5076 const struct sockaddr *to, int tolen); */
njn22cfccb2004-11-27 16:10:23 +00005077 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005078 VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005079 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005080 break;
5081
nethercote73b526f2004-10-31 18:48:21 +00005082 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00005083 /* int send(int s, const void *msg, size_t len, int flags); */
njn22cfccb2004-11-27 16:10:23 +00005084 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005085 VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005086 break;
5087
nethercote73b526f2004-10-31 18:48:21 +00005088 case VKI_SYS_RECVFROM:
jsgf855d93d2003-10-13 22:26:55 +00005089 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
5090 struct sockaddr *from, int *fromlen); */
njn22cfccb2004-11-27 16:10:23 +00005091 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005092 VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005093 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005094 break;
5095
nethercote73b526f2004-10-31 18:48:21 +00005096 case VKI_SYS_RECV:
jsgf855d93d2003-10-13 22:26:55 +00005097 /* int recv(int s, void *buf, int len, unsigned int flags); */
5098 /* man 2 recv says:
5099 The recv call is normally used only on a connected socket
5100 (see connect(2)) and is identical to recvfrom with a NULL
5101 from parameter.
5102 */
njn22cfccb2004-11-27 16:10:23 +00005103 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005104 VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005105 break;
5106
nethercote73b526f2004-10-31 18:48:21 +00005107 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00005108 /* int connect(int sockfd,
sewardj9efbbef2005-03-01 16:45:23 +00005109 struct sockaddr *serv_addr, int addrlen ); */
njn22cfccb2004-11-27 16:10:23 +00005110 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005111 VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005112 break;
5113
nethercote73b526f2004-10-31 18:48:21 +00005114 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005115 /* int setsockopt(int s, int level, int optname,
sewardj9efbbef2005-03-01 16:45:23 +00005116 const void *optval, int optlen); */
njn22cfccb2004-11-27 16:10:23 +00005117 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005118 VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005119 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005120 break;
5121
nethercote73b526f2004-10-31 18:48:21 +00005122 case VKI_SYS_GETSOCKOPT:
sewardj9efbbef2005-03-01 16:45:23 +00005123 /* int getsockopt(int s, int level, int optname,
5124 void *optval, socklen_t *optlen); */
njn22cfccb2004-11-27 16:10:23 +00005125 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005126 VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005127 ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005128 break;
5129
nethercote73b526f2004-10-31 18:48:21 +00005130 case VKI_SYS_GETSOCKNAME:
jsgf855d93d2003-10-13 22:26:55 +00005131 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00005132 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005133 VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005134 break;
5135
nethercote73b526f2004-10-31 18:48:21 +00005136 case VKI_SYS_GETPEERNAME:
jsgf855d93d2003-10-13 22:26:55 +00005137 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
njn22cfccb2004-11-27 16:10:23 +00005138 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
sewardj987a8eb2005-03-01 19:00:30 +00005139 VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005140 break;
5141
nethercote73b526f2004-10-31 18:48:21 +00005142 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00005143 /* int shutdown(int s, int how); */
njn22cfccb2004-11-27 16:10:23 +00005144 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005145 break;
5146
nethercote73b526f2004-10-31 18:48:21 +00005147 case VKI_SYS_SENDMSG: {
jsgf855d93d2003-10-13 22:26:55 +00005148 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
5149
5150 /* this causes warnings, and I don't get why. glibc bug?
5151 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00005152 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005153 */
sewardj987a8eb2005-03-01 19:00:30 +00005154 VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00005155 break;
5156 }
5157
nethercote73b526f2004-10-31 18:48:21 +00005158 case VKI_SYS_RECVMSG: {
jsgf855d93d2003-10-13 22:26:55 +00005159 /* int recvmsg(int s, struct msghdr *msg, int flags); */
5160
5161 /* this causes warnings, and I don't get why. glibc bug?
5162 * (after all it's glibc providing the arguments array)
njn22cfccb2004-11-27 16:10:23 +00005163 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
jsgf855d93d2003-10-13 22:26:55 +00005164 */
sewardj987a8eb2005-03-01 19:00:30 +00005165 VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
jsgf855d93d2003-10-13 22:26:55 +00005166 break;
5167 }
5168
5169 default:
njn22cfccb2004-11-27 16:10:23 +00005170 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
5171 SET_RESULT( -VKI_EINVAL );
jsgf17059e02003-10-19 16:46:06 +00005172 break;
jsgf855d93d2003-10-13 22:26:55 +00005173 }
sewardj9efbbef2005-03-01 16:45:23 +00005174# undef ARG2_0
5175# undef ARG2_1
5176# undef ARG2_2
5177# undef ARG2_3
5178# undef ARG2_4
5179# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00005180}
5181
nethercote85a456f2004-11-16 17:31:56 +00005182POST(sys_socketcall)
jsgf855d93d2003-10-13 22:26:55 +00005183{
sewardj9efbbef2005-03-01 16:45:23 +00005184# define ARG2_0 (((UWord*)ARG2)[0])
5185# define ARG2_1 (((UWord*)ARG2)[1])
5186# define ARG2_2 (((UWord*)ARG2)[2])
5187# define ARG2_3 (((UWord*)ARG2)[3])
5188# define ARG2_4 (((UWord*)ARG2)[4])
5189# define ARG2_5 (((UWord*)ARG2)[5])
5190
5191 UWord r;
njn22cfccb2004-11-27 16:10:23 +00005192 switch (ARG1 /* request */) {
jsgf855d93d2003-10-13 22:26:55 +00005193
sewardj9efbbef2005-03-01 16:45:23 +00005194 case VKI_SYS_SOCKETPAIR:
sewardj987a8eb2005-03-01 19:00:30 +00005195 VG_(generic_POST_sys_socketpair)( tid, RES, ARG2_0,
sewardj9efbbef2005-03-01 16:45:23 +00005196 ARG2_1, ARG2_2, ARG2_3 );
jsgf855d93d2003-10-13 22:26:55 +00005197 break;
5198
nethercote73b526f2004-10-31 18:48:21 +00005199 case VKI_SYS_SOCKET:
sewardj987a8eb2005-03-01 19:00:30 +00005200 r = VG_(generic_POST_sys_socket)( tid, RES );
sewardj9efbbef2005-03-01 16:45:23 +00005201 SET_RESULT(r);
5202 break;
jsgf855d93d2003-10-13 22:26:55 +00005203
nethercote73b526f2004-10-31 18:48:21 +00005204 case VKI_SYS_BIND:
jsgf855d93d2003-10-13 22:26:55 +00005205 /* int bind(int sockfd, struct sockaddr *my_addr,
5206 int addrlen); */
5207 break;
5208
nethercote73b526f2004-10-31 18:48:21 +00005209 case VKI_SYS_LISTEN:
jsgf855d93d2003-10-13 22:26:55 +00005210 /* int listen(int s, int backlog); */
5211 break;
5212
sewardj9efbbef2005-03-01 16:45:23 +00005213 case VKI_SYS_ACCEPT:
jsgf855d93d2003-10-13 22:26:55 +00005214 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
sewardj987a8eb2005-03-01 19:00:30 +00005215 r = VG_(generic_POST_sys_accept)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
sewardj9efbbef2005-03-01 16:45:23 +00005216 SET_RESULT(r);
5217 break;
jsgf855d93d2003-10-13 22:26:55 +00005218
nethercote73b526f2004-10-31 18:48:21 +00005219 case VKI_SYS_SENDTO:
jsgf855d93d2003-10-13 22:26:55 +00005220 break;
5221
nethercote73b526f2004-10-31 18:48:21 +00005222 case VKI_SYS_SEND:
jsgf855d93d2003-10-13 22:26:55 +00005223 break;
5224
nethercote73b526f2004-10-31 18:48:21 +00005225 case VKI_SYS_RECVFROM:
sewardj987a8eb2005-03-01 19:00:30 +00005226 VG_(generic_POST_sys_recvfrom)( tid, RES, ARG2_0, ARG2_1, ARG2_2,
sewardj9efbbef2005-03-01 16:45:23 +00005227 ARG2_3, ARG2_4, ARG2_5 );
jsgf855d93d2003-10-13 22:26:55 +00005228 break;
5229
nethercote73b526f2004-10-31 18:48:21 +00005230 case VKI_SYS_RECV:
sewardj987a8eb2005-03-01 19:00:30 +00005231 VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005232 break;
5233
nethercote73b526f2004-10-31 18:48:21 +00005234 case VKI_SYS_CONNECT:
jsgf855d93d2003-10-13 22:26:55 +00005235 break;
5236
nethercote73b526f2004-10-31 18:48:21 +00005237 case VKI_SYS_SETSOCKOPT:
jsgf855d93d2003-10-13 22:26:55 +00005238 break;
5239
nethercote73b526f2004-10-31 18:48:21 +00005240 case VKI_SYS_GETSOCKOPT:
sewardj987a8eb2005-03-01 19:00:30 +00005241 VG_(generic_POST_sys_getsockopt)( tid, RES, ARG2_0, ARG2_1,
sewardj9efbbef2005-03-01 16:45:23 +00005242 ARG2_2, ARG2_3, ARG2_4 );
jsgf855d93d2003-10-13 22:26:55 +00005243 break;
5244
nethercote73b526f2004-10-31 18:48:21 +00005245 case VKI_SYS_GETSOCKNAME:
sewardj987a8eb2005-03-01 19:00:30 +00005246 VG_(generic_POST_sys_getsockname)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005247 break;
5248
nethercote73b526f2004-10-31 18:48:21 +00005249 case VKI_SYS_GETPEERNAME:
sewardj987a8eb2005-03-01 19:00:30 +00005250 VG_(generic_POST_sys_getpeername)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
jsgf855d93d2003-10-13 22:26:55 +00005251 break;
5252
nethercote73b526f2004-10-31 18:48:21 +00005253 case VKI_SYS_SHUTDOWN:
jsgf855d93d2003-10-13 22:26:55 +00005254 break;
5255
nethercote73b526f2004-10-31 18:48:21 +00005256 case VKI_SYS_SENDMSG:
jsgf855d93d2003-10-13 22:26:55 +00005257 break;
5258
nethercote73b526f2004-10-31 18:48:21 +00005259 case VKI_SYS_RECVMSG:
sewardj987a8eb2005-03-01 19:00:30 +00005260 VG_(generic_POST_sys_recvmsg)( tid, RES, ARG2_0, ARG2_1 );
sewardj9efbbef2005-03-01 16:45:23 +00005261 break;
jsgf855d93d2003-10-13 22:26:55 +00005262
5263 default:
njn22cfccb2004-11-27 16:10:23 +00005264 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
jsgf855d93d2003-10-13 22:26:55 +00005265 VG_(core_panic)("... bye!\n");
5266 break; /*NOTREACHED*/
5267 }
sewardj9efbbef2005-03-01 16:45:23 +00005268# undef ARG2_0
5269# undef ARG2_1
5270# undef ARG2_2
5271# undef ARG2_3
5272# undef ARG2_4
5273# undef ARG2_5
jsgf855d93d2003-10-13 22:26:55 +00005274}
5275
nethercote85a456f2004-11-16 17:31:56 +00005276PRE(sys_newstat, 0)
jsgf855d93d2003-10-13 22:26:55 +00005277{
njn22cfccb2004-11-27 16:10:23 +00005278 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005279 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
njn22cfccb2004-11-27 16:10:23 +00005280 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
5281 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005282}
5283
nethercote85a456f2004-11-16 17:31:56 +00005284POST(sys_newstat)
jsgf855d93d2003-10-13 22:26:55 +00005285{
njn22cfccb2004-11-27 16:10:23 +00005286 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
jsgf855d93d2003-10-13 22:26:55 +00005287}
5288
nethercote85a456f2004-11-16 17:31:56 +00005289PRE(sys_statfs, 0)
jsgf855d93d2003-10-13 22:26:55 +00005290{
njn22cfccb2004-11-27 16:10:23 +00005291 PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
nethercotedc18c0a2004-11-14 20:06:27 +00005292 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
njn22cfccb2004-11-27 16:10:23 +00005293 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
5294 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
muellerd3502b62003-11-19 00:43:57 +00005295}
5296
nethercote85a456f2004-11-16 17:31:56 +00005297POST(sys_statfs)
mueller44cbaeb2003-11-19 08:56:44 +00005298{
njn22cfccb2004-11-27 16:10:23 +00005299 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
mueller44cbaeb2003-11-19 08:56:44 +00005300}
5301
nethercote85a456f2004-11-16 17:31:56 +00005302PRE(sys_statfs64, 0)
muellerd3502b62003-11-19 00:43:57 +00005303{
njn22cfccb2004-11-27 16:10:23 +00005304 PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
nethercotedc18c0a2004-11-14 20:06:27 +00005305 PRE_REG_READ3(long, "statfs64",
5306 const char *, path, vki_size_t, size, struct statfs64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005307 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
5308 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00005309}
5310
nethercote85a456f2004-11-16 17:31:56 +00005311POST(sys_statfs64)
muellerd3502b62003-11-19 00:43:57 +00005312{
njn22cfccb2004-11-27 16:10:23 +00005313 POST_MEM_WRITE( ARG3, ARG2 );
muellerd3502b62003-11-19 00:43:57 +00005314}
5315
nethercote85a456f2004-11-16 17:31:56 +00005316PRE(sys_symlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005317{
njn22cfccb2004-11-27 16:10:23 +00005318 PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
nethercote5a945af2004-11-14 18:37:07 +00005319 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00005320 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
5321 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00005322}
5323
njnc6168192004-11-29 13:54:10 +00005324// See comment above PRE(sys_lstat64) for an explanation of this #ifdef.
5325#ifndef __amd64__
nethercote85a456f2004-11-16 17:31:56 +00005326PRE(sys_stat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005327{
njn22cfccb2004-11-27 16:10:23 +00005328 PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005329 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005330 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
5331 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005332}
5333
nethercote85a456f2004-11-16 17:31:56 +00005334POST(sys_stat64)
jsgf855d93d2003-10-13 22:26:55 +00005335{
njn22cfccb2004-11-27 16:10:23 +00005336 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005337}
5338
nethercote85a456f2004-11-16 17:31:56 +00005339PRE(sys_fstat64, 0)
jsgf855d93d2003-10-13 22:26:55 +00005340{
njn22cfccb2004-11-27 16:10:23 +00005341 PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
nethercote2e1c37d2004-11-13 13:57:12 +00005342 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
njn22cfccb2004-11-27 16:10:23 +00005343 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005344}
5345
nethercote85a456f2004-11-16 17:31:56 +00005346POST(sys_fstat64)
jsgf855d93d2003-10-13 22:26:55 +00005347{
njn22cfccb2004-11-27 16:10:23 +00005348 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
jsgf855d93d2003-10-13 22:26:55 +00005349}
njnc6168192004-11-29 13:54:10 +00005350#endif
jsgf855d93d2003-10-13 22:26:55 +00005351
nethercote85a456f2004-11-16 17:31:56 +00005352PRE(sys_time, 0)
jsgf855d93d2003-10-13 22:26:55 +00005353{
5354 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00005355 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005356 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00005357 if (ARG1 != 0) {
5358 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005359 }
5360}
5361
nethercote85a456f2004-11-16 17:31:56 +00005362POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005363{
njn22cfccb2004-11-27 16:10:23 +00005364 if (ARG1 != 0) {
5365 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005366 }
5367}
5368
nethercote85a456f2004-11-16 17:31:56 +00005369PRE(sys_times, 0)
jsgf855d93d2003-10-13 22:26:55 +00005370{
njn22cfccb2004-11-27 16:10:23 +00005371 PRINT("sys_times ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00005372 PRE_REG_READ1(long, "times", struct tms *, buf);
njn22cfccb2004-11-27 16:10:23 +00005373 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005374}
5375
nethercote85a456f2004-11-16 17:31:56 +00005376POST(sys_times)
jsgf855d93d2003-10-13 22:26:55 +00005377{
njn22cfccb2004-11-27 16:10:23 +00005378 if (ARG1 != 0) {
5379 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
jsgf855d93d2003-10-13 22:26:55 +00005380 }
5381}
5382
nethercote85a456f2004-11-16 17:31:56 +00005383PRE(sys_umask, 0)
jsgf855d93d2003-10-13 22:26:55 +00005384{
njn22cfccb2004-11-27 16:10:23 +00005385 PRINT("sys_umask ( %d )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00005386 PRE_REG_READ1(long, "umask", int, mask);
jsgf855d93d2003-10-13 22:26:55 +00005387}
5388
nethercote85a456f2004-11-16 17:31:56 +00005389PRE(sys_unlink, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005390{
njn22cfccb2004-11-27 16:10:23 +00005391 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005392 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00005393 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005394}
5395
nethercote85a456f2004-11-16 17:31:56 +00005396PRE(sys_newuname, 0)
jsgf855d93d2003-10-13 22:26:55 +00005397{
njn22cfccb2004-11-27 16:10:23 +00005398 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00005399 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00005400 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005401}
5402
nethercote85a456f2004-11-16 17:31:56 +00005403POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005404{
njn22cfccb2004-11-27 16:10:23 +00005405 if (ARG1 != 0) {
5406 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005407 }
5408}
5409
nethercote85a456f2004-11-16 17:31:56 +00005410PRE(sys_utime, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005411{
njn22cfccb2004-11-27 16:10:23 +00005412 PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00005413 PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
njn22cfccb2004-11-27 16:10:23 +00005414 PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
5415 if (ARG2 != 0)
5416 PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
jsgf855d93d2003-10-13 22:26:55 +00005417}
5418
nethercote85a456f2004-11-16 17:31:56 +00005419PRE(sys_waitpid, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005420{
njn22cfccb2004-11-27 16:10:23 +00005421 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00005422 PRE_REG_READ3(long, "waitpid",
5423 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005424
njn22cfccb2004-11-27 16:10:23 +00005425 if (ARG2 != (Addr)NULL)
5426 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005427}
5428
nethercote85a456f2004-11-16 17:31:56 +00005429POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005430{
njn22cfccb2004-11-27 16:10:23 +00005431 if (ARG2 != (Addr)NULL)
5432 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005433}
5434
nethercote85a456f2004-11-16 17:31:56 +00005435PRE(sys_wait4, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005436{
njn22cfccb2004-11-27 16:10:23 +00005437 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
jsgf855d93d2003-10-13 22:26:55 +00005438
nethercote7f7e4d12004-11-15 12:28:58 +00005439 PRE_REG_READ4(long, "wait4",
5440 vki_pid_t, pid, unsigned int *, status, int, options,
5441 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00005442 if (ARG2 != (Addr)NULL)
5443 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5444 if (ARG4 != (Addr)NULL)
5445 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005446}
5447
nethercote85a456f2004-11-16 17:31:56 +00005448POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005449{
njn22cfccb2004-11-27 16:10:23 +00005450 if (ARG2 != (Addr)NULL)
5451 POST_MEM_WRITE( ARG2, sizeof(int) );
5452 if (ARG4 != (Addr)NULL)
5453 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005454}
5455
nethercote85a456f2004-11-16 17:31:56 +00005456PRE(sys_writev, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005457{
jsgf855d93d2003-10-13 22:26:55 +00005458 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005459 struct vki_iovec * vec;
njn22cfccb2004-11-27 16:10:23 +00005460 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005461 PRE_REG_READ3(ssize_t, "writev",
5462 unsigned long, fd, const struct iovec *, vector,
5463 unsigned long, count);
njn22cfccb2004-11-27 16:10:23 +00005464 if (!VG_(fd_allowed)(ARG1, "writev", tid, False)) {
5465 SET_RESULT( -VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005466 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005467 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005468 ARG2, ARG3 * sizeof(struct vki_iovec) );
5469 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005470 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005471 vec = (struct vki_iovec *)ARG2;
5472 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005473 PRE_MEM_READ( "writev(vector[...])",
5474 (Addr)vec[i].iov_base, vec[i].iov_len );
5475 }
jsgf855d93d2003-10-13 22:26:55 +00005476 }
5477}
5478
nethercote85a456f2004-11-16 17:31:56 +00005479PRE(sys_utimes, 0)
muellerd3502b62003-11-19 00:43:57 +00005480{
njn22cfccb2004-11-27 16:10:23 +00005481 PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
nethercoteac866b92004-11-15 20:23:15 +00005482 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
njn22cfccb2004-11-27 16:10:23 +00005483 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5484 if (ARG2 != 0)
5485 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
muellerd3502b62003-11-19 00:43:57 +00005486}
5487
nethercote85a456f2004-11-16 17:31:56 +00005488PRE(sys_sched_setaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005489{
njn22cfccb2004-11-27 16:10:23 +00005490 PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005491 PRE_REG_READ3(long, "sched_setaffinity",
5492 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005493 PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005494}
5495
nethercote85a456f2004-11-16 17:31:56 +00005496PRE(sys_sched_getaffinity, 0)
thughes2f8d5f82004-09-11 14:29:19 +00005497{
njn22cfccb2004-11-27 16:10:23 +00005498 PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
nethercote5b653bc2004-11-15 14:32:12 +00005499 PRE_REG_READ3(long, "sched_getaffinity",
5500 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
njn22cfccb2004-11-27 16:10:23 +00005501 PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005502}
5503
nethercote85a456f2004-11-16 17:31:56 +00005504POST(sys_sched_getaffinity)
thughes2f8d5f82004-09-11 14:29:19 +00005505{
njn22cfccb2004-11-27 16:10:23 +00005506 POST_MEM_WRITE(ARG3, ARG2);
thughes2f8d5f82004-09-11 14:29:19 +00005507}
5508
nethercote85a456f2004-11-16 17:31:56 +00005509PRE(sys_acct, 0)
nethercote2bc5a212004-04-10 00:26:10 +00005510{
njn22cfccb2004-11-27 16:10:23 +00005511 PRINT("sys_acct ( %p )", ARG1);
nethercote2b0cae62004-11-12 14:57:34 +00005512 PRE_REG_READ1(long, "acct", const char *, filename);
njn22cfccb2004-11-27 16:10:23 +00005513 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
nethercote2bc5a212004-04-10 00:26:10 +00005514}
5515
nethercote85a456f2004-11-16 17:31:56 +00005516PRE(sys_pause, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005517{
nethercote0df495a2004-11-11 16:38:21 +00005518 PRINT("sys_pause ( )");
5519 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005520}
5521
nethercotea3a2c142004-11-14 14:13:05 +00005522// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005523PRE(sys_sigsuspend, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005524{
thughesc3e85df2004-11-15 09:27:24 +00005525 /* The C library interface to sigsuspend just takes a pointer to
5526 a signal mask but this system call has three arguments - the first
5527 two don't appear to be used by the kernel and are always passed as
5528 zero by glibc and the third is the first word of the signal mask
5529 so only 32 signals are supported.
5530
5531 In fact glibc normally uses rt_sigsuspend if it is available as
5532 that takes a pointer to the signal mask so supports more signals.
5533 */
njn22cfccb2004-11-27 16:10:23 +00005534 PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
thughesd8e00412004-11-14 19:44:25 +00005535 PRE_REG_READ3(int, "sigsuspend",
5536 int, history0, int, history1,
nethercotea3a2c142004-11-14 14:13:05 +00005537 vki_old_sigset_t, mask);
jsgf855d93d2003-10-13 22:26:55 +00005538}
5539
nethercotea3a2c142004-11-14 14:13:05 +00005540// XXX: x86-specific
nethercote85a456f2004-11-16 17:31:56 +00005541PRE(sys_rt_sigsuspend, MayBlock)
nethercotea3a2c142004-11-14 14:13:05 +00005542{
thughesc3e85df2004-11-15 09:27:24 +00005543 /* The C library interface to sigsuspend just takes a pointer to
5544 a signal mask but this system call has two arguments - a pointer
5545 to the mask and the number of bytes used by it. The kernel insists
5546 on the size being equal to sizeof(sigset_t) however and will just
5547 return EINVAL if it isn't.
5548 */
njn22cfccb2004-11-27 16:10:23 +00005549 PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
nethercotea3a2c142004-11-14 14:13:05 +00005550 PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
njn22cfccb2004-11-27 16:10:23 +00005551 if (ARG1 != (Addr)NULL) {
5552 PRE_MEM_READ( "rt_sigsuspend(mask)", ARG1, sizeof(vki_sigset_t) );
nethercotea3a2c142004-11-14 14:13:05 +00005553 }
5554}
jsgf855d93d2003-10-13 22:26:55 +00005555
nethercote85a456f2004-11-16 17:31:56 +00005556PRE(sys_rt_sigtimedwait, MayBlock)
jsgf855d93d2003-10-13 22:26:55 +00005557{
nethercoteac866b92004-11-15 20:23:15 +00005558 PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
njn22cfccb2004-11-27 16:10:23 +00005559 ARG1,ARG2,ARG3,(ULong)ARG4);
nethercoteac866b92004-11-15 20:23:15 +00005560 PRE_REG_READ4(long, "rt_sigtimedwait",
5561 const vki_sigset_t *, set, vki_siginfo_t *, info,
5562 const struct timespec *, timeout, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005563 if (ARG1 != 0)
5564 PRE_MEM_READ( "rt_sigtimedwait(set)", ARG1, sizeof(vki_sigset_t));
5565 if (ARG2 != 0)
5566 PRE_MEM_WRITE( "rt_sigtimedwait(info)", ARG2, sizeof(vki_siginfo_t) );
nethercoteac866b92004-11-15 20:23:15 +00005567 PRE_MEM_READ( "rt_sigtimedwait(timeout)",
njn22cfccb2004-11-27 16:10:23 +00005568 ARG4, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00005569}
5570
nethercote85a456f2004-11-16 17:31:56 +00005571POST(sys_rt_sigtimedwait)
jsgf855d93d2003-10-13 22:26:55 +00005572{
njn22cfccb2004-11-27 16:10:23 +00005573 if (ARG2 != 0)
5574 POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005575}
5576
nethercote85a456f2004-11-16 17:31:56 +00005577PRE(sys_rt_sigqueueinfo, 0)
jsgf855d93d2003-10-13 22:26:55 +00005578{
njn22cfccb2004-11-27 16:10:23 +00005579 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005580 PRE_REG_READ3(long, "rt_sigqueueinfo",
5581 int, pid, int, sig, vki_siginfo_t *, uinfo);
njn22cfccb2004-11-27 16:10:23 +00005582 if (ARG2 != 0)
5583 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
jsgf855d93d2003-10-13 22:26:55 +00005584}
5585
nethercote85a456f2004-11-16 17:31:56 +00005586POST(sys_rt_sigqueueinfo)
jsgf855d93d2003-10-13 22:26:55 +00005587{
sewardjb5f6f512005-03-10 23:59:00 +00005588 PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
5589 PRE_REG_READ3(long, "rt_sigqueueinfo",
5590 int, pid, int, sig, vki_siginfo_t *, uinfo);
5591 if (ARG2 != 0)
5592 PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
5593 if (!VG_(client_signal_OK)(ARG2))
5594 SET_RESULT( -VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00005595}
5596
nethercoteb77dee62004-11-16 17:13:24 +00005597// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005598PRE(sys_sigaltstack, Special)
jsgf855d93d2003-10-13 22:26:55 +00005599{
5600 /* int sigaltstack(const stack_t *ss, stack_t *oss); */
njn22cfccb2004-11-27 16:10:23 +00005601 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005602 PRE_REG_READ2(int, "sigaltstack",
5603 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005604 if (ARG1 != 0) {
5605 PRE_MEM_READ( "sigaltstack(ss)", ARG1, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005606 }
njn22cfccb2004-11-27 16:10:23 +00005607 if (ARG2 != 0) {
5608 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005609 }
5610
njn4fbc86c2005-05-08 00:45:11 +00005611 SET_RESULT( VG_(do_sys_sigaltstack) (tid) );
jsgf855d93d2003-10-13 22:26:55 +00005612}
5613
nethercote85a456f2004-11-16 17:31:56 +00005614POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005615{
njn22cfccb2004-11-27 16:10:23 +00005616 if (RES == 0 && ARG2 != 0)
5617 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005618}
5619
nethercote71f05f32004-11-12 18:49:27 +00005620// XXX: x86-specific
njnb249fd72004-11-29 14:24:57 +00005621PRE(sys_rt_sigaction, Special)
nethercote686b5db2004-11-14 13:42:51 +00005622{
njn22cfccb2004-11-27 16:10:23 +00005623 PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
nethercote686b5db2004-11-14 13:42:51 +00005624 PRE_REG_READ4(long, "rt_sigaction",
5625 int, signum, const struct sigaction *, act,
nethercote85a456f2004-11-16 17:31:56 +00005626 struct sigaction *, oldact, vki_size_t, sigsetsize);
nethercote686b5db2004-11-14 13:42:51 +00005627
njn22cfccb2004-11-27 16:10:23 +00005628 if (ARG2 != 0)
5629 PRE_MEM_READ( "rt_sigaction(act)", ARG2, sizeof(struct vki_sigaction));
5630 if (ARG3 != 0)
5631 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005632
njnb249fd72004-11-29 14:24:57 +00005633 // XXX: doesn't seem right to be calling do_sys_sigaction for
5634 // sys_rt_sigaction... perhaps this function should be renamed
5635 // VG_(do_sys_rt_sigaction)() --njn
sewardjb5f6f512005-03-10 23:59:00 +00005636
5637 SET_RESULT(
5638 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
5639 (struct vki_sigaction *)ARG3)
5640 );
nethercote686b5db2004-11-14 13:42:51 +00005641}
5642
nethercote85a456f2004-11-16 17:31:56 +00005643POST(sys_rt_sigaction)
nethercote686b5db2004-11-14 13:42:51 +00005644{
njn22cfccb2004-11-27 16:10:23 +00005645 if (RES == 0 && ARG3 != 0)
5646 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
nethercote686b5db2004-11-14 13:42:51 +00005647}
jsgf855d93d2003-10-13 22:26:55 +00005648
njnc6168192004-11-29 13:54:10 +00005649// XXX: This syscall is not used on amd64 -- it only provides
5650// sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
5651// This wrapper is only suitable for 32-bit architectures.
5652#ifndef __amd64__
njnb249fd72004-11-29 14:24:57 +00005653PRE(sys_sigprocmask, Special)
jsgf855d93d2003-10-13 22:26:55 +00005654{
sewardj970ac792004-12-31 18:09:32 +00005655 vki_old_sigset_t* set;
5656 vki_old_sigset_t* oldset;
5657 vki_sigset_t bigger_set;
5658 vki_sigset_t bigger_oldset;
5659
njn22cfccb2004-11-27 16:10:23 +00005660 PRINT("sys_sigprocmask ( %d, %p, %p )",ARG1,ARG2,ARG3);
nethercote7fbe08a2004-11-15 19:03:27 +00005661 PRE_REG_READ3(long, "sigprocmask",
5662 int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset);
njn22cfccb2004-11-27 16:10:23 +00005663 if (ARG2 != 0)
5664 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_old_sigset_t));
5665 if (ARG3 != 0)
5666 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005667
njnb249fd72004-11-29 14:24:57 +00005668 // Nb: We must convert the smaller vki_old_sigset_t params into bigger
5669 // vki_sigset_t params.
sewardj970ac792004-12-31 18:09:32 +00005670 set = (vki_old_sigset_t*)ARG2;
5671 oldset = (vki_old_sigset_t*)ARG3;
nethercote7fbe08a2004-11-15 19:03:27 +00005672
sewardj1f276622004-12-06 16:18:58 +00005673 VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t));
5674 VG_(memset)(&bigger_oldset, 0, sizeof(vki_sigset_t));
5675 if (set)
5676 bigger_set.sig[0] = *(vki_old_sigset_t*)set;
nethercote7fbe08a2004-11-15 19:03:27 +00005677
njn4fbc86c2005-05-08 00:45:11 +00005678 SET_RESULT(
5679 VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
5680 set ? &bigger_set : NULL,
5681 oldset ? &bigger_oldset : NULL)
5682 );
nethercote7fbe08a2004-11-15 19:03:27 +00005683
njnb249fd72004-11-29 14:24:57 +00005684 if (oldset)
5685 *oldset = bigger_oldset.sig[0];
nethercote7fbe08a2004-11-15 19:03:27 +00005686}
5687
nethercote85a456f2004-11-16 17:31:56 +00005688POST(sys_sigprocmask)
nethercote7fbe08a2004-11-15 19:03:27 +00005689{
njn22cfccb2004-11-27 16:10:23 +00005690 if (RES == 0 && ARG3 != 0)
5691 POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005692}
njnc6168192004-11-29 13:54:10 +00005693#endif
nethercote7fbe08a2004-11-15 19:03:27 +00005694
njnb249fd72004-11-29 14:24:57 +00005695PRE(sys_rt_sigprocmask, Special)
nethercote7fbe08a2004-11-15 19:03:27 +00005696{
njn22cfccb2004-11-27 16:10:23 +00005697 PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
nethercote7fbe08a2004-11-15 19:03:27 +00005698 PRE_REG_READ4(long, "rt_sigprocmask",
5699 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset,
5700 vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005701 if (ARG2 != 0)
5702 PRE_MEM_READ( "rt_sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
5703 if (ARG3 != 0)
5704 PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
nethercote7fbe08a2004-11-15 19:03:27 +00005705
5706 // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
njn22cfccb2004-11-27 16:10:23 +00005707 if (sizeof(vki_sigset_t) != ARG4)
5708 SET_RESULT( -VKI_EMFILE );
sewardj004e8ca2005-02-28 17:27:04 +00005709 else {
njn4fbc86c2005-05-08 00:45:11 +00005710 SET_RESULT( VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,
5711 (vki_sigset_t*) ARG2,
5712 (vki_sigset_t*) ARG3 )
5713 );
sewardj004e8ca2005-02-28 17:27:04 +00005714 }
jsgf855d93d2003-10-13 22:26:55 +00005715}
5716
nethercote85a456f2004-11-16 17:31:56 +00005717POST(sys_rt_sigprocmask)
jsgf855d93d2003-10-13 22:26:55 +00005718{
njn22cfccb2004-11-27 16:10:23 +00005719 if (RES == 0 && ARG3 != 0)
5720 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005721}
5722
sewardjb5f6f512005-03-10 23:59:00 +00005723PRE(sys_sigpending, 0)
jsgf855d93d2003-10-13 22:26:55 +00005724{
njn22cfccb2004-11-27 16:10:23 +00005725 PRINT( "sys_sigpending ( %p )", ARG1 );
nethercote17258dc2004-11-12 19:55:08 +00005726 PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
njn22cfccb2004-11-27 16:10:23 +00005727 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
jsgf855d93d2003-10-13 22:26:55 +00005728}
5729
nethercote85a456f2004-11-16 17:31:56 +00005730POST(sys_sigpending)
jsgf855d93d2003-10-13 22:26:55 +00005731{
njn22cfccb2004-11-27 16:10:23 +00005732 POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
jsgf855d93d2003-10-13 22:26:55 +00005733}
5734
sewardjb5f6f512005-03-10 23:59:00 +00005735PRE(sys_rt_sigpending, 0)
nethercotea6395d12004-11-15 19:23:46 +00005736{
njn22cfccb2004-11-27 16:10:23 +00005737 PRINT( "sys_rt_sigpending ( %p )", ARG1 );
nethercotea6395d12004-11-15 19:23:46 +00005738 PRE_REG_READ2(long, "rt_sigpending",
5739 vki_sigset_t *, set, vki_size_t, sigsetsize);
njn22cfccb2004-11-27 16:10:23 +00005740 PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
nethercotea6395d12004-11-15 19:23:46 +00005741}
5742
nethercote85a456f2004-11-16 17:31:56 +00005743POST(sys_rt_sigpending)
nethercotea6395d12004-11-15 19:23:46 +00005744{
njn22cfccb2004-11-27 16:10:23 +00005745 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
nethercotea6395d12004-11-15 19:23:46 +00005746}
jsgf855d93d2003-10-13 22:26:55 +00005747
nethercote85a456f2004-11-16 17:31:56 +00005748PRE(sys_mq_open, 0)
thughes8579b102004-08-14 18:52:27 +00005749{
nethercote330abb52004-11-16 12:58:04 +00005750 PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
njn22cfccb2004-11-27 16:10:23 +00005751 ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
nethercote330abb52004-11-16 12:58:04 +00005752 PRE_REG_READ4(long, "mq_open",
5753 const char *, name, int, oflag, vki_mode_t, mode,
5754 struct mq_attr *, attr);
njn22cfccb2004-11-27 16:10:23 +00005755 PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
5756 if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
5757 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
nethercoteef0c7662004-11-06 15:38:43 +00005758 PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
thughes8579b102004-08-14 18:52:27 +00005759 (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
nethercoteef0c7662004-11-06 15:38:43 +00005760 PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
thughes8579b102004-08-14 18:52:27 +00005761 (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
5762 }
5763}
5764
nethercote85a456f2004-11-16 17:31:56 +00005765POST(sys_mq_open)
thughes8579b102004-08-14 18:52:27 +00005766{
njn22cfccb2004-11-27 16:10:23 +00005767 if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
5768 VG_(close)(RES);
5769 SET_RESULT( -VKI_EMFILE );
thughes8579b102004-08-14 18:52:27 +00005770 } else {
5771 if (VG_(clo_track_fds))
njn22cfccb2004-11-27 16:10:23 +00005772 VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
thughes8579b102004-08-14 18:52:27 +00005773 }
thughes8579b102004-08-14 18:52:27 +00005774}
5775
nethercote85a456f2004-11-16 17:31:56 +00005776PRE(sys_mq_unlink, 0)
thughes8579b102004-08-14 18:52:27 +00005777{
njn22cfccb2004-11-27 16:10:23 +00005778 PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
nethercote330abb52004-11-16 12:58:04 +00005779 PRE_REG_READ1(long, "mq_unlink", const char *, name);
njn22cfccb2004-11-27 16:10:23 +00005780 PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
thughes8579b102004-08-14 18:52:27 +00005781}
5782
nethercote85a456f2004-11-16 17:31:56 +00005783PRE(sys_mq_timedsend, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005784{
nethercote330abb52004-11-16 12:58:04 +00005785 PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
njn22cfccb2004-11-27 16:10:23 +00005786 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005787 PRE_REG_READ5(long, "mq_timedsend",
5788 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
5789 unsigned int, msg_prio, const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005790 if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
5791 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005792 } else {
njn22cfccb2004-11-27 16:10:23 +00005793 PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
5794 if (ARG5 != 0)
5795 PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
nethercote73b526f2004-10-31 18:48:21 +00005796 sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005797 }
5798}
5799
nethercote85a456f2004-11-16 17:31:56 +00005800PRE(sys_mq_timedreceive, MayBlock)
thughes8579b102004-08-14 18:52:27 +00005801{
nethercote330abb52004-11-16 12:58:04 +00005802 PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
njn22cfccb2004-11-27 16:10:23 +00005803 ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
nethercote330abb52004-11-16 12:58:04 +00005804 PRE_REG_READ5(ssize_t, "mq_timedreceive",
5805 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
5806 unsigned int *, msg_prio,
5807 const struct timespec *, abs_timeout);
njn22cfccb2004-11-27 16:10:23 +00005808 if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
5809 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005810 } else {
njn22cfccb2004-11-27 16:10:23 +00005811 PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
5812 if (ARG4 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005813 PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
njn22cfccb2004-11-27 16:10:23 +00005814 ARG4, sizeof(unsigned int) );
5815 if (ARG5 != 0)
nethercoteef0c7662004-11-06 15:38:43 +00005816 PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
njn22cfccb2004-11-27 16:10:23 +00005817 ARG5, sizeof(struct vki_timespec) );
thughes8579b102004-08-14 18:52:27 +00005818 }
5819}
5820
nethercote85a456f2004-11-16 17:31:56 +00005821POST(sys_mq_timedreceive)
thughes8579b102004-08-14 18:52:27 +00005822{
njn22cfccb2004-11-27 16:10:23 +00005823 POST_MEM_WRITE( ARG2, ARG3 );
5824 if (ARG4 != 0)
5825 POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
thughes8579b102004-08-14 18:52:27 +00005826}
5827
nethercote85a456f2004-11-16 17:31:56 +00005828PRE(sys_mq_notify, 0)
thughes8579b102004-08-14 18:52:27 +00005829{
njn22cfccb2004-11-27 16:10:23 +00005830 PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
nethercote330abb52004-11-16 12:58:04 +00005831 PRE_REG_READ2(long, "mq_notify",
5832 vki_mqd_t, mqdes, const struct sigevent *, notification);
njn22cfccb2004-11-27 16:10:23 +00005833 if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
5834 SET_RESULT( -VKI_EBADF );
5835 else if (ARG2 != 0)
nethercote330abb52004-11-16 12:58:04 +00005836 PRE_MEM_READ( "mq_notify(notification)",
njn22cfccb2004-11-27 16:10:23 +00005837 ARG2, sizeof(struct vki_sigevent) );
thughes8579b102004-08-14 18:52:27 +00005838}
5839
nethercote85a456f2004-11-16 17:31:56 +00005840PRE(sys_mq_getsetattr, 0)
thughes8579b102004-08-14 18:52:27 +00005841{
njn22cfccb2004-11-27 16:10:23 +00005842 PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
nethercote330abb52004-11-16 12:58:04 +00005843 PRE_REG_READ3(long, "mq_getsetattr",
5844 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
5845 struct mq_attr *, omqstat);
njn22cfccb2004-11-27 16:10:23 +00005846 if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
5847 SET_RESULT( -VKI_EBADF );
thughes8579b102004-08-14 18:52:27 +00005848 } else {
njn22cfccb2004-11-27 16:10:23 +00005849 if (ARG2 != 0) {
5850 const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
nethercoteef0c7662004-11-06 15:38:43 +00005851 PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
thughes8579b102004-08-14 18:52:27 +00005852 (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
5853 }
njn22cfccb2004-11-27 16:10:23 +00005854 if (ARG3 != 0)
5855 PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
thughes8579b102004-08-14 18:52:27 +00005856 sizeof(struct vki_mq_attr) );
5857 }
5858}
5859
nethercote85a456f2004-11-16 17:31:56 +00005860POST(sys_mq_getsetattr)
thughes8579b102004-08-14 18:52:27 +00005861{
njn22cfccb2004-11-27 16:10:23 +00005862 if (ARG3 != 0)
5863 POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
thughes8579b102004-08-14 18:52:27 +00005864}
5865
nethercote85a456f2004-11-16 17:31:56 +00005866PRE(sys_timer_create, 0)
thughese1a925d2004-08-30 19:50:02 +00005867{
njn22cfccb2004-11-27 16:10:23 +00005868 PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
nethercote92b2fd52004-11-16 16:15:41 +00005869 PRE_REG_READ3(long, "timer_create",
5870 vki_clockid_t, clockid, struct sigevent *, evp,
5871 vki_timer_t *, timerid);
njn22cfccb2004-11-27 16:10:23 +00005872 if (ARG2 != 0)
5873 PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
5874 PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005875}
5876
nethercote85a456f2004-11-16 17:31:56 +00005877POST(sys_timer_create)
thughese1a925d2004-08-30 19:50:02 +00005878{
njn22cfccb2004-11-27 16:10:23 +00005879 POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
thughese1a925d2004-08-30 19:50:02 +00005880}
5881
nethercote85a456f2004-11-16 17:31:56 +00005882PRE(sys_timer_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005883{
njn22cfccb2004-11-27 16:10:23 +00005884 PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
nethercote92b2fd52004-11-16 16:15:41 +00005885 PRE_REG_READ4(long, "timer_settime",
5886 vki_timer_t, timerid, int, flags,
5887 const struct itimerspec *, value,
5888 struct itimerspec *, ovalue);
njn22cfccb2004-11-27 16:10:23 +00005889 PRE_MEM_READ( "timer_settime(value)", ARG3,
thughese1a925d2004-08-30 19:50:02 +00005890 sizeof(struct vki_itimerspec) );
njn22cfccb2004-11-27 16:10:23 +00005891 if (ARG4 != 0)
5892 PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
thughese1a925d2004-08-30 19:50:02 +00005893 sizeof(struct vki_itimerspec) );
5894}
5895
nethercote85a456f2004-11-16 17:31:56 +00005896POST(sys_timer_settime)
thughese1a925d2004-08-30 19:50:02 +00005897{
njn22cfccb2004-11-27 16:10:23 +00005898 if (ARG4 != 0)
5899 POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005900}
5901
nethercote85a456f2004-11-16 17:31:56 +00005902PRE(sys_timer_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005903{
njn22cfccb2004-11-27 16:10:23 +00005904 PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005905 PRE_REG_READ2(long, "timer_gettime",
5906 vki_timer_t, timerid, struct itimerspec *, value);
njn22cfccb2004-11-27 16:10:23 +00005907 PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
thughese1a925d2004-08-30 19:50:02 +00005908 sizeof(struct vki_itimerspec));
5909}
5910
nethercote85a456f2004-11-16 17:31:56 +00005911POST(sys_timer_gettime)
thughese1a925d2004-08-30 19:50:02 +00005912{
njn22cfccb2004-11-27 16:10:23 +00005913 POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
thughese1a925d2004-08-30 19:50:02 +00005914}
5915
nethercote85a456f2004-11-16 17:31:56 +00005916PRE(sys_timer_getoverrun, 0)
thughese1a925d2004-08-30 19:50:02 +00005917{
njn22cfccb2004-11-27 16:10:23 +00005918 PRINT("sys_timer_getoverrun( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005919 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005920}
5921
nethercote85a456f2004-11-16 17:31:56 +00005922PRE(sys_timer_delete, 0)
thughese1a925d2004-08-30 19:50:02 +00005923{
njn22cfccb2004-11-27 16:10:23 +00005924 PRINT("sys_timer_delete( %p )", ARG1);
nethercote92b2fd52004-11-16 16:15:41 +00005925 PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
thughese1a925d2004-08-30 19:50:02 +00005926}
5927
nethercote85a456f2004-11-16 17:31:56 +00005928PRE(sys_clock_settime, 0)
thughese1a925d2004-08-30 19:50:02 +00005929{
njn22cfccb2004-11-27 16:10:23 +00005930 PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005931 PRE_REG_READ2(long, "clock_settime",
5932 vki_clockid_t, clk_id, const struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005933 PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005934}
5935
nethercote85a456f2004-11-16 17:31:56 +00005936PRE(sys_clock_gettime, 0)
thughese1a925d2004-08-30 19:50:02 +00005937{
njn22cfccb2004-11-27 16:10:23 +00005938 PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
nethercote92b2fd52004-11-16 16:15:41 +00005939 PRE_REG_READ2(long, "clock_gettime",
5940 vki_clockid_t, clk_id, struct timespec *, tp);
njn22cfccb2004-11-27 16:10:23 +00005941 PRE_MEM_WRITE( "clock_gettime(tp)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005942}
5943
nethercote85a456f2004-11-16 17:31:56 +00005944POST(sys_clock_gettime)
thughese1a925d2004-08-30 19:50:02 +00005945{
njn22cfccb2004-11-27 16:10:23 +00005946 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005947}
5948
nethercote85a456f2004-11-16 17:31:56 +00005949PRE(sys_clock_getres, 0)
thughese1a925d2004-08-30 19:50:02 +00005950{
njn22cfccb2004-11-27 16:10:23 +00005951 PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
5952 // Nb: we can't use "RES" as the param name because that's a macro
nethercote92b2fd52004-11-16 16:15:41 +00005953 // defined above!
5954 PRE_REG_READ2(long, "clock_getres",
njne1268d32004-11-27 16:57:18 +00005955 vki_clockid_t, clk_id, struct timespec *, res);
5956 PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005957}
5958
nethercote85a456f2004-11-16 17:31:56 +00005959POST(sys_clock_getres)
thughese1a925d2004-08-30 19:50:02 +00005960{
njn22cfccb2004-11-27 16:10:23 +00005961 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
thughese1a925d2004-08-30 19:50:02 +00005962}
5963
nethercote4fa681f2004-11-08 17:51:39 +00005964
5965/* ---------------------------------------------------------------------
nethercote8ff888f2004-11-17 17:11:45 +00005966 Executing the syscalls
nethercote4fa681f2004-11-08 17:51:39 +00005967 ------------------------------------------------------------------ */
5968
nethercote85a456f2004-11-16 17:31:56 +00005969static UInt bad_flags = Special;
jsgf855d93d2003-10-13 22:26:55 +00005970static void bad_before(ThreadId tid, ThreadState *tst)
5971{
5972 VG_(message)
nethercote44d9aaa2004-11-04 19:38:14 +00005973 (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
fitzhardinge98abfc72003-12-16 02:05:15 +00005974 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +00005975 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge98abfc72003-12-16 02:05:15 +00005976 }
jsgf855d93d2003-10-13 22:26:55 +00005977 VG_(message)
5978 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
5979 VG_(message)
5980 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
5981
njn22cfccb2004-11-27 16:10:23 +00005982 SET_RESULT( -VKI_ENOSYS );
jsgf855d93d2003-10-13 22:26:55 +00005983}
5984
nethercote8ff888f2004-11-17 17:11:45 +00005985static const struct SyscallTableEntry bad_sys =
5986 { &bad_flags, bad_before, NULL };
nethercote64220ff2004-11-10 17:43:43 +00005987
sewardjb5f6f512005-03-10 23:59:00 +00005988static const struct SyscallTableEntry *get_syscall_entry(UInt syscallno)
5989{
5990 const struct SyscallTableEntry *sys;
nethercote4fa681f2004-11-08 17:51:39 +00005991
sewardjb5f6f512005-03-10 23:59:00 +00005992 if (syscallno < VGA_(syscall_table_size) &&
5993 VGA_(syscall_table)[syscallno].before != NULL)
5994 sys = &VGA_(syscall_table)[syscallno];
5995 else
5996 sys = &bad_sys;
5997
5998 return sys;
5999}
6000
6001/* Perform post-syscall actions */
6002void VG_(post_syscall) (ThreadId tid)
6003{
6004 const struct SyscallTableEntry *sys;
6005 UInt flags;
6006 Bool mayBlock;
6007 ThreadState *tst = VG_(get_ThreadState)(tid);
6008 Int syscallno;
6009
6010 vg_assert(VG_(is_running_thread)(tid));
6011
6012 syscallno = tst->syscallno;
6013 tst->syscallno = -1;
6014
6015 vg_assert(syscallno != -1);
6016
6017 sys = get_syscall_entry(syscallno);
6018 flags = *(sys->flags_ptr);
6019
6020 mayBlock = !!( flags & MayBlock );
6021
6022 if (sys->after != NULL &&
6023 ((flags & PostOnFail) != 0 || !VG_(is_kerror)(RES))) {
6024 if (0)
6025 VG_(printf)("post_syscall: calling sys_after tid=%d syscallno=%d\n",
6026 tid, syscallno);
6027 (sys->after)(tid, tst);
6028 }
6029
6030 /* Do any post-syscall actions
6031
6032 NOTE: this is only called if the syscall completed. If the
6033 syscall was restarted, then it will call the Tool's
6034 pre_syscall again, without calling post_syscall (ie, more
6035 pre's than post's) */
6036 if (VG_(needs).syscall_wrapper) {
6037 //VGP_PUSHCC(VgpSkinSysWrap);
6038 TL_(post_syscall)(tid, syscallno, RES);
6039 //VGP_POPCC(VgpSkinSysWrap);
6040 }
6041}
6042
6043
6044void VG_(client_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00006045{
sewardj018f7622002-05-15 21:13:39 +00006046 ThreadState* tst;
nethercotec8734892004-11-10 18:57:37 +00006047 UInt syscallno, flags;
nethercote8ff888f2004-11-17 17:11:45 +00006048 const struct SyscallTableEntry *sys;
nethercote1fe55d62004-11-12 11:02:00 +00006049 Bool isSpecial = False;
6050 Bool mayBlock = False;
6051 Bool runInLWP = False;
jsgf855d93d2003-10-13 22:26:55 +00006052 Bool syscall_done = False; /* we actually ran the syscall */
sewardjde4a1d02002-03-22 01:27:54 +00006053
njn25e49d8e72002-09-23 09:36:25 +00006054 VGP_PUSHCC(VgpCoreSysWrap);
sewardjde4a1d02002-03-22 01:27:54 +00006055
jsgf855d93d2003-10-13 22:26:55 +00006056 tst = VG_(get_ThreadState)(tid);
sewardj018f7622002-05-15 21:13:39 +00006057
nethercote44d9aaa2004-11-04 19:38:14 +00006058 syscallno = (UInt)SYSNO;
jsgf855d93d2003-10-13 22:26:55 +00006059
jsgf855d93d2003-10-13 22:26:55 +00006060 /* the syscall no is in %eax. For syscalls with <= 6 args,
6061 args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
6062 For calls with > 6 args, %ebx points to a lump of memory
sewardjde4a1d02002-03-22 01:27:54 +00006063 containing the args.
6064
6065 The result is returned in %eax. If this value >= 0, the call
6066 succeeded, and this is the return value. If < 0, it failed, and
6067 the negation of this value is errno. To be more specific,
njn22cfccb2004-11-27 16:10:23 +00006068 if RES is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
sewardjde4a1d02002-03-22 01:27:54 +00006069 (kernel 2.4.9 sources, include/asm-i386/errno.h)
6070 then it indicates an error. Otherwise it doesn't.
6071
6072 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
6073 (inclusive?) indicate error returns. Not sure where the -4095
6074 comes from.
6075 */
6076
sewardjb5f6f512005-03-10 23:59:00 +00006077 vg_assert(VG_(is_running_thread)(tid));
6078 vg_assert(tst->syscallno == -1);
jsgf855d93d2003-10-13 22:26:55 +00006079 tst->syscallno = syscallno;
sewardjde4a1d02002-03-22 01:27:54 +00006080
sewardjb5f6f512005-03-10 23:59:00 +00006081 /* Make sure the tmp signal mask matches the real signal
6082 mask; sigsuspend may change this. */
sewardj62601592005-03-26 13:48:19 +00006083 vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
sewardjb5f6f512005-03-10 23:59:00 +00006084
6085 sys = get_syscall_entry(syscallno);
nethercote85a456f2004-11-16 17:31:56 +00006086 flags = *(sys->flags_ptr);
sewardjde4a1d02002-03-22 01:27:54 +00006087
sewardjb5f6f512005-03-10 23:59:00 +00006088 /* !! is standard idiom to turn an int->bool */
6089 isSpecial = !!( flags & Special );
6090 mayBlock = !!( flags & MayBlock );
6091 // At most one of these should be true
6092 vg_assert( isSpecial + mayBlock <= 1 );
nethercotec8734892004-11-10 18:57:37 +00006093
jsgf855d93d2003-10-13 22:26:55 +00006094 /* Do any pre-syscall actions */
6095 if (VG_(needs).syscall_wrapper) {
njn4be0a692004-11-22 18:10:36 +00006096 VGP_PUSHCC(VgpToolSysWrap);
njn31ebc3f2004-11-22 19:57:39 +00006097 TL_(pre_syscall)(tid, syscallno);
njn4be0a692004-11-22 18:10:36 +00006098 VGP_POPCC(VgpToolSysWrap);
jsgf855d93d2003-10-13 22:26:55 +00006099 }
6100
nethercoteef0c7662004-11-06 15:38:43 +00006101 PRINT("SYSCALL[%d,%d](%3d)%s%s:",
6102 VG_(getpid)(), tid, syscallno,
nethercotec8734892004-11-10 18:57:37 +00006103 isSpecial ? " special" : "",
nethercote1fe55d62004-11-12 11:02:00 +00006104 runInLWP ? " runInLWP" : "");
jsgf855d93d2003-10-13 22:26:55 +00006105
sewardjb5f6f512005-03-10 23:59:00 +00006106 tst->syscall_result_set = False;
6107
nethercotec8734892004-11-10 18:57:37 +00006108 if (isSpecial) {
jsgf855d93d2003-10-13 22:26:55 +00006109 /* "Special" syscalls are implemented by Valgrind internally,
6110 and do not generate real kernel calls. The expectation,
6111 therefore, is that the "before" function not only does the
6112 appropriate tests, but also performs the syscall itself and
6113 sets the result. Special syscalls cannot block. */
nethercote1fe55d62004-11-12 11:02:00 +00006114 vg_assert(!mayBlock && !runInLWP);
jsgf855d93d2003-10-13 22:26:55 +00006115
6116 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00006117 /* This *must* result in tst->syscall_result_set becoming
6118 True. */
jsgf855d93d2003-10-13 22:26:55 +00006119
sewardjb5f6f512005-03-10 23:59:00 +00006120 // vg_assert(tst->sys_flags == flags);
sewardj004e8ca2005-02-28 17:27:04 +00006121 vg_assert(tst->syscall_result_set == True);
thughesbaa46e52004-07-29 17:44:23 +00006122
njn22cfccb2004-11-27 16:10:23 +00006123 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006124 syscall_done = True;
6125 } else {
6126 (sys->before)(tst->tid, tst);
sewardja93f66a2005-02-28 20:50:29 +00006127 /* This *may* result in tst->syscall_result_set becoming
6128 True. */
jsgf855d93d2003-10-13 22:26:55 +00006129
sewardj004e8ca2005-02-28 17:27:04 +00006130 if (tst->syscall_result_set) {
6131 /* "before" decided to provide a syscall result itself, so
6132 don't do anything - just pretend the syscall happened. */
6133 PRINT(" ==> %lld (0x%llx)\n", (Long)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006134 syscall_done = True;
sewardjb5f6f512005-03-10 23:59:00 +00006135 } else if (mayBlock) {
6136 vki_sigset_t mask;
6137
6138 vg_assert(!(flags & PadAddr));
6139
6140 /* Syscall may block, so run it asynchronously */
nethercoteef0c7662004-11-06 15:38:43 +00006141 PRINT(" --> ...\n");
sewardjb5f6f512005-03-10 23:59:00 +00006142
6143 mask = tst->sig_mask;
6144 VG_(sanitize_client_sigmask)(tid, &mask);
6145
6146 VG_(set_sleeping)(tid, VgTs_WaitSys);
6147 VGA_(client_syscall)(syscallno, tst, &mask);
6148 /* VGA_(client_syscall) may not return if the syscall was
6149 interrupted by a signal. In that case, flow of control
6150 will end up back in the scheduler via the signal
6151 machinery. */
6152 VG_(set_running)(tid);
njn6f46a302005-03-11 05:07:16 +00006153 PRINT("SYSCALL[%d,%d](%3d) --> %lld (0x%llx)\n",
sewardjb5f6f512005-03-10 23:59:00 +00006154 VG_(getpid)(), tid, syscallno, (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006155 } else {
6156 /* run the syscall directly */
sewardjb5f6f512005-03-10 23:59:00 +00006157 if (flags & PadAddr)
6158 VG_(pad_address_space)(VG_(client_end));
6159
njnca6fef02004-11-29 16:49:18 +00006160 RES = VG_(do_syscall6)(syscallno, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
njn22cfccb2004-11-27 16:10:23 +00006161 PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
jsgf855d93d2003-10-13 22:26:55 +00006162 syscall_done = True;
6163 }
6164 }
6165
sewardjb5f6f512005-03-10 23:59:00 +00006166 vg_assert(VG_(is_running_thread)(tid));
jsgf855d93d2003-10-13 22:26:55 +00006167
njn4fbc86c2005-05-08 00:45:11 +00006168 // The RES part is redundant -- we're assigning the value to itself --
6169 // but we need this call to tell the tool that the assignment has
6170 // occurred.
sewardjb5f6f512005-03-10 23:59:00 +00006171 SET_SYSCALL_RETVAL(tid, RES);
fitzhardingef0f911c2003-11-09 09:51:33 +00006172
sewardjb5f6f512005-03-10 23:59:00 +00006173 VG_(post_syscall)(tid);
jsgf855d93d2003-10-13 22:26:55 +00006174
sewardjb5f6f512005-03-10 23:59:00 +00006175 if (flags & PadAddr) {
6176 vg_assert(!mayBlock);
6177 VG_(unpad_address_space)(VG_(client_end));
6178 //VG_(sanity_check_memory)();
fitzhardingee1c06d82003-10-30 07:21:44 +00006179 }
6180
sewardjb5f6f512005-03-10 23:59:00 +00006181 /* VG_(post_syscall) should set this */
6182 vg_assert(tst->syscallno == -1);
sewardj2e93c502002-04-12 11:12:52 +00006183
njn25e49d8e72002-09-23 09:36:25 +00006184 VGP_POPCC(VgpCoreSysWrap);
sewardj2e93c502002-04-12 11:12:52 +00006185}
6186
sewardjde4a1d02002-03-22 01:27:54 +00006187/*--------------------------------------------------------------------*/
nethercote8ff888f2004-11-17 17:11:45 +00006188/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00006189/*--------------------------------------------------------------------*/
njnb94b81e2003-09-09 11:27:59 +00006190